第一章 认识 PyQt5
1.1 PyQt 框架简介
- Python 支持的 GUI 控件集
- PyQt
- 用户创建 GUI 应用程序的跨平台工具包。它将 Python 和 Qt 库成功融合在一起。Qt 库是目前最强大的 GUI 库之一
- PyQt5官网
- Tkinter
- wxPython
- Kivy
- PyGUI
- Libavg
- PyQt
1.1.1 PyQt5 的特点
- 基于高性能的 Qt 的 GUI 控件集
- 能够跨平台运行在主流系统上
- 使用信号/槽机制进行通讯
- 对 Qt 库的完全封装
- 可以使用 Qt 成熟的 IDE 进行图形界面设计,并自动生成可以执行的 Python 代码
- 提供了一整套种类繁多的窗口控件
1.1.2 Qt 和 PyQt 的关系
- PyQt 是 Qt 框架在 Python 语言上的实现
- PyQt 向 Python 程序员提供了完整的 Qt 应用程序接口的函数,几乎可以用 Python 做任何 Qt 想做的事情
- 基于 Python 语言开发 Qt 的代码将会是原来使用 C++ 开发的 50%~60%
- Qt 的信号/槽机制相比于回调函数(callback)机制更加安全简洁
1.1.3 其他图形界面开发库的介绍
-
Tkinter
- Tkinter 是绑定了 Python 的 Tk GUI 工具集
- 就是 Python 包装的 tcl 代码,通过内嵌在 python 解释器内部的 Tcl 解释器实现的。
- 调用 Tkinter 库
- 将其转换为 Tcl 命令
- Tcl 解释器进行命令的解释执行
-
wxPython
- wxPython 是 Python 对跨平台的 GUI 工具集的 wxWidgets(用 C++ 编写)的包装,作为 Python 的一个扩展模块来实现
- wxPython 是比较流行的 Tkinter 的一个代替品,跨平台性比较良好
-
PyGTK
- PyGTK 是 Python 对 GTK+GUI 库的一系列包装,在 windows 系统上不友好,毕竟是使用的 GTK 的 GUI 库
-
PySide----目前已经停止更新了,最新的才支持 Qt 4.8 版本
- PySide 目前是由 Qt 官方在维护,是 Python 对跨平台的 GUI 工具集 Qt 的另一个包装,捆绑在 Python 当中
1. 上述的前三个库,没有 Qt Designer---可视化创建UI文件,可以通过工具快速编译为Python文件
2. 最后一个库也已经停止更新了
1.1.4 PyQt4/PyQt5
- PyQt5 不再向下兼容使用 PyQt4 编写的程序,因为 PyQt5 进行了重大变动
- PyQt5 不再去支持 Python2.6 之前的版本了,官方只提供了 Python3.x 版本的安装包
- PyQt5 对一些模块进行了重构,废弃了好一些模块
- PyQt5 对网页的支持与时俱进,PyQt4 对网页的支持的基础引擎是 WebKit,对互联网新生事物尤其是 JavaScript 的支持不是很完美,PyQt5 则是使用了谷歌团队的 chromium 内核引擎,基本上完美支持互联网的新生事物
- PyQt5 仅支持新式的信号和槽,对旧式的不再去支持
- PyQt5 不再去支持 Qt5.0 中标记已经废弃或者过时的 API
- PyQt5 在程序需要时才去释放 GIL,而 PyQt4 是在执行完毕程序后强制释放 GIL
- 官方对 PyQt4 不再会有重大的更新和维护了,所以目前主流的还是使用 PyQt5
1.2 PyQt5 环境搭建
1.2.1 在 Windows 下搭建 PyQt5 环境
- 安装 Python 环境 建议 3.5.3+
- 安装 PyQt 以及其常用工具 建议 5.9+
1. pip install -i https://pypi.douban.com/simple --trusted-host pypi.douban.com PyQt5-tools
+ 其实推荐直接安装这个就完事了,因为先安装下面的那个在安装这个,还是会根据兼容性重新安装PyQt5的
+ 如果直接先安装这个报错的话,那么就先安装下面的PyQt5再去安装这个(一般不会报错的)
2. pip install -i https://pypi.douban.com/simple --trusted-host pypi.douban.com PyQt5
- Eric 建议 6.17
1.2.3 在 Windows 环境下 PyQt5 的安装测试
- cmd 进入安装 PyQt5 的 python 环境
- import PyQt5 不报错说明安装成功
- help(PyQt5) 查看 PyQt5 所依赖的模块
1.2.4 安装其他 Python 模块
pip install xxxx
1.2.5 使用 PyQt5 的 API 文档
- dir()可以查看一个类或者对象的相关属性
- help()可以查看一个类或者对象的相关说明文档
为了方便查阅说明文档,我们可以使用代码将其输出写入文件中
import sys
from PyQt5.QtWidgets import QWidget
out = sys.stdout
sys.stdout = open('xxx.txt', 'w', encoding='utf-8')
help(QWidget)
sys.stdout.close()
sys.stdout = out
1.3 Eric6 的安装与使用
概念 Eric 是一个全功能的 Python 编辑器和 IDE,与 PyQt5 的结合,非常方便实现界面与业务逻辑的分离,快速开发 GUI
Eric6 的优点:
- 跨多平台良好
- 调试器支持设置断点、单步调试、查看变量值等
- 支持工程
- 支持自动补全
- 支持智能感知
- 支持自动语法检查
- 自持缩进。会自动判断流程控制语句
- 支持代码折叠
- 支持很多小工具,比如正则表达式、测试器
- 与 Qt Designer 结合很好,方便 GUI 的开发
- 支持代码的版本管理 如 SVN
- 使用 PyQt5 作为图形库,界面美观、简洁
- 支持在线自动更新
1.3.1 Eric 的安装以及汉化
pip install -i https://pypi.douban.com/simple --trusted-host pypi.douban.com QScintilla
- 在指定环境安装
### 切换到eric的目录下安装
python install.py
### 1. 没有报错就表示安装成功
### 2. 安装完成之后,如果在eric6文件夹下没有生成eric.bat文件,就需要进入eric6\eric文件夹中双击eric6.pyw文件
小技巧 可以直接安装 Qsci 模块。它会连带着将依赖模块一起安装
小坑爹 最好不要使用虚拟环境去安装 Eric,要是使用推荐使用 Adaconda
1. 安装成功Eric之后,桌面上的快捷方式会在打不开
2. 因为pythonw.exe在真实环境与虚拟环境中的位置不一样,此时我们可以使用notepad++等第三方编辑器打开那个cmd文件
3. 修改pythonw.exe文件的正确位置即可解决打不开报错等坑爹问题
4. 或者直接将真实环境下的pythonw3.exe pythonw.exe pythonw.pdb(pythonw相关的文件复制到虚拟环境指定位置)
无敌踩坑
-
无法定位程序输入点 OPENSSL_sk_new_reserve 于动态链接库 C:\Windows\System32\libssl-1_1-x64.dll 上
- 将虚拟环境下的基础环境中 D:\Program Files\Python37\DLLs 中的 libssl-1_1-x64.dll 复制到上述报错目录(记得先备份,以免后续出问题)
-
pythonw.exe 虚拟环境下不存在的问题
- 直接将真实环境下的 pythonw3.exe pythonw.exe pythonw.pdb(pythonw 相关的文件复制到虚拟环境指定位置)
-
Eric-Code Info Provider:No source code documentation provider has been registered
1.3.2 Eric 的相关配置
1.3.3 安装自动补全插件 jedi
- jedi 是一个超级棒的 Python 自动补全库,可以在很多编辑器以及 IDE 中使用
pip install -i https://pypi.douban.com/simple --trusted-host pypi.douban.com jedi
- 在菜单中选择插件进行 Eric 的插件安装
1.3.4 测试 Eric6
import sys
from PyQt5.QtWidgets import QWidget, QApplication
if __name__ == '__main__':
app = QApplication(sys.argv)
q = QWidget()
q.resize(360, 360)
q.show()
sys.exit(app.exec_())
1.3.5 Eric 的基本使用
第二章 Python 的基础知识
第三章 Qt Designer 的使用
3.1 Qt Designer 快速入门
-
Qt Designer 是一款强大灵活并且可视化的 GUI 设计工具
-
.ui 文件有两种方式转换为 py 文件,并被其他 python 文件引用
- 命令的方式
- 手工的方式(Eric 手工转换)
-
Qt Designer 优点:
- 使用简单,可以通过拖拽点击的方式完成 UI 设计
- 转换 python 文件简单
路径一般是在安装的 PyQt5-tools 中
3.1.1 新建主窗口
- 新建一个 Main 窗口
3.1.2 窗口主要区域介绍
3.1.3 查看 UI 文件
3.1.4 将.ui 文件转换为.py 文件
Qt Designer 设计的界面保存为 ui 文件,内容结构类似 XML,我们需要的是 py 文件,就需要将 ui 文件转换为 py 文件
- ui-->py 文件的转换方法
-
通过 Eric6 将 ui 文件转换为 py 文件
- 打开一个 Eric 项目,然后切换到窗体
- 右键添加一个窗体
- 右键编译窗体
- 返回到源代码目录会发现多了一个 Ui_xxx.py 文件
-
通过命令行把 ui 文件转换为 py 文件
- PyQt5 安装成功后,pyuic5 命令默认安装在对应的 python 的 Scripts 目录下
- pyuic5 -o xxxx.py xxxx.ui 就可以将 ui 文件转换为 py 文件
-
通过 python 脚本把 ui 文件转换为 py 文件
-
import os
CurrDir = './'
def listUiFile():
FileList = []
files = os.listdir(CurrDir)
for fileName in files:
if os.path.splitext(fileName)[1] == '.ui':
FileList.append(fileName)
return FileList
def ui2py(UiFileName):
return os.path.splitext(UiFileName)[0] + '.py'
def runMain():
FileList = listUiFile()
for uifile in FileList:
pyfile = ui2py(uifile)
cmd = 'pyuic5 -o {} {} '.format(pyfile, uifile)
os.system(cmd)
if __name__ == '__main__':
runMain()
注意后两种方式转换出来 py 文件后,需要加上如下代码才能真正运行
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_())
3.1.5 界面与逻辑分离
我们要做的其实很简单只需要继承 ui 转换的那个 py 文件中的窗口类
实现如下代码就可以运行
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_())
小技巧可以将 MainWindow = QtWidgets.QMainWindow()、ui = Ui_MainWindow()、ui.setupUi(MainWindow)这三行代码的实现放进我们派生类的构造函数中即 init()方法中
import sys
from FirstMainWidget import *
from PyQt5.QtWidgets import QApplication,QMainWindow
class MyMainWindow(QMainWindow,Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
if __name__ == '__main__':
app = QApplication(sys.argv)
myWin = MyMainWindow()
myWin.show()
sys.exit(app.exec_())
解析个人见解
- 将这行代码 MainWindow = QtWidgets.QMainWindow()放进 QMainWindow 这个父类中的__init__()中实现
- ui = Ui_MainWindow()、ui.setupUi(MainWindow)将这两行代码放进派生类的__init__()中实现
- 因为派生类继承 Ui 那个类,所以 self 就是 ui 对象,而派生类也继承自 QMainWindow,所以 self 同时也是 QMainWindow 对象,所以有 self.setupUi(self)
3.2 布局管理
小知识
普通小控件的基类是 QtWidgets.QFrame
四大布局
- 垂直布局
概念控件默认按照从上至下的顺序进行纵向添加 - 水平布局
概念控件默认按照从左到右的顺序进行纵向添加 - 栅格布局
概念将窗口控件放入一个网格之中,然后将它们合理地划分成若干行 row 和列 column,并把其中的每个窗口控件放置在合适的单元 cell 中,这里的单元即是由行列交叉划分出来的空间 - 表单布局
概念控件以两列的形式布局在表单中,左侧是标签,右侧是输入控件
提示一般布局有两种方式 - 通过布局管理器显式指明使用什么布局(右键选择使用怎样的布局)
- 通过容器控件进行布局(如拖拽左侧的容器控件)
3.2.1 使用布局管理器
3.2.2 使用容器进行布局
本质使用容器进行控件布局其实还是要调用布局管理器进行统筹布局
3.3 Qt Designer 实战应用
了解属性编辑器的四大属性:
- geometry
- sizePolicy
- minimumSize
- maximumSize
3.3.1 绝对布局
geometry----[(215,140),75*23] 距离窗口左上角(215,140) 大小(75x23)
self.pushButton = QtWidgets.QpushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(215,140,75,23)
self.pushButton.setObjectName("pushButton")
3.3.2 使用布局管理器布局
-
垂直布局
将几个控件使用垂直布局管理器布局后,其 geometry 属性都是灰色的,表示它们的位置和大小已经由垂直布局管理器接管了 -
栅格布局
grid.Layout.addWidget(窗口控件,行位置,列位置,要合并的行数,要合并的列数)后两个参数是可选的 默认就是 1,1 表示占据当前的行列位置,不进行合并操作 -
水平布局
- Vertical Spacer 表示两个水平方向上布局不要彼此挨着
- Horizontal Spacer 表示垂直方向上的布局不要紧挨
- Horizontal Line 表示某个控件跟左侧的的布局不是一个类别的,所以用一条线将其分开来
一个基本原则 PyQt 有一个基本原则
主窗口中的所有窗口控件都有自己的父类
-
minimumSize 和 maximumSize 属性
小提示每个控件都有自己的两个尺寸- sizeHint 尺寸提示 窗口控件的期望尺寸
- minimumSize 最小尺寸 窗口控件的压缩最小尺寸
-
sizePolicy 属性
作用
如果窗口控件在布局管理器中的布局不能满足我们的需求,那么就可以设置 sizePolicy 来实现布局的微调
3.3.3 其他需要注意的内容
重点使用 Qt Designer 开发一个完整的 GUI 程序流程如下
-
Qt Designer 布局的顺序
- 将一个窗口控件拖入窗口中并放置在大致的正确位置上,除了容器 container 窗口,一般不需要调整窗口的尺寸大小
- 对于要用代码引用的窗口控件,应指定一个名字,对应需要微调的窗口控件,可以设置其对应的属性
- 重复以上步骤,直到所需要的全部窗口控件都放到了窗口中
- 如有需要,在窗口控件之间可以用分割线以及距离控件
- 选择需要布局的窗口控件,使用布局管理器或者分窗口对它们进行布局
- 重复上一步,直到所有窗口控件和分隔符都布局好为止
- 单击窗口,并使用布局管理器对齐进行布局
- 为窗口的标签设置伙伴关系
- 如果按键次序有问题,则需要设置窗口的 Tab 键次序
- 在适当的地方为内置的信号和槽建立信号与槽的链接
- 预览窗口,并检查所有内容是否按照预想进行工作
- 设置窗口的对象名。窗口的标题并进行保存
- 使用 Eric 等类似工具编译窗口,然后根据需要生成对应的对话框代码
- 进行正常的代码编写工作,即编写业务逻辑文件
-
使用布局管理器对窗体进行布局
针对窗体的布局,那是会将布局管理器布满整个窗体屏幕的,一般用不到
小技巧当我们布局时出现很多步错误时,撤销比较麻烦时,可以使用单击窗体空白处,选择布局---> 打破布局(还原到初始布局状态) -
设置伙伴关系
- 在 display widgets 名字前加上&
- 名字需要是英文的
- Alt+S 快捷键可以快速定位伙伴关系
-
设置 Tab 键顺序
- 菜单---Edit----设置 Tab 键次序
- 鼠标右键----制表符顺序列表--上下拖动控件进行排序
3.3.4 测试程序
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.layoutWidget = QtWidgets.QWidget(self.centralwidget)
self.layoutWidget.setGeometry(QtCore.QRect(0, 130, 821, 171))
self.layoutWidget.setObjectName("layoutWidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.layoutWidget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.label_6 = QtWidgets.QLabel(self.layoutWidget)
self.label_6.setText("")
self.label_6.setObjectName("label_6")
self.verticalLayout.addWidget(self.label_6)
self.label = QtWidgets.QLabel(self.layoutWidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(1)
sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
self.label.setSizePolicy(sizePolicy)
self.label.setObjectName("label")
self.verticalLayout.addWidget(self.label)
self.label_2 = QtWidgets.QLabel(self.layoutWidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(3)
sizePolicy.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth())
self.label_2.setSizePolicy(sizePolicy)
self.label_2.setObjectName("label_2")
self.verticalLayout.addWidget(self.label_2)
self.label_3 = QtWidgets.QLabel(self.layoutWidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(1)
sizePolicy.setVerticalStretch(1)
sizePolicy.setHeightForWidth(self.label_3.sizePolicy().hasHeightForWidth())
self.label_3.setSizePolicy(sizePolicy)
self.label_3.setObjectName("label_3")
self.verticalLayout.addWidget(self.label_3)
self.horizontalLayout.addLayout(self.verticalLayout)
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem)
self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setObjectName("gridLayout")
self.label_5 = QtWidgets.QLabel(self.layoutWidget)
self.label_5.setObjectName("label_5")
self.gridLayout.addWidget(self.label_5, 0, 0, 1, 1)
self.label_4 = QtWidgets.QLabel(self.layoutWidget)
self.label_4.setObjectName("label_4")
self.gridLayout.addWidget(self.label_4, 0, 1, 1, 1)
self.doubleSpinBox_returns_min = QtWidgets.QDoubleSpinBox(self.layoutWidget)
self.doubleSpinBox_returns_min.setObjectName("doubleSpinBox_returns_min")
self.gridLayout.addWidget(self.doubleSpinBox_returns_min, 1, 0, 1, 1)
self.doubleSpinBox_returns_max = QtWidgets.QDoubleSpinBox(self.layoutWidget)
self.doubleSpinBox_returns_max.setObjectName("doubleSpinBox_returns_max")
self.gridLayout.addWidget(self.doubleSpinBox_returns_max, 1, 1, 1, 1)
self.doubleSpinBox_maxdrawdown_min = QtWidgets.QDoubleSpinBox(self.layoutWidget)
self.doubleSpinBox_maxdrawdown_min.setObjectName("doubleSpinBox_maxdrawdown_min")
self.gridLayout.addWidget(self.doubleSpinBox_maxdrawdown_min, 2, 0, 1, 1)
self.doubleSpinBox_maxdrawdown_max = QtWidgets.QDoubleSpinBox(self.layoutWidget)
self.doubleSpinBox_maxdrawdown_max.setObjectName("doubleSpinBox_maxdrawdown_max")
self.gridLayout.addWidget(self.doubleSpinBox_maxdrawdown_max, 2, 1, 1, 1)
self.doubleSpinBox_sharp_min = QtWidgets.QDoubleSpinBox(self.layoutWidget)
self.doubleSpinBox_sharp_min.setObjectName("doubleSpinBox_sharp_min")
self.gridLayout.addWidget(self.doubleSpinBox_sharp_min, 3, 0, 1, 1)
self.doubleSpinBox_sharp_max = QtWidgets.QDoubleSpinBox(self.layoutWidget)
self.doubleSpinBox_sharp_max.setObjectName("doubleSpinBox_sharp_max")
self.gridLayout.addWidget(self.doubleSpinBox_sharp_max, 3, 1, 1, 1)
self.horizontalLayout.addLayout(self.gridLayout)
self.line = QtWidgets.QFrame(self.layoutWidget)
self.line.setFrameShape(QtWidgets.QFrame.VLine)
self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line.setObjectName("line")
self.horizontalLayout.addWidget(self.line)
spacerItem1 = QtWidgets.QSpacerItem(400, 20, QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem1)
self.pushButton = QtWidgets.QPushButton(self.layoutWidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pushButton.sizePolicy().hasHeightForWidth())
self.pushButton.setSizePolicy(sizePolicy)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.toolBar = QtWidgets.QToolBar(MainWindow)
self.toolBar.setObjectName("toolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
self.toolBar_2 = QtWidgets.QToolBar(MainWindow)
self.toolBar_2.setObjectName("toolBar_2")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar_2)
self.toolBar_3 = QtWidgets.QToolBar(MainWindow)
self.toolBar_3.setObjectName("toolBar_3")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar_3)
self.label_3.setBuddy(self.doubleSpinBox_sharp_min)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
MainWindow.setTabOrder(self.doubleSpinBox_returns_min, self.doubleSpinBox_maxdrawdown_min)
MainWindow.setTabOrder(self.doubleSpinBox_maxdrawdown_min, self.doubleSpinBox_sharp_min)
MainWindow.setTabOrder(self.doubleSpinBox_sharp_min, self.doubleSpinBox_returns_max)
MainWindow.setTabOrder(self.doubleSpinBox_returns_max, self.doubleSpinBox_maxdrawdown_max)
MainWindow.setTabOrder(self.doubleSpinBox_maxdrawdown_max, self.doubleSpinBox_sharp_max)
MainWindow.setTabOrder(self.doubleSpinBox_sharp_max, self.pushButton)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(_translate("MainWindow", "&收益"))
self.label_2.setText(_translate("MainWindow", "最大回数"))
self.label_3.setText(_translate("MainWindow", "&sharp比"))
self.label_5.setText(_translate("MainWindow", "最小值"))
self.label_4.setText(_translate("MainWindow", "最大值"))
self.pushButton.setText(_translate("MainWindow", "开始"))
self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
self.toolBar_2.setWindowTitle(_translate("MainWindow", "toolBar_2"))
self.toolBar_3.setWindowTitle(_translate("MainWindow", "toolBar_3"))
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_())
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于