0

PyQT4 for Python に問題があります。機能に接続されたテキストとボタンを含むラベルがあります。この関数は、最初にラベルのテキストを変更してから、他の関数を呼び出すことができます。これには問題があります。最初に関数が実行され、次にラベルのテキストが変更されます。

コード:

# -*- coding: utf-8 -*-
import time
import sys
from PyQt4 import QtCore, QtGui

def timesleep():
    print("start sleep")
    time.sleep(5)
    print("stop sleep")



class AnyWidget(QtGui.QWidget):
    def __init__(self,*args):

        QtGui.QWidget.__init__(self,*args)
        self.setWindowTitle("PETHARD")
        boxlay = QtGui.QHBoxLayout(self)
        frame = QtGui.QFrame(self) # Фрейм
        frame.setFrameShape(QtGui.QFrame.StyledPanel)
        frame.setFrameShadow(QtGui.QFrame.Raised)

        gridlay = QtGui.QGridLayout(frame) # Менеджер размещения элементов во фрейме
        label = QtGui.QLabel(u"Welcome",frame) # Текстовая метка.
        global glabel
        glabel = label
        gridlay.addWidget(label,0,0)
        button1 = QtGui.QPushButton(u"Load From MC", frame)
        self.connect(button1, QtCore.SIGNAL("clicked()"), self.ts)
        gridlay.addWidget(button1,1,0)
        boxlay.addWidget(frame)

    def ts(self):
        global glabel
        glabel.setText(u"Waiting...")
        timesleep()

if __name__=="__main__":
    app = QtGui.QApplication(sys.argv)
    aw = AnyWidget()
    aw.show()
    sys.exit(app.exec_())

この問題を解決するために私を助けてください。

4

3 に答える 3

2

レンダリングは後でアプリで行われるため、このように機能します。したがって、glabel.textはすぐに変更されますがts、描画はループの最後で行われるため、関数呼び出し後に画面に変更されたテキストが表示されます。

(新しいテキストのレンダリング後に)新しいフレームで関数を本当に呼び出したい場合は、タイマーを使用します。

timer = QtCore.QTimer()
QtCore.QObject.connect(
    timer,
    QtCore.SIGNAL("timeout()"),
    self.ts
)
timer.start(10)

10ミリ秒後に関数を呼び出す必要があるため、実際にはおそらくレンダリング後に呼び出されます。

于 2013-02-08T12:10:54.993 に答える
1

GUI を実行時間の長い関数と結び付けたくはありません。ラベルが更新されないことは、問題の 1 つの兆候にすぎません。関数が呼び出される前に更新するラベルを取得しても、GUI は「フリーズ」します。長時間実行される関数が完了するまで、ウィジェットはユーザーに応答しません。

このような関数を実行する必要がある場合は、それぞれを細かく分割して GUI に制御を渡す方法があるかどうかを確認するか、別のスレッドを使用して関数を実行することを検討してください。

import time
import sys
from PyQt4 import QtCore, QtGui


class TimeSleep(QtCore.QThread):
    def __init__(self, parent=None):
        QtCore.QThread.__init__(self, parent)
        self.parent = parent

    def run(self):
        print("start sleep")
        time.sleep(5)
        print("stop sleep")
        self.parent.glabel.setText(u"Done")


class AnyWidget(QtGui.QWidget):
    def __init__(self, *args):

        QtGui.QWidget.__init__(self, *args)
        self.setWindowTitle("PETHARD")
        boxlay = QtGui.QHBoxLayout(self)
        frame = QtGui.QFrame(self)  # Фрейм
        frame.setFrameShape(QtGui.QFrame.StyledPanel)
        frame.setFrameShadow(QtGui.QFrame.Raised)

        gridlay = QtGui.QGridLayout(
            frame)  # Менеджер размещения элементов во фрейме
        label = QtGui.QLabel(u"Welcome", frame)  # Текстовая метка.
        self.glabel = label
        gridlay.addWidget(label, 0, 0)
        button1 = QtGui.QPushButton(u"Load From MC", frame)
        self.connect(button1, QtCore.SIGNAL("clicked()"), self.ts)
        gridlay.addWidget(button1, 1, 0)
        boxlay.addWidget(frame)

    def ts(self):
        self.glabel.setText(u"Waiting...")
        self.thread = TimeSleep(parent=self)
        self.thread.start()


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    aw = AnyWidget()
    aw.show()
    sys.exit(app.exec_())

これは、長時間実行される関数を処理する方法に関するwiki ページです。

于 2013-02-08T12:29:55.260 に答える
1

ラベルのテキストが変更されていますが、メイン スレッドをブロックしているため、Qt にペイントする機会がありません。

とを使用QCoreApplication::processEventsQCoreApplication::flushます。

def ts(self):
    glabel.setText(u"Waiting...")
    QtCore.QCoreApplication.processEvents()
    QtCore.QCoreApplication.flush()
    timesleep()
于 2013-02-08T12:48:05.787 に答える