#!/usr/bin/python3 import tkinter as tk from select import select from subprocess import check_call from tkinter import * from pathlib import Path from tkinter import ttk from wg_func import (TunnelActiv, ListTunnels, ImportTunnel, ConToDict, GreenLabel, ShowAddress, FileHandle, ExportTunnels, OnOff, msg_window, WirePyUpdate, res, version, path_to_file2, path_to_file3, MyToolTip) tcl_path = Path('/usr/share/TK-Themes') class MainWindow(tk.Tk): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.my_tool_tip = None self.switch_on = None self.switch_off = None self.x_width = 600 self.y_height = 400 self.monitor_center_x = self.winfo_screenwidth() / 2 - (self.x_width / 2) self.monitor_center_y = self.winfo_screenheight() / 2 - (self.y_height / 2) self.resizable(width=False, height=False) self.title('Wire-Py') self.geometry('%dx%d+%d+%d' % (self.x_width, self.y_height, self.monitor_center_x, self.monitor_center_y)) self.style = ttk.Style(self) self.tk.call('source', str(tcl_path) + '/water.tcl') #self.tk.call('source', 'TK-Themes/water.tcl') with open(path_to_file3, 'r') as read_file: if 'light' in read_file: self.tk.call('set_theme', 'light') else: self.tk.call('set_theme', 'dark') ''' Load the image file from disk. ''' self.wg_icon = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_vpn.png') # Set it as the window icon. self.iconphoto(True, self.wg_icon) #Set on or off in file def on_off(): if set_option.get() == 1: with open(path_to_file2, 'w') as set_file2: set_file2.write('Update off') if set_option.get() == 0: with open(path_to_file2, 'w') as set_file2: set_file2.write('Update on') # Set dark or light def theme_change_light(): if self.tk.call("ttk::style", "theme", "use") == "water-dark": # Set light theme self.tk.call('set_theme', 'light') with open(path_to_file3, 'w') as theme_set2: theme_set2.write('light') def theme_change_dark(): if not self.tk.call("ttk::style", "theme", "use") == "water-dark": # Set dark theme self.tk.call('set_theme', 'dark') with open(path_to_file3, 'w') as theme_set2: theme_set2.write('dark') def instruction(): """img_w, img_i, w_title, w_txt hand over""" iw = r'/usr/share/icons/wp-icons/48/wg_vpn.png' ii = r'/usr/share/icons/wp-icons/48/wg_msg.png' wt = 'Instruction' msg_t = 'Here comes the instructions for Wire-Py' msg_window(iw, ii, wt, msg_t) ''' Frame for Menu ''' self.menu_frame = ttk.Frame(self) self.menu_frame.configure(relief='flat') self.menu_frame.grid(column=0, row=0, sticky='w') self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) # App Menu self.version_lb = ttk.Label(self.menu_frame, text=version) self.version_lb.config(font=('Ubuntu', 11), foreground='#00c4ff') self.version_lb.grid(column=0, row=0, padx=10) def version_mouse_enter(event): """ The mouse moves into the Version widget """ window.my_tool_tip = MyToolTip(event.x_root, event.y_root, f'Version: {version[2:]}') def version_mouse_leave(event): """ The mouse moves from the entry widget """ ''' Remove Tool-Tip ''' window.my_tool_tip.destroy() self.options_btn = ttk.Menubutton(self.menu_frame, text='Options') self.options_btn.grid(column=1, row=0) def sets_mouse_enter(event): """ The mouse moves into the entry widget """ window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'Click for Settings') def sets_mouse_leave(event): """ The mouse moves from the entry widget """ ''' Remove Tool-Tip ''' window.my_tool_tip.destroy() self.version_lb.bind('', version_mouse_enter) self.version_lb.bind('', version_mouse_leave) self.options_btn.bind('', sets_mouse_enter) self.options_btn.bind('', sets_mouse_leave) set_option = tk.IntVar() self.settings = tk.Menu(self) self.options_btn.configure(menu=self.settings, style='Toolbutton') self.settings.add_checkbutton(label='Disable updates', command=on_off, variable=set_option) self.settings.add_command(label='Light', command=theme_change_light) self.settings.add_command(label='Dark', command=theme_change_dark) ''' Help BTN Menu / Label ''' self.help_btn = ttk.Menubutton(self.menu_frame, text='Help') self.help_btn.grid(column=2, row=0) def help_mouse_enter(event): """ The mouse moves into the entry widget """ window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'Click for Help') def help_mouse_leave(event): """ The mouse moves from the entry widget """ ''' Remove Tool-Tip ''' window.my_tool_tip.destroy() self.help_btn.bind('', help_mouse_enter) self.help_btn.bind('', help_mouse_leave) self.readme = tk.Menu(self) self.help_btn.configure(menu=self.readme, style='Toolbutton') self.readme.add_command(label='Instruction', command=instruction) ''' Update Label ''' self.updates_lb = ttk.Label(self.menu_frame) self.updates_lb.grid(column=3, row=0, padx=10) if res == 'False': set_option.set(value=1) self.updates_lb.configure(text='Update search off') def disable_mouse_enter(event): """ The mouse moves into the entry widget """ window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'Updates you have disabled') def disable_mouse_leave(event): """ The mouse moves from the entry widget """ ''' Remove Tool-Tip ''' window.my_tool_tip.destroy() self.updates_lb.bind('', disable_mouse_enter) self.updates_lb.bind('', disable_mouse_leave) elif res == 'No Internet Connection!': self.updates_lb.configure(text='No Server Connection!', foreground='red') elif res == 'No Updates': self.updates_lb.configure(text='No Updates') def congratulations_mouse_enter(event): """ The mouse moves into the entry widget """ window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'Congratulations! Wire-Py is up to date') def congratulations_mouse_leave(event): """ The mouse moves from the entry widget """ ''' Remove Tool-Tip ''' window.my_tool_tip.destroy() self.updates_lb.bind('', congratulations_mouse_enter) self.updates_lb.bind('', congratulations_mouse_leave) else: set_option.set(value=0) text = f'Update {res} available!' ''' Update BTN Menu''' self.update_btn = ttk.Menubutton(self.menu_frame, text=text) self.update_btn.grid(column=4, row=0, padx=0) def download_mouse_enter(event): """ The mouse moves into the entry widget """ window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'Click to download new version') def download_mouse_leave(event): """ The mouse moves from the entry widget """ ''' Remove Tool-Tip ''' window.my_tool_tip.destroy() self.update_btn.bind('', download_mouse_enter) self.update_btn.bind('', download_mouse_leave) self.download = tk.Menu(self) self.update_btn.configure(menu=self.download, style='Toolbutton') self.download.add_command(label='Download', command=WirePyUpdate.download) FrameWidgets(self).grid() class StartStopBTN: """ Show Start and Stop Button in Label """ def __init__(self): self.lb_frame_btn_lbox = None self.wg_switch = None self.btn_stst = None self.wg_vpn_start = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_vpn-start.png') self.wg_vpn_stop = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_vpn-stop.png') def button_stop(self): self.btn_stst = ttk.Button(self.lb_frame_btn_lbox, image=self.wg_vpn_stop, command=self.wg_switch, padding=0) self.btn_stst.grid(column=0, row=0, padx=5, pady=8) def stop_mouse_enter(event): """ The mouse moves into the entry widget """ window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'Click to stop selected Wireguard Tunnel') def stop_mouse_leave(event): """ The mouse moves from the entry widget """ ''' Remove Tool-Tip ''' window.my_tool_tip.destroy() self.btn_stst.bind('', stop_mouse_enter) self.btn_stst.bind('', stop_mouse_leave) def button_start(self): self.btn_stst = ttk.Button(self.lb_frame_btn_lbox, image=self.wg_vpn_start, command=self.wg_switch, padding=0) self.btn_stst.grid(column=0, row=0, padx=5, pady=8) def empty_list_start_mouse_enter(event): """ The mouse moves into the entry widget """ window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'No tunnels to start in the list') def empty_list_start_mouse_leave(event): """ The mouse moves from the entry widget """ ''' Remove Tool-Tip ''' window.my_tool_tip.destroy() def start_mouse_enter(event): """ The mouse moves into the entry widget """ window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'Click to start selected Wireguard Tunnel') def start_mouse_leave(event): """ The mouse moves from the entry widget """ ''' Remove Tool-Tip ''' window.my_tool_tip.destroy() tl = ListTunnels.tl_list() if len(tl) == 0: self.btn_stst.bind('', empty_list_start_mouse_enter) self.btn_stst.bind('', empty_list_start_mouse_leave) else: self.btn_stst.bind('', start_mouse_enter) self.btn_stst.bind('', start_mouse_leave) class FrameWidgets(ttk.Frame): def __init__(self, container, **kwargs): super().__init__(container, **kwargs) self.btn_stst = None self.auto_con = None self.enp = None self.DNS = None self.add = None self.data = None self.peer = None self.lb_tunnel = None self.wg_read = None self.wg_vpn_start = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_vpn-start.png') self.wg_vpn_stop = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_vpn-stop.png') self.imp_pic = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_import.png') self.tr_pic = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_trash.png') self.exp_pic = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_export.png') self.warning_pic = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/64/error.png') ''' Show active Tunnel ''' self.a = TunnelActiv.active() ''' Label Frame 1 ''' self.lb_frame_btn_lbox = ttk.Frame(self) self.lb_frame_btn_lbox.configure(relief='flat') self.lb_frame_btn_lbox.grid(column=0, rowspan=3, row=1) self.columnconfigure(0, weight=1) self.rowconfigure(1, weight=1) ''' Label Frame 2 ''' self.lb_frame = ttk.Frame(self) self.lb_frame.configure(relief='solid') self.lb_frame.grid(column=2, row=2, sticky='snew', padx=20, pady=5) self.columnconfigure(2, weight=1) self.rowconfigure(2, weight=1) ''' Label Frame 3 ''' self.lb_frame2 = ttk.Frame(self) self.lb_frame2.configure(relief='solid') self.lb_frame2.grid(column=2, row=3, sticky='snew', padx=20, pady=5) self.columnconfigure(2, weight=1) self.rowconfigure(3, weight=1) ''' Show active Label ''' self.select_tunnel = None self.lb = ttk.Label(self, text='Active: ') self.lb.config(font=('Ubuntu', 11, 'bold')) self.lb.grid(column=2, row=1, padx=15, pady=4, sticky='w') self.columnconfigure(2, weight=1) self.rowconfigure(0, weight=1) ''' Label to Show active Tunnel ''' self.StrVar = tk.StringVar(value=self.a) GreenLabel.green_show_label(self) ''' Interface Label ''' self.interface = ttk.Label(self.lb_frame, text='Interface') self.interface.grid(column=0, row=3, sticky='we', padx=120) self.interface.config(font=('Ubuntu', 9)) ''' Peer Label ''' self.peer = ttk.Label(self.lb_frame2, text='Peer') self.peer.config(font=('Ubuntu', 9)) self.peer.grid(column=0, row=4, sticky='we', padx=130) ''' Listbox with Scrollbar ''' def box_info_mouse_enter(event): """ The mouse moves into the entry widget """ window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'You must first import\na Wireguard tunnel') def box_info_mouse_leave(event): """ The mouse moves from the entry widget """ ''' Remove Tool-Tip ''' window.my_tool_tip.destroy() def enable_check_box(event): if len(tl) != 0: self.wg_autostart.configure(state='normal') self.lb_rename.config(state='normal') self.lb_rename.delete(0, tk.END) self.btn_rename.config(state='normal') self.l_box = tk.Listbox(self.lb_frame_btn_lbox, selectmode='single') self.l_box.config(relief='ridge', font=('Ubuntu', 12, 'bold')) self.l_box.grid(column=1, rowspan=4, row=0, sticky='ns') tl = ListTunnels.tl_list() if len(tl) == 0: self.l_box.bind('', box_info_mouse_enter) self.l_box.bind('', box_info_mouse_leave) self.l_box.event_add('<>', '') self.l_box.bind('<>', enable_check_box) self.scrollbar = ttk.Scrollbar(self.lb_frame_btn_lbox, orient='vertical', command=self.l_box.yview) self.scrollbar.grid(column=1, rowspan=4, row=0, sticky='nse') self.l_box.configure(yscrollcommand=self.scrollbar.set) self.rowconfigure(0, weight=1) ''' Tunnel List ''' self.tl = ListTunnels.tl_list() for tunnels in self.tl: self.l_box.insert("end", tunnels) self.l_box.update() ''' Button Vpn ''' if self.a != '': StartStopBTN.button_stop(self) wg_read = Path('/etc/wire_py') / str(self.a + '.conf') with open(wg_read, 'r') as file: data = ConToDict.covert_to_dict(file) ''' Address Label ''' ShowAddress.init_and_report(self, data) ShowAddress.show_data(self) else: StartStopBTN.button_start(self) ''' Address Label ''' self.add = tk.StringVar() self.DNS = tk.StringVar() self.enp = tk.StringVar() ShowAddress.label_empty(self) ShowAddress.show_data(self) ''' Button Import ''' self.btn_i = ttk.Button(self.lb_frame_btn_lbox, image=self.imp_pic, command=lambda: ImportTunnel.wg_import_select(self), padding=0) self.btn_i.grid(column=0, row=1, padx=15, pady=8) def import_mouse_enter(event): """ The mouse moves into the entry widget """ window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'Click to import a Wireguard Tunnel') def import_mouse_leave(event): """ The mouse moves from the entry widget """ ''' Remove Tool-Tip ''' window.my_tool_tip.destroy() self.btn_i.bind('', import_mouse_enter) self.btn_i.bind('', import_mouse_leave) def delete(): try: self.select_tunnel = self.l_box.curselection() select_tl = self.l_box.get(self.select_tunnel[0]) with open('/etc/wire_py/' + select_tl + '.conf', 'r+') as file2: key = ConToDict.covert_to_dict(file2) pre_key = key[3] check_call(['nmcli', 'connection', 'delete', select_tl]) self.l_box.delete(self.select_tunnel[0]) if Path.is_file(Path('/etc/wire_py/wg_py')): path_to_file = Path('/etc/wire_py') / 'wg_py' a_con = Path.read_text(path_to_file) if select_tl == a_con: self.selected_option.set(0) self.autoconnect_var.set('no Autoconnect') self.wg_autostart.configure(state='disabled') Path.unlink(path_to_file) Path.unlink(Path('/etc/wire_py') / str(select_tl + '.conf')) with open('/etc/wire_py/.keys', 'r') as readfile: with open('/etc/wire_py/.keys2', 'w') as writefile: for line in readfile: if pre_key not in line.strip("\n"): writefile.write(line) file_one = Path('/etc/wire_py/.keys2') file_two = file_one.with_name('.keys') file_one.replace(file_two) ''' for disable checkbox when Listbox empty ''' if len(tl) == 0: self.wg_autostart.configure(state='disabled') if self.a != '' and self.a == select_tl: self.StrVar.set(value='') StartStopBTN.button_start(self) self.l_box.update() ''' Address Label ''' self.add.set('') self.DNS.set('') self.enp.set('') return select_tl except IndexError: if len(tl) != 0: """img_w, img_i, w_title, w_txt hand over""" iw = r'/usr/share/icons/wp-icons/64/info.png' ii = r'/usr/share/icons/wp-icons/48/wg_msg.png' wt = 'Select tunnel' msg_t = 'Please select a tunnel from the list.' msg_window(iw, ii, wt, msg_t) else: """img_w, img_i, w_title, w_txt hand over""" iw = r'/usr/share/icons/wp-icons/64/info.png' ii = r'/usr/share/icons/wp-icons/48/wg_msg.png' wt = 'Select tunnel' msg_t = 'Please first import tunnel.' msg_window(iw, ii, wt, msg_t) ''' Button Trash ''' self.btn_tr = ttk.Button(self.lb_frame_btn_lbox, image=self.tr_pic, command=delete, padding=0, style='CButton.TButton') self.btn_tr.grid(column=0, row=2, padx=15, pady=8) def empty_list_del_mouse_enter(event): """ The mouse moves into the entry widget """ window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'No tunnels to delete in the list') def empty_list_del_mouse_leave(event): """ The mouse moves from the entry widget """ ''' Remove Tool-Tip ''' window.my_tool_tip.destroy() def delete_mouse_enter(event): """ The mouse moves into the entry widget """ window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'Click to delete a Wireguard Tunnel\nSelect from the list!') def delete_mouse_leave(event): """ The mouse moves from the entry widget """ ''' Remove Tool-Tip ''' window.my_tool_tip.destroy() if len(tl) == 0: self.btn_tr.bind('', empty_list_del_mouse_enter) self.btn_tr.bind('', empty_list_del_mouse_leave) else: self.btn_tr.bind('', delete_mouse_enter) self.btn_tr.bind('', delete_mouse_leave) ''' Button Export ''' self.btn_exp = ttk.Button(self.lb_frame_btn_lbox, image=self.exp_pic, command=ExportTunnels.wg_export, padding=0) self.btn_exp.grid(column=0, row=3, padx=15, pady=8) def empty_list_mouse_enter(event): """ The mouse moves into the entry widget """ window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'No Tunnels in List for Export') def empty_list_mouse_leave(event): """ The mouse moves from the entry widget """ ''' Remove Tool-Tip ''' window.my_tool_tip.destroy() def export_mouse_enter(event): """ The mouse moves into the entry widget """ window.my_tool_tip = MyToolTip(event.x_root, event.y_root, ' Click to export all\nWireguard Tunnel to Zipfile') def export_mouse_leave(event): """ The mouse moves from the entry widget """ ''' Remove Tool-Tip ''' window.my_tool_tip.destroy() if len(tl) == 0: self.btn_exp.bind('', empty_list_mouse_enter) self.btn_exp.bind('', empty_list_mouse_leave) else: self.btn_exp.bind('', export_mouse_enter) self.btn_exp.bind('', export_mouse_leave) ''' Label Entry ''' self.lb_rename = ttk.Entry(self, width=20) self.lb_rename.grid(column=2, row=4, padx=30, pady=15, sticky='nw') self.lb_rename.insert(0, 'Max. 12 characters!') self.lb_rename.config(state='disable') def rename_mouse_enter(event): """ The mouse moves into the entry widget """ window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'To rename a tunnel, you need to\nselect a tunnel from the list') def rename_no_active_mouse_leave(event): """ The mouse moves from the entry widget """ ''' Remove Tool-Tip ''' window.my_tool_tip.destroy() def rename_no_active_mouse_enter(event): """ The mouse moves into the entry widget """ window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'To rename a tunnel, at least one must be in the list') def rename_mouse_leave(event): """ The mouse moves from the entry widget """ ''' Remove Tool-Tip ''' window.my_tool_tip.destroy() if len(tl) != 0: self.lb_rename.bind('', rename_mouse_enter) self.lb_rename.bind('', rename_mouse_leave) else: self.lb_rename.bind('', rename_no_active_mouse_enter) self.lb_rename.bind('', rename_no_active_mouse_leave) def tl_rename(): special_characters = ['\\', '/', '{', '}', ' '] if len(self.lb_rename.get()) > 12: """img_w, img_i, w_title, w_txt hand over""" iw = r'/usr/share/icons/wp-icons/64/info.png' ii = r'/usr/share/icons/wp-icons/48/wg_msg.png' wt = 'Renaming not possible' msg_t = 'The new name may contain only 12 characters.' msg_window(iw, ii, wt, msg_t) elif len(self.lb_rename.get()) == 0: """img_w, img_i, w_title, w_txt hand over""" iw = r'/usr/share/icons/wp-icons/64/info.png' ii = r'/usr/share/icons/wp-icons/48/wg_msg.png' wt = 'Renaming not possible' msg_t = 'At least one character must be entered.' msg_window(iw, ii, wt, msg_t) elif any(ch in special_characters for ch in self.lb_rename.get()): """img_w, img_i, w_title, w_txt hand over""" iw = r'/usr/share/icons/wp-icons/64/info.png' ii = r'/usr/share/icons/wp-icons/48/wg_msg.png' wt = 'Renaming not possible' msg_t = 'No valid sign. These must not be used.\nBlank, Slash, Backslash and { }\n' msg_window(iw, ii, wt, msg_t) else: try: self.select_tunnel = self.l_box.curselection() select_tl = self.l_box.get(self.select_tunnel[0]) ''' nmcli connection modify old connection.id iphone ''' check_call(['nmcli', 'connection', 'modify', select_tl, 'connection.id', self.lb_rename.get()]) source = Path('/etc/wire_py') / str(select_tl + '.conf') destination = source.with_name(str(self.lb_rename.get() + '.conf')) source.replace(destination) self.l_box.delete(self.select_tunnel[0]) self.l_box.insert("end", self.lb_rename.get()) self.l_box.update() new_a_connect = self.lb_rename.get() self.lb_rename.delete(0, tk.END) if self.a != '' and self.a == select_tl: self.a = TunnelActiv.active() self.StrVar.set(value=self.a) if Path.is_file(Path('/etc/wire_py/wg_py')): path_to_file = Path('/etc/wire_py') / 'wg_py' a_con = Path.read_text(path_to_file) if select_tl == a_con: self.autoconnect_var.set(value=new_a_connect) Path.write_text(path_to_file, new_a_connect) return select_tl except IndexError: """img_w, img_i, w_title, w_txt hand over""" iw = r'/usr/share/icons/wp-icons/64/info.png' ii = r'/usr/share/icons/wp-icons/48/wg_msg.png' wt = 'Renaming not possible' msg_t = 'Please select a tunnel from the list.' msg_window(iw, ii, wt, msg_t) ''' Button Rename ''' self.btn_rename = ttk.Button(self, text='Rename', state='disable', command=tl_rename, padding=4, style='RnButton.TButton') self.btn_rename.grid(column=2, row=4, padx=20, pady=15, sticky='ne') ''' Check Buttons ''' self.selected_option = tk.IntVar() self.autoconnect_var = tk.StringVar() self.autoconnect_var.set(self.auto_con) ''' Frame for Labels, Entry and Button''' self.autoconnect = ttk.Label(self, textvariable=self.autoconnect_var) self.autoconnect.config(font=('Ubuntu', 11)) self.autoconnect.grid(column=0, row=4, sticky='ne', padx=10, pady=15) self.wg_autostart = ttk.Checkbutton(self, text='Autoconnect on:', variable=self.selected_option, command=lambda: FileHandle.box_set(self)) self.wg_autostart.grid(column=0, row=4, pady=15, padx=15, sticky='nw') def chk_mouse_enter(event): """ The mouse moves into the entry widget """ window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'You must have at least one\n' 'tunnel in the list,to use the autostart') def chk_mouse_leave(event): """ The mouse moves from the entry widget """ ''' Remove Tool-Tip ''' window.my_tool_tip.destroy() if len(tl) == 0: self.wg_autostart.bind('', chk_mouse_enter) self.wg_autostart.bind('', chk_mouse_leave) else: def chk_a_mouse_enter(event): """ The mouse moves into the entry widget """ window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'To use the autostart, a tunnel must be selected from the list') def chk_a_mouse_leave(event): """ The mouse moves from the entry widget """ ''' Remove Tool-Tip ''' window.my_tool_tip.destroy() self.wg_autostart.bind('', chk_a_mouse_enter) self.wg_autostart.bind('', chk_a_mouse_leave) OnOff.on_off(self) def wg_switch(self): self.a = TunnelActiv.active() try: if self.a == '': StartStopBTN.button_start(self) self.select_tunnel = self.l_box.curselection() select_tl = self.l_box.get(self.select_tunnel[0]) check_call(['nmcli', 'connection', 'up', select_tl]) wg_read = Path('/etc/wire_py') / str(select_tl + '.conf') with open(wg_read, 'r') as file: data = ConToDict.covert_to_dict(file) ''' Address Label ''' ShowAddress.init_and_report(self, data) ShowAddress.show_data(self) ''' Button Start/Stop ''' StartStopBTN.button_stop(self) self.a = TunnelActiv.active() self.StrVar = tk.StringVar() self.StrVar.set(self.a) GreenLabel.green_show_label(self) elif self.a != '': ''' Button Start/Stop ''' StartStopBTN.button_stop(self) check_call(['nmcli', 'connection', 'down', self.a]) ''' Button Start/Stop ''' StartStopBTN.button_start(self) self.a = TunnelActiv.active() self.StrVar.set('') GreenLabel.green_show_label(self) ''' Address Label ''' self.add.set('') self.DNS.set('') self.enp.set('') ShowAddress.show_data(self) except IndexError: tl = ListTunnels.tl_list() if len(tl) != 0: """img_w, img_i, w_title, w_txt hand over""" iw = r'/usr/share/icons/wp-icons/64/info.png' ii = r'/usr/share/icons/wp-icons/48/wg_msg.png' wt = 'Select tunnel' msg_t = 'Please select a tunnel from the list.' msg_window(iw, ii, wt, msg_t) else: """img_w, img_i, w_title, w_txt hand over""" iw = r'/usr/share/icons/wp-icons/64/info.png' ii = r'/usr/share/icons/wp-icons/48/wg_msg.png' wt = 'Select tunnel' msg_t = 'Please first import tunnel.' msg_window(iw, ii, wt, msg_t) if __name__ == '__main__': window = MainWindow() """ the hidden files are hidden in Filedialog """ try: window.tk.call('tk_getOpenFile', '-foobarbaz') except TclError: pass window.tk.call('set', '::tk::dialog::file::showHiddenBtn', '0') window.tk.call('set', '::tk::dialog::file::showHiddenVar', '0') window.mainloop()