Python tk():在脚本中使用时没有窗口出现(控制台工作)

时间:2015-04-28 08:03:10

标签: python-2.7 tkinter window root tk

这个简单的脚本我有以下问题:

from Tkinter import *
root = Tk()
while 1:
   pass

我认为,在第二行之后,每个人都会期望出现一个Tkinter窗口。但事实并非如此! 如果我将这一行放入Python控制台(没有无限循环),它就可以工作。

[我想在这里添加一张图片,但是因为我是新手,所以我可以: - ()

但是运行脚本(双击Windows资源管理器中的* .py文件)只会产生一个空的Python控制台!

背景: 其实我想用Snack for Python。这是基于Tkinter。这意味着我必须首先创建一个Tk()实例。在Python控制台中一切正常。但我想用至少一个Python脚本编写一个更大的程序,因此我不能每次都将整个程序输入控制台: - )

我已经安装了Python 2.7和Tcl / Tk 8.5(请记住:它可以在控制台中运行)

编辑:所以这是我的解决方案:

首先,我创建了一个类CSoundPlayer:

from Tkinter import*
import tkSnack

class CSoundPlayer:
    def __init__(self, callbackFunction):
        self.__activated = False
        self.__callbackFunction = callbackFunction
        self.__sounds = []
        self.__numberOfSounds = 0
        self.__root = Tk()
        self.__root.title("SoundPlayer")
        tkSnack.initializeSnack(self.__root)

    def __mainFunction(self):
        self.__callbackFunction()
        self.__root.after(1, self.__mainFunction)
        pass

    def activate(self):
        self.__activated = True
        self.__root.after(1, self.__mainFunction)
        self.__root.mainloop()

    def loadFile(self, fileName):
        if self.__activated:
            self.__sounds.append(tkSnack.Sound(load=fileName))
            self.__numberOfSounds += 1
            # return the index of the new sound
            return self.__numberOfSounds - 1
        else:
            return -1

    def play(self, soundIndex):
        if self.__activated:
            self.__sounds[soundIndex].play()
        else:
            return -1

然后,应用程序本身必须在类中实现,因此在移交给CSoundPlayer()构造函数时定义main():

class CApplication:
    def __init__(self):
        self.__programCounter = -1
        self.__SoundPlayer = CSoundPlayer(self.main)
        self.__SoundPlayer.activate()

    def main(self):
        self.__programCounter += 1
        if self.__programCounter == 0:
            self.__sound1 = self.__SoundPlayer.loadFile("../mysong.mp3")
            self.__SoundPlayer.play(self.__sound1)
        # here the cyclic code starts:
        print self.__programCounter

CApplication()

如您所见,mainloop()不是在构造函数中调用,而是在activate()方法中调用。这是因为CApplication永远不会获得对CSoundPlayer对象的引用,因为它停留在mainloop中。 CApplication类的代码本身会产生很多开销。实际的“应用程序代码”放在CApplication.main()中 - 代码只能通过程序计数器控制一次。

现在我将它放到下一级并将MIDI设备的轮询过程放在CApplication.main()中。因此,我将使用MIDI命令作为播放声音文件的触发器。我希望性能足以适应延迟。

您有任何优化建议吗?

1 个答案:

答案 0 :(得分:1)

您必须启动事件循环。没有事件循环,tkinter无法实际绘制窗口。移除while循环并将其替换为mainloop

from Tkinter import *
root = Tk()
root.mainloop()

如果您需要进行轮询(如问题的评论中所述),请编写一个轮询的函数,并使用after定期运行该函数:

def poll():
    <do the polling here>

    # in 100ms, call the poll function again
    root.after(100, poll)

您在控制台中不需要主循环的原因取决于您对控制台&#34;的含义。在IDLE和其他一些交互式解释器中,tkinter在交互式运行时有一种特殊的模式,不需要你调用mainloop。本质上,mainloop是控制台输入循环。