2016-03-30 2 views
0

поэтому я делаю приложение, которое делает заметки (аналогично Windows Sticky Notes). Так как мне нужно отображать несколько заметок одновременно, я использовал класс, который наследует от Thread, а также создает окно tkinter. Проблема в том, что мои окна не открываются одновременно. Второй открывается после первого закрытия. Вот код. Что я делаю не так? Есть ли другой способ, который я могу использовать? [На данный момент я просто отображение заметок я жестко закодированные.]Как запустить несколько окон tkinter одновременно в Python?

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() 
+0

использовать виджет Toplevel? –

ответ

0

Вместо подклассов Thread просто подкласс Toplevel, верхний уровень в Tkinter отдельное окно в том же приложении, которое звучит как именно то, что вы пытаетесь достичь:

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(), чтобы получить текущее название окна и self.title("new title"), чтобы его изменить.

+0

Спасибо, это сработало! Спасибо за предложение о названии, я довольно новичок в python, и я это очень хорошо понял :) – Me95

+0

, обычно используя атрибут под названием 'title', было бы прекрасно, это было единственное, что действительно нужно было изменить для вашего кода чтобы сделать его совместимым с подклассом «Toplevel» –

+0

, если он не вызывал кучу ошибок «str object is not callable», когда я его тестировал, я бы оставил его именно так, как вы его получили. :) –

1

Если все, что вам нужно, это несколько окон примечание, то вы определенно не нужны темы. 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() 
Смежные вопросы