Multithreading PyQt5:进度指示器作为覆盖
我又在玩弄PyQt5了,这一次我被困在如何在方法执行时间稍长时向gui中添加类似于a的内容 为了做到这一点,我有一个(超级)简单的gui,只有一个按钮。当点击按钮时,应用程序会在控制台上打印15秒钟的“hello world!”(这只是为了查看它实际上正在做什么) 我现在的问题是:当一个方法的执行时间超过例如4秒(直到该方法完成,进度指示器应该再次消失)时,我如何将进度指示器“覆盖”到我的gui上?我有一个来自的进度指示器的示例脚本。但不幸的是,当我把它添加到我的玩具示例中时,我不知所措。我们将非常感谢您的帮助 我正在使用:Multithreading PyQt5:进度指示器作为覆盖,multithreading,python-3.x,pyqt,pyqt5,python-multithreading,Multithreading,Python 3.x,Pyqt,Pyqt5,Python Multithreading,我又在玩弄PyQt5了,这一次我被困在如何在方法执行时间稍长时向gui中添加类似于a的内容 为了做到这一点,我有一个(超级)简单的gui,只有一个按钮。当点击按钮时,应用程序会在控制台上打印15秒钟的“hello world!”(这只是为了查看它实际上正在做什么) 我现在的问题是:当一个方法的执行时间超过例如4秒(直到该方法完成,进度指示器应该再次消失)时,我如何将进度指示器“覆盖”到我的gui上?我有一个来自的进度指示器的示例脚本。但不幸的是,当我把它添加到我的玩具示例中时,我不知所措。我们将
PyQt5.6.0
,Python3.5.2
我的代码:
design.py(gui文件)
main.py:(主脚本):
main.py(更新):
从PyQt5导入QtWidgets
从线程导入线程、计时器
从设计导入Ui_主窗口,QProgressIndicator
导入时间
类ToyEx(QtWidgets.QMainWindow,Ui_MainWindow):
定义初始化(自):
qtwidts.QMainWindow.\uuuu init\uuuuu(self)
self.ui=ui\u主窗口()
self.ui.setupUi(self)
self.ui.button.clicked.connect(self.threadfuncts)
def线程函数(自身):
线程(target=gorepeat).start()
计时器(4,线程(目标=test\u progressindicator).start())#
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'design.ui'
#
# Created by: PyQt5 UI code generator 5.6
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(300, 300)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(105, 140, 113, 32))
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 22))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "PushButton"))
from PyQt5 import QtWidgets
import time
from design import Ui_MainWindow
class ToyEx(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.pushButton.clicked.connect(self.gorepeat)
def gorepeat(self):
"""
print sth for 15 seconds
"""
end_time = time.time() + 15 * 1
print(end_time)
while time.time() < end_time:
print('hello world!')
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
form = ToyEx()
form.show()
app.exec_()
"""
adapted to PyQt5 from:
Author: Jared P. Sutton <jpsutton@gmail.com>
License: LGPL
Note: I've licensed this code as LGPL because it was a complete translation of the code found here...
https://github.com/mojocorp/QProgressIndicator
sourcecode from here: https://github.com/mojocorp/QProgressIndicator
"""
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import time
class QProgressIndicator(QWidget):
m_angle = None
m_timerId = None
m_delay = None
m_displayedWhenStopped = None
m_color = None
def __init__(self, parent):
# Call parent class constructor first
super(QProgressIndicator, self).__init__(parent)
# Initialize Qt Properties
self.setProperties()
# Intialize instance variables
self.m_angle = 0
self.m_timerId = -1
self.m_delay = 40
self.m_displayedWhenStopped = False
self.m_color = Qt.black
# Set size and focus policy
self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
self.setFocusPolicy(Qt.NoFocus)
# Show the widget
self.show()
def animationDelay(self):
return self.delay
def isAnimated(self):
return (self.m_timerId != -1)
def isDisplayedWhenStopped(self):
return self.displayedWhenStopped
def getColor(self):
return self.color
def sizeHint(self):
return QSize(20, 20)
def startAnimation(self):
self.m_angle = 0
if self.m_timerId == -1:
self.m_timerId = self.startTimer(self.m_delay)
def stopAnimation(self):
if self.m_timerId != -1:
self.killTimer(self.m_timerId)
self.m_timerId = -1
self.update()
def setAnimationDelay(self, delay):
if self.m_timerId != -1:
self.killTimer(self.m_timerId)
self.m_delay = delay
if self.m_timerId != -1:
self.m_timerId = self.startTimer(self.m_delay)
def setDisplayedWhenStopped(self, state):
self.displayedWhenStopped = state
self.update()
def setColor(self, color):
self.m_color = color
self.update()
def timerEvent(self, event):
self.m_angle = (self.m_angle + 30) % 360
self.update()
def paintEvent(self, event):
if (not self.m_displayedWhenStopped) and (not self.isAnimated()):
return
width = min(self.width(), self.height())
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
outerRadius = (width - 1) * 0.5
innerRadius = (width - 1) * 0.5 * 0.48
capsuleHeight = outerRadius - innerRadius
capsuleWidth = capsuleHeight * .23 if (width > 32) else capsuleHeight * .35
capsuleRadius = capsuleWidth / 2
for i in range(0, 12):
color = QColor(self.m_color)
if self.isAnimated():
color.setAlphaF(1.0 - (i / 12.0))
else:
color.setAlphaF(0.2)
painter.setPen(Qt.NoPen)
painter.setBrush(color)
painter.save()
painter.translate(self.rect().center())
painter.rotate(self.m_angle - (i * 30.0))
painter.drawRoundedRect(capsuleWidth * -0.5, (innerRadius + capsuleHeight) * -1, capsuleWidth,
capsuleHeight, capsuleRadius, capsuleRadius)
painter.restore()
def setProperties(self):
self.delay = pyqtProperty(int, self.animationDelay, self.setAnimationDelay)
self.displayedWhenStopped = pyqtProperty(bool, self.isDisplayedWhenStopped, self.setDisplayedWhenStopped)
self.color = pyqtProperty(QColor, self.getColor, self.setColor)
def TestProgressIndicator():
app = QApplication(sys.argv)
t_end = time.time() + 10 *1
progress = QProgressIndicator(None)
progress.setAnimationDelay(70)
progress.startAnimation()
# Execute the application
sys.exit(app.exec_())
if __name__ == "__main__":
TestProgressIndicator()
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'design.ui'
#
# Created by: PyQt5 UI code generator 5.6
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(300, 300)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(105, 140, 113, 32))
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 22))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "PushButton"))
class QProgressIndicator(QtWidgets.QWidget):
m_angle = None
m_timerId = None
m_delay = None
m_displayedWhenStopped = None
m_color = None
def __init__(self, parent):
# Call parent class constructor first
super(QProgressIndicator, self).__init__(parent)
# palette = QPalette(self.palette())
# palette.setColor(palette.Background, Qt.transparent)
# self.setPalette(palette)
# Initialize Qt Properties
self.setProperties()
# Intialize instance variables
self.m_angle = 0
self.m_timerId = -1
self.m_delay = 40
self.m_displayedWhenStopped = False
#self.m_color = Qt.black
self.m_color = QtCore.Qt.transparent
# Set size and focus policy
self.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
self.setFocusPolicy(QtCore.Qt.NoFocus)
# Show the widget
self.show()
def animationDelay(self):
return self.delay
def isAnimated(self):
return (self.m_timerId != -1)
def isDisplayedWhenStopped(self):
return self.displayedWhenStopped
def getColor(self):
return self.color
def sizeHint(self):
return QtCore.QSize(50, 50)
def startAnimation(self):
self.m_angle = 0
if self.m_timerId == -1:
self.m_timerId = self.startTimer(self.m_delay)
def stopAnimation(self):
if self.m_timerId != -1:
self.killTimer(self.m_timerId)
self.m_timerId = -1
self.update()
def setAnimationDelay(self, delay):
if self.m_timerId != -1:
self.killTimer(self.m_timerId)
self.m_delay = delay
if self.m_timerId != -1:
self.m_timerId = self.startTimer(self.m_delay)
def setDisplayedWhenStopped(self, state):
self.displayedWhenStopped = state
self.update()
def setColor(self, color):
self.m_color = color
self.update()
def timerEvent(self, event):
self.m_angle = (self.m_angle + 30) % 360
self.update()
def paintEvent(self, event):
if (not self.m_displayedWhenStopped) and (not self.isAnimated()):
return
width = min(self.width(), self.height())
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
outerRadius = (width - 1) * 0.5
innerRadius = (width - 1) * 0.5 * 0.48
capsuleHeight = outerRadius - innerRadius
capsuleWidth = capsuleHeight * .23 if (width > 32) else capsuleHeight * .35
capsuleRadius = capsuleWidth / 2
for i in range(0, 12):
color = QtGui.QColor(self.m_color)
if self.isAnimated():
color.setAlphaF(1.0 - (i / 12.0))
else:
color.setAlphaF(0.2)
painter.setPen(QtCore.Qt.NoPen)
painter.setBrush(color)
painter.save()
painter.translate(self.rect().center())
painter.rotate(self.m_angle - (i * 30.0))
painter.drawRoundedRect(capsuleWidth * -0.5, (innerRadius + capsuleHeight) * -1, capsuleWidth,
capsuleHeight, capsuleRadius, capsuleRadius)
painter.restore()
def setProperties(self):
self.delay = QtCore.pyqtProperty(int, self.animationDelay, self.setAnimationDelay)
self.displayedWhenStopped = QtCore.pyqtProperty(bool, self.isDisplayedWhenStopped, self.setDisplayedWhenStopped)
self.color = QtCore.pyqtProperty(QtGui.QColor, self.getColor, self.setColor)
from PyQt5 import QtWidgets
from threading import Thread, Timer
from design import Ui_MainWindow, QProgressIndicator
import time
class ToyEx(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.pushButton.clicked.connect(self.threadfuncts)
def threadfuncts(self):
Thread(target=gorepeat).start()
Timer(4, Thread(target=test_progressindicator).start()) # <-- THIS DOES NOT WORK!
def gorepeat():
"""
print sth for 15 seconds
"""
end_time = time.time() + 15 * 1
while time.time() < end_time:
print('hello world!')
def test_progressindicator():
progress = QProgressIndicator(None)
progress.setAnimationDelay(70)
progress.startAnimation()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
form = ToyEx()
form.show()
app.exec_()