简体   繁体   English

Tkinter上运行的多个应用程序/文件/ Windows实例

[英]Multiple application/file/windows instances running on tkinter

Here is a sample situation: 这是一个示例情况:

I have written a tk GUI that opens and edits eg .txt files. 我写了一个tk GUI,可以打开和编辑.txt文件。 I'm currently on a mac, but I might also want to run this on windows. 我目前在Mac上,但我可能还想在Windows上运行它。 Currently the main Application class creates its own internal tk.Tk() like so 当前,主要的Application类创建自己的内部tk.Tk()如下所示

    import tkinter as tk

class App:
    def __init__(self):
        self.root = tk.Tk()
        tk.Label(master=self.root,text="content").pack()

if __name__ == '__main__':
    a=App()
    a.root.mainloop()

I want to add multi file capabilities to the application. 我想向应用程序添加多文件功能。 In the current system this would result in 2 tk.Tk() instances running which I couldn't get to work and people say is unpredictable. 在当前系统中,这将导致2个tk.Tk()实例运行,但我无法正常工作,人们说这是不可预测的。

I want to be able to close any of the multiple files and still have the application running until the last window is closed and then the application quit or stays without a window (like on a mac). 我希望能够关闭多个文件中的任何一个,并且仍要运行应用程序,直到关闭最后一个窗口,然后应用程序退出或保持没有窗口(例如在Mac上)。

My problem is that if I use tk.Toplevel() for each of my windows I have a ugly default tk.Tk() window which I would need to hide which seams inelegant. 我的问题是,如果我对每个窗口都使用tk.Toplevel() ,则我的丑陋的默认tk.Tk()窗口将需要隐藏tk.Tk()接缝。 It would also be messy to determine which file is currently in focus for actions with the menubar. 用菜单栏确定当前焦点在哪个文件上对于操作来说也很麻烦。

I'm also considering each file being it's own application instance like on Windows, but that would fill the dock with repeated icons and be inconsistent with the rest of the system. 我还在考虑像Windows一样,每个文件都是其自己的应用程序实例,但是这样会使重复的图标充满坞站,并且与系统的其余部分不一致。

Here are the possible way I came up with: Multiple Tks (Works but more complex examples are unpredictable): 这是我想出的可能方法:多个Tks(有效,但更复杂的示例是不可预测的):

import tkinter as tk

class App:
    def __init__(self):
        self.root = tk.Tk()
        tk.Label(master=self.root,text="content").pack()
        tk.Button(master=self.root,text="new_window",command=self.open).pack()

    def open(self):
        App()

if __name__ == '__main__':
    a=App()
    a.root.mainloop()

Hidden tk window and multiple Toplevels (Needs hiding the Tk and the osx menubar commands like view->change_colors would need to manaly decide where to direct comands): 隐藏的tk窗口和多个顶层(需要隐藏Tk和osx菜单栏命令,例如view-> change_colors,需要费力地决定将命令指示在哪里):

import tkinter as tk

class App:
    def __init__(self):
        self.root = tk.Toplevel()
        tk.Label(master=self.root,text="content").pack()
        tk.Button(master=self.root,text="new_window",command=self.open).pack()

    def open(self):
        App()

if __name__ == '__main__':
    tk.Tk()
    a=App()
    a.root.mainloop()

Each Window is its own Application and fully independant (Dosn't fit in with the other mac applications, the implementation is ugly): 每个窗口都是其自己的应用程序,并且是完全独立的(与其他mac应用程序不匹配,实现很难看):

#!/usr/local/bin/python3
import tkinter as tk
import sys,os

class App:
    def __init__(self):
        self.root = tk.Tk()
        tk.Label(master=self.root,text="content").pack()
        tk.Button(master=self.root,text="new_window",command=self.open).pack()

    def open(self):
        os.system(sys.argv[0]+"&")

if __name__ == '__main__':
    a=App()
    a.root.mainloop()

I was alos think of maybe doing it with threads but I think I must be over thinking it so I came here. 我当时还没有想过可能要用线程来做,但是我想我必须考虑一下,所以我来了。 Is there a generally accepted way of doing this in tk? 在tk中有一种普遍接受的方法吗?

The generally accepted way is just like you describe: use Toplevel for additional windows, and hide the root window if you don't want to see it. 普遍接受的方式就像您描述的那样:对其他窗口使用Toplevel ,如果不想看到,则隐藏根窗口。

Another choice is to make your main program a non-GYI app, and each window is created by spawning a new process. 另一个选择是使您的主程序成为非GYI应用程序,并且通过生成新进程来创建每个窗口。

Hidden tk window and multyple Toplevels (Needs hiding the Tk and the osx menubar commands like view->change_colors would need to manaly decide where to direct comands): 隐藏的tk窗口和多个顶层(需要隐藏Tk和osx菜单栏命令,例如view-> change_colors,需要费力地决定将命令指向何处):

It is easy to get into "which goes with what" hell with multiple Toplevels. 使用多个顶级级别很容易进入“随什么而行”地狱。 Instead create a separate class for each new Toplevel with built in responses to button clicks, etc. Pass "root" to the class and let it create, update, and destroy as necessary, and keep track of it's own variables. 而是为每个新的Toplevel创建一个单独的类,并具有对按钮单击等的内置响应。将“ root”传递给该类,让它根据需要创建,更新和销毁,并跟踪其自身的变量。 If you want to use variables elsewhere, then store the class instance when the Toplevel classes are called and create the variables within the class as instance attributes. 如果要在其他地方使用变量,请在调用顶级类时存储类实例,并在该类中将变量创建为实例属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM