无法在 ubuntu 16.04.2 上的 tkinter 中使用 tk.mainloop()

Unable use tk.mainloop() in tkinter on ubuntu 16.04.2

每当我在 ubuntu 16.04.2 上使用 tk.mainloop() 尝试 运行 一个简单的 tkinter 程序 - 或该母校的任何程序时,我无法打开应用程序 window,window 图标上显示一个问号。

这是我的程序 运行ning:

import tkinter as tk

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

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

这是一个屏幕截图,显示了每当我 运行 它时程序的输出:

在此之前,我收到一条错误消息,提示可以加载 _tkinter。为了解决这个问题,我使用 sudo apt-get update 然后 sudo apt-get install python3-tk 下载了 ubuntu 的最新版本 tkinter。如果这也很重要,我在 windows 10.

的双引导配置中使用 ubuntu

我也读过 How can I fix program icons that appear as a question mark in the Launcher? and Why do some open applications appear as “question marks” in the Unity launcher?,但这些问题似乎是关于如何修复应用程序桌面图标,而不是如何修复不会 运行 的应用程序。此外,问题似乎与特定的 ubuntu 应用程序有关。

有谁知道为什么 ubuntu 没有正确 运行 应用 tkinter 以及如何解决这个问题?

尝试像这样稍微更改程序的主要部分:

if __name__ == '__main__':
    root = tk.Tk()
    your_class_instance = MainApplication(root)
    print(your_class_instance)
    root.mainloop()

您将在终端上看到如下内容:.140449273960656

现在让我们回到您的原始代码:

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

您将在您的终端上看到 None

为什么? 那是因为 tkinter 的布局管理器 (pack(), place() and grid()) 总是 return None 并且 MainApplication class 没有小部件。

也就是说,你什么都不显示。

注意pack(your_options_list)在这一行没有用:

MainApplication(root).pack(side="top", fill="both", expand=True)

它不仅没有用,而且会阻止应用程序进一步扩展,因为无法使用 MainApplication class.

的实例

也许这对于你的实际问题来说不是必需的,但作为旁注,因为你使用的是 Python 3,你可以使用:super().__init__(parent, *args, **kwargs) 而不是 super(MainApplication, self).__init__(parent, *args, **kwargs)

证明提供的解释。

我为您的问题提供的解释(上面的 为什么?)指出有 2 个事实导致您出现这种情况。如果满足其中之一,则问题消失:

  1. 保留 pack() 但要求 MainApplication 绘制至少一个小部件:

    import tkinter as tk
    
    
    class MainApplication(tk.Frame):
        def __init__(self, parent, *args, **kwargs):
            super(MainApplication, self).__init__(parent, *args, **kwargs)
            # I add these 2 following lines
            self.parent = parent
            self.initialize_gui()
    
    def initialize_gui(self):
       # Ok, let us draw one useless button for a test
       self.button_1 = tk.Button(self.parent, text="Do nothing")
       self.button_1.pack()
    
    
    if __name__ == '__main__':
        root = tk.Tk()
        MainApplication(root).pack(side="top", fill="both", expand=True)
        root.mainloop()
    

您将看到 GUI:

  1. MainApplicationclass不绘制任何小部件但删除pack():

    import tkinter as tk
    
    
    class MainApplication(tk.Frame):
        def __init__(self, parent, *args, **kwargs):
            super(MainApplication, self).__init__(parent, *args, **kwargs)       
    
    
    if __name__ == '__main__':
        root = tk.Tk()
        MainApplication(root) # Remove pack(...)
        root.mainloop()
    

您可以看到 GUI:

虽然我看起来不像,但 tkinter window 实际上就在那里。它很小很容易看到,因为它里面没有小部件来扩展它。一旦您开始向 window 添加小部件,它就会变得可见。

例如,要使用相关代码显示 window,

import tkinter as tk


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


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

您可以添加一个 tk.Button() 小部件来强制 window 展开:

import tkinter as tk


class MainApplication(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        super(MainApplication, self).__init__(parent, *args, **kwargs)
        # create a button widget to force the window to expand to fit
        # the button
        self.btn = tk.Button(self, text='btn', bg='blue')
        self.btn.pack(side='bottom')


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

显示以下内容window: