Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python PyQt4 GUI中的标签不随FOR循环的每个循环更新_Python_For Loop_Label_Pyqt4 - Fatal编程技术网

Python PyQt4 GUI中的标签不随FOR循环的每个循环更新

Python PyQt4 GUI中的标签不随FOR循环的每个循环更新,python,for-loop,label,pyqt4,Python,For Loop,Label,Pyqt4,我遇到了一个问题,我希望使用GUI从python程序运行几个命令行函数。我不知道我的问题是特定于PyQt4还是与我对python代码的不当使用有关 我想做的是让GUI上的标签更改其文本值,以通知用户正在执行哪个命令。但是,当我使用for循环运行多个命令时,问题就出现了。我希望标签在每个循环中都能自我更新,但是,程序并不是在每个循环中都更新GUI标签,而是在整个for循环完成后才自我更新,并且只显示最后执行的命令 我在GUI环境中使用PyQt4。我已经确定标签的文本变量确实随着每个循环而更新,但是

我遇到了一个问题,我希望使用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在循环结束之前不会重新绘制

以下是您可以采取的措施:

  • 将长时间运行的循环移动到辅助线程,在主线程中绘制GUI

  • 在循环中调用
    app.processEvents()
    。这使Qt有机会处理事件并重新绘制GUI

  • 分解循环,让它使用超时为0的


使用线程是最好的选择,但它比调用processEvents需要做更多的工作。用计时器计时是一种老式的方式,不再被推荐。(请参阅文档)

您对这种GUI的工作原理有一个基本的误解。QtGUI必须在自己的事件循环中运行。相反,您的循环会运行,GUI无法在循环执行之间完成其工作。也就是说,当您的
for
循环正在运行时,GUI代码不会占用CPU时间,也不会更新


您可以设置一个带有事件的计时器,并在该事件的处理程序中执行一定时间的代码-这将解决您的问题。

或者您可以调用
repaint()
立即更新GUI。

非常感谢!我发现app.processEvents()只在每个命令完成后才更改标签,这太晚了,而且还跳过了一些命令。所做的工作是使用run方法创建一个新的QThread对象,并在按下按钮时调用run方法。这就是你的意思吗?这是我使用的代码。我以前从未学过线程,所以如果我不明智地应用了它,请告诉我。类RunCommands(Core.QThread):def run(self):for i in commands:win.label1.setText(i)os.system(i)噢,天哪,注释没有打印出来,我输入了新的行和选项卡:(@Ronny:听起来不错,但是你应该调用
start()
而不是
run()
。感谢您在回复的第一段中所作的解释。现在,这让我对正在发生的事情有了更多的了解,也帮助我更好地理解了Georg回答背后的原因。但是,我不理解您提出的实际解决方案。我是一名编程新手。也许是一个简单的大纲可能涉及的代码草图会很有帮助。尽管我现在已经找到了一个似乎有效的解决方案,但我也很想了解您提出的替代方案。@Ronny:了解QTimer并看看它的一些用法示例-我想您会明白的