2017-02-22 60 views
0

我即將開始一個新的Python3/tkinter項目,我想確保儘可能多地使用代碼。我創建一個應用程序,都會有,現在,一個窗口由3個方面:Python3/tkinter是否可以創建一個工具欄到一個單獨的類,但仍然允許它與主應用程序進行交互?

  • 工具欄
  • 中心/主區域
  • 狀態欄

我試圖保持主應用程序類儘可能乾淨,將代碼卸載到其他輔助類。所以,遵循一些教程並根據我一直在做的工作進行調整,直到現在,我已經能夠設置一個外部工具欄類,可以根據需要從主應用程序中更改。現在,我正在嘗試爲工具欄創建一個類,但是恐怕不可能在單獨的類中創建按鈕和它們各自的回調函數,因爲我不知道如何使它們調用函數在主應用程序中。這甚至可能嗎?

這就是我現在:

#!/usr/bin/python3 

from tkinter import * 
from tkinter import ttk 


class App: 
    """ main class for the application """ 
    def __init__(self,master): 
     mainframe = ttk.Frame(master) 
     topframe = ttk.Frame(mainframe) 
     centerframe = ttk.Frame(mainframe) 
     bottomframe = ttk.Frame(mainframe) 

     my_toolbar = Toolbar(topframe) 

     my_statusbar = StatusBar(mainframe) 
     my_statusbar.set("This is the statusbar") 

     centerlabel = ttk.Label(centerframe, text="Center stuff goes here") 
     centerlabel.pack() 

     topframe.pack(side=TOP, fill=X) 
     centerframe.pack(side=TOP, fill=BOTH) 
     bottomframe.pack(side=BOTTOM, fill=X)   
     mainframe.pack(side=TOP, expand=True, fill=BOTH) 


    def button_function(self, *event): 
     print("filter") 


class StatusBar(ttk.Frame): 
    """ Simple Status Bar class - based on Frame """ 
    def __init__(self,master): 
     ttk.Frame.__init__(self,master) 
     self.label = ttk.Label(self,anchor=W) 
     self.label.pack() 
     self.pack(side=BOTTOM, fill=X) 

    def set(self,texto): 
     self.label.config(text=texto) 
     self.label.update_idletasks() 
    def clear(self): 
     self.label.config(text="") 
     self.label.update_idletasks() 


class Toolbar: 
    """ Toolbar """ 
    def button_one(self): 
     print("button 1 pressed") 

    def button_two(self): 
     print("button 2 pressed") 

    def __init__(self,master): 
     self.button1 = ttk.Button(master,text="One",command=self.button_one()) 
     self.button2 = ttk.Button(master,text="Two",command=self.button_two()) 
     self.button1.grid(row=0,column=0) 
     self.button2.grid(row=0,column=1) 


if __name__ == "__main__": 
    root = Tk() 
    app = App(root) 
    root.mainloop() 

比方說,我需要button1以更新一些信息被顯示有觸發button_function()。我是否應該簡單地將工具欄移動到App類中,例如從其__init__()中調用的類方法?或者,還有更好的方法?

也許我應該補充一點,我打算稍後添加一些可能可以使用這些常規類中的一些的窗口Toplevel。我想以一種很好的方式鋪平道路。

回答

1

這當然是可能的。這裏有兩種可能性。第一個使應用程序從ttk.Frame繼承而不是使用大型機。然後,你可以通過應用程序爲主的工具欄等。這裏是重做代碼:

#!/usr/bin/python3 

import tkinter as tk 
from tkinter import ttk 


class App(ttk.Frame): 
    """ main class for the application """ 
    def __init__(self,master,*args,**kwargs): 
     super().__init__(master,*args,**kwargs) 


     self.my_toolbar = Toolbar(self) 

     self.my_statusbar = StatusBar(self) 
     self.my_statusbar.set("This is the statusbar") 

     self.centerframe = CenterFrame(self) 

     self.pack(side=tk.TOP, expand=True, fill=tk.BOTH) 


    def button_function(self, *event): 
     print("filter") 


class CenterFrame(ttk.Frame): 

    def __init__(self,master,*args,**kwargs): 
     super().__init__(master,*args,**kwargs) 
     self.master = master 
     self.pack(side=tk.BOTTOM, fill=tk.X) 
     self.centerlabel = ttk.Label(self, text="Center stuff goes here") 
     self.centerlabel.pack() 


class StatusBar(ttk.Frame): 
    """ Simple Status Bar class - based on Frame """ 
    def __init__(self,master): 
     ttk.Frame.__init__(self,master) 
     self.master = master 
     self.label = ttk.Label(self,anchor=tk.W) 
     self.label.pack() 
     self.pack(side=tk.BOTTOM, fill=tk.X) 

    def set(self,texto): 
     self.label.config(text=texto) 
     self.label.update_idletasks() 
    def clear(self): 
     self.label.config(text="") 
     self.label.update_idletasks() 


class Toolbar(ttk.Frame): 
    """ Toolbar """ 
    def button_one(self): 
     print("button 1 pressed") 

    def button_two(self): 
     print("button 2 pressed") 
     self.master.button_function() 

    def __init__(self,master): 
     super().__init__(master) 
     self.master = master 
     self.pack(side=tk.TOP, fill=tk.X) 
     self.button1 = ttk.Button(self,text="One",command=self.button_one) 
     self.button2 = ttk.Button(self,text="Two",command=self.button_two) 
     self.button1.grid(row=0,column=0) 
     self.button2.grid(row=0,column=1) 


if __name__ == "__main__": 
    root = tk.Tk() 
    app = App(root) 
    root.mainloop() 

第二個是隻通過應用作爲參數傳遞給其他類。

1

您錯過了一些self.,按鈕命令分配不需要括號,之後您可以從程序中的任何位置調用按鈕配置。所以對於Button1的命令,這將是:

app.my_toolbar.button1.config(command=app.button_function) 

我按原樣修復的錯誤,而不是使程序更好:

#!/usr/bin/python3 

from tkinter import * 
from tkinter import ttk 


class App: 
    """ main class for the application """ 
    def __init__(self,master): 
     self.mainframe = ttk.Frame(master) 
     self.topframe = ttk.Frame(self.mainframe) 
     self.centerframe = ttk.Frame(self.mainframe) 
     self.bottomframe = ttk.Frame(self.mainframe) 

     self.my_toolbar = Toolbar(self.topframe) 

     self.my_statusbar = StatusBar(self.mainframe) 
     self.my_statusbar.set("This is the statusbar") 

     self.centerlabel = ttk.Label(self.centerframe, text="Center stuff goes here") 
     self.centerlabel.pack() 

     self.topframe.pack(side=TOP, fill=X) 
     self.centerframe.pack(side=TOP, fill=BOTH) 
     self.bottomframe.pack(side=BOTTOM, fill=X) 
     self.mainframe.pack(side=TOP, expand=True, fill=BOTH) 


    def button_function(self, *event): 
     print("filter") 


class StatusBar(ttk.Frame): 
    """ Simple Status Bar class - based on Frame """ 
    def __init__(self,master): 
     ttk.Frame.__init__(self,master) 
     self.label = ttk.Label(self,anchor=W) 
     self.label.pack() 
     self.pack(side=BOTTOM, fill=X) 

    def set(self,texto): 
     self.label.config(text=texto) 
     self.label.update_idletasks() 
    def clear(self): 
     self.label.config(text="") 
     self.label.update_idletasks() 


class Toolbar: 
    """ Toolbar """ 
    def button_one(self): 
     print("button 1 pressed") 

    def button_two(self): 
     print("button 2 pressed") 

    def __init__(self,master): 
     self.button1 = ttk.Button(master,text="One",command=self.button_one) 
     self.button2 = ttk.Button(master,text="Two",command=self.button_two) 
     self.button1.grid(row=0,column=0) 
     self.button2.grid(row=0,column=1) 


if __name__ == "__main__": 
    root = Tk() 
    app = App(root) 

    app.my_toolbar.button1.config(command=app.button_function) 

    root.mainloop() 
相關問題