我遇到了一个问题,我希望使用GUI从python程序运行几个命令行函数。我不知道我的问题是特定于PyQt4还是与我对python代码的错误使用有关。
我想做的是在我的GUI上有一个标签,改变它的文本值,通知用户正在执行哪个命令。但是,当我使用for循环运行多个命令时,就会出现问题。我希望标签用每个循环更新自己,但是,程序并不是用每个循环更新GUI标签,而是只在整个for循环完成后更新自己,并且只显示最后执行的命令。
我正在为我的GUI环境使用PyQt4。我已经确定了标签的文本变量确实是随着每个循环而更新的,但是,它实际上并没有在GUI中可视化地显示出来。
有没有办法让我强制标签自我更新?我在循环中尝试了update()和repaint()方法,但它们没有任何区别。
我非常感谢你的帮助。 谢谢您。
罗尼。
下面是我使用的代码:
# -*- coding: utf-8 -*-
import sys, os
from PyQt4 import QtGui, QtCore
Gui = QtGui
Core = QtCore
# ================================================== CREATE WINDOW OBJECT CLASS
class Win(Gui.QWidget):
def __init__(self, parent = None):
Gui.QWidget.__init__(self, parent)
# --------------------------------------------------- SETUP PLAY BUTTON
self.but1 = Gui.QPushButton("Run Commands",self)
self.but1.setGeometry(10,10, 200, 100)
# -------------------------------------------------------- SETUP LABELS
self.label1 = Gui.QLabel("No Commands running", self)
self.label1.move(10, 120)
# ------------------------------------------------------- SETUP ACTIONS
self.connect(self.but1, Core.SIGNAL("clicked()"), runCommands)
# ======================================================= RUN COMMAND FUNCTION
def runCommands():
for i in commands:
win.label1.setText(i) # Make label display the command being run
print win.label1.text() # This shows that the value is actually
# changing with every loop, but its just not
# being reflected in the GUI label
os.system(i)
# ======================================================================== MAIN
# ------------------------------------------------------ THE TERMINAL COMMANDS
com1 = "espeak 'senntence 1'"
com2 = "espeak 'senntence 2'"
com3 = "espeak 'senntence 3'"
com4 = "espeak 'senntence 4'"
com5 = "espeak 'senntence 5'"
commands = (com1, com2, com3, com4, com5)
# --------------------------------------------------- SETUP THE GUI ENVIRONMENT
app = Gui.QApplication(sys.argv)
win = Win()
win.show()
sys.exit(app.exec_())
标签更新得很好,但是在循环结束之前不会重绘GUI。
以下是您可以采取的措施:
将长时间运行的循环移动到辅助线程,在主线程中绘制图形用户界面。
在循环中调用
app.processEvents()
。这使Qt有机会处理事件并重新绘制GUI。中断循环并使用超时为0的QTimer运行它。
使用线程是最好的选择,但是要做的工作比调用processEvents要多得多。用计时器来计时是一种过时的方式,不再被推荐。(见文件)
你对这样一个GUI的工作原理有一个基本的误解。Qt GUI必须在自己的事件循环中运行。相反,循环会运行,而GUI无法在循环执行之间执行其工作。也就是说,当您的
for
循环运行时,GUI代码不会获得CPU时间,也不会更新。你可以用一个事件设置一个计时器,并在这个事件的处理程序中执行你的代码一段时间-这将解决你的问题。
或者您可以调用
repaint()
它可以立即更新GUI。相关问题 更多 >
编程相关推荐