Tkinter Best Practices?
Verfasst: Donnerstag 21. Juni 2018, 14:24
Grüße miteinander,
mal eine kurze Frage. Ich habe schon einige Beispiele gesehen, in denen Klassen für Tkinter GUIs folgendermaßen initialisiert werden:
Allerdings funktioniert dasselbe ja auch mit einem Konstrukt wie:
Bei der zweiten Variante sehe ich, dass ich nochmal auf ein Objekt zugreifen muss anstatt dies im Laufe der weiteren Klasse über 'self' zu tun. Weiterhin scheint die erste Variante auf den ersten Blick etwas eleganter.
Gilt aber die zweite Variante als No-Go?
Meine zweite Frage ist, ob es sinnig ist, die eigenen Funktionen für das bewegen von Fenster etc. nachzubilden, um ein etwas anderes Look & Feel in Tk zu bekommen. Beispielsweise:
Danke schonmal Vorab für eure Mühe.
mal eine kurze Frage. Ich habe schon einige Beispiele gesehen, in denen Klassen für Tkinter GUIs folgendermaßen initialisiert werden:
Code: Alles auswählen
class Test( tkinter.Tk ):
def __init__( self ):
tkinter.Tk.__init__( self )
oder
class Canvas( tk.Canvas ):
self.app_win = app_win
tk.Canvas.__init__( self, app_win ... )
Code: Alles auswählen
class Test( object ):
def __init__( self ):
self.root = tk.Tk()
Gilt aber die zweite Variante als No-Go?
Meine zweite Frage ist, ob es sinnig ist, die eigenen Funktionen für das bewegen von Fenster etc. nachzubilden, um ein etwas anderes Look & Feel in Tk zu bekommen. Beispielsweise:
Code: Alles auswählen
import sys
if sys.version_info.major == 3:
import tkinter as tk
import tkinter.font as tkF
from tkinter import ttk
else:
import Tkinter as tk
import Tkinter as ttk
class GOUS( object ):
def __init__( self ):
self.root = tk.Tk()
# Setup Dimensions of Window
self.root.overrideredirect( True )
self.width = self.root.winfo_screenwidth()
self.height = self.root.winfo_screenheight()
self.width = self.width - ( self.width / 3 )
self.height = self.height - ( self.height / 3 )
top = self.root.winfo_toplevel()
top.rowconfigure( 0, weight=1 )
top.columnconfigure( 0, weight=1 )
self.root.geometry( "{}x{}+{}+{}".format( int( self.width ), int( self.height ), \
int( ( self.root.winfo_screenwidth() - self.width ) / 2 ), \
int( ( self.root.winfo_screenheight() - self.height ) / 2 ) ) )
self.root.rowconfigure( 0, weight=1 )
self.root.columnconfigure( 0, weight=1 )
# AppCanvas
self.AppCanvas = tk.Canvas( self.root, height=self.height, width=self.width )
self.AppCanvas.grid( ipadx=0, ipady=0, padx=0, pady=0, sticky="news" )
self.AppCanvas.configure( bg="#2b2b2b", relief="ridge", highlightthickness=0 )
# Setup Default Bindings
self.root.bind( "<KeyPress-F11>", self.toggle_fullscreen )
self.root.bind( "<KeyPress-Escape>", self.exit_event )
self.AppCanvas.bind( "<Configure>", self.resize_win )
# Default Values
self.queued_exit = False
self.force_no_exit = False
self.root.after( 800,self.check_exit )
self.fullscreen = False
# Test for MenuBar
self.testbar = GOUSMenu( self.AppCanvas, self.root, "menu_bar" )
self.root.mainloop()
def exit_event( self, event=False ):
self.root.bell()
self.queued_exit = True
def check_exit( self ):
if self.queued_exit and not self.force_no_exit:
self.root.destroy()
self.root.after( 800, self.check_exit )
def resize_win( self, event ):
xscale = float( event.width ) / float( self.AppCanvas.configure( 'width' )[-1] )
yscale = float( event.height ) / float( self.AppCanvas.configure( 'height' )[-1] )
self.AppCanvas.configure( width=event.width, height=event.height )
def toggle_fullscreen( self, event ):
self.fullscreen = not self.fullscreen
self.root.overrideredirect( not self.fullscreen )
self.root.attributes( '-fullscreen', self.fullscreen )
class GOUSMenu( object ):
def __init__( self, canvas_win, root_window, menu_name, x=0, y=0, height=30, width=0, grab=True ):
self.root = canvas_win
self.window = root_window
self.menu_name = menu_name
self.width = width
if self.width == 0:
self.width = int( self.root.configure( 'width' )[-1] )
self.height = height
self.root.create_rectangle( x, y, self.width, self.height, fill="#2b5555", width=0, \
tags=("{}.gous.top_wingrab".format( self.menu_name ), \
"{}.gous.top_MenuBar".format( self.menu_name ) ) )
self.root.create_line( 0, self.height - 1, self.width, self.height - 1, width=1, \
fill="#999999", tags=("{}.gous.top_Menu_separator".format( self.menu_name ), \
"{}.gous.gous.top_MenuBar".format( self.menu_name ) ) )
# Move the Window
self.menu_grabbed = False
self.win_old_pos = [0,0]
self.root.tag_bind( "{}.gous.top_wingrab".format( self.menu_name ), sequence="<ButtonPress-1>", func=self.grab_menu )
self.root.tag_bind( "{}.gous.top_wingrab".format( self.menu_name ), sequence="<ButtonRelease-1>", func=self.release_menu )
self.root.tag_bind( "{}.gous.top_wingrab".format( self.menu_name ), sequence="<Motion>", func=self.move_menu )
def grab_menu( self, event ):
self.menu_grabbed = True
self.win_old_pos[0] = event.x_root
self.win_old_pos[1] = event.y_root
def release_menu( self, event ):
self.menu_grabbed = False
self.win_old_pos = [0,0]
def trigger_exit( self, event ):
self.window.event_generate( "<KeyPress-Escape>" )
def move_menu( self, event ):
if self.menu_grabbed:
new_x = event.x_root - self.win_old_pos[0]
new_y = event.y_root - self.win_old_pos[1]
win_pos = self.window.geometry()
win_pos = win_pos.replace( 'x', ' ' )
win_pos = win_pos.replace( '+', ' ' )
win_pos = win_pos.split( ' ' )
self.window.geometry( "{}x{}+{}+{}".format( int( self.root.configure( 'width' )[-1] ), \
int( self.root.configure( 'height' )[-1] ), \
int( win_pos[2] ) + new_x, int( win_pos[3] ) + new_y ) )
self.win_old_pos[0] = event.x_root
self.win_old_pos[1] = event.y_root
if __name__ == '__main__':
gous = GOUS()