Python Tkinter 自定义窗口的优化

一位初学者在学习 Tkinter 几个月后,希望知道他所编写的 Tkinter 自定义窗口代码是否可以接受。主要是想了解在编码风格和思维方式上有哪些方面可以改进,没有具体的用户信息。

import Tkinter as tk

''' Creating Tkinter Tk instance '''
class Application(tk.Tk):
    def __init__(self,*args,**kwargs):
        tk.Tk.__init__(self,*args,**kwargs)
        self.bind("<ButtonPress-1>", self.StartMove)
        self.bind("<ButtonRelease-1>", self.StopMove)
        self.bind("<B1-Motion>", self.OnMotion)
        self.Init()
        self.Layout()
        self.AddButtons()

    ''' Setting Main Tk window size & styles '''
    def Init(self):
        self.geometry("1280x700+0+0")
        self.overrideredirect(True)
        self['background'] = '#201F29'
        self['highlightthickness'] = 2
        self['relief'] = 'groove'

    '''Layout of the Tk window'''
    def Layout(self):
        self.exitmenu = tk.Frame(self)
        self.exitmenu.place(x = 1217,  y = 0)
        self.container = tk.Frame(self,width = 1268,height = 648 , relief = 'flat',bd = 0)
        self.container.place(x = 5,y = 40)

    ''' Adding Exit button and Minimize button to the Tk window'''
    def AddButtons(self):
        self.minibutton = tk.Button(self.exitmenu,text = '0',font=('webdings',8,'bold'),relief = 'flat' , command = self.minimize )
        self.minibutton.pack(side = 'left')
        self.exitbutton = tk.Button(self.exitmenu,text = 'r',font=('webdings',8),relief = 'flat' ,bg = '#DB6B5A', command = self.destroy )
        self.exitbutton.pack(side = 'left')

    def minimize(self):
        self.overrideredirect(False)
        self.wm_state('iconic')
        self.overrideredirect(True)

    '''Methods for moving window frame'''
    def StartMove(self, event):
        self.x = event.x
        self.y = event.y

    def StopMove(self, event):
        self.x = None
        self.y = None

    def OnMotion(self, event):
        x1 = self.x
        y1 = self.y
        x2 = event.x
        y2 = event.y
        deltax = x2 - x1
        deltay = y2 - y1
        a = self.winfo_x() + deltax
        b = self.winfo_y() + deltay
        self.geometry("+%s+%s" % (a, b))


def Main():
    app = Application()
    app.mainloop()

if __name__ == "__main__":
    Main()

2、解决方案

a. 代码可读性的改进

  • 首先,建议使用单行代码风格,而不是将代码分割成多行。这将使代码更加简洁易读。
  • 其次,建议使用 PEP-8 编码约定,这将使代码更加符合 Python 社区的编码标准。
  • 第三,建议使用注释来解释代码的逻辑,这将使代码更加易于理解。

b. 代码逻辑的改进

  • 可以在初始化 Application 类时设置窗口的标题,而不是在 Init 方法中设置。
  • 可以在 Layout 方法中使用 grid 布局管理器,而不是使用 place 布局管理器。
  • 可以在 AddButtons 方法中使用 pack 布局管理器,而不是使用 place 布局管理器。
  • 可以在 OnMotion 方法中使用 winfo_pointerxy 方法获取鼠标的绝对位置,而不是使用 event.xevent.y

代码例子

import tkinter as tk

class Application(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tkinter Custom Window")
        self.geometry("1280x700")
        self.overrideredirect(True)
        self['background'] = '#201F29'
        self['highlightthickness'] = 2
        self['relief'] = 'groove'

        self.exit_menu = tk.Frame(self)
        self.exit_menu.grid(row=0, column=1, sticky="ne")
        self.minimize_button = tk.Button(self.exit_menu, text="-", font=('webdings', 8, 'bold'), relief='flat', command=self.minimize)
        self.minimize_button.pack(side='left')
        self.exit_button = tk.Button(self.exit_menu, text="r", font=('webdings', 8), relief='flat', bg='#DB6B5A', command=self.destroy)
        self.exit_button.pack(side='left')

        self.container = tk.Frame(self, width=1268, height=648, relief='flat', bd=0)
        self.container.grid(row=1, column=0, columnspan=2)

        self.bind("<ButtonPress-1>", self.start_move)
        self.bind("<ButtonRelease-1>", self.stop_move)
        self.bind("<B1-Motion>", self.on_motion)

    def minimize(self):
        self.overrideredirect(False)
        self.wm_state('iconic')
        self.overrideredirect(True)

    def start_move(self, event):
        self.x = event.x
        self.y = event.y

    def stop_move(self, event):
        self.x = None
        self.y = None

    def on_motion(self, event):
        x1 = self.x
        y1 = self.y
        x2 = event.x
        y2 = event.y
        deltax = x2 - x1
        deltay = y2 - y1
        a = self.winfo_x() + deltax
        b = self.winfo_y() + deltay
        self.geometry("+%s+%s" % (a, b))

def main():
    app = Application()
    app.mainloop()

if __name__ == "__main__":