Python 如何用信号控制QProgressBar
按下按钮开始100轮循环。使用Python 如何用信号控制QProgressBar,python,qt,pyqt,qprogressbar,Python,Qt,Pyqt,Qprogressbar,按下按钮开始100轮循环。使用QLabel.setText()我们从clicked()函数的范围内更新self.label 除了更新self.label之外,我们还想更新progressbar。 但是由于progressbar是一个局部变量,我们无法从onClick()函数内部更新它 将进度条声明为: self.progressbar = ProgressBar(self) 代码声明一个本地progressbar对象,该对象连接到自定义的“customSignal”,使用: QtCore.Q
QLabel.setText()
我们从clicked()
函数的范围内更新self.label
除了更新self.label
之外,我们还想更新progressbar
。
但是由于progressbar
是一个局部变量,我们无法从onClick()函数内部更新它
将进度条声明为:
self.progressbar = ProgressBar(self)
代码声明一个本地progressbar
对象,该对象连接到自定义的“customSignal”,使用:
QtCore.QObject.connect(self,QtCore.SIGNAL(“customSignal(int)”),progressbar,QtCore.SLOT(“setValue(int)”)
将四个参数传递给QtCore.QObject.connect()
第一个参数self
是将发出信号的对象。由于执行“每秒睡眠处理”的函数是在主对话框
实例下声明的,因此我们在这里传递self
第二个参数是信号本身的名称:“customSignal”
progressbar
对象用作第三个参数,其方法setValue
用作最后第四个参数
--------------------
除了链接到progressbar方法外,以下是相同解决方案的变体。
导入时间
class ProgressBar(QtGui.QProgressBar):
def __init__(self, parent=None):
super(ProgressBar, self).__init__(parent=parent)
def set_to_value(self, value):
self.setValue(value)
QtGui.qApp.processEvents()
return True
def closeEvent(self, event):
self._active=False
class Dialog(QtGui.QDialog):
def __init__(self):
QtGui.QDialog.__init__(self, parent=None)
layout = QtGui.QVBoxLayout()
self.setLayout(layout)
self.label = QtGui.QLabel('idle...')
layout.addWidget(self.label)
progressbar = ProgressBar(self)
QtCore.QObject.connect(self, QtCore.SIGNAL("customSignal(int)"), progressbar.set_to_value )
layout.addWidget(progressbar)
button = QtGui.QPushButton('Process')
button.clicked.connect(self.clicked)
layout.addWidget(button)
def clicked(self):
for value in range(101):
message = '...processing %s of 100'%value
self.label.setText(message)
self.emit(QtCore.SIGNAL("customSignal(int)"), value)
QtGui.qApp.processEvents()
time.sleep(1)
if __name__ == '__main__':
app = QtGui.QApplication([])
dialog = Dialog()
dialog.resize(300, 100)
dialog.show()
app.exec_()
======================
此代码现在将自定义信号链接到Qt中称为Slot的函数
from PySide import QtCore, QtGui
import time
class ProgressBar(QtGui.QProgressBar):
def __init__(self, parent=None):
super(ProgressBar, self).__init__(parent=parent)
@QtCore.Slot(int)
def set_to_value(self, value):
self.setValue(value)
QtGui.qApp.processEvents()
return True
def closeEvent(self, event):
self._active=False
class Dialog(QtGui.QDialog):
def __init__(self):
QtGui.QDialog.__init__(self, parent=None)
layout = QtGui.QVBoxLayout()
self.setLayout(layout)
self.label = QtGui.QLabel('idle...')
layout.addWidget(self.label)
progressbar = ProgressBar(self)
# QtCore.QObject.connect(self, QtCore.SIGNAL("customSignal(int)"), progressbar.set_to_value )
QtCore.QObject.connect(self, QtCore.SIGNAL("customSignal(int)"), progressbar, QtCore.SLOT("set_to_value(int)"))
layout.addWidget(progressbar)
button = QtGui.QPushButton('Process')
button.clicked.connect(self.clicked)
layout.addWidget(button)
def clicked(self):
for value in range(101):
message = '...processing %s of 100'%value
self.label.setText(message)
self.emit(QtCore.SIGNAL("customSignal(int)"), value)
QtGui.qApp.processEvents()
time.sleep(1)
if __name__ == '__main__':
dialog = Dialog()
dialog.resize(300, 100)
dialog.show()
为什么要手动调用qApp.processEvents()
?该示例似乎没有涉及线程或其他进程…我假设问题标题不正确?如果您实际使用线程,还需要考虑其他因素。@three_Pinepples:我只是想让问题中的代码尽可能简单。目标是找到一种从声明小部件的实例外部、从另一个外部线程内部或从另一个外部进程内部控制小部件的方法。
class ProgressBar(QtGui.QProgressBar):
def __init__(self, parent=None):
super(ProgressBar, self).__init__(parent=parent)
def set_to_value(self, value):
self.setValue(value)
QtGui.qApp.processEvents()
return True
def closeEvent(self, event):
self._active=False
class Dialog(QtGui.QDialog):
def __init__(self):
QtGui.QDialog.__init__(self, parent=None)
layout = QtGui.QVBoxLayout()
self.setLayout(layout)
self.label = QtGui.QLabel('idle...')
layout.addWidget(self.label)
progressbar = ProgressBar(self)
QtCore.QObject.connect(self, QtCore.SIGNAL("customSignal(int)"), progressbar.set_to_value )
layout.addWidget(progressbar)
button = QtGui.QPushButton('Process')
button.clicked.connect(self.clicked)
layout.addWidget(button)
def clicked(self):
for value in range(101):
message = '...processing %s of 100'%value
self.label.setText(message)
self.emit(QtCore.SIGNAL("customSignal(int)"), value)
QtGui.qApp.processEvents()
time.sleep(1)
if __name__ == '__main__':
app = QtGui.QApplication([])
dialog = Dialog()
dialog.resize(300, 100)
dialog.show()
app.exec_()
from PySide import QtCore, QtGui
import time
class ProgressBar(QtGui.QProgressBar):
def __init__(self, parent=None):
super(ProgressBar, self).__init__(parent=parent)
@QtCore.Slot(int)
def set_to_value(self, value):
self.setValue(value)
QtGui.qApp.processEvents()
return True
def closeEvent(self, event):
self._active=False
class Dialog(QtGui.QDialog):
def __init__(self):
QtGui.QDialog.__init__(self, parent=None)
layout = QtGui.QVBoxLayout()
self.setLayout(layout)
self.label = QtGui.QLabel('idle...')
layout.addWidget(self.label)
progressbar = ProgressBar(self)
# QtCore.QObject.connect(self, QtCore.SIGNAL("customSignal(int)"), progressbar.set_to_value )
QtCore.QObject.connect(self, QtCore.SIGNAL("customSignal(int)"), progressbar, QtCore.SLOT("set_to_value(int)"))
layout.addWidget(progressbar)
button = QtGui.QPushButton('Process')
button.clicked.connect(self.clicked)
layout.addWidget(button)
def clicked(self):
for value in range(101):
message = '...processing %s of 100'%value
self.label.setText(message)
self.emit(QtCore.SIGNAL("customSignal(int)"), value)
QtGui.qApp.processEvents()
time.sleep(1)
if __name__ == '__main__':
dialog = Dialog()
dialog.resize(300, 100)
dialog.show()