在开始本文之前提醒各位朋友,Python记得安装PyQt5库文件,Python语言功能很强,但是Python自带的GUI开发库Tkinter功能很弱,难以开发出专业的GUI。好在Python语言的开放性,很容易将其他语言(特别是C/C++)的类库封装为Python绑定,而Qt是非常优秀的C++ GUI 类库,所以就有了PyQt。
安装指令如下所示:
pip install pyqt5
这也Python基础知识,不在本专栏主讲范畴,简单聊聊。
Qt Designer,即Qt设计师,是一个强大、灵活的可视化GUI设计工具,可以帮助我们加快开发PyQt程序的速度。
Qt Designer 是专门用来制作PyQt程序中UI界面的工具,它生成的UI界面是一个后缀为.ui 的文件。制作程序UI界面,一般可以通过UI制作工具和纯代码编写两种方式来实现,我们主要是通过Qt Creator制作完成。
该文件使用非常简单,可以通过命令将.ui文件转换成.py格式的文件,并被其他Python文件引用,也可以通过Eric 6进行手工转换。
本博文以命令的方式为主,手工的方式为辅,但是原理和结果是一样的,各位可以根据自己的偏好进行选择。
Qt Designer 符合MVC(模型―视图—控制器)设计模式,做到了显示和业务逻辑的分离,具有以下优点:
Qt Creator 的界面很简洁,上方是主菜单栏,左侧是主工具栏,窗口的中间部分是工作区。根据设计内容不同,工作区会显示不同的内容。

主窗口左侧是主工具栏,主工具栏提供了项目文件编辑、窗体设计、程序调试、项目设置等各种功能按钮。
在左侧主工具栏单击“Welcome(欢迎)”按钮后显示实例的界面。这时工作区的左侧有 “Projects”、“Examples(示例)”、“Tutorials(教程)”、“Get Started Now”几个按钮,单击后会在主工作区显示相应的内容:
学习一种编程语言或编程环境,通常会先编写一个“Hello World”程序。我们也用 Qt Creator 编写一个“Hello World”程序,以初步了解 Qt Creator 设计应用程序的基本过程,对使用 Qt Creator 编写 Qt Python 应用程序建立初步的了解。
第1步:单击 Qt Creator 的菜单项文件->新建文件或项目,出现如下图所示的对话框。在这个对话框里选择需要创建的项目或文件的模板。

Qt Creator 可以创建多种项目,在最左侧的列表框中单击“Application”,中间的列表框中列出了可以创建的应用程序的模板,各类应用程序如下:
第2步:这里创建一个Qt for Python - Empty应用程序模板就可以,如下图所示:



第3步:鼠标右击main工程,在工程下新建一个主窗口的界面ui文件,如下图所示:





此时工程文件如下所示:

第4步:双击进入mainwindow.ui文件,设计Hello,world!显示效果,如下所示:

使用代码编辑软件打开UI文件,可见相关的数据参数,如下所示:

使用Qt Designer 设计的用户界面默认保存为.ui文件,其内容结构类似于XML,但这种文件并不是我们想要的,我们想要的是.py 文件,所以还需要使用其他方法将.ui文件转换为.py文件。本博文聊聊3种方法。
最简单的方法是通过Eric 6手工编译.ui文件,只需要单击鼠标就能完成。

第1步,下载Eric 6软件,下载地址:The Eric Python IDE - Download
下载Eric 6后,点击install.py文件进行安装,如下所示:

安装中~

安装完成后,可在Python安装包路径:找到eric6文件夹,例如我的Python安装的D盘,路径为:D:\Python_3.8.3\Lib\site-packages\eric6,并找到eric6.pyw文件,点击运行,效果如下所示:

第2步:配置Eric6,进入菜单栏 设置->首选项,如下所示:

在左侧列表中选择项目->多重项目,点击右侧图标后选定工程文件位置,我这里是桌面文件夹,如下所示:

第3步:建立项目,菜单栏中选择项目->新建,创建项目,效果如下所示:

点击OK后,注意,Eric 6存在许多奇奇怪怪不知名的问题,点击是否将已有文件添加到工程YES,可能会卡死,这里点击NO,仅仅创建项目即可,如下所示:

第4步:导入UI文件并编译,此时可见左侧项目浏览器点亮可编辑,如下所示:

点击窗体,添加窗体(也就是咱设计好的UI文件),如下所示:



此时可见源代码下有编译好的Python文件:Ui_mainwindow.py,如下所示:

可在桌面Demo文件夹中点击查看,如下所示:

UI文件转换的Python代码内容如下所示:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'C:\Users\Administrator\Desktop\Demo\mainwindow.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(320, 240)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(80, 50, 151, 141))
font = QtGui.QFont()
font.setPointSize(15)
self.label.setFont(font)
self.label.setObjectName("label")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.actioncheng = QtWidgets.QAction(MainWindow)
self.actioncheng.setObjectName("actioncheng")
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(_translate("MainWindow", "Hello,World!"))
self.actioncheng.setText(_translate("MainWindow", "cheng"))
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_())
运行Python文件,即可查看GUI效果,如下所示:

Python命令行将UI文件编译成Python文件依托于pyuic5命令。
PyQt 5安装成功后,pyuic5命令默认安装在Python安装包目录Scripts文件下,例如我的安装在:D:\Python_3.8.3\Scripts,效果如下所示:

第1步:执行指令,将UI文件生成Python代码,指令如下所示:
pyuic5 -o mainwindow.py mainwindow.ui
此时将mainwindow.ui生成mainwindow.py文件,效果如下所示:

第2步:将mainwindow.py添加入Qt Creator当时创建的工程,如下所示:

最后在main函数中编写调用GUI的程序(可参见 2.1、Eric 6编译 调用的例程代码),6行代码如下所示:
# This Python file uses the following encoding: utf-8
import sys
from PySide2.QtWidgets import QApplication
#添加的所需库文件
from PyQt5 import QtCore, QtGui, QtWidgets
#mainwindow.ui Python文件
import mainwindow
if __name__ == "__main__":
app = QApplication([])
#此处调用GUI的程序
widgets = QtWidgets.QMainWindow()
ui = mainwindow.Ui_MainWindow()
ui.setupUi(widgets)
widgets.show()
#结束
sys.exit(app.exec_())
点击运行,GUI效果如下所示:

最后补充一点, Qt Creator运行Python文件需要提前安装配置好Python环境,否则无法正常编译运行,这里就不再赘述安装过程了。

有些朋友可能对2.2、Python命令行编译的方式不熟悉或者不太喜欢,这里再拓展讲讲Python脚本编译的方法,脚本本质上是用Python代码把上述操作封装起来,脚本代码如下所示:
import os
import os.path
dir ='./' #文件所在的路径
#找出路径下所有的.ui文件
def listUiFile():
list = []
files = os.listdir(dir)
for filename in files:
#print(filename)
if os.path.splitext(filename)[1] == '.ui':
list.append(filename)
return list
#把扩展名未.ui的转换成.py的文件
def transPyFile(filename):
return os.path.splitext(filename)[0] + '.py'
#通过命令把.ui文件转换成.py文件
def runMain():
list = listUiFile()
for uifile in list:
pyfile = transPyFile(uifile)
cmd = 'pyuic5 -o {pyfile} {uifile}'.format(pyfile=pyfile, uifile=uifile)
os.system(cmd)
if __name__ =="__main__":
runMain()
只要把脚本代码Python文件放在需要转换UI界面文件的目录下,直接运行,就可以将UI文件编译为Python文件。
通过之前的内容学会了如何制作.ui文件,以及如何把.ui文件转换成.py文件,最后再补充讲讲界面、逻辑分离思想。
值得注意的是,由于这里的.py文件是由.ui文件编译而来的,因此当.py文件发生变化时,对应的.py文件也会发生变化。可以把这种由.ui文件编译而来的.py文件称为界面文件。
由于界面文件每次编译时都会初始化,所以需要新建一个.py文件调用界面文件,这个新建的.py文件被称为逻辑文件,也可以称为业务文件。
界面文件和逻辑文件是两个相对独立的文件,通过上述方法就实现了界面与逻辑的分离(也可以说是“显示和业务逻辑的分离")。
实现界面与逻辑的分离方法很简单,只需要新建一个逻辑处理Python文件,继承界面文件的主窗口类即可,后续项目我们会讲到实际的应用。
如果以后想要更新界面,只需要对.ui文件进行更新,然后再编译成对应的.py 文件即可。而逻辑文件则视情况做一些调整,一般情况下不需要调整太多。
参考资料:
1、快速熟悉 PyQt5 与 Eric6 的极速 GUI 开发
2、完美安装 Anaconda3 + PyQt5 + Eric6
3、关于pyuic5命令详细介绍,参考官网:Using Qt Designer — PyQt v5.15 Reference Guide
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
我正在使用i18n从头开始构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在rubyonrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚