Метка в PyQt4 GUI не обновляется с каждым циклом цикла FOR

У меня проблема, где я хочу запустить несколько функций командной строки из программы python с помощью GUI. Я не знаю, является ли моя проблема специфичной для в составе PyQt4 или если это связано с моим плохим использованием кода python.

Я хочу, чтобы метка на моем GUI изменила текстовое значение, чтобы сообщить пользователю, какая команда выполняется. Однако моя проблема возникает, когда я запускаю несколько команд с помощью на петли. Я хотел бы, чтобы лейбл обновился сам с каждым циклом, однако, программа не обновляет метку GUI с каждым циклом, вместо этого она обновляет себя только один раз весь на цикл завершен и отображает только последнюю выполненную команду.

Я использую PyQt4 для своей среды GUI. И я установил, что текстовая переменная для метки действительно обновляется с каждым циклом, но на самом деле она не отображается визуально в GUI.

есть ли способ заставить лейбл обновиться? Я пробовал update () и перекрашивать() методы внутри цикла, но они не имеют никакого значения.

Я бы очень признателен за любую помощь. Спасибо.

Рони.

вот код, который я использую:

# -*- 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_())

2 ответов


метка обновляется все в порядке,но GUI не перерисовывается до конца вашего цикла.

вот что вы можете сделать о нем:

  • переместите свой длительный цикл во вторичный поток, рисование GUI происходит в основном потоке.

  • вызов app.processEvents() в цикле. Это дает Qt возможность обрабатывать события и перерисовывать GUI.

  • разбейте цикл и позвольте ему работать с помощью QTimer с таймаутом 0.

использование потока является лучшим вариантом, но включает в себя немного больше работы, чем просто вызов processEvents. Делать это с помощью таймера-это старомодный способ и больше не рекомендуется. (см. документацию)


у вас есть основное непонимание того, как работает такой GUI. Графический интерфейс Qt должен работать в собственном цикле событий. Вместо этого выполняется цикл, и GUI не может выполнять свою работу между исполнениями вашего цикла. То есть, пока ваш for цикл работает код GUI не получает время процессора и не будет обновляться.

вы можете настроить таймер с событием и выполнить свой код в обработчиках этого события заданное количество времени - это решит вашу проблему.