为什么要设计这个程序
Windows 批处理文件 (.bat)运行非常方便,双击即可,但是对于非计算机专业的人使用来说就不是那么容易接受(黑框的显示显得太简陋,影响用户体验),基于此设计了一个基于PyQT封装Windows 批处理文件 (.bat)运行的UI程序。
程序设计
设计思路
- UI界面的设计。
- 按下启动按钮是需要运行.bat文件并将.bat文件输出结果打印到UI界面上。
- 按下终止按钮结束.bat文件运行。
- 为了方式用户误操作,在按下运行、终止按钮时需要检查.bat文件是否在运行。
UI设计
默认有QT设计的基础,如没有该基础建议参考学习以下文章:http://t.csdn.cn/52gCQ
首先贴上整体设计界面,
界面由简单的几部分构成,左上侧为一个logo,利用Qlabel加载,在PyQT-Tool里的design设计器中配置图片路径,
在红色部分浏览选中logo图片文件。
输出信息的文本框采用plainTextEdit控件,设置不可写(只读),防止用户误操作。
最后start与end按钮采用QPushButton控件,并修改这两个控件的名字,
UI设计自此完成,保存文件名ui.ui。
调用设计好的UI并编写相应功能
生成UI的py文件
利用
pyuic5 -o ui.py ui. ui
生成UI的对应py文件
调用UI生成的py文件并实现相应功能
算法整体流程为:
新建一个py文件main.py
导入必要的包
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from ui import Ui_Form # ui生成的py文件中的类
import subprocess #用于线程通信的包
from PyQt5.QtCore import pyqtSignal,QObject# 信号与槽
import threading #关于线程的包
定义类生成,继承Ui_Form(ui生成的py文件中的类):
class Demo(QWidget,Ui_Form):
# 信号,将信息Msg利用信号包装发给槽函数
signal = pyqtSignal(str)
def __init__(self):
super(Demo, self).__init__()
self.setupUi(self)
#cmd 进程
self.thread_cmd = None
#将信号连接到指定的槽函数
self.signal.connect(self.Slot_Msg)
# 设置主界面
QApplication.setStyle('Fusion')
self.setWindowTitle('套壳') # 设置窗体名称
self.setWindowIcon(QIcon('ico.png')) # 设置窗体图标
self.resize(750, 500) # 更改窗体大小
self.setFixedSize(self.width(), self.height()) # 禁止拉伸窗口大小
self.pushButton_start.clicked.connect(self.creat_thread)
self.pushButton_end.clicked.connect(self.end_thread)
# start按钮绑定的槽函数,非阻塞函数以防程序卡住
def creat_thread(self):
tt = threading.Thread(target=self.start_thread,daemon=False)
tt.start()
#发射信号
self.signal.emit("查询线程!")
# start按钮绑定的槽函数启动的非守护线程——creat_thread运行结束该线程不会被结束。
def start_thread(self):
if type(self.thread_cmd) != type(None):
#发射信号
self.signal.emit("线程已在启动!")
# print("进程已在启动!")
else:
#发射信号
self.signal.emit("线程未启动,启动线程!")
self.thread_cmd = subprocess.Popen("time.bat", shell = True, stdout = subprocess.PIPE)
for i in iter(self.thread_cmd.stdout.readline, ''):
if len(i) < 1:
break
#发射信号
self.signal.emit(i.decode('gbk').strip())
# print(i.decode('gbk').strip())
# end按钮绑定的槽函数,判断线程状态决定是否终止
def end_thread(self):
if type(self.thread_cmd) != type(None):
self.thread_cmd.terminate()
self.thread_cmd = None
#发射信号
self.signal.emit("线程已终结!")
else:
#发射信号
self.signal.emit("线程未启动!")
# print("进程未启动!")
# 槽函数,接收来自signal的信息,并将该信息添加显示在文本框
def Slot_Msg(self,Msg):
self.plainTextEdit.appendPlainText(Msg)
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = Demo()
demo.show()
sys.exit(app.exec_())