(PySide6)使用qt designer设计ui组件生成python代码且导入到主界面

前言

最近在入坑pyside做一下桌面开发,下面以其他人做的软件说明一下如何实现:
1、使用qt designer进行组件开发
2、导出到py代码
3、使用qt designer导入这个自定义插件再进行开发

下面是需要用到的基础以及项目源代码:
https://github.com/muziing/PySide6-Code-Tutorial

https://github.com/Jai-wei/YOLOv8-PySide6-GUI

ps:本文是以YOLOv8-PySide6-GUI 里面的home界面作为例子,截取其中一个界面元素作为ui组件,再行开发的。请自行准备素材以及项目代码。

ps2:默认你已经知道怎么使用qt designer,怎么打开qt designer,怎么新建ui文件,怎么将ui文件导出为 py代码。

过程

项目代码如下:
在这里插入图片描述

ps:红线画出来的是我先行摸索探索做的ui组件,花了点时间终于打通了。

运行界面如下:

在这里插入图片描述

组件编写说明

组件场景,如下图:
在这里插入图片描述
下面要将这个显示块,total targets做成一个组件(如果你看过home里面的xml或者home.py代码会发现,就一个显示块里面包含的组件不少的,拿它来组件化很合适)。
home.py里面相关代码如下:

        self.Target_QF = QFrame(self.QF_Group)
        self.Target_QF.setObjectName(u"Target_QF")
        self.Target_QF.setMinimumSize(QSize(170, 80))
        self.Target_QF.setMaximumSize(QSize(170, 80))
        self.Target_QF.setToolTipDuration(0)
        self.Target_QF.setStyleSheet(u"QFrame#Target_QF{\n"
"color: rgb(255, 255, 255);\n"
"border-radius: 15px;\n"
"background-color: qradialgradient(cx:0, cy:0, radius:1, fx:0.1, fy:0.1, stop:0 rgb(253, 139, 133),  stop:1 rgb(248, 194, 152));\n"
"border: 1px outset rgb(252, 194, 149)\n"
"}\n"
"")
        self.Target_QF.setFrameShape(QFrame.Shape.StyledPanel)
        self.Target_QF.setFrameShadow(QFrame.Shadow.Raised)
        self.verticalLayout_9 = QVBoxLayout(self.Target_QF)
        self.verticalLayout_9.setSpacing(0)
        self.verticalLayout_9.setObjectName(u"verticalLayout_9")
        self.verticalLayout_9.setContentsMargins(0, 0, 0, 0)
        self.Target_top = QFrame(self.Target_QF)
        self.Target_top.setObjectName(u"Target_top")
        self.Target_top.setStyleSheet(u"border:none")
        self.Target_top.setFrameShape(QFrame.Shape.StyledPanel)
        self.Target_top.setFrameShadow(QFrame.Shadow.Raised)
        self.horizontalLayout_7 = QHBoxLayout(self.Target_top)
        self.horizontalLayout_7.setSpacing(0)
        self.horizontalLayout_7.setObjectName(u"horizontalLayout_7")
        self.horizontalLayout_7.setContentsMargins(0, 3, 0, 3)
        self.label_6 = QLabel(self.Target_top)
        self.label_6.setObjectName(u"label_6")
        self.label_6.setMaximumSize(QSize(16777215, 30))
        font2 = QFont()
        font2.setFamilies([u"Segoe UI"])
        font2.setPointSize(16)
        font2.setBold(True)
        font2.setItalic(True)
        self.label_6.setFont(font2)
        self.label_6.setStyleSheet(u"color: rgba(255, 255, 255,210);\n"
"padding-left:12px;\n"
"font: 700 italic 16pt \"Segoe UI\";")
        self.label_6.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.label_6.setIndent(0)

        self.horizontalLayout_7.addWidget(self.label_6)


        self.verticalLayout_9.addWidget(self.Target_top)

        self.line_3 = QFrame(self.Target_QF)
        self.line_3.setObjectName(u"line_3")
        self.line_3.setMaximumSize(QSize(16777215, 1))
        self.line_3.setStyleSheet(u"background-color: rgba(255, 255, 255, 89);")
        self.line_3.setFrameShape(QFrame.Shape.HLine)
        self.line_3.setFrameShadow(QFrame.Shadow.Sunken)

        self.verticalLayout_9.addWidget(self.line_3)

        self.Target_bottom = QFrame(self.Target_QF)
        self.Target_bottom.setObjectName(u"Target_bottom")
        self.Target_bottom.setStyleSheet(u"border:none")
        self.Target_bottom.setFrameShape(QFrame.Shape.StyledPanel)
        self.Target_bottom.setFrameShadow(QFrame.Shadow.Raised)
        self.verticalLayout_10 = QVBoxLayout(self.Target_bottom)
        self.verticalLayout_10.setSpacing(0)
        self.verticalLayout_10.setObjectName(u"verticalLayout_10")
        self.verticalLayout_10.setContentsMargins(0, 6, 0, 6)
        self.Target_num = QLabel(self.Target_bottom)
        self.Target_num.setObjectName(u"Target_num")
        self.Target_num.setMinimumSize(QSize(0, 30))
        self.Target_num.setMaximumSize(QSize(16777215, 30))
        font3 = QFont()
        font3.setFamilies([u"Microsoft YaHei UI"])
        font3.setPointSize(17)
        font3.setBold(False)
        font3.setItalic(False)
        font3.setUnderline(False)
        self.Target_num.setFont(font3)
        self.Target_num.setStyleSheet(u"color: rgb(255, 255, 255);\n"
"font: 17pt \"Microsoft YaHei UI\";")
        self.Target_num.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.verticalLayout_10.addWidget(self.Target_num, 0, Qt.AlignmentFlag.AlignTop)


        self.verticalLayout_9.addWidget(self.Target_bottom)

        self.verticalLayout_9.setStretch(1, 2)
        self.verticalLayout_9.setStretch(2, 1)

        self.horizontalLayout_3.addWidget(self.Target_QF)

稍微分析下,里面有一个top , bottom, 中间有一根横线line,top里面有一个label,bottom里面也有一个label。。。
复杂度可以成为一个组件。

组件规则说明

假设组件名称为:
ColorfulBlock,
一个组件由三部分组成:
A/ ui_colorfulblock.ui – xml形式的ui文件,由qt designer使用维护,方便随时修改。注意·:根元素是QFrame且objectName是ColorfulBlock (根元素的objectName会影响生成的python代码的类名称,规则是: Ui_objectName,例如这里指定的objectName是ColorfulBlock,那么 ui的类名为:Ui_ColorfulBlock)
B/ ui_colorfulblock.py – 从ui文件导出的界面py代码。
C/ ctrl_colorfulblock.py – 备用。 这个是类似于控制器的角色,用于手动修改更新组件状态以及数据绑定,更新或者删除数据等等。将它提取出来做控制器是因为,ui会经常变动的。每次都要自动生成以及覆盖。

创建组件:

打开 qt designer,选择好创建的组件:
在这里插入图片描述

然后看到:
在这里插入图片描述
好了,先保存一下,保存到项目的ui目录下:
在这里插入图片描述

然后,先关闭了qt designer先,因为接下来是要直接从home.ui复制了total targets那一部分ui代码到ui_colorfulblock.ui中(全手工操作)。

打开home.ui找到 total targets部分xml代码:
小提示:先找到 Target_QF 所在的widget标签,再整个标签都复制了:
代码应该如下:

       <widget class="QFrame" name="Target_QF">
                    <property name="minimumSize">
                     <size>
                      <width>170</width>
                      <height>80</height>
                     </size>
                    </property>
                    <property name="maximumSize">
                     <size>
                      <width>170</width>
                      <height>80</height>
                     </size>
                    </property>
                    <property name="toolTipDuration">
                     <number>0</number>
                    </property>
                    <property name="styleSheet">
                     <string notr="true">QFrame#Target_QF{
color: rgb(255, 255, 255);
border-radius: 15px;
background-color: qradialgradient(cx:0, cy:0, radius:1, fx:0.1, fy:0.1, stop:0 rgb(253, 139, 133),  stop:1 rgb(248, 194, 152));
border: 1px outset rgb(252, 194, 149)
}
</string>
                    </property>
                    <property name="frameShape">
                     <enum>QFrame::Shape::StyledPanel</enum>
                    </property>
                    <property name="frameShadow">
                     <enum>QFrame::Shadow::Raised</enum>
                    </property>
                    <layout class="QVBoxLayout" name="verticalLayout_9" stretch="0,2,1">
                     <property name="spacing">
                      <number>0</number>
                     </property>
                     <property name="leftMargin">
                      <number>0</number>
                     </property>
                     <property name="topMargin">
                      <number>0</number>
                     </property>
                     <property name="rightMargin">
                      <number>0</number>
                     </property>
                     <property name="bottomMargin">
                      <number>0</number>
                     </property>
                     <item>
                      <widget class="QFrame" name="Target_top">
                       <property name="styleSheet">
                        <string notr="true">border:none</string>
                       </property>
                       <property name="frameShape">
                        <enum>QFrame::Shape::StyledPanel</enum>
                       </property>
                       <property name="frameShadow">
                        <enum>QFrame::Shadow::Raised</enum>
                       </property>
                       <layout class="QHBoxLayout" name="horizontalLayout_7">
                        <property name="spacing">
                         <number>0</number>
                        </property>
                        <property name="leftMargin">
                         <number>0</number>
                        </property>
                        <property name="topMargin">
                         <number>3</number>
                        </property>
                        <property name="rightMargin">
                         <number>0</number>
                        </property>
                        <property name="bottomMargin">
                         <number>3</number>
                        </property>
                        <item>
                         <widget class="QLabel" name="label_6">
                          <property name="maximumSize">
                           <size>
                            <width>16777215</width>
                            <height>30</height>
                           </size>
                          </property>
                          <property name="font">
                           <font>
                            <family>Segoe UI</family>
                            <pointsize>16</pointsize>
                            <italic>true</italic>
                            <bold>true</bold>
                           </font>
                          </property>
                          <property name="styleSheet">
                           <string notr="true">color: rgba(255, 255, 255,210);
padding-left:12px;
font: 700 italic 16pt &quot;Segoe UI&quot;;</string>
                          </property>
                          <property name="text">
                           <string>Total Targets</string>
                          </property>
                          <property name="alignment">
                           <set>Qt::AlignmentFlag::AlignCenter</set>
                          </property>
                          <property name="indent">
                           <number>0</number>
                          </property>
                         </widget>
                        </item>
                       </layout>
                      </widget>
                     </item>
                     <item>
                      <widget class="Line" name="line_3">
                       <property name="maximumSize">
                        <size>
                         <width>16777215</width>
                         <height>1</height>
                        </size>
                       </property>
                       <property name="styleSheet">
                        <string notr="true">background-color: rgba(255, 255, 255, 89);</string>
                       </property>
                       <property name="orientation">
                        <enum>Qt::Orientation::Horizontal</enum>
                       </property>
                      </widget>
                     </item>
                     <item>
                      <widget class="QFrame" name="Target_bottom">
                       <property name="styleSheet">
                        <string notr="true">border:none</string>
                       </property>
                       <property name="frameShape">
                        <enum>QFrame::Shape::StyledPanel</enum>
                       </property>
                       <property name="frameShadow">
                        <enum>QFrame::Shadow::Raised</enum>
                       </property>
                       <layout class="QVBoxLayout" name="verticalLayout_10">
                        <property name="spacing">
                         <number>0</number>
                        </property>
                        <property name="leftMargin">
                         <number>0</number>
                        </property>
                        <property name="topMargin">
                         <number>6</number>
                        </property>
                        <property name="rightMargin">
                         <number>0</number>
                        </property>
                        <property name="bottomMargin">
                         <number>6</number>
                        </property>
                        <item alignment="Qt::AlignmentFlag::AlignTop">
                         <widget class="QLabel" name="Target_num">
                          <property name="minimumSize">
                           <size>
                            <width>0</width>
                            <height>30</height>
                           </size>
                          </property>
                          <property name="maximumSize">
                           <size>
                            <width>16777215</width>
                            <height>30</height>
                           </size>
                          </property>
                          <property name="font">
                           <font>
                            <family>Microsoft YaHei UI</family>
                            <pointsize>17</pointsize>
                            <italic>false</italic>
                            <bold>false</bold>
                            <underline>false</underline>
                           </font>
                          </property>
                          <property name="styleSheet">
                           <string notr="true">color: rgb(255, 255, 255);
font: 17pt &quot;Microsoft YaHei UI&quot;;</string>
                          </property>
                          <property name="text">
                           <string/>
                          </property>
                          <property name="alignment">
                           <set>Qt::AlignmentFlag::AlignCenter</set>
                          </property>
                         </widget>
                        </item>
                       </layout>
                      </widget>
                     </item>
                    </layout>
                   </widget>
             

将这部分复制到新建的ui_colorfulblock.ui中:
例如:
在这里插入图片描述
把第一个widget给替换掉,结果如下:
在这里插入图片描述
补充一点:
class里面的是类名,你需要替换为自己的组件名称:

<class>ColorfulBlock</class>

保存下,然后使用qt designer打开,如下:
在这里插入图片描述
看到效果了,最初一步已经成功了。
下面要修改objectName:
在这里插入图片描述
修改为我们的组件名称:
在这里插入图片描述
针对于这个组件还有一个坑,就是它使用了样式,且样式里面指定了 Target_QF,但是我们的组件的objectName都改了,当然也要修改样式了:
在这里插入图片描述
修改为:
在这里插入图片描述
基本可用了,下面就导出一下py代码:

pyside6-uic ui_colorfulblock.ui -o ui_colorfulblock.py

然后看到:
在这里插入图片描述

下面就是一个关键点了。
第一,我们的组件是继承了QFrame制作的,但是这里使用的是object,所以这里要改为父类为QFrame。
第二,因为qt designer 使用自定义控件是使用 promote (提升)方式的,生成的代码会是:

## 伪代码
self.ColorfulBlock = Ui_ColorfulBlock(self.QF_Group)
self.ColorfulBlock.setObjectName(u"ColorfulBlock")

这种形式,就是说,构造器至少有一个参数,接收了被提升的qframe对象的,而组件自动生成的代码是不会有构造器,而且 setupUi也不会自动运行,就是说,我们要添加一个构造器且在构造器里面运行setupUi,下面基本是每一个生成的ui都需要用到的(当然有另一种方式是不需要的,详情请看项目的main.py是怎么做的):

下面做出如下修改:
在这里插入图片描述

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setupUi(self)

好了,下面来处理home.ui,导入我们抽取出去的组件。

在这里插入图片描述

首先需要将 Target_QF下面的所有子元素都删除掉,styleSheet也清空一下,且objectName修改为ColorfulBlock,然后,选择ColorfulBlock进行提升(promote):

1/
在这里插入图片描述
注意,清空属性不是删除字符串-那是变成空字符串而已,要点击后面的那个 删除按钮才行的。
在这里插入图片描述

下面进行提升
2、
在这里插入图片描述

下面说明一下,
header file 其实是 需要调用这个组件class时候的 路径,这里在ui文件夹下面的ui_colorfulblock.py所以路径是:
ui.ui_colorfulblock
class name就是类名了。
在这里插入图片描述

在这里插入图片描述
好了,可以尝试将home.ui导出一下py:

## ps:我的项目源码是改过的,请自行按照自己的源码进行修改。
pyside6-uic page_home.ui -o page_home.py

得到了:
在这里插入图片描述

然后得到了这部分代码。
好了,尝试运行一下:
在这里插入图片描述
resource_rc文件是在ui目录下面的,应该改为:

import ui.resources_rc

再尝试:
在这里插入图片描述
在main文件下面还有对Target_QF的调用,明显是不行的,都注释掉,还有部分代码–明显引用了组件里面的元素,也要替换掉,例如:
在这里插入图片描述

再尝试:
在这里插入图片描述

替换组件成功。

  • 19
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,我可以为您提供一些关于使用 PySide2 和 Qt Designer 设计 Python 用户登录界面的指导。 首先,您需要安装 PySide2 库和 Qt Designer 工具。可以通过 pip 安装 PySide2,命令如下: ``` pip install PySide2 ``` Qt DesignerQt 开发工具包中的一个可视化界面设计工具,您可以从 Qt 官网下载并安装。 在 Qt Designer设计登录界面后,您需要将 .ui 文件转换为 .py 文件PySide2 提供了一个名为 pyside2-uic 的工具来完成这个转换过程。您可以在终端中使用以下命令将 .ui 文件转换为 .py 文件: ``` pyside2-uic input.ui -o output.py ``` 在 Python 代码中,您需要导入 PySide2 库和转换后的 .py 文件,然后创建登录界面并显示它。以下是一个简单的示例代码: ```python import sys from PySide2.QtWidgets import QApplication, QDialog from output import Ui_LoginDialog class LoginDialog(QDialog, Ui_LoginDialog): def __init__(self): super().__init__() self.setupUi(self) if __name__ == '__main__': app = QApplication(sys.argv) login_dialog = LoginDialog() login_dialog.show() sys.exit(app.exec_()) ``` 在这个示例中,我们导入PySide2 库和转换后的 .py 文件,并创建了一个名为 LoginDialog 的 QDialog 子类。我们还在 LoginDialog 类的构造函数中调用了 setupUi() 方法,该方法由 pyside2-uic 工具生成,用于将 .ui 文件中的部件添加到 QDialog 中。 最后,我们创建了一个 QApplication 实例、一个 LoginDialog 实例,并显示了登录界面。最后,我们调用 app.exec_() 方法进入 Qt 事件循环,等待用户与登录界面交互。 希望这些信息可以帮助您开始设计 Python 用户登录界面

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值