当导入用tkinter和ttk编写的模块时,stuff不会

2024-10-01 07:39:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我对编程,Python,这个网站还不太熟悉,实际上基本上都在使用这类网站,所以请听我说完。在

我一直在用tkinter模块和ttk模块为一个更大的程序编写一个模块,当我将自己的模块导入主程序时,由于某种原因,没有一个ttk东西能正常工作。我是说,它看起来,但是我为它写的风格=ttk.风格();s.configure…等)无论如何都不会更改它。当我独立运行模块时,一切正常。当它被导入到主程序中时,它就是没有

不仅如此,在使用输入框时,我刚刚发现,我被告知使用它们的方式,例如,var=StringVar()作为textvariable(当模块独立运行时,它也能正常工作),现在只在以下情况下将变量var保留为空变量获取称为()。现在,我已经通过删除StringVar()的所有提及来对其进行了排序(希望我知道这些函数有多冗余),但我仍然想知道为什么将它们导入主程序会导致它们严重故障。我会给你一些示例代码,但有太多的东西我很难有足够的选择性。。。在

如果你能提供任何指导,我将不胜感激。在

编辑:给你这样的东西会有帮助吗?在

在stackoverflowmodule.py在

import sys
from tkinter import *
from tkinter import ttk
import time
from random import randint, choice

class Decimals():
    def Question1(self):
        DECFrame.destroy()
        frame1=ttk.Frame(DECmaster, height=height, width=width, style="NewFrame.TFrame")
        frame1.pack()
        Q1Label=ttk.Label(frame1, text="Question 1:", style="TitleLabel.TLabel")
        Q1Label.grid(column=0, row=0, pady=(50,0))     
        answer=StringVar()
        entry1=ttk.Entry(frame1, textvariable=answer)
        entry1.grid(column=0, row=1, pady=(200,0))
        # Typing in Hello should give a correct answer.
        def Question1Attempt():            
            attempt=answer.get()            
            if attempt!="Hello":
                print("Incorrect")
            else:
                print("Correct")
        button=ttk.Button(frame1, text="Ok", command=Question1Attempt)
        button.grid(column=0, row=2, pady=(30,0))


def Start():
    global DECmaster
    global s
    global DECFrame
    global DEC
    global width
    global height
    DECmaster = Tk()

    width=str(1000)
    height=str(800)
    x1=str(0)
    y1=str(0)

    DECmaster.geometry(width+"x"+height+"+"+x1+"+"+y1)
    DECmaster.configure(bg="#8afff0")

    s=ttk.Style()
    s.configure("NewFrame.TFrame", background="#8afff0")
    s.configure("TitleLabel.TLabel", foreground= "blue", background="#8afff0")

    DECFrame=ttk.Frame(DECmaster, style="NewFrame.TFrame")
    DECFrame.pack()

    TitleLabel=ttk.Label(DECFrame, text="Test for Decimals", style="TitleLabel.TLabel")
    TitleLabel.grid(column=1, row=0, pady=(50,0), sticky=N)

    DEC=Decimals()
    button=ttk.Button(DECFrame, text="Start", command=DEC.Question1)
    button.grid(column=2, row=2, pady=(200,0), sticky=N)

    DECmaster.mainloop()

在stackoverflowprogram.py在

^{pr2}$

我意识到这里面有很多东西,但如果没有这些,我就无法真正证明我的观点。再次感谢。在


Tags: 模块importconfigurecolumnwidthglobalgridrow
2条回答

不能创建tkinter.Tk的两个实例。如果你这样做,两件事中的一件会发生。在

脚本中的大多数代码可能无法运行,因为它正在等待模块的mainloop完成,直到您退出为止。在

如果结构不同,最终将得到两个Tk实例,其中只有一个实际正在运行。脚本中的一些代码会碰巧找到正确的Tk实例(或者在封面下正确的实际Tk对象),因为有很多共享的全局内容只是假设“某处或其他地方”存在一个Tk并设法找到。但是其他代码会找到错误的代码,并且没有任何效果。或者,有时候,事情会产生错误的影响,或者导致崩溃,谁知道呢。在

您需要将顶级应用程序放在一个地方,无论是模块还是使用它的脚本,然后让另一个地方从那里访问它。在


一种方法是编写模块,使其代码可以用Tk实例调用。然后,使用__main__技巧,这样,如果您直接将模块作为脚本运行(而不是从另一个脚本导入它),它将创建一个Tk实例并调用该代码。这里有一个非常简单的例子。在

在tkmodule.py公司名称:

from tkinter import *

def say_hi():
    print("Hello, world!")

def create_interface(window):
    hi = Button(window, text='Hello', command=say_hi)
    hi.pack()

if __name__ == '__main__':
    root = Tk()
    create_interface(root)
    root.mainloop()

在tkscript.py公司名称:

^{pr2}$

现在,当您运行tkscript.py时,它拥有一个Tk实例,并将其传递给自己的create_frame和{}。但是如果您只运行tkmodule.py拥有一个Tk实例,并将其传递给自己的create_frame。不管怎样,只有一个Tk实例和一个主循环,每个人都可以使用它。在

请注意,如果需要两个顶级窗口,则必须在某处显式地创建一个Toplevel。(而且您不希望总是在tkmodule.py中创建一个,或者当您运行模块本身时,它将创建一个新窗口,并将默认窗口保留为空。)


当然,一种更简单的方法是将所有的GUI内容放入那些从不创建自己的Tk实例的模块中,并编写导入相应模块并驱动它们的脚本。在

问题的根源是您创建了多次Tk的实例。Tkinter应用程序只能有一个Tk类的实例,并且必须恰好调用一次mainloop。如果需要其他窗口,则应创建Toplevelhttp://effbot.org/tkinterbook/toplevel.htm)的实例。在

如果您想用可重用代码创建模块,请让您的模块创建Frame(或者{}的子类,如果您要创建dialos)。然后,主脚本将创建Tk的实例,并将这些框架放置在主窗口或子窗口中。在

如果您希望有时将模块用作可重用组件,有时用作可运行程序,请将“可运行程序”部分放入特殊的If语句中:

# module1.py
import Tkinter as tk
class Module1(tk.Frame):
    def __init__(self, *args, **kwargs):
        label = tk.Label(self, text="I am module 1")
        label.pack(side="top", fill="both", expand=True)

# this code will not run if this module is imported
if __name__ == "__main__":
    root = tk.Tk()
    m1 = Module1(root)
    m1.pack(side="top", fill="both", expand=True)

在上面的代码中,如果您像python module1.py那样运行它,那么最后一个if语句中的代码将运行。它将创建一个根窗口,创建一个框架实例,并使该框架填充主窗口。在

但是,如果将上述代码导入到另一个程序中,If语句中的代码将而不是运行,因此不会得到Tk的多个实例。在

假设您有两个类似于上面的模块,并且希望编写一个使用它们的程序,并且每个模块都应该放在一个单独的窗口中。您可以通过编写第三个脚本来实现这一点:

^{pr2}$

有了上面的代码,两个模块中的代码可以用三种方式使用:作为独立程序,作为单个窗口中的单独框架,或作为单独窗口中的单独框架。在

相关问题 更多 >