python - 单击按钮时调用脚本
问题描述
我有一个程序,这是它的简单想法。首先我运行 main_window.py 它将打开 sub_window.py 这个 sub_window 有 2 个按钮运行和停止。
当我单击运行按钮时,我需要运行 hello.py 脚本并关闭子窗口 GUI,就像我单击停止时一样,我需要停止 hello.py 脚本并关闭子窗口 GUI。
我当前的代码给了我“NameError: name 'Dialog' is not defined”错误。
这是 main_window.py 代码
from PyQt5 import QtCore, QtGui, QtWidgets
import sub_window
class Ui_MainWindow(object):
def sub(self):
self.subwin = QtWidgets.QDialog()
self.ui = sub_window.Ui_Dialog()
self.ui.setupUi(self.subwin)
self.subwin.show()
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(397, 157)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.btnClick = QtWidgets.QPushButton(self.centralwidget)
self.btnClick.setGeometry(QtCore.QRect(100, 50, 161, 51))
self.btnClick.setObjectName("btnClick")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
################### Butten Event ##################################
self.btnClick.clicked.connect(self.sub)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Main Window"))
self.btnClick.setText(_translate("MainWindow", "Click"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
这是 sub_window.py 代码
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def funRun(self):
Dialog.hide()
exec(open("hello.py").read())
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(332, 108)
self.btnRun = QtWidgets.QPushButton(Dialog)
self.btnRun.setGeometry(QtCore.QRect(50, 40, 101, 31))
self.btnRun.setObjectName("btnRun")
self.btnStop = QtWidgets.QPushButton(Dialog)
self.btnStop.setGeometry(QtCore.QRect(180, 40, 101, 31))
self.btnStop.setObjectName("btnStop")
self.retranslateUi(Dialog)
################### Butten Event ##################################
self.btnRun.clicked.connect(self.funRun)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Sub Window"))
self.btnRun.setText(_translate("Dialog", "Run"))
self.btnStop.setText(_translate("Dialog", "Stop"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
这是 hello.py 代码
import time
while True:
print("Hello")
time.sleep(1)
解决方案
首先,您不应该修改由 pyuic 生成的 .py,如生成的文件和文档的警告所示,因此您必须通过再次运行 pyuic 命令来恢复这些文件。
考虑到上述情况,您必须创建一个 main.py 来实现逻辑。另一方面,使用它不是很好的做法,exec()
因此在这种情况下,您必须修改“hello.py”,以便将无限循环封装在一个函数中。您还必须记住,无限循环不能在同一个 GUI 线程中执行,因此您必须在辅助线程中执行它:
主文件
from PyQt5 import QtCore, QtGui, QtWidgets
from main_window import Ui_MainWindow
from sub_window import Ui_Dialog
import threading
from hello import task
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.dialog = Dialog()
self.btnClick.clicked.connect(self.dialog.show)
class Dialog(QtWidgets.QDialog, Ui_Dialog):
def __init__(self, parent=None):
super(Dialog, self).__init__(parent)
self.setupUi(self)
self.btnRun.clicked.connect(self.run)
@QtCore.pyqtSlot()
def run(self):
threading.Thread(target=task, daemon=True).start()
self.hide()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
你好.py
import time
def task():
while True:
print("Hello")
time.sleep(1)
如果 hello.py 无法修改或exec()
必须使用,那么您必须创建一个执行该任务的函数:
主文件
from PyQt5 import QtCore, QtGui, QtWidgets
from main_window import Ui_MainWindow
from sub_window import Ui_Dialog
import threading
def task():
with open("hello.py") as f:
exec(f.read())
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.dialog = Dialog()
self.btnClick.clicked.connect(self.dialog.show)
class Dialog(QtWidgets.QDialog, Ui_Dialog):
def __init__(self, parent=None):
super(Dialog, self).__init__(parent)
self.setupUi(self)
self.btnRun.clicked.connect(self.run)
@QtCore.pyqtSlot()
def run(self):
threading.Thread(target=task, daemon=True).start()
self.hide()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
推荐阅读
- javascript - 只能看到 javascript 部分的代码,而不是网页上的 html
- loopbackjs - 如何使用middlewre在环回中使用会话
- liferay - javax.servlet-api-3.0.1.jar 未在 liferay 6.1 和 tomcat 7.0 中加载
- angular-material - 找不到树的树控件
- vue.js - 为什么我应该使用 v-bind 作为样式
- python - 运行 for 循环以求和不同字典的元素
- javascript - IE11 中的 javascript setInterval() 语法错误
- javascript - iframe 调整大小问题
- node.js - 保护 csrf Nodejs 表单
- vba - VBA 在两个不同的工作簿中复制和过去