• PySide6之初级使用


    • 背景介绍
      pyside6提供了Qt6的Python侧API. 在GUI程序撰写方面, 笔者不太喜欢频繁的编译过程, 倾向于随时更改代码即时查看效果. 因此, 推荐在简单应用的情况下使用pyside6, 而非直接的Qt6. 本文以一个简单的计算器实现作为案例展示笔者pyside6使用流程.
    • 使用pyside6-designer绘制并生成ui文件
      ①. 安装pyside6
           终端运行: pip install pyside6 
      ②. 打开pyside6-designer
           终端运行: pyside6-designer 
      ③. 于pyside6-designer中利用左侧控件栏绘制出如下界面

      注意, 可以在右侧对象栏中改变相应控件对象的名称.
      ④. 保存该界面为ui文件, 并命名为calculator.ui. calculator.ui文件内容如下,
        1 <?xml version="1.0" encoding="UTF-8"?>
        2 <ui version="4.0">
        3  <class>Form</class>
        4  <widget class="QWidget" name="Form">
        5   <property name="geometry">
        6    <rect>
        7     <x>0</x>
        8     <y>0</y>
        9     <width>440</width>
       10     <height>288</height>
       11    </rect>
       12   </property>
       13   <property name="windowTitle">
       14    <string>Form</string>
       15   </property>
       16   <layout class="QVBoxLayout" name="verticalLayout">
       17    <item>
       18     <widget class="QTextBrowser" name="txtb_show"/>
       19    </item>
       20    <item>
       21     <layout class="QGridLayout" name="gridLayout">
       22      <item row="0" column="0">
       23       <widget class="QPushButton" name="btn_ac">
       24        <property name="text">
       25         <string>AC</string>
       26        </property>
       27       </widget>
       28      </item>
       29      <item row="0" column="3">
       30       <widget class="QPushButton" name="btn_divide">
       31        <property name="text">
       32         <string>÷</string>
       33        </property>
       34       </widget>
       35      </item>
       36      <item row="1" column="0">
       37       <widget class="QPushButton" name="btn_7">
       38        <property name="text">
       39         <string>7</string>
       40        </property>
       41       </widget>
       42      </item>
       43      <item row="1" column="1">
       44       <widget class="QPushButton" name="btn_8">
       45        <property name="text">
       46         <string>8</string>
       47        </property>
       48       </widget>
       49      </item>
       50      <item row="1" column="2">
       51       <widget class="QPushButton" name="btn_9">
       52        <property name="text">
       53         <string>9</string>
       54        </property>
       55       </widget>
       56      </item>
       57      <item row="1" column="3">
       58       <widget class="QPushButton" name="btn_multiply">
       59        <property name="text">
       60         <string>×</string>
       61        </property>
       62       </widget>
       63      </item>
       64      <item row="2" column="0">
       65       <widget class="QPushButton" name="btn_4">
       66        <property name="text">
       67         <string>4</string>
       68        </property>
       69       </widget>
       70      </item>
       71      <item row="2" column="1">
       72       <widget class="QPushButton" name="btn_5">
       73        <property name="text">
       74         <string>5</string>
       75        </property>
       76       </widget>
       77      </item>
       78      <item row="2" column="2">
       79       <widget class="QPushButton" name="btn_6">
       80        <property name="text">
       81         <string>6</string>
       82        </property>
       83       </widget>
       84      </item>
       85      <item row="2" column="3">
       86       <widget class="QPushButton" name="btn_subtract">
       87        <property name="text">
       88         <string></string>
       89        </property>
       90       </widget>
       91      </item>
       92      <item row="3" column="0">
       93       <widget class="QPushButton" name="btn_1">
       94        <property name="text">
       95         <string>1</string>
       96        </property>
       97       </widget>
       98      </item>
       99      <item row="3" column="1">
      100       <widget class="QPushButton" name="btn_2">
      101        <property name="text">
      102         <string>2</string>
      103        </property>
      104       </widget>
      105      </item>
      106      <item row="3" column="2">
      107       <widget class="QPushButton" name="btn_3">
      108        <property name="text">
      109         <string>3</string>
      110        </property>
      111       </widget>
      112      </item>
      113      <item row="3" column="3">
      114       <widget class="QPushButton" name="btn_add">
      115        <property name="text">
      116         <string>+</string>
      117        </property>
      118       </widget>
      119      </item>
      120      <item row="4" column="3">
      121       <widget class="QPushButton" name="btn_equal">
      122        <property name="text">
      123         <string>=</string>
      124        </property>
      125       </widget>
      126      </item>
      127      <item row="4" column="0">
      128       <widget class="QPushButton" name="btn_0">
      129        <property name="text">
      130         <string>0</string>
      131        </property>
      132       </widget>
      133      </item>
      134      <item row="4" column="1">
      135       <widget class="QPushButton" name="btn_lbracket">
      136        <property name="text">
      137         <string>(</string>
      138        </property>
      139       </widget>
      140      </item>
      141      <item row="4" column="2">
      142       <widget class="QPushButton" name="btn_rbracket">
      143        <property name="text">
      144         <string>)</string>
      145        </property>
      146       </widget>
      147      </item>
      148      <item row="0" column="2">
      149       <widget class="QPushButton" name="btn_dot">
      150        <property name="text">
      151         <string>.</string>
      152        </property>
      153       </widget>
      154      </item>
      155      <item row="0" column="1">
      156       <widget class="QPushButton" name="btn_ce">
      157        <property name="text">
      158         <string>CE</string>
      159        </property>
      160       </widget>
      161      </item>
      162     </layout>
      163    </item>
      164   </layout>
      165  </widget>
      166  <resources/>
      167  <connections/>
      168 </ui>
      View Code
    • 使用pyside6演示ui文件
      本文以一个main.py文件为例, 采用如下方式演示ui文件, 并补充其中操作逻辑. main.py文件内容如下,
       1 # 计算器实现案例
       2 
       3 from PySide6 import QtCore
       4 from PySide6 import QtWidgets
       5 from PySide6 import QtUiTools
       6 
       7 
       8 class Calculator(QtWidgets.QWidget):     # 此处继承的类型需与designer中选择的类型保持一致
       9 
      10     def __init__(self, parent=None):
      11         super(Calculator, self).__init__(parent)
      12 
      13         uiname = "/Users/xxhbdk/Desktop/projects_blog/pyside6/calculator.ui"  # 1. 设置ui文件路径
      14         self.ui = QtUiTools.QUiLoader().load(uiname)  # 2. 实例化
      15         self.ui.setParent(self)                       # 3. 设置父控件
      16         self.__equal_tab = False
      17 
      18         self.__create_connections()
      19 
      20 
      21     def __create_connections(self):
      22         self.ui.btn_ac.clicked.connect(self.__print_clr_all)
      23         self.ui.btn_ce.clicked.connect(self.__print_clr_end)
      24         self.ui.btn_lbracket.clicked.connect(lambda : self.__print_line_end("("))
      25         self.ui.btn_rbracket.clicked.connect(lambda : self.__print_line_end(")"))
      26         self.ui.btn_divide.clicked.connect(lambda : self.__print_line_end("÷"))
      27         self.ui.btn_7.clicked.connect(lambda : self.__print_line_end("7"))
      28         self.ui.btn_8.clicked.connect(lambda : self.__print_line_end("8"))
      29         self.ui.btn_9.clicked.connect(lambda : self.__print_line_end("9"))
      30         self.ui.btn_multiply.clicked.connect(lambda : self.__print_line_end("×"))
      31         self.ui.btn_4.clicked.connect(lambda : self.__print_line_end("4"))
      32         self.ui.btn_5.clicked.connect(lambda : self.__print_line_end("5"))
      33         self.ui.btn_6.clicked.connect(lambda : self.__print_line_end("6"))
      34         self.ui.btn_subtract.clicked.connect(lambda : self.__print_line_end("-"))
      35         self.ui.btn_1.clicked.connect(lambda : self.__print_line_end("1"))
      36         self.ui.btn_2.clicked.connect(lambda : self.__print_line_end("2"))
      37         self.ui.btn_3.clicked.connect(lambda : self.__print_line_end("3"))
      38         self.ui.btn_add.clicked.connect(lambda : self.__print_line_end("+"))
      39         self.ui.btn_0.clicked.connect(lambda : self.__print_line_end("0"))
      40         self.ui.btn_dot.clicked.connect(lambda : self.__print_line_end("."))
      41         self.ui.btn_equal.clicked.connect(self.__equal)
      42 
      43 
      44     def __equal(self):
      45         txt =  self.ui.txtb_show.toPlainText()
      46         txt = txt.replace("×", "*")
      47         txt = txt.replace("÷", "/")
      48         try:
      49             ret = str(round(eval(txt), 9))
      50         except Exception as e:
      51             ret = str(e)
      52 
      53         self.__print_line_new(ret)
      54         self.__equal_tab = True
      55 
      56 
      57     def __print_line_end(self, msg):
      58         if self.__equal_tab:
      59             self.__print_clr_all()
      60             self.__equal_tab = False
      61         self.ui.txtb_show.insertPlainText(msg)
      62 
      63 
      64     def __print_clr_all(self):
      65         self.ui.txtb_show.clear()
      66 
      67 
      68     def __print_clr_end(self):
      69         self.ui.txtb_show.textCursor().deletePreviousChar()
      70 
      71 
      72     def __print_line_new(self, msg):
      73         self.ui.txtb_show.append(msg)
      74         
      75         
      76 
      77 if __name__ == "__main__":
      78     app = QtWidgets.QApplication([])
      79 
      80     obj = Calculator()
      81     obj.show()
      82 
      83     app.exec()
      View Code
      可见, ui文件的引入步骤如下,
      ①. 设置ui文件路径
      ②. 实例化
      ③. 设置父控件
      执行上述main.py, 演示界面如下,
    • 使用pyside6-uic翻译ui文件为py文件
      于终端运行如下命令翻译ui文件, 并生成同名py文件,
      pyside6-uic ./calculator.ui -o ./calculator.py 
      其中, calculator.ui需要提供正确的路径, calculator.py为翻译后的py文件. calculator.py文件内容如下,
        1 # -*- coding: utf-8 -*-
        2 
        3 ################################################################################
        4 ## Form generated from reading UI file 'calculator.ui'
        5 ##
        6 ## Created by: Qt User Interface Compiler version 6.2.2
        7 ##
        8 ## WARNING! All changes made in this file will be lost when recompiling UI file!
        9 ################################################################################
       10 
       11 from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
       12     QMetaObject, QObject, QPoint, QRect,
       13     QSize, QTime, QUrl, Qt)
       14 from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
       15     QFont, QFontDatabase, QGradient, QIcon,
       16     QImage, QKeySequence, QLinearGradient, QPainter,
       17     QPalette, QPixmap, QRadialGradient, QTransform)
       18 from PySide6.QtWidgets import (QApplication, QGridLayout, QPushButton, QSizePolicy,
       19     QTextBrowser, QVBoxLayout, QWidget)
       20 
       21 class Ui_Form(object):
       22     def setupUi(self, Form):
       23         if not Form.objectName():
       24             Form.setObjectName(u"Form")
       25         Form.resize(440, 288)
       26         self.verticalLayout = QVBoxLayout(Form)
       27         self.verticalLayout.setObjectName(u"verticalLayout")
       28         self.txtb_show = QTextBrowser(Form)
       29         self.txtb_show.setObjectName(u"txtb_show")
       30 
       31         self.verticalLayout.addWidget(self.txtb_show)
       32 
       33         self.gridLayout = QGridLayout()
       34         self.gridLayout.setObjectName(u"gridLayout")
       35         self.btn_ac = QPushButton(Form)
       36         self.btn_ac.setObjectName(u"btn_ac")
       37 
       38         self.gridLayout.addWidget(self.btn_ac, 0, 0, 1, 1)
       39 
       40         self.btn_divide = QPushButton(Form)
       41         self.btn_divide.setObjectName(u"btn_divide")
       42 
       43         self.gridLayout.addWidget(self.btn_divide, 0, 3, 1, 1)
       44 
       45         self.btn_7 = QPushButton(Form)
       46         self.btn_7.setObjectName(u"btn_7")
       47 
       48         self.gridLayout.addWidget(self.btn_7, 1, 0, 1, 1)
       49 
       50         self.btn_8 = QPushButton(Form)
       51         self.btn_8.setObjectName(u"btn_8")
       52 
       53         self.gridLayout.addWidget(self.btn_8, 1, 1, 1, 1)
       54 
       55         self.btn_9 = QPushButton(Form)
       56         self.btn_9.setObjectName(u"btn_9")
       57 
       58         self.gridLayout.addWidget(self.btn_9, 1, 2, 1, 1)
       59 
       60         self.btn_multiply = QPushButton(Form)
       61         self.btn_multiply.setObjectName(u"btn_multiply")
       62 
       63         self.gridLayout.addWidget(self.btn_multiply, 1, 3, 1, 1)
       64 
       65         self.btn_4 = QPushButton(Form)
       66         self.btn_4.setObjectName(u"btn_4")
       67 
       68         self.gridLayout.addWidget(self.btn_4, 2, 0, 1, 1)
       69 
       70         self.btn_5 = QPushButton(Form)
       71         self.btn_5.setObjectName(u"btn_5")
       72 
       73         self.gridLayout.addWidget(self.btn_5, 2, 1, 1, 1)
       74 
       75         self.btn_6 = QPushButton(Form)
       76         self.btn_6.setObjectName(u"btn_6")
       77 
       78         self.gridLayout.addWidget(self.btn_6, 2, 2, 1, 1)
       79 
       80         self.btn_subtract = QPushButton(Form)
       81         self.btn_subtract.setObjectName(u"btn_subtract")
       82 
       83         self.gridLayout.addWidget(self.btn_subtract, 2, 3, 1, 1)
       84 
       85         self.btn_1 = QPushButton(Form)
       86         self.btn_1.setObjectName(u"btn_1")
       87 
       88         self.gridLayout.addWidget(self.btn_1, 3, 0, 1, 1)
       89 
       90         self.btn_2 = QPushButton(Form)
       91         self.btn_2.setObjectName(u"btn_2")
       92 
       93         self.gridLayout.addWidget(self.btn_2, 3, 1, 1, 1)
       94 
       95         self.btn_3 = QPushButton(Form)
       96         self.btn_3.setObjectName(u"btn_3")
       97 
       98         self.gridLayout.addWidget(self.btn_3, 3, 2, 1, 1)
       99 
      100         self.btn_add = QPushButton(Form)
      101         self.btn_add.setObjectName(u"btn_add")
      102 
      103         self.gridLayout.addWidget(self.btn_add, 3, 3, 1, 1)
      104 
      105         self.btn_equal = QPushButton(Form)
      106         self.btn_equal.setObjectName(u"btn_equal")
      107 
      108         self.gridLayout.addWidget(self.btn_equal, 4, 3, 1, 1)
      109 
      110         self.btn_0 = QPushButton(Form)
      111         self.btn_0.setObjectName(u"btn_0")
      112 
      113         self.gridLayout.addWidget(self.btn_0, 4, 0, 1, 1)
      114 
      115         self.btn_lbracket = QPushButton(Form)
      116         self.btn_lbracket.setObjectName(u"btn_lbracket")
      117 
      118         self.gridLayout.addWidget(self.btn_lbracket, 4, 1, 1, 1)
      119 
      120         self.btn_rbracket = QPushButton(Form)
      121         self.btn_rbracket.setObjectName(u"btn_rbracket")
      122 
      123         self.gridLayout.addWidget(self.btn_rbracket, 4, 2, 1, 1)
      124 
      125         self.btn_dot = QPushButton(Form)
      126         self.btn_dot.setObjectName(u"btn_dot")
      127 
      128         self.gridLayout.addWidget(self.btn_dot, 0, 2, 1, 1)
      129 
      130         self.btn_ce = QPushButton(Form)
      131         self.btn_ce.setObjectName(u"btn_ce")
      132 
      133         self.gridLayout.addWidget(self.btn_ce, 0, 1, 1, 1)
      134 
      135 
      136         self.verticalLayout.addLayout(self.gridLayout)
      137 
      138 
      139         self.retranslateUi(Form)
      140 
      141         QMetaObject.connectSlotsByName(Form)
      142     # setupUi
      143 
      144     def retranslateUi(self, Form):
      145         Form.setWindowTitle(QCoreApplication.translate("Form", u"Form", None))
      146         self.btn_ac.setText(QCoreApplication.translate("Form", u"AC", None))
      147         self.btn_divide.setText(QCoreApplication.translate("Form", u"\u00f7", None))
      148         self.btn_7.setText(QCoreApplication.translate("Form", u"7", None))
      149         self.btn_8.setText(QCoreApplication.translate("Form", u"8", None))
      150         self.btn_9.setText(QCoreApplication.translate("Form", u"9", None))
      151         self.btn_multiply.setText(QCoreApplication.translate("Form", u"\u00d7", None))
      152         self.btn_4.setText(QCoreApplication.translate("Form", u"4", None))
      153         self.btn_5.setText(QCoreApplication.translate("Form", u"5", None))
      154         self.btn_6.setText(QCoreApplication.translate("Form", u"6", None))
      155         self.btn_subtract.setText(QCoreApplication.translate("Form", u"\u2212", None))
      156         self.btn_1.setText(QCoreApplication.translate("Form", u"1", None))
      157         self.btn_2.setText(QCoreApplication.translate("Form", u"2", None))
      158         self.btn_3.setText(QCoreApplication.translate("Form", u"3", None))
      159         self.btn_add.setText(QCoreApplication.translate("Form", u"+", None))
      160         self.btn_equal.setText(QCoreApplication.translate("Form", u"=", None))
      161         self.btn_0.setText(QCoreApplication.translate("Form", u"0", None))
      162         self.btn_lbracket.setText(QCoreApplication.translate("Form", u"(", None))
      163         self.btn_rbracket.setText(QCoreApplication.translate("Form", u")", None))
      164         self.btn_dot.setText(QCoreApplication.translate("Form", u".", None))
      165         self.btn_ce.setText(QCoreApplication.translate("Form", u"CE", None))
      166     # retranslateUi
      View Code
    • 使用pyside6演示py文件
      同样以一个main.py文件为例, 展示如何引入翻译后的calculator.py, 并演示之.
      当前工程结构如下,

      main.py文件内容如下,
       1 # 计算器实现案例
       2 
       3 from PySide6 import QtCore
       4 from PySide6 import QtWidgets
       5 from PySide6 import QtUiTools
       6 import argparse                  # 0. 额外导入, 暂时无需关注
       7 
       8 from calculator import Ui_Form   # 1. 引入calculator模块
       9 
      10 
      11 class Calculator(QtWidgets.QWidget):     # 此处继承的类型需与designer中选择的类型保持一致
      12 
      13     def __init__(self, parent=None):
      14         super(Calculator, self).__init__(parent)
      15 
      16         # uiname = "/Users/xxhbdk/Desktop/projects_blog/pyside6/calculator.ui"  # ui文件路径
      17         # self.ui = QtUiTools.QUiLoader().load(uiname)
      18         # self.ui.setParent(self)
      19         self.ui = Ui_Form()      # 2. 实例化
      20         self.ui.setupUi(self)    # 3. 设置父控件
      21         self.__equal_tab = False
      22 
      23         self.__create_connections()
      24 
      25 
      26     def __create_connections(self):
      27         self.ui.btn_ac.clicked.connect(self.__print_clr_all)
      28         self.ui.btn_ce.clicked.connect(self.__print_clr_end)
      29         self.ui.btn_lbracket.clicked.connect(lambda : self.__print_line_end("("))
      30         self.ui.btn_rbracket.clicked.connect(lambda : self.__print_line_end(")"))
      31         self.ui.btn_divide.clicked.connect(lambda : self.__print_line_end("÷"))
      32         self.ui.btn_7.clicked.connect(lambda : self.__print_line_end("7"))
      33         self.ui.btn_8.clicked.connect(lambda : self.__print_line_end("8"))
      34         self.ui.btn_9.clicked.connect(lambda : self.__print_line_end("9"))
      35         self.ui.btn_multiply.clicked.connect(lambda : self.__print_line_end("×"))
      36         self.ui.btn_4.clicked.connect(lambda : self.__print_line_end("4"))
      37         self.ui.btn_5.clicked.connect(lambda : self.__print_line_end("5"))
      38         self.ui.btn_6.clicked.connect(lambda : self.__print_line_end("6"))
      39         self.ui.btn_subtract.clicked.connect(lambda : self.__print_line_end("-"))
      40         self.ui.btn_1.clicked.connect(lambda : self.__print_line_end("1"))
      41         self.ui.btn_2.clicked.connect(lambda : self.__print_line_end("2"))
      42         self.ui.btn_3.clicked.connect(lambda : self.__print_line_end("3"))
      43         self.ui.btn_add.clicked.connect(lambda : self.__print_line_end("+"))
      44         self.ui.btn_0.clicked.connect(lambda : self.__print_line_end("0"))
      45         self.ui.btn_dot.clicked.connect(lambda : self.__print_line_end("."))
      46         self.ui.btn_equal.clicked.connect(self.__equal)
      47 
      48 
      49     def __equal(self):
      50         txt =  self.ui.txtb_show.toPlainText()
      51         txt = txt.replace("×", "*")
      52         txt = txt.replace("÷", "/")
      53         try:
      54             ret = str(round(eval(txt), 9))
      55         except Exception as e:
      56             ret = str(e)
      57 
      58         self.__print_line_new(ret)
      59         self.__equal_tab = True
      60 
      61 
      62     def __print_line_end(self, msg):
      63         if self.__equal_tab:
      64             self.__print_clr_all()
      65             self.__equal_tab = False
      66         self.ui.txtb_show.insertPlainText(msg)
      67 
      68 
      69     def __print_clr_all(self):
      70         self.ui.txtb_show.clear()
      71 
      72 
      73     def __print_clr_end(self):
      74         self.ui.txtb_show.textCursor().deletePreviousChar()
      75 
      76 
      77     def __print_line_new(self, msg):
      78         self.ui.txtb_show.append(msg)
      79         
      80         
      81 
      82 if __name__ == "__main__":
      83     app = QtWidgets.QApplication([])
      84 
      85     obj = Calculator()
      86     obj.show()
      87 
      88     app.exec()
      View Code
      可见, 主要是将ui文件的引入步骤替换如下:
      ①. 引入翻译后的py文件模块
      ②. 实例化
      ③. 设置父控件
      执行上述main.py, 演示界面如下,
    • 使用nuitka工具打包为独立app
      ①. 安装nuitka
           终端运行: pip3 install nuitka 
      ②. 将当前工程打包为独立app
           终端运行: nuitka3 --onefile --macos-disable-console --enable-plugin=pyside6 main.py -o calculator.app 
      打包完成后, 于当前目录下生成可执行文件"calculator.app". 双击该可执行文件, 运行效果如下,

      可以看到, 可执行文件运行符合预期.
    • 注意事项
      ①. macos下python部分模块导入可能存在问题, 终端运行app发现后, 可手动在py文件中额外导入, 如笔者手动额外导入的argparse模块;
      ②. macos下nuitka最终输出文件之后缀".app"需手动添加, 如不添加, 则运行带有终端;
      ③. 本文着重阐述pyside6配合nuitka之使用流程, 具体API使用细节, 请大家参考官方文档等资料.
    • 参考文档
      ①. https://doc.qt.io/qtforpython/contents.html
      ②. https://nuitka.net/doc/user-manual.html
  • 相关阅读:
    Conversions
    Mispelling4
    A hard puzzle
    Easier Done Than Said?
    利用map可以对很大的数出现的次数进行记数
    A+B Coming
    结构体成员变量
    NSString 类介绍及用法
    复习回顾
    函数与方法对比
  • 原文地址:https://www.cnblogs.com/xxhbdk/p/15938805.html
Copyright © 2020-2023  润新知