""" Python script for a GUI-dialog. Description: Python script to provide an abstract GUI for other python scripts. That way we've all the GUI-related code within one single file and are able to easily modify GUI-stuff in a central place. Author: Sebastian Sauer Copyright: Published as-is without any warranties. """ def getHome(): """ Return the homedirectory. """ import os try: home = os.getenv("HOME") if not home: import pwd user = os.getenv("USER") or os.getenv("LOGNAME") if not user: pwent = pwd.getpwuid(os.getuid()) else: pwent = pwd.getpwnam(user) home = pwent[6] return home except (KeyError, ImportError): return os.curdir class TkDialog: """ This class is used to wrap Tkinter into a more abstract interface.""" def __init__(self, title): import tkinter self.root = tkinter.Tk() self.root.title(title) self.root.deiconify() mainframe = self.Frame(self, self.root) self.widget = mainframe.widget class Widget: def __init__(self, dialog, parent): self.dialog = dialog self.parent = parent #def setVisible(self, visibled): pass #def setEnabled(self, enabled): pass class Frame(Widget): def __init__(self, dialog, parent): #TkDialog.Widget.__init__(self, dialog, parent) import tkinter self.widget = tkinter.Frame(parent) self.widget.pack() class Label(Widget): def __init__(self, dialog, parent, caption): #TkDialog.Widget.__init__(self, dialog, parent) import tkinter self.widget = tkinter.Label(parent, text=caption) self.widget.pack(side=tkinter.TOP) class CheckBox(Widget): def __init__(self, dialog, parent, caption, checked = True): #TkDialog.Widget.__init__(self, dialog, parent) import tkinter self.checkstate = tkinter.IntVar() self.checkstate.set(checked) self.widget = tkinter.Checkbutton(parent, text=caption, variable=self.checkstate) self.widget.pack(side=tkinter.TOP) def isChecked(self): return self.checkstate.get() class List(Widget): def __init__(self, dialog, parent, caption, items): #TkDialog.Widget.__init__(self, dialog, parent) import tkinter listframe = tkinter.Frame(parent) listframe.pack() tkinter.Label(listframe, text=caption).pack(side=tkinter.LEFT) self.items = items self.variable = tkinter.StringVar() itemlist = tkinter.OptionMenu(*(listframe, self.variable) + tuple( items )) itemlist.pack(side=tkinter.LEFT) def get(self): return self.variable.get() def set(self, index): self.variable.set( self.items[index] ) class Button(Widget): def __init__(self, dialog, parent, caption, commandmethod): #TkDialog.Widget.__init__(self, dialog, parent) import tkinter self.widget = tkinter.Button(parent, text=caption, command=self.doCommand) self.commandmethod = commandmethod self.widget.pack(side=tkinter.LEFT) def doCommand(self): try: self.commandmethod() except: #TODO why the heck we arn't able to redirect exceptions? import traceback import io fp = io.StringIO() traceback.print_exc(file=fp) import tkinter.messagebox tkinter.messagebox.showerror("Exception", fp.getvalue()) #self.dialog.root.destroy() class Edit(Widget): def __init__(self, dialog, parent, caption, text): #TkDialog.Widget.__init__(self, dialog, parent) import tkinter self.widget = tkinter.Frame(parent) self.widget.pack() label = tkinter.Label(self.widget, text=caption) label.pack(side=tkinter.LEFT) self.entrytext = tkinter.StringVar() self.entrytext.set(text) self.entry = tkinter.Entry(self.widget, width=36, textvariable=self.entrytext) self.entry.pack(side=tkinter.LEFT) def get(self): return self.entrytext.get() class FileChooser(Edit): def __init__(self, dialog, parent, caption, initialfile = None, filetypes = None): TkDialog.Edit.__init__(self, dialog, parent, caption, initialfile) import tkinter self.initialfile = initialfile self.entrytext.set(initialfile) btn = tkinter.Button(self.widget, text="...", command=self.browse) btn.pack(side=tkinter.LEFT) if filetypes: self.filetypes = filetypes else: self.filetypes = (('All files', '*'),) def browse(self): import os text = self.entrytext.get() d = os.path.dirname(text) or os.path.dirname(self.initialfile) f = os.path.basename(text) or os.path.basename(self.initialfile) import tkinter.filedialog file = tkinter.filedialog.asksaveasfilename( initialdir=d, initialfile=f, #defaultextension='.html', filetypes=self.filetypes ) if file: self.entrytext.set( file ) class MessageBox: def __init__(self, dialog, typename, caption, message): self.widget = dialog.widget self.typename = typename self.caption = str(caption) self.message = str(message) def show(self): import tkinter.messagebox if self.typename == "okcancel": return tkinter.messagebox.askokcancel(self.caption, self.message,icon=tkmessageBox.QESTION) else: tkinter.messagebox.showinfo(self.caption, self.message) return True def show(self): self.root.mainloop() def close(self): self.root.destroy() class TQtDialog: """ This class is used to wrap PyTQt/PyTDE into a more abstract interface.""" def __init__(self, title): from TQt import tqt class Dialog(tqt.TQDialog): def __init__(self, parent = None, name = None, modal = 0, fl = 0): tqt.TQDialog.__init__(self, parent, name, modal, fl) tqt.TQDialog.accept = self.accept self.layout = tqt.TQVBoxLayout(self) self.layout.setSpacing(6) self.layout.setMargin(11) class Label(tqt.TQLabel): def __init__(self, dialog, parent, caption): tqt.TQLabel.__init__(self, parent) self.setText("%s" % caption.replace("\n","
")) class Frame(tqt.TQHBox): def __init__(self, dialog, parent): tqt.TQHBox.__init__(self, parent) self.widget = self self.setSpacing(6) class Edit(tqt.TQHBox): def __init__(self, dialog, parent, caption, text): tqt.TQHBox.__init__(self, parent) self.setSpacing(6) label = tqt.TQLabel(caption, self) self.edit = tqt.TQLineEdit(self) self.edit.setText( str(text) ) self.setStretchFactor(self.edit, 1) label.setBuddy(self.edit) def get(self): return self.edit.text() class Button(tqt.TQPushButton): #def __init__(self, *args): def __init__(self, dialog, parent, caption, commandmethod): #apply(tqt.TQPushButton.__init__, (self,) + args) tqt.TQPushButton.__init__(self, parent) self.commandmethod = commandmethod self.setText(caption) tqt.TQObject.connect(self, tqt.SIGNAL("clicked()"), self.commandmethod) class CheckBox(tqt.TQCheckBox): def __init__(self, dialog, parent, caption, checked = True): #TkDialog.Widget.__init__(self, dialog, parent) tqt.TQCheckBox.__init__(self, parent) self.setText(caption) self.setChecked(checked) #def isChecked(self): # return self.isChecked() class List(tqt.TQHBox): def __init__(self, dialog, parent, caption, items): tqt.TQHBox.__init__(self, parent) self.setSpacing(6) label = tqt.TQLabel(caption, self) self.combo = tqt.TQComboBox(self) self.setStretchFactor(self.combo, 1) label.setBuddy(self.combo) for item in items: self.combo.insertItem( str(item) ) def get(self): return self.combo.currentText() def set(self, index): self.combo.setCurrentItem(index) class FileChooser(tqt.TQHBox): def __init__(self, dialog, parent, caption, initialfile = None, filetypes = None): #apply(tqt.TQHBox.__init__, (self,) + args) tqt.TQHBox.__init__(self, parent) self.setMinimumWidth(400) self.initialfile = initialfile self.filetypes = filetypes self.setSpacing(6) label = tqt.TQLabel(caption, self) self.edit = tqt.TQLineEdit(self) self.edit.setText(self.initialfile) self.setStretchFactor(self.edit, 1) label.setBuddy(self.edit) browsebutton = Button(dialog, self, "...", self.browseButtonClicked) #tqt.TQObject.connect(browsebutton, tqt.SIGNAL("clicked()"), self.browseButtonClicked) def get(self): return self.edit.text() def browseButtonClicked(self): filtermask = "" import types if isinstance(self.filetypes, tuple): for ft in self.filetypes: if len(ft) == 1: filtermask += "%s\n" % (ft[0]) if len(ft) == 2: filtermask += "%s|%s (%s)\n" % (ft[1],ft[0],ft[1]) if filtermask == "": filtermask = "All files (*.*)" else: filtermask = filtermask[:-1] filename = None try: print("TQtDialog.FileChooser.browseButtonClicked() tdefile.KFileDialog") # try to use the tdefile module included in pytde import tdefile filename = tdefile.KFileDialog.getOpenFileName(self.initialfile, filtermask, self, "Save to file") except: print("TQtDialog.FileChooser.browseButtonClicked() tqt.TQFileDialog") # fallback to TQt filedialog filename = tqt.TQFileDialog.getOpenFileName(self.initialfile, filtermask, self, "Save to file") if filename != None and filename != "": self.edit.setText(filename) class MessageBox: def __init__(self, dialog, typename, caption, message): self.widget = dialog.widget self.typename = typename self.caption = str(caption) self.message = str(message) def show(self): result = 1 if self.typename == "okcancel": result = tqt.TQMessageBox.question(self.widget, self.caption, self.message, "&Ok", "&Cancel", "", 1) else: tqt.TQMessageBox.information(self.widget, self.caption, self.message, "&Ok") result = 0 if result == 0: return True return False self.app = tqt.tqApp self.dialog = Dialog(self.app.mainWidget(), "Dialog", 1, tqt.TQt.WDestructiveClose) self.dialog.setCaption(title) self.widget = tqt.TQVBox(self.dialog) self.widget.setSpacing(6) self.dialog.layout.addWidget(self.widget) self.Frame = Frame self.Label = Label self.Edit = Edit self.Button = Button self.CheckBox = CheckBox self.List = List self.FileChooser = FileChooser self.MessageBox = MessageBox def show(self): from TQt import tqt tqt.TQApplication.setOverrideCursor(tqt.TQt.arrowCursor) self.dialog.exec_loop() tqt.TQApplication.restoreOverrideCursor() def close(self): print("TQtDialog.close()") self.dialog.close() #self.dialog.deleteLater() class Dialog: """ Central class that provides abstract GUI-access to the outer world. """ def __init__(self, title): self.dialog = None try: print("Trying to import PyTQt...") self.dialog = TQtDialog(title) print("PyTQt is our toolkit!") except: try: print("Failed to import PyTQt. Trying to import TkInter...") self.dialog = TkDialog(title) print("Falling back to TkInter as our toolkit!") except: raise Exception("Failed to import GUI-toolkit. Please install the PyTQt or the Tkinter python module.") self.widget = self.dialog.widget def show(self): self.dialog.show() def close(self): self.dialog.close() def addFrame(self, parentwidget): return self.dialog.Frame(self.dialog, parentwidget.widget) def addLabel(self, parentwidget, caption): return self.dialog.Label(self.dialog, parentwidget.widget, caption) def addCheckBox(self, parentwidget, caption, checked = True): return self.dialog.CheckBox(self.dialog, parentwidget.widget, caption, checked) def addButton(self, parentwidget, caption, commandmethod): return self.dialog.Button(self.dialog, parentwidget.widget, caption, commandmethod) def addEdit(self, parentwidget, caption, text): return self.dialog.Edit(self.dialog, parentwidget.widget, caption, text) def addFileChooser(self, parentwidget, caption, initialfile = None, filetypes = None): return self.dialog.FileChooser(self.dialog, parentwidget.widget, caption, initialfile, filetypes) def addList(self, parentwidget, caption, items): return self.dialog.List(self.dialog, parentwidget.widget, caption, items) def showMessageBox(self, typename, caption, message): return self.dialog.MessageBox(self.dialog, typename, caption, message)