PyQt5-资源文件的使用

窗体可视化设计

新建一个Qt Widgets Application项目QtApp,创建窗体时选择窗体基类为QWidget,新建窗体类的名称设置为默认的Widegt。创建项目后,对窗体Widget.ui进行可视化设计,设计好的窗体如下图所示。

image

该窗体在设计时采用了布局管理方法。“年龄设置”分组框用的是组件面板Container分组里的GroupBox组件,其内部组件按网格状布局;“姓名设置”分组框里的组件也按网格状布局;最下方的按钮和多个空格组件使用了组件面板Container分组里的Frame组件作为容器,采用水平布局。窗口的主布局采用垂直布局。

窗体上所有组件的层次关系如下图所示,下图还显示了各个组件的objectName及其所属的类。用于设置年龄的是一个QSlider组件,在属性编辑器里设置其minimum属性为0,maximum属性为100。

image

image

创建和使用资源文件

其中 图标可以去阿里巴巴图标网
https://www.iconfont.cn/user/detail?spm=a313x.7781069.1998910419.dfa9d9a29&uid=9992
进行获取

在资源浏览器中

image

点击编辑资源

image

image

image

image

将图标导入到资源文件里后,就可以在窗体设计时使用图标了。例如,要设置“关闭”按钮的图标,在属性编辑器中有icon属性,点击右侧下拉菜单中的“ChooseResource...”,就可以在项目的资源文件里为按钮选择图标了。

image

image

窗体文件和资源文件的编译

在Qt Creator里设计的资源文件要在Python程序里使用,需要使用pyrcc5.exe工具软件将资源文件res.qrc编译为一个对应的Python文件res_rc.py。执行编译的指令如下:

image

image

image

那么这里 先将自己设计好的ui转为py文件

image

image

窗体业务逻辑类的设计

将上个示例创建的文件human.py复制到本示例目录下。

human.py文件的代码如下:

## 自定义信号与槽的演示
import sys
from PyQt5.QtCore import QObject,pyqtSlot,pyqtSignal

class Human(QObject):
    ##定义一个带str类型参数的信号
    nameChanged=pyqtSignal(str)
    ##overload型信号有两种参数 一种是int,另一种是str
    ageChanged=pyqtSignal([int],[str])

    def __init__(self,name='Mike',age=10,parent=None):
        super().__init__(parent)
        self.setAge(age)
        self.setName(name)

    def setAge(self,age):
        self.__age=age
        self.ageChanged.emit(self.__age)# 发射int参数信号
        if age <= 18:
            ageInfo = "你是少年"
        elif (18 < age <= 35):
            ageInfo = "你是年轻人"
        elif (35 < age <= 55):
            ageInfo = "你是中年人"
        elif (55 < age <= 80):
            ageInfo = "您是老人"
        else:
            ageInfo = "您是寿星啊"
        self.ageChanged[str].emit(ageInfo)#发射str参数信号

    def setName(self, name):
        self._name = name

        self.nameChanged.emit(self._name)

class Responsor (QObject):
    @pyqtSlot(int)
    def do_ageChanged_int(self,age):
        print("你的年龄是:"+str(age))

    @pyqtSlot(str)
    def do_ageChanged_str(self, ageInfo):
        print(ageInfo)

    ## @pyqtSlot (str)
    def do_nameChanged(self,name):
        print("Hello," + name)

if __name__ == "__main__":##测试程序
    print("**创建对象时**")
    boy=Human("Boy",16)
    resp=Responsor()
    boy.nameChanged.connect(resp.do_nameChanged)
    ##overload的信号,两个槽函数不能同名,关联时需要给信号加参数区分
    boy.ageChanged.connect(resp.do_ageChanged_int)# 默认参数,int型
    boy.ageChanged[str].connect(resp.do_ageChanged_str)# str型参数
    print("\n**建立关联后**")
    boy.setAge(35)# 发射两个ageChanged信号
    boy.setName("Jack")  # 发射nameChanged信号
    boy.ageChanged[str].disconnect(resp.do_ageChanged_str)  # 断开关联
    print("\n **断开ageChanged[str]的关联后**")
    boy.setAge(10)
    # 发射两个ageChanged信号

采用单继承方法设计一个窗体业务逻辑类QmyWidget,保存为文件myWidget.py,该文件的完整内容如下:

import sys
from PyQt5.QtWidgets import  QWidget,QApplication
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtGui import QIcon

from ui_QtAPP import Ui_Form
from human import Human
class QmyWidget(QWidget):
    def __init__(self,parent=None):
        super().__init__(parent) #调用父类构造函数
        self.ui=Ui_Form() #创建UI对象
        self.ui.setupUi(self) #构造UI
        self.boy=Human("Boy",16)
        self.boy.nameChanged.connect(self.do_nameChanged)
        self.boy.ageChanged.connect(self.do_ageChanged_int)
        self.boy.ageChanged[str].connect(self.do_ageChanged_str)

    ## ====由connectSlotsByName()自动与组件的信号关联的槽函数=====
    def on_horizontalSlider_valueChanged(self,value):
        self.boy.setAge(value)

    def on_pushButton_clicked(self):
        hisName=self.ui.lineEdit_3.text()
        self.boy.setName(hisName)

    ## =======自定义槽函数=======
    def do_nameChanged(self,name):
        self.ui.lineEdit_4.setText("Hello,"+name)

    @pyqtSlot(int)
    def do_ageChanged_int(self, age):
        self.ui.lineEdit.setText(str(age))

    @pyqtSlot(str)
    def do_ageChanged_str(self, info):
        self.ui.lineEdit_2.setText(info)

if __name__ == "__main__": ##用于当前窗体测试
    app=QApplication(sys.argv)
    icon=QIcon(":/icon/img1.png")
    app.setWindowIcon(icon)
    form=QmyWidget()
    form.show()
    sys.exit(app.exec_())

程序myWidget.py可以当作主程序直接运行,但是建议单独编写一个主程序文件appMain.py,此文件的代码如下:

## GUI应用程序主程序
import sys
from PyQt5.QtWidgets import  QApplication
from myWidget import  QmyWidget

app = QApplication(sys.argv) # 创建app,用QApplication类
myWidget = QmyWidget() #创建窗体
myWidget.show()
sys.exit(app.exec_())

整个项目的框架如下所示:
image

image

整体效果如下:

image

为应用程序设置图标

可以为应用程序设置一个图标,这样,应用程序的每个窗体将自动使用这个图标作为窗体的图标。在myWidget.py文件的测试程序部分添加设置应用程序图标的代码:

image

就是从资源文件里提取了一个图标作为应用程序的图标。当然,也可以使用QWidget的setWindowIcon()函数为一个窗体单独设置图标。

上述程序中应用程序没有显示图标 是因为代码后面有误

正确代码为

if __name__ == "__main__": ##用于当前窗体测试
    app=QApplication(sys.argv)
    icon=QIcon(":icon/img1.png")
    app.setWindowIcon(icon)
    form=QmyWidget()
    form.show()
    sys.exit(app.exec_())

所以最终的全部代码为:

import sys
from PyQt5.QtWidgets import  QWidget,QApplication
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtGui import QIcon

from ui_QtAPP import Ui_Form
from human import Human
class QmyWidget(QWidget):
    def __init__(self,parent=None):
        super().__init__(parent) #调用父类构造函数
        self.ui=Ui_Form() #创建UI对象
        self.ui.setupUi(self) #构造UI
        self.boy=Human("Boy",16)
        self.boy.nameChanged.connect(self.do_nameChanged)
        self.boy.ageChanged.connect(self.do_ageChanged_int)
        self.boy.ageChanged[str].connect(self.do_ageChanged_str)

    ## ====由connectSlotsByName()自动与组件的信号关联的槽函数=====
    def on_horizontalSlider_valueChanged(self,value):
        self.boy.setAge(value)

    def on_pushButton_clicked(self):
        hisName=self.ui.lineEdit_3.text()
        self.boy.setName(hisName)

    ## =======自定义槽函数=======
    def do_nameChanged(self,name):
        self.ui.lineEdit_4.setText("Hello,"+name)

    @pyqtSlot(int)
    def do_ageChanged_int(self, age):
        self.ui.lineEdit.setText(str(age))

    @pyqtSlot(str)
    def do_ageChanged_str(self, info):
        self.ui.lineEdit_2.setText(info)

if __name__ == "__main__": ##用于当前窗体测试
    app=QApplication(sys.argv)
    icon=QIcon(":icon/img1.png")
    app.setWindowIcon(icon)
    form=QmyWidget()
    form.show()
    sys.exit(app.exec_())

效果如下:

image

posted @ 2021-07-07 09:48  司砚章  阅读(309)  评论(0编辑  收藏  举报