python - 没有完成的信号
问题描述
永远不会self.onFinished
通过self.process.finished.connect()
信号达到功能。该过程完成后,我想向对话框提供其他命令。
class UpdateDialog(QtWidgets.QDialog):
outputSignal = QtCore.pyqtSignal(str)
errorSignal = QtCore.pyqtSignal(str)
def __init__(self, parent = None):
super(UpdateDialog, self).__init__(parent)
uic.loadUi(os.path.join(os.environ.get("ROOT_PATH"), "testd.ui"), self)
self.process = QtCore.QProcess()
self.completed = False
self.process.readyReadStandardOutput.connect(self.onReadyReadStandardOutput)
self.process.readyReadStandardError.connect(self.onReadyReadStandardError)
def onReadyReadStandardOutput(self):
error = self.process.readAllStandardError().data().decode()
self.plainTextEdit_st.appendPlainText(error)
self.errorSignal.emit(error)
def onReadyReadStandardError(self):
error = self.process.readAllStandardError().data().decode()
self.plainTextEdit_st.appendPlainText(error)
self.errorSignal.emit(error)
def run(self, command):
self.plainTextEdit_st.clear()
self.process.finished.connect(self.onFinished)
self.process.start(command)
def onFinished(self):
self.completed = True
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
dialog = UpdateDialog()
dialog.show()
dialog.errorSignal.connect(lambda error: print(error))
dialog.outputSignal.connect(lambda output: print(output))
dialog.run("git clone --progress https://github.com/myrepo/test.git C:\\test\\")
if dialog.completed:
print("test")
sys.exit(app.exec_())
解决方案
Qt 通过信号异步工作,也就是说,启动的任务(例如 run 方法)不会立即执行,而是在 eventloop 执行后的瞬间执行,因此当您评估 dialgo.completed 时,它甚至还没有完成。启动 QProcess。
Qt 使用面向事件的编程范式工作,因此逻辑是实现一个函数,该函数在发生某些事情时执行某些操作,例如,您想在触发完成信号时打印文本,那么该任务必须在关联的插槽中完成信号:
def onFinished(self):
print("test")
顺序逻辑不能直接在 Qt 中工作,因此您必须更改实现以实现您想要的。
类似的替代方案是:
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
dialog = UpdateDialog()
dialog.show()
dialog.errorSignal.connect(print)
dialog.outputSignal.connect(print)
dialog.run("git clone --progress https://github.com/myrepo/test.git C:\\test\\")
def handle_finished():
print("test")
dialog.process.finished.connec(handle_finished)
sys.exit(app.exec_())
或者:
class UpdateDialog(QtWidgets.QDialog):
outputSignal = QtCore.pyqtSignal(str)
errorSignal = QtCore.pyqtSignal(str)
finished = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(UpdateDialog, self).__init__(parent)
uic.loadUi(os.path.join(os.environ.get("ROOT_PATH"), "testd.ui"), self)
self.process = QtCore.QProcess()
self.process.readyReadStandardOutput.connect(self.onReadyReadStandardOutput)
self.process.readyReadStandardError.connect(self.onReadyReadStandardError)
self.process.finished.connect(self.finished)
def onReadyReadStandardOutput(self):
output = self.process.readAllStandardError().data().decode()
self.plainTextEdit_st.appendPlainText(output)
self.outputSignal.emit(output)
def onReadyReadStandardError(self):
error = self.process.readAllStandardError().data().decode()
self.plainTextEdit_st.appendPlainText(error)
self.errorSignal.emit(error)
def run(self, command):
self.plainTextEdit_st.clear()
self.process.start(command)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
dialog = UpdateDialog()
dialog.show()
dialog.errorSignal.connect(print)
dialog.outputSignal.connect(print)
dialog.run("git clone --progress https://github.com/myrepo/test.git C:\\test\\")
def handle_finished():
print("test")
dialog.finished.connec(handle_finished)
sys.exit(app.exec_())
我建议您阅读Signals & Slots,以便您了解更多关于 Qt 的工作原理
推荐阅读
- android - 为什么不调用“onPropertyChanged”?
- python - Python中的重构表
- python - 在 Python 3 中初始化数组的两种方法之间的差异
- dart - 如何在颤振中使用 BottomAppBar 进行导航
- file - 在 unix 中删除文件需要什么权限?
- c++ - 完全专用的模板函数是否与常规函数相同?
- c - 指向具有可变数量参数的函数的指针数组
- elasticsearch - 在 Elasticsearch 6.6 和 NEST 6.6 中具有排序和分页变量的 SearchTemplate
- typescript - shims-tsx.d.ts 文件在 Vue-Typescript 项目中的作用是什么?
- powershell - 使用参数列表在服务器上调用远程 .exe