我想知道,如何停止函数iniciar
每次点击按钮self.runButton.clicked.connect(self.iniciar)
该程序冻结,我无法再采取行动。
我希望计时器在函数iniciar
无限重复时继续工作。
按钮self.runButton1
也会停止功能iniciar
。
我的代码:
#!/usr/bin/env python3
# Program created for play audios of time in zapoteco'
#
# Created by: Python 3.6, PyQt5 5.9.2.
#
# Author: Raul Espinosa raul@ninja-code.de
#
# WARNING! All changes made in this file will be lost!
#
# Version 0.2 GUI
import time
import subprocess
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(383, 263)
palette = QtGui.QPalette()
brush = QtGui.QBrush(QtGui.QColor(164, 0, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Button, brush)
brush = QtGui.QBrush(QtGui.QColor(138, 226, 52))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Light, brush)
brush = QtGui.QBrush(QtGui.QColor(164, 0, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Text, brush)
brush = QtGui.QBrush(QtGui.QColor(173, 127, 168))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
brush = QtGui.QBrush(QtGui.QColor(114, 159, 207))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Window, brush)
brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Shadow, brush)
brush = QtGui.QBrush(QtGui.QColor(164, 0, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Button, brush)
brush = QtGui.QBrush(QtGui.QColor(138, 226, 52))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Light, brush)
brush = QtGui.QBrush(QtGui.QColor(164, 0, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Text, brush)
brush = QtGui.QBrush(QtGui.QColor(173, 127, 168))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
brush = QtGui.QBrush(QtGui.QColor(114, 159, 207))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Window, brush)
brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Shadow, brush)
brush = QtGui.QBrush(QtGui.QColor(46, 52, 54))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Button, brush)
brush = QtGui.QBrush(QtGui.QColor(138, 226, 52))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Light, brush)
brush = QtGui.QBrush(QtGui.QColor(190, 190, 190))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Text, brush)
brush = QtGui.QBrush(QtGui.QColor(114, 159, 207))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
brush = QtGui.QBrush(QtGui.QColor(114, 159, 207))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Window, brush)
brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
brush.setStyle(QtCore.Qt.SolidPattern)
palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Shadow, brush)
Form.setPalette(palette)
Form.setPalette(palette)
self.label = QtWidgets.QLabel(Form)
self.label.setGeometry(QtCore.QRect(10, 0, 361, 181))
self.label.setObjectName("label")
self.horizontalSlider = QtWidgets.QSlider(Form)
self.horizontalSlider.setGeometry(QtCore.QRect(110, 240, 160, 16))
self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)
self.horizontalSlider.setObjectName("horizontalSlider")
self.horizontalSlider.setRange(0,100)
self.horizontalSlider.setSingleStep(1)
self.horizontalSlider.valueChanged.connect(self.valueHandler)
self.runButton = QtWidgets.QPushButton(Form)
self.runButton.setGeometry(QtCore.QRect(50, 180, 80, 25))
self.runButton.setObjectName("runButton")
self.runButton.clicked.connect(self.iniciar)
self.runButton1 = QtWidgets.QPushButton(Form)
self.runButton1.setGeometry(QtCore.QRect(250, 180, 80, 25))
self.runButton1.setObjectName("runButton1")
self.label_2 = QtWidgets.QLabel(Form)
self.label_2.setGeometry(QtCore.QRect(160, 220, 55, 17))
self.label_2.setObjectName("label_2")
self.timer = QtCore.QTimer(Form)
self.timer.timeout.connect(self.Time)
self.timer.start(1000)
self.lcdNumber = QtWidgets.QLCDNumber(Form)
self.lcdNumber.setGeometry(QtCore.QRect(280, 0, 101, 61))
self.lcdNumber.setInputMethodHints(QtCore.Qt.ImhNone)
self.lcdNumber.setFrameShape(QtWidgets.QFrame.NoFrame)
self.lcdNumber.setFrameShadow(QtWidgets.QFrame.Raised)
self.lcdNumber.setSmallDecimalPoint(True)
self.lcdNumber.setDigitCount(5)
self.lcdNumber.setMode(QtWidgets.QLCDNumber.Dec)
self.lcdNumber.setSegmentStyle(QtWidgets.QLCDNumber.Flat)
self.lcdNumber.display(time.strftime("%H"+":"+"%M"))
#tiempo = time.strftime("%H"+":"+"%M")
#print (tiempo)
#self.lcdNumber.setProperty("value", 12:20)
self.lcdNumber.setObjectName("lcdNumber")
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def Time(self):
self.lcdNumber.display(time.strftime("%H"+":"+"%M"))
def valueHandler(self,value):
scaledValue = float(value)/100
print (scaledValue) , type(scaledValue)
return scaledValue
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "XIGABA"))
Form.setToolTip(_translate("Form", "<html><head/><body><pre style=\" margin-top:0px; margin-bottom:15px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; background-color:#ffffff;\"><span style=\" font-family:\'monospace\'; background-color:#ffffff;\">Creado con Software Libre.</span></pre></body></html>"))
self.label.setToolTip(_translate("Form", "<html><head/><body><p>Dictador de horario.</p></body></html>"))
self.label.setText(_translate("Form", "<html><head/><body><pre align=\"center\" style=\" margin-top:15px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; background-color:#729fcf;\"><a name=\"taag_output_text\"/><span style=\" font-family:\'monospace\'; color:#555753; background-color:#729fcf;\">)</span><span style=\" font-family:\'monospace\'; color:#555753; background-color:#729fcf;\"> ( </span></pre><pre align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; background-color:#729fcf;\"><span style=\" font-family:\'monospace\'; color:#555753; background-color:#729fcf;\"> ( /( )\\ ) ( ( ( ( </span></pre><pre align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; background-color:#729fcf;\"><span style=\" font-family:\'monospace\'; color:#555753; background-color:#729fcf;\"> )\\()|()/( )\\ ) )\\ ( )\\ )\\ </span></pre><pre align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; background-color:#729fcf;\"><span style=\" font-family:\'monospace\'; color:#555753; background-color:#729fcf;\">((_)\\ /(_)|()/( ((((_)( )((_|(((_)( </span></pre><pre align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; background-color:#729fcf;\"><span style=\" font-family:\'monospace\'; color:#555753; background-color:#729fcf;\">__((_|_)) /(_))_)\\ _ )((_)_ )\\ _ )\\ </span></pre><pre align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; background-color:#729fcf;\"><span style=\" font-family:\'monospace\'; color:#555753; background-color:#729fcf;\">\\ \\/ /_ _|(_)) __(_)_\\(_) _ )(_)_\\(_) </span></pre><pre align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; background-color:#729fcf;\"><span style=\" font-family:\'monospace\'; color:#555753; background-color:#729fcf;\"> > < | | | (_ |/ _ \\ | _ \\ / _ \\ </span></pre><pre align=\"center\" style=\" margin-top:0px; margin-bottom:15px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; background-color:#729fcf;\"><span style=\" font-family:\'monospace\'; color:#555753; background-color:#729fcf;\">/_/\\_\\___| \\___/_/ \\_\\|___//_/ \\_\\ </span></pre><pre align=\"center\" style=\" margin-top:0px; margin-bottom:15px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; background-color:#729fcf;\"><span style=\" font-family:\'monospace\'; font-size:6pt; color:#555753; background-color:#729fcf;\">version 0.2 GUI</span></pre></body></html>"))
self.runButton.setText(_translate("Form", "Iniciar"))
self.runButton1.setText(_translate("Form", "Detener"))
self.label_2.setText(_translate("Form", "<html><head/><body><pre align=\"center\" style=\" margin-top:0px; margin-bottom:15px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; background-color:#000000;\"><a name=\"taag_output_text\"/><span style=\" font-family:\'monospace\'; color:#ef2929; background-color:#000000;\">VOLUMEN</span></pre></body></html>"))
def iniciar(self):
self.runButton1.setEnabled(True)
position = self.horizontalSlider.value()
scaledValue = float(position)/100
print (scaledValue) , type(scaledValue)
while (True):
time.sleep(0.5)
second_test = time.strftime('%S')
minute_test = time.strftime('%M')
hour_test = time.strftime('%H')
tiempo = time.strftime("%H"+":"+"%M")
print (tiempo)
self.lcdNumber.setProperty("value", tiempo)
if int(minute_test) == int(00) and int(second_test) == int(00):
print ('llego al hora exacta')
filen = 'HRS' + hour_test + '_O.mp3.mp3'
print (filen)
subprocess.Popen(["play", filen, "vol", scaledValue]).communicate()
elif int(second_test) == int(00):
print ('llego al minuto')
filen = 'HRS' + hour_test + '.mp3'
filen2 = 'MIN' + minute_test + '.mp3.mp3'
print (filen)
print (filen2)
subprocess.Popen(["play", filen, "vol", str(scaledValue)]).communicate()
subprocess.Popen(["play", filen2, "vol", str(scaledValue)]).communicate()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
ui = Ui_Form()
ui.setupUi(Form)
Form.show()
sys.exit(app.exec_())
我使用的是python3.6和pyqt5
答案 0 :(得分:1)
像你所使用的while一样阻塞循环不适合用于GUI,因为它们不允许你执行GUI的典型任务,如检查事件,信号和插槽。
在Qt中,因此也有PyQt,有一些方法可以避免这些问题,你的情况可能的解决方案是使用线程,实现它们的一种简单方法是使用QRunnable和QThreadPool,但在此之前建议改革你的代码。
Qt Designer提供了一个可以在窗口小部件中实现设计的类,但它不是窗口小部件,创建一个继承自相应窗口小部件并使用初始类来填充它的类是合适的。
class Widget(QtWidgets.QWidget, Ui_Form):
def __init__(self, *args, **kwargs):
QtWidgets.QWidget.__init__(self, *args, **kwargs)
self.setupUi(self)
self.runButton.clicked.connect(self.iniciar)
self.timer.timeout.connect(self.update_time)
self.horizontalSlider.valueChanged.connect(self.valueHandler)
def update_time(self):
self.lcdNumber.display(time.strftime("%H" + ":" + "%M"))
def valueHandler(self, value):
scaledValue = float(value) / 100
print(scaledValue), type(scaledValue)
return scaledValue
def iniciar(self):
self.runButton1.setEnabled(True)
position = self.horizontalSlider.value()
scaledValue = float(position) / 100
print(scaledValue), type(scaledValue)
self.runnable = Runnable(self)
QtCore.QThreadPool.globalInstance().start(self.runnable)
在下一节我实现QRunnable
并传递小部件,这个小部件将用于通信和更新GUI数据,因为Qt的规则是不应该从另一个线程更新GUI ,解决方法是使用QMetaObject.invokeMethod
:
class Runnable(QtCore.QRunnable):
def __init__(self, w, *args, **kwargs):
QtCore.QRunnable.__init__(self, *args, **kwargs)
self.w = w
self.position_initial = self.w.horizontalSlider.value()
def run(self):
scaledValue = float(self.position_initial) / 100
print(scaledValue)
while True:
time.sleep(0.5)
second_test = time.strftime('%S')
minute_test = time.strftime('%M')
hour_test = time.strftime('%H')
tiempo = time.strftime("%H" + ":" + "%M")
print(tiempo)
QtCore.QMetaObject.invokeMethod(self.w.lcdNumber, "display",
QtCore.Qt.QueuedConnection,
QtCore.Q_ARG(str, tiempo))
if int(minute_test) == int(00) and int(second_test) == int(00):
print('llego al hora exacta')
filen = 'HRS' + hour_test + '_O.mp3.mp3'
print(filen)
subprocess.Popen(["play", filen, "vol", scaledValue]).communicate()
elif int(second_test) == int(00):
print('llego al minuto')
filen = 'HRS' + hour_test + '.mp3'
filen2 = 'MIN' + minute_test + '.mp3.mp3'
print(filen)
print(filen2)
subprocess.Popen(["play", filen, "vol", str(scaledValue)]).communicate()
subprocess.Popen(["play", filen2, "vol", str(scaledValue)]).communicate()
然后,正如iniciar
方法中所实现的那样,我们通过QThreadPool
调用runnable:
self.runnable = Runnable(self)
QtCore.QThreadPool.globalInstance().start(self.runnable)
可以在以下link找到完整的代码。
<强> PS 强>:
如果你想添加一个停止,我们必须更改一些东西,例如而不是True,你应该使用一个标志,并改变标志的状态:
class Runnable(QtCore.QRunnable):
def __init__(self, w, *args, **kwargs):
QtCore.QRunnable.__init__(self, *args, **kwargs)
self.w = w
self.position_initial = self.w.horizontalSlider.value()
self.m_stopped = False
def run(self):
scaledValue = float(self.position_initial) / 100
print(scaledValue)
while not self.m_stopped:
[...]
def stop(self):
self.m_stopped = True
然后我们创建了detener
方法:
def detener(self):
self.runButton.setEnabled(True)
self.runButton1.setEnabled(False)
self.runnable.stop()