Python环境搭建好后如何运行.py,【界面】使用QT designer、python搭建界面程序

文章目录 前言1. 预安装的软件与库2. Qt Designer 的界面设计3. Qt 逻辑编写4. 封装成可执行文件5. 总结

前言

PyQt 是Python语言的GUI编程解决方案之一,是类似于 Tkinter 的一个高级库。 为了更好的辅助PyQt界面的搭建,可以通过Qt Designer完成GUI界面设计。 使用Qt Designer可以通过拖拽、点击完成GUI界面设计,并且设计完成后生成的.ui程序可以通过 pyuic5 命令直接转换成.py文件以供python程序调用。 搭建完界面并写好逻辑后,还可通过 pyinstaller 将.py文件封装成.exe文件,以供没有python解释器的用户使用。 本文以搭建标注工具界面程序为例。

1. 预安装的软件与库 Qt Designer: pip install —pre pyqt5-tools~=5.11 (位于\Python36\Lib\site-packages\pyqt5_tools\designer.exe,也可通过这里下载)PyQt5: pip install PyQt5pip install pyinstaller 2. Qt Designer 的界面设计

Qt Designer 的界面主要分为四大区:项目区、控件区、编辑区、属性区。 具体而言,就是在【控件区】里点击添加需要的控件,这些控件的效果会在【编辑区】里实时显示,并在【属性区】这些控件的属性,【项目区】用于显示控件间的层级关系。 在这里插入图片描述 在新建一个窗口后,一般需要通过 Container 确定外部轮廓,可选用常见的 Frame 控件,再在 Frame 里边选用 Layouts 来规范后续控件的排列样式,常用水平或垂直排列,最后再选用具体部件往里边填充。 常用的控件有各种Button(按钮)、Label(静态显示文本框)、Text Edit(输入输出文本框)、listWidget(列表显示框)、Check Box(选中框)、各种Slider(滑动条)等。

每一个组件都有可设置的属性,最重要的通用属性有 objectName (用于在后续逻辑编写时指明时哪个控件),text (用于在GUI里在控件上显示), geometry (用于设置控件位置和尺寸,但控件位于Layer中时就不可设置了)。 在这里插入图片描述 设计好界面之后保存可以生成my_win.ui文件,它可以直接在python代码里被加载使用,但为了在代码里进一步调用修改等,更好的方法是将.ui文件转换成相应的.py文件。这需要借助 \Python36\Scripts\pyuic5.exe工具。 pyuic5 -o my_win.py my_win.ui

3. Qt 逻辑编写

很多控件都可以通过点击(或其他操作)触发事件,事件响应可自由编写,通过 connect 函数绑定。

#!/usr/bin/env python3# -*- coding: utf-8 -*-"""Created on Sun June 12 12:06:21 2020@author: weiquan fan"""import sys, osfrom PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox, QCompleter, QFileDialogfrom PyQt5.QtMultimedia import QMediaContent, QMediaPlayerfrom PyQt5.QtCore import pyqtSignal, QEventfrom PyQt5.Qt import QUrlfrom my_win import Ui_MainWindowimport csvroot_path_metadata = "./data/"if not os.path.exists(root_path_metadata):os.makedirs(root_path_metadata)class mainWin(QMainWindow, Ui_MainWindow):doubleClicked_speaker = pyqtSignal()doubleClicked_dialog = pyqtSignal()def __init__(self, parent=None):super(mainWin, self).__init__(parent)self.setupUi(self)## emotionself.refresh_1()self.radioButton.clicked.connect(self.showPos)self.radioButton_2.clicked.connect(self.showNeu)self.radioButton_3.clicked.connect(self.showNeg)## DAself.refresh_2()## dialog identityself.refresh_3()self.frame_9.setHidden(True)self.checkBox_5.stateChanged.connect(self.use_subsysdem3)self.radioButton_5.clicked.connect(self.personA)self.radioButton_4.clicked.connect(self.personB)## save buttonsself.refresh_save()self.btn_save.clicked.connect(self.save_data)self.btn_save_2.clicked.connect(self.save_dialog_data)## historyself.list_speaker = []self.list_dialog = []self.lineEdit_speaker.installEventFilter(self)self.lineEdit.installEventFilter(self)self.doubleClicked_speaker.connect(self.completer_name_speaker)self.doubleClicked_dialog.connect(self.completer_name_dialog)## video playerself.player = QMediaPlayer()self.player.setVideoOutput(self.wgt_player)self.btn_open.clicked.connect(self.openVideoFile)self.btn_play_pause.clicked.connect(self.playPause)self.player.durationChanged.connect(self.getDuration)self.player.positionChanged.connect(self.getPosition)self.sld_duration.sliderMoved.connect(self.updatePosition)## for opening videodef openVideoFile(self):name = QFileDialog.getOpenFileName()[0]self.lineEdit.setText(name.split('/')[-1])self.player.setMedia(QMediaContent(QUrl.fromLocalFile(name)))# self.player.setMedia(QMediaContent(QFileDialog.getOpenFileUrl()[0]))self.player.play()def playPause(self):if self.player.state()==1:self.player.pause()else:self.player.play()def getDuration(self, d):self.sld_duration.setRange(0, d)self.sld_duration.setEnabled(True)self.displayTime(d)def getPosition(self, p):self.sld_duration.setValue(p)self.displayTime(p)def displayTime(self, ms):minutes = int(ms/60000)seconds = int((ms-minutes*60000)/1000)dur_ms = self.sld_duration.maximum()dur_min = int(dur_ms/60000)dur_sec = int((dur_ms-dur_min*60000)/1000)self.lab_duration.setText('{:0>2d}:{:0>2d} / {:0>2d}:{:0>2d}'.format(minutes, seconds, dur_min, dur_sec))def updatePosition(self, v):self.player.setPosition(v)self.displayTime(self.sld_duration.maximum()-v)## for historydef eventFilter(self, widget, event):if widget == self.lineEdit_speaker:if event.type() == QEvent.MouseButtonDblClick:self.doubleClicked_speaker.emit()elif widget == self.lineEdit:if event.type() == QEvent.MouseButtonDblClick:self.doubleClicked_dialog.emit()return super().eventFilter(widget, event)def completer_name_dialog(self):self.completer = QCompleter(self.list_dialog)self.lineEdit.setCompleter(self.completer)self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)self.completer.complete()self.completer.popup()def completer_name_speaker(self):self.completer = QCompleter(self.list_speaker)self.lineEdit_speaker.setCompleter(self.completer)self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)self.completer.complete()self.completer.popup()## for label 1def showPos(self):self.listWidget.clear()self.listWidget.addItem("高兴")self.listWidget.addItem("兴奋")self.listWidget.addItem("自豪")self.listWidget.addItem("满足")self.listWidget.addItem("感激")self.listWidget.addItem("自信")self.listWidget.addItem("轻松")self.listWidget.addItem("羡慕")def showNeg(self):self.listWidget.clear()self.listWidget.addItem("生气")self.listWidget.addItem("伤心")self.listWidget.addItem("害怕")self.listWidget.addItem("烦恼")self.listWidget.addItem("孤独")self.listWidget.addItem("羞愧")self.listWidget.addItem("恶心")self.listWidget.addItem("失望")self.listWidget.addItem("郁闷")self.listWidget.addItem("不安")self.listWidget.addItem("紧张")self.listWidget.addItem("无奈")self.listWidget.addItem("纠结")def showNeu(self):self.listWidget.clear()self.listWidget.addItem("共情")self.listWidget.addItem("平静")## for label 3def use_subsysdem3(self):if self.checkBox_5.isChecked():self.frame_9.setHidden(False)else:self.refresh_3()self.frame_9.setHidden(True)def personA(self):self.frame_3.setHidden(False)self.frame_8.setHidden(True)def personB(self):self.frame_3.setHidden(True)self.frame_8.setHidden(False)def refresh_gui(self):self.refresh_1()self.refresh_2()self.refresh_3()self.refresh_save()def refresh_1(self):self.buttonGroup_2.setExclusive(False)self.radioButton.setChecked(False)self.radioButton_2.setChecked(False)self.radioButton_3.setChecked(False)self.buttonGroup_2.setExclusive(True)self.listWidget.clear()self.checkBox_3.setChecked(True)self.checkBox_2.setChecked(True)self.checkBox.setChecked(True)self.checkBox_4.setChecked(False)def refresh_2(self):self.listWidget_2.clear()self.listWidget_2.addItem("问候")self.listWidget_2.addItem("提问")self.listWidget_2.addItem("回答")self.listWidget_2.addItem("陈述观点")self.listWidget_2.addItem("陈述非观点")self.listWidget_2.addItem("道歉")self.listWidget_2.addItem("命令")self.listWidget_2.addItem("赞同")self.listWidget_2.addItem("反对")self.listWidget_2.addItem("表达知会")self.listWidget_2.addItem("欣赏")self.listWidget_2.addItem("叹词")self.listWidget_2.addItem("结束对话") self.listWidget_2.addItem("引用") self.listWidget_2.addItem("其他") def refresh_3(self):# self.checkBox_5.setChecked(False)self.buttonGroup.setExclusive(False)self.radioButton_4.setChecked(False)self.radioButton_5.setChecked(False)self.buttonGroup.setExclusive(True)self.buttonGroup_3.setExclusive(False)self.radioButton_6.setChecked(False)self.radioButton_7.setChecked(False)self.radioButton_8.setChecked(False)self.radioButton_9.setChecked(False)self.radioButton_10.setChecked(False)self.buttonGroup_3.setExclusive(True)# self.frame_9.setHidden(True)self.frame_3.setHidden(True)self.frame_8.setHidden(True) def refresh_save(self):self.lineEdit_2.setText('0')self.lineEdit_3.setText('0')self.lineEdit_4.setText('0')self.lineEdit_5.setText('0')self.lineEdit_6.setText('0')self.lineEdit_7.setText('0')self.lineEdit_speaker.setText('')def save_data(self):## check many thingstry:self.label_val = self.buttonGroup_2.checkedButton().text()self.label_emotion = self.listWidget.selectedItems()[0].text()except:QMessageBox.information(self,'提示','请选择具体情感后再重新保存', QMessageBox.Yes)return Falsetry:self.label_da = self.listWidget_2.selectedItems()[0].text()except:QMessageBox.information(self,'提示','请选择对话状态后再重新保存', QMessageBox.Yes)return Falseself.label_iden_isok = self.checkBox_5.isChecked()if self.label_iden_isok:if self.buttonGroup.checkedId() == -1:QMessageBox.information(self,'提示','您已勾选该对话身份可标,请选择说话人身份后再重新保存', QMessageBox.Yes)return Falseelse:self.label_iden = self.buttonGroup.checkedButton().text()if self.label_iden == "倾诉者":self.label_reason = self.lineEdit_reason.text()self.label_result = self.lineEdit_result.text()self.label_reaction = "空"else:self.label_reason = "空"self.label_result = "空"try:self.label_reaction = self.buttonGroup_3.checkedButton().text()except:QMessageBox.information(self,'提示','您已勾选该对话身份可标,请选择倾诉者反应后再重新保存', QMessageBox.Yes)return Falseelse:self.label_iden = "不可标"self.label_reason = "不可标"self.label_result = "不可标"self.label_reaction = "不可标"if self.lineEdit_speaker.text() == '':QMessageBox.information(self,'提示','请输入说话人姓名', QMessageBox.Yes)return Falseelse:self.name_speaker = self.lineEdit_speaker.text()try:self.start_time = "{}:{}:{}".format(int(self.lineEdit_2.text()), int(self.lineEdit_3.text()), int(self.lineEdit_4.text()))self.end_time = "{}:{}:{}".format(int(self.lineEdit_5.text()), int(self.lineEdit_6.text()), int(self.lineEdit_7.text()))except:QMessageBox.information(self,'提示','时间应输入整数', QMessageBox.Yes)return Falseif self.lineEdit.text() == '':QMessageBox.information(self,'提示','请输入视频名字', QMessageBox.Yes)return Falseelse:self.name_dialog = self.lineEdit.text()if not os.path.exists(root_path_metadata+self.name_dialog+'.csv'):with open(root_path_metadata+self.name_dialog+'.csv',"a",newline='',encoding='utf_8_sig') as csvfile: writer = csv.writer(csvfile, delimiter=',')writer.writerow(['视频名字', '说话者姓名', '起始时间', '结束时间', '情绪(粗粒度)', '情绪(细粒度)', '是否基于音频', '是否基于视频', '是否基于文本', '是否难以标注', '对话状态', '是否可标对话身份', '说话人身份', '起因', '结果', '倾诉者反应'])## saveself.label_emotion_audio_based = self.checkBox_3.isChecked()self.label_emotion_video_based = self.checkBox_2.isChecked()self.label_emotion_text_based = self.checkBox.isChecked()self.label_emotion_hard = self.checkBox_4.isChecked()onelist = [self.name_dialog, self.name_speaker, self.start_time, self.end_time, self.label_val, self.label_emotion, self.label_emotion_audio_based, self.label_emotion_video_based, self.label_emotion_text_based, self.label_emotion_hard, self.label_da, self.label_iden_isok, self.label_iden, self.label_reason, self.label_result, self.label_reaction]with open(root_path_metadata+self.name_dialog+'.csv',"a",newline='',encoding='utf_8_sig') as csvfile: writer = csv.writer(csvfile, delimiter=',')writer.writerow(onelist)self.refresh_gui()self.list_dialog.append(self.name_dialog)self.list_speaker.append(self.name_speaker)self.list_dialog = list(set(self.list_dialog))self.list_speaker = list(set(self.list_speaker))# self.lineEdit.setCompleter(QCompleter(self.list_dialog))# self.lineEdit_speaker.setCompleter(QCompleter(self.list_speaker))return Truedef save_dialog_data(self):flag_save_success = self.save_data()if flag_save_success == False: return 0QMessageBox.about(self,'提示','对话保存成功')self.refresh_gui()self.lineEdit.setText('')self.lineEdit_reason.setText('')self.lineEdit_result.setText('')self.checkBox_5.setChecked(False)self.frame_9.setHidden(True)def del_last_data(self):try:with open(root_path_metadata+self.name_dialog+'.csv',"r",newline='',encoding='utf_8_sig') as csvfile: data = csvfile.readlines()del data[-1]with open(root_path_metadata+self.name_dialog+'.csv',"w",newline='',encoding='utf_8_sig') as csvfile: writer = csv.writer(csvfile, delimiter=',')for row in data:writer.writerow(row.strip().split(','))# writer.writerows(data)QMessageBox.about(self,'提示','上一句的标注已删除')except:QMessageBox.information(self,'提示','该视频尚未保存任何数据', QMessageBox.Yes)if __name__ == '__main__':app = QApplication(sys.argv)main_win = mainWin()main_win.show()# main_win.showFullScreen()sys.exit(app.exec_()) 4. 封装成可执行文件

对于编写好的.py文件,若是需要更好的给没有python编辑器的人使用,则需要封装成.exe文件,这可以通过 pyinstaller 命令来完成。

pyinstaller -F biaozhu.py

pyinstaller 有两种常见的模式: -F: 將程式打包成单一的执行文件(适合比较简单的代码) -D: 打包多個文件,exe及依赖的东西会一起放置在dist資料夾里(适合框架形式的程式)

在打包过程中,包含如下步骤

在路径下生成了biaozhu.spec: 包含打包时相关的设定建立build 文件夹,放置了log记录和相关文件建立dist 文件夹,放置了可执行文件,若是 —F 模式,则里边仅有一个.exe文件

另外,若是打包失败,可以通过改写.spec文件,再通过 pyinstaller -D XXX.spec 重新打包。 如果是库的 import 问题,可以通过 hiddenimport 里放置库名来hidden掉该错误。

5. 总结

以前只知道 Tkinter 可以来实现 python 的界面设计,但感觉并不那么友好。 而这次学习到的 PyQt 以及相应的 Qt designer则很好的解决了这一问题,可以通过拉拽进行布局,就像c++的SDL一样。完成界面设计后的逻辑编写才是更让人头疼的问题,容易产生各种bug,只能慢慢调。 最后完成程序之后还可以转成.exe文件,从而可以直接给别人使用,这个是意料之外的惊喜。

如何搭建python开发环境用Python写一个简单的集成开发 ...python编程完怎么运行_使用Xcode怎么编写并运行Python ...利用Python开发App实战,从基础到实践 - 知乎【界面】使用QT designer、python搭建界面程序_weiquan ...ubuntu 18.04搭建python环境(pycharm+anaconda) | 更新 ...python代码在线运行环境_51CTO博客pytest自动化测试框架,真正做到从0到1由浅入深详细讲解 ...二、Python2.7的安装并与Python3.8共存 - 相关文章virtualenv 环境下 Django + Nginx + Gunicorn+ Supervisor ...还不知道怎么运行Python代码,教你部署开发环境,快来撸代码了python3.6中使用web.py创建简单webservice并使用pyinstaller打包成可执行程序使用ez_setup.py安装setuptools报错云服务器上运行python程序(PyCharm本地编辑同步服务器+Anaconda)挂载跑实验详细教程Python UI界面开发环境搭建 运行pyuic5.exe 报错 Error in input file: no element found: line 1, column ...阿里云(腾讯云)服务器使用宝塔,搭建Python环境运行 django 程序Python/这篇文章一步步带你打造Python研发环境(详解)在服务器上搭建自己的python环境(针对小白)Visual studio Code 如何搭建python 开发环境简单而直接的Python web 框架:web.pyVScode配置Python开发环境Python3.7搭建Django框架项目Python环境在Win10系统下的搭建Python Pytest 自动化测试框架搭建ubuntu下使用Anaconda搭建python环境离线环境安装python第三方库Python3虚拟环境 venv搭建轻量级虚拟环境python所在路径如何用docker发布多个Springboot、Python应用环境(含开发、测试、生产)python flask搭建web应用Flask笔记-任务框架搭建VsCode配置Python环境-详细教程我的世界minecraft最新版1.16.5服务器及其Python开发环境搭建python环境搭建和pycharm的安装配置及汉化(零基础小白版)PhyCharm + python3.7 + pyside2 学习笔记(1) 环境搭建python3.8 roboframework环境搭建ride启动失败,解决办法三:搭建Jenkins+python接口自动化环境Python创建virtualenv(虚拟环境搭建python可视化方案】pyecharts + Django 框架windows下python的web环境搭建使用
python直接运行py文件python文件如何直接运行python 如何运行 py文件python运行python文件python 运行一个文件怎么运行python的 py文件python如何运行一个文件在python中运行py文件python的运行环境是如何搭建的python运行的环境python运行环境和开发环境python运行环境的安装和配置搭建python运行环境应该注意什么python环境怎么搭建如何安装python运行环境python的搭建环境python的运行环境python环境搭建步骤七夕送朋友祝福语幽默厨师最高级别排名吉利美日1.8t自动新车发动机意识来源于人脑对不对野菊花有什么样的精神2k19mycareeroffline各种蚊帐的安装方法一个职业老千的泣血经历全文笔趣阁app去广告破解眷恋的近义词逆变器开关怎么接