python的Qt框架PySide6(3)Qt Widgets Designer界面设计器和界面应用

勇哥注:

Qt Widgets Designer是类似C#编辑form窗体的编辑器,可以拖放控件的方式编辑界面。

然后就是python端怎么使用这个界面了。



(一)查找Qt Widgets Designer的安装位置

使用下面脚本:

import os
import sys

def find_pyside6_installation():
    """
    查找PySide6的安装位置
    """
    try:
        # 尝试导入PySide6
        import PySide6
       
        # 获取PySide6模块的文件路径
        pyside6_path = os.path.dirname(PySide6.__file__)
       
        # 获取PySide6版本
        pyside6_version = PySide6.__version__
       
        # 打印详细信息
        print("✅ PySide6安装信息:")
        print(f"  版本: {pyside6_version}")
        print(f"  安装路径: {pyside6_path}")
       
        # 检查Qt Designer是否存在
        designer_path = os.path.join(pyside6_path, 'designer.exe')
        if os.path.exists(designer_path):
            print(f"\n✅ Qt Designer已找到:")
            print(f"  位置: {designer_path}")
        else:
            print("\n❌ Qt Designer未找到,可能在其他位置或未包含在当前版本中")
       
        # 检查其他重要组件
        print("\n? 检查重要组件:")
       
        # 检查Qt目录
        qt_dir = os.path.join(pyside6_path, 'Qt')
        if os.path.exists(qt_dir):
            print(f"  ✅ Qt目录: {qt_dir}")
       
        # 检查常用模块
        common_modules = ['QtCore', 'QtGui', 'QtWidgets', 'QtNetwork']
        for module_name in common_modules:
            module_path = os.path.join(pyside6_path, f'{module_name}.pyd')
            if os.path.exists(module_path):
                print(f"  ✅ {module_name} 模块已找到")
       
        return True
       
    except ImportError:
        print("❌ 错误: PySide6未安装!")
        print("\n? 安装建议:")
        print("  1. 使用pip安装: pip install PySide6")
        print("  2. 使用清华源安装: pip install PySide6 -i https://pypi.tuna.tsinghua.edu.cn/simple")
       
        # 检查是否有pip
        try:
            import pip
            print(f"  当前Python解释器: {sys.executable}")
        except ImportError:
            print("  无法检测pip,请确保Python环境正确配置")
           
        return False
    except Exception as e:
        print(f"❌ 发生未知错误: {str(e)}")
        return False

if __name__ == "__main__":
    print("? 正在查找PySide6安装位置...\n")
    success = find_pyside6_installation()
   
    print("\n? 总结:")
    if success:
        print("  PySide6已成功安装并找到位置")
    else:
        print("  请安装PySide6后再次运行此脚本")
       
    # 在Windows上按任意键继续
    if sys.platform == 'win32':
        print("\n按任意键关闭窗口...")
        import msvcrt
        msvcrt.getch()

返回结果:

? 正在查找PySide6安装位置...


✅ PySide6安装信息:

  版本: 6.10.0

  安装路径: C:\Python313\Lib\site-packages\PySide6


✅ Qt Designer已找到:

  位置: C:\Python313\Lib\site-packages\PySide6\designer.exe


? 检查重要组件:

  ✅ QtCore 模块已找到

  ✅ QtGui 模块已找到

  ✅ QtWidgets 模块已找到

  ✅ QtNetwork 模块已找到


? 总结:

  PySide6已成功安装并找到位置


根据结果,创建桌面快捷方式,方便以后使用。


(二)创建向导

image.png

这里说下向导中几种窗口类型:

(1)Dialog xxxx

(2)Main Window

(3)Widget

其中,Main Window是带有状态条、菜单栏、工具条的标准windows窗口。

Widget是基础窗口,但是它与Dialog还是有区别,如下:


主要区别

1. 1.    用途和交互模式

   - Dialog (对话框) : 主要用于短期任务和与用户的简短交互,通常作为模态窗口(会阻塞父窗口操作),适合需要用户输入或确认的场景

   - Widget (窗口部件) : 是基础UI元素,更通用,可以作为独立窗口或嵌入到其他窗口中,适合构建主要界面或可复用组件

2. 2.    生命周期管理

   - Dialog : 通常使用 exec() 方法运行自己的事件循环,不会出现"一闪而过"的问题

   - Widget : 如果作为局部变量且只用 show() 方法,函数执行完毕后会被销毁,导致窗口消失

3. 3.   功能特性

   - Dialog : 支持返回值、默认按钮配置和右下角大小调整手柄

   - Widget : 更基础,没有这些特定于对话框的功能

4. 4.   窗口层次结构

   - Dialog : 即使设置了父窗口,也始终作为顶级窗口,但默认位置会显示在父窗口中央

   - Widget : 根据创建方式可以是顶级窗口或子窗口部件

实际使用建议

- 需要用户输入信息、确认操作时,使用 Dialog

- 构建应用程序主界面或复杂组件时,使用 Widget

- 对于Widget窗口,如果希望它稳定显示,需要正确管理其生命周期(如创建为成员变量或使用 setAttribute(Qt::WA_DeleteOnClose) )


(三)由界面文件生成py文件


image.png

敲入指令生成py文件:

pyside6-uic input_file.ui -o output_file.py

image.png


(四)应用界面文件

应用生成的output_file.py界面文件。


(4.1)方式一:把demo1.py这个界面放到QMainWindow的central widge里面去。

具体实现方式是:

1.   首先创建了一个QWidget作为QMainWindow的中心部件:

      self.central_widget = QWidget() 和 self.setCentralWidget(self.central_widget)

2.   然后实例化了demo1.py中的Ui_Form类: self.ui = Ui_Form()

3.   最后将UI设置到中心部件上: self.ui.setupUi(self.central_widget)

这种方式是PySide6/PyQt中常用的UI集成模式,它结合了Qt Designer设计的界面(通过uic工具转换为Python代码)

和自定义的QMainWindow类,既保留了Qt Designer可视化设计的便利性,

又能在Python代码中添加自定义的逻辑和功能。

import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QMessageBox
from demo1 import Ui_Form

class SimpleWindow(QMainWindow):
    def __init__(self):
        super().__init__()
       
        # 创建一个QWidget作为中心部件
        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)
       
        # 创建UI对象并设置到中心部件
        self.ui = Ui_Form()
        self.ui.setupUi(self.central_widget)
       
        # 设置窗口标题
        self.setWindowTitle("PySide6测试窗口 - 使用demo1界面")
       
        # 绑定btnOK按钮的点击事件
        self.ui.btnOK.clicked.connect(self.show_message)
       
        # 设置窗口大小为demo1.ui中设计的尺寸
        self.resize(346, 202)
   
    def show_message(self):
        """显示一个弹窗信息"""
        QMessageBox.information(self, "提示", "按钮被点击了!这是一个测试弹窗信息。")

if __name__ == "__main__":
    # 创建应用程序实例
    app = QApplication(sys.argv)
   
    # 创建窗口实例
    window = SimpleWindow()
    window.show()
   
    # 运行应用程序的主循环
    sys.exit(app.exec())


(4.2)方式二:直接继承UI类

这种实现方式也是PyQt/PySide中常用的UI集成模式,它结合了Qt Designer生成的UI和自定义的窗口类,

使代码更加简洁直观,避免了额外的UI对象层次。

import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QMessageBox
from demo1 import Ui_Form

class SimpleWindow(QMainWindow, Ui_Form):
    def __init__(self):
        super().__init__()
       
        # 直接调用setupUi方法设置UI
        self.setupUi(self)
       
        # 设置窗口标题
        self.setWindowTitle("PySide6测试窗口 - 直接继承UI类")
       
        # 绑定btnOK按钮的点击事件
        self.btnOK.clicked.connect(self.show_message)
       
        # 设置窗口大小为demo1.ui中设计的尺寸
        self.resize(346, 202)
   
    def show_message(self):
        """显示一个弹窗信息"""
        QMessageBox.information(self, "提示", "按钮被点击了!这是一个测试弹窗信息。")

if __name__ == "__main__":
    # 创建应用程序实例
    app = QApplication(sys.argv)
   
    # 创建窗口实例
    window = SimpleWindow()
    window.show()
   
    # 运行应用程序的主循环
    sys.exit(app.exec())


(4.3)方式三:使用QWidget作为主窗口

使用QWidget作为主窗口是一种更轻量级的实现方式,适合不需要菜单栏、

工具栏和状态栏等QMainWindow特有功能的简单应用程序。

这种方式更符合demo1.ui的原始设计意图,因为从demo1.py可以看出,Ui_Form是为QWidget设计的。


import sys
from PySide6.QtWidgets import QApplication, QWidget, QMessageBox
from demo1 import Ui_Form

class SimpleWindow(QWidget, Ui_Form):
    def __init__(self):
        super().__init__()
       
        # 直接调用setupUi方法设置UI
        self.setupUi(self)
       
        # 设置窗口标题
        self.setWindowTitle("PySide6测试窗口 - 使用QWidget作为主窗口")
       
        # 绑定btnOK按钮的点击事件
        self.btnOK.clicked.connect(self.show_message)
       
        # 设置窗口大小为demo1.ui中设计的尺寸
        #self.resize(346, 202)
   
    def show_message(self):
        """显示一个弹窗信息"""
        QMessageBox.information(self, "提示", "按钮被点击了!这是一个测试弹窗信息。")

if __name__ == "__main__":
    # 创建应用程序实例
    app = QApplication(sys.argv)
   
    # 创建窗口实例
    window = SimpleWindow()
    window.show()
   
    # 运行应用程序的主循环
    sys.exit(app.exec())


(4.4)方式四:动态加载UI文件

动态加载带来了无需重新生成Python代码的便利性,特别适合UI频繁变动的开发阶段。

import sys
from PySide6.QtWidgets import QApplication, QWidget, QMessageBox
from PySide6.QtUiTools import QUiLoader
from PySide6.QtCore import QFile

class SimpleWindow(QWidget):
    def __init__(self):
        super().__init__()
       
        # 使用QUiLoader动态加载UI文件
        loader = QUiLoader()
        ui_file = QFile("demo1.ui")
        ui_file.open(QFile.ReadOnly)
        self.ui = loader.load(ui_file, self)
        ui_file.close()
       
        # 设置窗口标题
        self.setWindowTitle("PySide6测试窗口 - 动态加载UI文件")
       
        # 绑定btnOK按钮的点击事件
        self.ui.btnOK.clicked.connect(self.show_message)

       
        # 调整窗口大小以适应UI内容
        self.resize(self.ui.size())
   
    def show_message(self):
        """显示一个弹窗信息"""
        QMessageBox.information(self, "提示", "按钮被点击了!这是一个测试弹窗信息。")

if __name__ == "__main__":
    # 创建应用程序实例
    app = QApplication(sys.argv)
   
    # 创建窗口实例
    window = SimpleWindow()
    window.show()
   
    # 运行应用程序的主循环
    sys.exit(app.exec())

这种方式也有其问题,如下:

在使用QUiLoader动态加载UI文件的方式下,IDE无法为 self.ui.btnOK 中的 btnOK 提供语法补全功能。

这是因为:

1. 1.   类型信息缺失 :当使用动态加载时, self.ui 的类型在编译时(或IDE分析时)是未知的,

IDE无法确定它包含哪些属性和方法。

2. 2.   动态特性限制 :Python是动态类型语言,而UI元素是在运行时通过 loader.load() 方法动态创建的,

IDE无法在静态分析阶段知道这些元素的存在。

3. 3.   对比静态加载方式 :当使用 from demo1 import Ui_Form 并继承该类时,

IDE可以通过分析生成的Python代码,知道 btnOK 等UI元素的存在,从而提供语法补全。

4. 4.   优缺点权衡 :动态加载虽然牺牲了IDE的自动补全支持,但带来了无需重新生成Python代码的便利性,

特别适合UI频繁变动的开发阶段。

5. 5.  可能的解决方案 :一些高级IDE或插件可能提供有限的支持,但通常需要额外配置或使用类型提示(type hints)

来帮助IDE理解动态创建的对象结构。


image.png


(4.5)方式五:

多重继承与委托模式结合 复杂应用中可能结合多种模式,例如使用一个单独的控制器类来处理业务逻辑,而UI类只负责界面展示。



每种方式都有其适用场景,可以根据项目需求、团队习惯和代码维护性等因素选择合适的集成方式



本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:
本帖最后由 勇哥,很想停止 于 2025-10-10 09:37:28 编辑

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2025年10月    »
12345
6789101112
13141516171819
20212223242526
2728293031
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864