如何在Python中同时运行多个tkinter窗口?

2024-10-01 13:29:41 发布

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

所以我正在制作一个记录笔记的应用程序(类似于Windows便笺)。因为我需要同时显示多个注释,所以我使用了一个继承自Thread的类并创建了一个tkinter窗口。问题是我的窗户不能同时打开。第二个在第一个关闭后打开。这是密码。我做错什么了?还有别的方法可以用吗?[目前我只显示我已硬编码的笔记。]

from tkinter import *
from threading import Thread

class Note(Thread):
nid = 0
title = ""
message = ""

    def __init__(self, nid, title, message):
      Thread.__init__(self)
      self.nid = nid
      self.title = title
      self.message = message


    def display_note_gui(self): 
      '''Tkinter to create a note gui window with parameters '''    
      window = Tk()
      window.title(self.title)
      window.geometry("200x200")
      window.configure(background="#BAD0EF")

      title = Entry(relief=FLAT, bg="#BAD0EF", bd=0)
      title.pack(side=TOP)
      scrollBar = Scrollbar(window, takefocus=0, width=20)
      textArea = Text(window, height=4, width=1000, bg="#BAD0EF", font=("Times", "14"))
      scrollBar.pack(side=RIGHT, fill=Y)
      textArea.pack(side=LEFT, fill=Y)
      scrollBar.config(command=textArea.yview)
      textArea.config(yscrollcommand=scrollBar.set)
      textArea.insert(END, self.message)
      window.mainloop()

    def run(self):
      self.display_note_gui()

new_note1 = Note(0, "Hello", "Hi, how are you?")
new_note1.start()
new_note1.join()


new_note2 = Note(1, "2", "How's everyone else?")
new_note2.start()
new_note2.join()

Tags: selfmessagenewtitledefguiwindowthread
2条回答

如果你只需要多个便笺窗口,那么你绝对不需要线程。Tkinter可以管理几十个或几百个打开的窗口。在

只需为根窗口以外的每个窗口创建Toplevel的实例。这里有一个有点过度设计的例子:

import Tkinter as tk

class Notepad(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.text = tk.Text(self, wrap="word")
        self.vsb = tk.Scrollbar(self, orient="vertical", comman=self.text.yview)
        self.text.configure(yscrollcommand=self.vsb.set)
        self.vsb.pack(side="right", fill="y")
        self.text.pack(side="left", fill="both", expand=True)

def main():
    root = tk.Tk()
    Notepad(root).pack(fill="both", expand=True)
    for i in range(5):
        top = tk.Toplevel(root)
        Notepad(top).pack(fill="both", expand=True)

    root.mainloop()

if __name__ == "__main__":
    main()

tkinter中的顶层不是子类化Thread,而是子类Toplevel,它是同一应用程序中的一个单独的窗口,听起来就像您正试图完成的:

from tkinter import *
#from threading import Thread #no longer needed

class Note(Toplevel):
    nid = 0
    #title = "" #this would block the method to override the current title
    message = ""

    def __init__(self, master, nid, title, message):
      Toplevel.__init__(self,master)
      self.nid = nid 
      self.title(title) #since toplevel widgets define a method called title you can't store it as an attribute
      self.message = message
      self.display_note_gui() #maybe just leave that code part of the __init__?


    def display_note_gui(self): 
      '''Tkinter to create a note gui window with parameters '''    
      #no window, just self
      self.geometry("200x200")
      self.configure(background="#BAD0EF")
      #pass self as the parent to all the child widgets instead of window
      title = Entry(self,relief=FLAT, bg="#BAD0EF", bd=0)
      title.pack(side=TOP)
      scrollBar = Scrollbar(self, takefocus=0, width=20)
      textArea = Text(self, height=4, width=1000, bg="#BAD0EF", font=("Times", "14"))
      scrollBar.pack(side=RIGHT, fill=Y)
      textArea.pack(side=LEFT, fill=Y)
      scrollBar.config(command=textArea.yview)
      textArea.config(yscrollcommand=scrollBar.set)
      textArea.insert(END, self.message)
      #self.mainloop() #leave this to the root window

    def run(self):
      self.display_note_gui()

root = Tk()
root.withdraw() #hide the root so that only the notes will be visible

new_note1 = Note(root, 0, "Hello", "Hi, how are you?")
#new_note1.start()
#new_note1.join()


new_note2 = Note(root, 1, "2", "How's everyone else?")
#new_note2.start()
#new_note2.join()

root.mainloop() #still call mainloop on the root

请注意,您可以调用self.title()来获取窗口的当前标题,并调用{}来更改它,而不是将标题存储为属性。在

相关问题 更多 >