gpt4 book ai didi

python - PyQt 进度条的忙碌指示

转载 作者:太空狗 更新时间:2023-10-29 22:00:31 25 4
gpt4 key购买 nike

我正在尝试编写一个显示忙碌指示的脚本在执行任务时。而当任务结束时,进度条将填充到最后显示 100% 任务已完成。我只想让进度条显示任务正在进行。但是当我开始时任务,忙指示停止。在我看来,指示和任务不能一起继续了。请帮我。这是我的代码:

from PyQt4 import QtCore, QtGui
from time import sleep
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s

try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)

class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.resize(344, 159)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.pb = QtGui.QProgressBar(self.centralwidget)
self.pb.setGeometry(QtCore.QRect(20, 20, 301, 31))
self.pb.setProperty("value", 0)
self.pb.setObjectName(_fromUtf8("pb"))
self.btn = QtGui.QPushButton(self.centralwidget)
self.btn.setGeometry(QtCore.QRect(20, 70, 98, 27))
self.btn.setObjectName(_fromUtf8("btn"))
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 344, 25))
self.menubar.setObjectName(_fromUtf8("menubar"))
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName(_fromUtf8("statusbar"))
MainWindow.setStatusBar(self.statusbar)

self.retranslateUi(MainWindow)
QtCore.QObject.connect(self.btn, QtCore.SIGNAL(_fromUtf8("clicked()")), self.action)
QtCore.QMetaObject.connectSlotsByName(MainWindow)

def action(self):
self.pb.setRange(0, 0)
sleep(3) # Here I want to run a command.For example: os.system('copy something')
self.pb.setRange(0, 100)
self.pb.setValue(100)
QtGui.qApp.processEvents()

def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
self.btn.setText(_translate("MainWindow", "Start", None))


if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())

最佳答案

首先,直接编辑使用 QtDesigner 创建的代码不是一个好主意。您可能已经看到 # WARNING! 这行在此文件中所做的所有更改都将丢失! 位于文档顶部。对于这样一个简单的小部件,您最好手动编码。

其次,仔细看看 action 槽的实际作用。

def action(self):
self.pb.setRange(0, 0) # Un
sleep(3) # <-- Your slot blocks HERE
self.pb.setRange(0, 100)
self.pb.setValue(100)
QtGui.qApp.processEvents()

当您的插槽在 sleep 中被阻塞时,您的 progressBar 没有理由更新它的值。当调用 action 时,插槽线程休眠 3 秒,然后将进度条设置为完整的 100。

您不能指望 progressBar 在您的任务运行时神奇地自行更新。如果您不知道需要多长时间并且您不能分步进行分割,您应该考虑使用 pulsed ProgressBar(参见下面的示例 1)。如果您可以轻松获得任务的进度(比如复制 n 个文件),则应该相应地更新 progressBar 的值。

无论哪种方式,您都应该使用 QThread 来获得非阻塞行为,并使用 signals 在您的线程和主应用程序之间进行通信。

  • 主应用程序启动 QThread 实现长时间运行的任务。
  • QThread 通知主应用程序任务进展(如果可用)或完成

示例 1 - Pulse ProgressBar:

如果最小值和最大值都设置为 0,进度条将显示忙碌指示符而不是步数百分比。

class MyCustomWidget(QtGui.QWidget):

def __init__(self, parent=None):
super(MyCustomWidget, self).__init__(parent)
layout = QtGui.QVBoxLayout(self)

# Create a progress bar and a button and add them to the main layout
self.progressBar = QtGui.QProgressBar(self)
self.progressBar.setRange(0,1)
layout.addWidget(self.progressBar)
button = QtGui.QPushButton("Start", self)
layout.addWidget(button)

button.clicked.connect(self.onStart)

self.myLongTask = TaskThread()
self.myLongTask.taskFinished.connect(self.onFinished)

def onStart(self):
self.progressBar.setRange(0,0)
self.myLongTask.start()

def onFinished(self):
# Stop the pulsation
self.progressBar.setRange(0,1)


class TaskThread(QtCore.QThread):
taskFinished = QtCore.pyqtSignal()
def run(self):
time.sleep(3)
self.taskFinished.emit()

示例 2 - 经典 ProgressBar:

class MyCustomWidget(QtGui.QWidget):

def __init__(self, parent=None):
super(MyCustomWidget, self).__init__(parent)
layout = QtGui.QVBoxLayout(self)

self.progressBar = QtGui.QProgressBar(self)
self.progressBar.setRange(0,100)
button = QtGui.QPushButton("Start", self)
layout.addWidget(self.progressBar)
layout.addWidget(button)

button.clicked.connect(self.onStart)

self.myLongTask = TaskThread()
self.myLongTask.notifyProgress.connect(self.onProgress)


def onStart(self):
self.myLongTask.start()

def onProgress(self, i):
self.progressBar.setValue(i)


class TaskThread(QtCore.QThread):
notifyProgress = QtCore.pyqtSignal(int)
def run(self):
for i in range(101):
self.notifyProgress.emit(i)
time.sleep(0.1)

关于python - PyQt 进度条的忙碌指示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19442443/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com