【问题标题】:Running a function until another one would be done运行一个函数,直到另一个函数完成
【发布时间】:2021-09-08 18:21:05
【问题描述】:

我的目标是在创建 label2 之前使 label1(绿色)可见,并将其隐藏在 secondLabel 的末尾,但是当我运行此代码时,它只显示 label2(橙色)。 (在我的实际代码中,第二个函数需要很长时间才能加载,这就是我添加单次拍摄的原因)

只有绿色标签可见->(大约两秒)->只有橙色标签可见

import sys
from PyQt5 import QtCore, QtGui, QtWidgets

labelList = [None, None]

def empty():
    pass

def firstLabel(frame):
    label1 = QtWidgets.QLabel(window)
    label1.setGeometry(240, 80, 40, 40)
    label1.setStyleSheet("background-color: rgb(20, 87, 30)")
    labelList[0] = label1
    secondLabel(frame)

def secondLabel(frame):
    timer = QtCore.QTimer(window)
    timer.singleShot(2000, empty)
    label2 = QtWidgets.QLabel(window)
    label2.setGeometry(20, 40, 200, 120)
    label2.setStyleSheet("background-color: rgb(255, 75, 20);")
    label2.show()
    labelList[1] = label2
    labelList[0].hide()

def myFunc(frame):
    firstLabel(frame)

app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QWidget()
window.setFixedWidth(300)
window.setFixedHeight(200)
window.setWindowTitle("Window")
window.move(100, 50)

frame = QtWidgets.QFrame(window)
frame.setGeometry(0, 0, 300, 200)
frame.setStyleSheet("background-color: rgb(208, 208, 208);")
myFunc(frame)

window.show()
sys.exit(app.exec_())

【问题讨论】:

  • 两件事: 1. Qt 不太适合过程模式,应该首选更 OOP 的方法(涉及使用类); 2.如果你有一个需要很长时间才能完成的功能,你应该使用QThread,这几乎强制使用类:虽然它可以实现,但它只会做事不必要的复杂。
  • @musicamante 我使用了普通线程,但它们不起作用。普通线程的唯一限制是您不能创建 qt 对象,但可以在它们上使用 qt 方法。没用。有什么办法可以使这个问题起作用吗? (使用类等)
  • @GrantWard101 请提供带有普通线程minimal reproducible example
  • @GrantWard101 这就是我谈到 QThread 的原因。普通的 python 线程不允许与主 UI 线程交互,但是在子类 QThread(或移动到 QThread 的 QObject 子类)中使用信号允许这样做,因为信号连接是线程安全的。我再说一遍,如果你想要一个 valid 实现,那么类是必需的。不要试图通过使用“工作”的复杂而复杂的系统来找到自己的方式,它只会使事情变得不必要的困难(并且容易出现错误和意外行为);了解类的工作原理以及如何使用它们。

标签: python pyqt5


【解决方案1】:

我设法使用时间模块解决了这个问题。这并不理想,但适用于这种情况。

import time
import threading
import sys
from PyQt5 import QtCore, QtGui, QtWidgets

labelList = [None, None]

def empty():
    pass

def firstLabel(frame):
    label1 = QtWidgets.QLabel(window)
    label1.setGeometry(240, 80, 40, 40)
    label1.setStyleSheet("background-color: rgb(20, 87, 30)")
    labelList[0] = label1
    secondLabel(frame)

def secondLabel(frame):
    time.sleep(2)
    labelList[1].show()
    labelList[0].hide()

def myFunc(frame):
    timer.singleShot(2000, empty)

app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QWidget()
window.setFixedWidth(300)
window.setFixedHeight(200)
window.setWindowTitle("Window")
window.move(100, 50)

frame = QtWidgets.QFrame(window)
frame.setGeometry(0, 0, 300, 200)
frame.setStyleSheet("background-color: rgb(208, 208, 208);")

timer = QtCore.QTimer(window)
label1 = QtWidgets.QLabel(window)
label1.setGeometry(240, 80, 40, 40)
label1.setStyleSheet("background-color: rgb(20, 87, 30)")
labelList[0] = label1

label2 = QtWidgets.QLabel(window)
label2.setGeometry(20, 40, 200, 120)
label2.setStyleSheet("background-color: rgb(255, 75, 20);")
label2.hide()
labelList[1] = label2

threading.Thread(target = secondLabel, args = (frame,), daemon = True).start()

window.show()
sys.exit(app.exec_())

【讨论】:

  • 抱歉,这不是一个有效的解决方案。我知道您使用的是time.sleep 而不是您的长流程,但这不是 UI 程序的行为方式,因为需要很长时间的函数应该移到一个线程中,这样它们就不会完全阻止 UI 交互和正确绘图。
猜你喜欢
  • 2019-11-14
  • 2012-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-28
  • 1970-01-01
  • 1970-01-01
  • 2022-11-17
相关资源
最近更新 更多