我应该在哪里放置主循环?

时间:2013-05-25 13:27:57

标签: python loops tkinter pyqt systray

我有一个用IDLE3.3和tkinter编写的程序,我不知道在哪里放置mainloop()。该程序会创建一个系统托盘图标,如果您单击上下文菜单中的“新笔记”,则会创建一个小笔记。如果在Note。 init ()的末尾有“self.root.mainloop()”行,则会显示注释,但只显示一个注释。如果我创建第二个,第一个音符已经死了,没有进一步发生。 但是如果我不在init方法中调用mainloop(),我会看到创建了几个注释,因为它是在shell中打印的。 所以问题是,我应该在哪里放置主循环,以便每个新创建的notw都显示并起作用?对不起那个可能很愚蠢的问题,但我无法弄清楚。

from tkinter import *
import sys
from PyQt4.QtGui import *
import threading


class Note():

    yellow=["#e7e37c","#d9d574"]

    def __init__(self,noteset=None, properties=None):
        self.root=Tk()
        self.noteset=noteset
        self.properties=properties
        self.screen_width = self.root.winfo_screenwidth()      
        self.screen_height = self.root.winfo_screenheight()    
        print("No initial properties to load => creating new note")
        self.notecolor=self.yellow[0]
        self.gripcolor=self.yellow[1]
        self.root.overrideredirect(1) 
        self.text=""
        self.font="arial"
        self.fontsize=10  
        self.sizeX=250 
        self.sizeY=200
        self.posX=int(self.screen_width/2 - self.sizeX/2)   
        self.posY=int(self.screen_height/2 - self.sizeY/2)
        self.root.wm_geometry("%sx%s+%s+%s"   %(self.sizeX,  self.sizeY,  self.posX,  self.posY) )           
        self.root.wm_attributes("-topmost",1)
        self.GUI()
        self.bindings()

        self.root.mainloop()

    def bindings(self):
        self.frmGRIP.bind("<ButtonPress-1>", self.StartMove)
        self.frmGRIP.bind("<ButtonRelease-1>", self.StopMove)
        self.frmGRIP.bind("<B1-Motion>", self.OnMotion)

    def StartMove(self, event):
        self.startx = event.x
        self.starty = event.y
    def OnMotion(self, event):           
        mousex,mousey=self.root.winfo_pointerxy()
        self.root.geometry("+%s+%s" % (mousex-self.startx, mousey-self.starty))
    def StopMove(self, event):
        self.posX = self.root.winfo_x()
        self.posY = self.root.winfo_y()

    def GUI(self):                 
        self.frmTOP=Frame(master=self.root,height=15)
        self.frmBOTTOM=Frame(master=self.root,width=300,height=300)
        self.frmGRIP=Frame(self.frmTOP,bg=self.gripcolor,height=15)
        self.frmRESIZE=Frame(self.frmBOTTOM,width=300,height=10)
        self.frmTEXT=Frame(self.frmBOTTOM,bg=self.notecolor,width=300,height=300)
        self.frmRESIZE_empty=Frame(self.frmRESIZE,bg=self.notecolor,height=10)
        self.frmRESIZE_grip=Frame(self.frmRESIZE,bg=self.gripcolor,width=10,height=10)

        self.frmTOP.pack(fill=X,expand=NO)
        self.frmBOTTOM.pack(side=BOTTOM,fill=BOTH,expand=YES) 
        self.frmGRIP.pack(side=LEFT,fill=X,expand=YES)
        self.frmRESIZE.pack(side=BOTTOM,fill=X)        
        self.frmTEXT.pack(side=BOTTOM,fill=BOTH,expand=YES)
        self.frmRESIZE_empty.pack(side=LEFT,fill=X,expand=YES)
        self.frmRESIZE_grip.pack(side=LEFT,expand=NO)

        self.T=Text(self.frmTEXT,
                    height=6,width=30,
                    bd=0,wrap=WORD,pady=3,padx=5,
                    bg=self.notecolor,undo=1,
                    font=(self.font,self.fontsize)
                    )
        self.T.insert(END,self.text)
        self.T.pack(fill=BOTH,expand=YES)        

class Noteset():
    def __init__(self):
        self.notes = []
    def newNote(self):
        note=Note(noteset=self)
        self.notes.append(note)
        print(self.notes)
        return note

class Main():
    def __init__(self):
        self.N=Noteset()
        app = QApplication(sys.argv)

        trayIcon = QSystemTrayIcon(QIcon("J:\\python\\SimpleNotes.ico"), app)
        menu = QMenu()

        ActionNewNote = menu.addAction("new Note")
        ActionNewNote.triggered.connect(self.newNote)
        trayIcon.setContextMenu(menu)
        trayIcon.show()

        app.exec()

    def newNote(self):
        self.N.newNote()


Main()

2 个答案:

答案 0 :(得分:1)

将gui框架混合起来并不是一个好主意,因为每个主循环都会相互阻塞,最好在一个或另一个中编写整个代码。

答案 1 :(得分:1)

您无法一起成功使用Qt和Tkinter。此外,如果您从上面删除Qt,则还有一个问题,即您不应创建多个Tk的实例。

要回答您的具体问题,mainloop通常是您执行的最后一行代码。由于它是一个无限循环,所以在调用mainloop之后的任何代码都不会执行,直到主窗口被销毁。

Tkinter应用程序的正常结构如下:

import Tkinter as tk
class MyApp(...):
    def __init__(self, root, ...):
        ...
    ...

root = tk.Tk()
myApp(root)
root.mainloop()