将TKinter GUI与单独的.py文件结合使用,并将功能绑定到GUI文件中的按钮

时间:2018-01-07 00:49:15

标签: python user-interface tkinter

我正在尝试用C#编程几年后自己编写python代码。到目前为止,我发现转换非常困难,但希望通过一些持久性我最终会理解python

我的问题:在尝试了像wxglade和wxformbuilder之类的程序之后,我对这些程序为你提供一个漂亮的单独GUI文件的方式感到很迷惑,这样你就可以将所有函数放在一个单独的主文件中。但是,我想对tkinter GUI应用相同的原理,但我无法弄明白,也无法找到有关它的文档。

假设我有两个文件: GUI.py:

from tkinter import * 

class BotGUI:

    def __init__(self, master):
        # ***** Creation of the frame for all items to be on *****
        xWidth=800
        yWidth=500
        margin=100
        outer_frame=Frame(master, width=xWidth, height=yWidth, bg='lightgray')
        outer_frame.pack(ipadx=margin, ipady=margin)
        button1 = Button(outer_frame, text = "Print something", command = printcommand)
        button1.pack()

    #Virtual event handlers
    def printcommand(self, event):
        event.Skip()

然后是一个名为Main.py的文件:

from tkinter import *
import GUI

class GUI_Functions(GUI.BotGUI):

    def __init__(self,parent):
        GUI.BotGUI.__init__(self, parent)

    def printcommand(self, event):
        print("The bind was successful!")

if __name__ == '__main__':
    root = Tk()
    GUI_Frame = GUI.BotGUI(root)
    root.mainloop()

以上代码导致错误:

NameError: global name 'printcommand' is not defined

我无法弄清楚如何使这个工作用于tkinter GUI。希望有人可以帮我一点!

(使用visual studio :()

在C#中创建GUI非常容易

4 个答案:

答案 0 :(得分:0)

您收到错误,因为Python不知道在哪里找到函数printcommand

首先导入文件Main.py,以便在GUI.py中使用它。

import Main.py

现在的问题是方法printcommand实例方法,这意味着您需要有一个对象来调用它。

要做到这一点。

  • 创建GUIFunctions类的实例并使用对象
  • 引用该方法

guifuncs = Main.GUIFunctions(master)

command = guifuncs.printcommand

注意:您必须使用上面使用的导入语法为带有Main的Main.py引用添加前缀。

我希望这会对您有所帮助,如果您有任何其他问题,请随时在下面发表评论!

答案 1 :(得分:0)

Python找不到名为“printcommand”的全局函数,实际上没有全局函数“printcommand”。您必须通过将button1添加到回调定义来告诉self.回调命令是本地函数。看起来应该是这样的:
command = self.printcommand

这将导致另一个问题,即按钮回调不会传回事件。我通过删除事件参数解决了这个问题,使GUI.py中的printcommand函数看起来像这样:

def printcommand(self):
    pass

如果确实需要将值传递给回调函数this page at Effbot,那么这是一个很好的起点。

答案 2 :(得分:0)

正如迈克尔所回答的那样,我缺少了#34; import Main"在我的GUI.py文件中,运行后我在代码中发现了一些其他的小错误,所以请在下面找到我用来运行的代码:

GUI.py文件:

from tkinter import * 
import Main


class BotGUI:

    def __init__(self, master):
        # ***** Import the guifunctions from the Main.py file
        guifuncs = Main.GUI_Functions(master)

        # ***** Creation of the frame for all items to be on *****
        xWidth=800
        yWidth=500
        margin=100
        outer_frame=Frame(master, width=xWidth, height=yWidth, bg='lightgray')
        outer_frame.pack(ipadx=margin, ipady=margin)
        button1 = Button(outer_frame, text = "Print something", command = guifuncs.printcommand)
        button1.pack()

和Main.py文件:

from tkinter import * 
import GUI


class GUI_Functions():

    def __init__(self,parent):
        pass

    def printcommand(self):
        print("The bind was successful!")

if __name__ == '__main__':
    root = Tk()
    GUI_Frame = GUI.BotGUI(root)
    root.mainloop()

感谢Micheal指出了这个问题!还要感谢Alex为effbot.org提供了有用的链接!

答案 3 :(得分:0)

希望这会有所帮助。

创建一个名为“ guiFactory.py”的文件

def createButton(self, Button, text, command, highlightbackground, compound, x, y):
    self.nav_button = Button(self, text =text, command=command, highlightbackground=highlightbackground, compound=compound) 
    self.nav_button.place(x = x, y = y)

在主应用程序文件中。

import tkinter as tk
from tkinter import StringVar, IntVar, messagebox, OptionMenu, Button, Label, filedialog as fd 
import guiFactory

class MainApplication(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent

        # Canvas Size
        parent.geometry("300x350")
        self.configure(bg="#3E4149")
        parent.title("Test Application") 

        # Submit Button
        def convertFilesHandler():
            print("Do Something")

        # buttons
        convertBtn = guiFactory.createButton(self, Button, "Convert", convertFilesHandler, "#3E4149", "center", 200, 250)

if __name__ == "__main__":
    root = tk.Tk()
    MainApplication(root).pack(side="top", fill="both", expand=True)
    root.mainloop()