1. 程式人生 > 其它 >PySide6直接載入UI檔案實現介面和程式碼分離

PySide6直接載入UI檔案實現介面和程式碼分離

直接載入,無需再生成相應的py檔案。

參考:Using .ui files from Designer or QtCreator with QUiLoader and pyside6-uic — Qt for Python

入口檔案 simpleApp.py

from mainWindow import Window
from qt import QApplication, QIcon, _exec

if __name__ == '__main__':
    app = QApplication([])
    app.setWindowIcon(QIcon("logo.png"))    #
新增圖示 w = Window() w.ui.show() #w.win.show() _exec(app)
simpleApp.py

介面控制元件屬性設定檔案 mainWindow.py

import sys
from PySide6.QtGui import QScreen
from PySide6.QtCore import QFile
from PySide6.QtUiTools import QUiLoader
from PySide6.QtWidgets import QApplication, QButtonGroup, QLabel, QMessageBox

class Window: def __init__(self): super(Window, self).__init__() # 從ui檔案中載入UI定義 qfile = QFile("mainPage.ui") qfile.open(QFile.ReadOnly) qfile.close() # 從UI定義中動態建立一個相應的視窗物件 self.ui = QUiLoader().load(qfile) if not self.ui:
print(QUiLoader().errorString()) sys.exit(-1) self.center() # 訊號處理 self.ui.pushButton.clicked.connect(self.btnClick) # self.button.clicked.connect(self.btnClick) def btnClick(self): info = self.ui.textEdit.toPlainText() # 獲取文字資訊 # info = self.textEdit.toPlainText() print(info) # self.appLabel = QLabel() # self.appLabel.setAlignment(Qt.AlignCenter) # self.appLabel.alignment = Qt.AlignCenter # self.appLabel.setText(info) # self.appLabel.setWindowTitle(info) # self.appLabel.setGeometry(300, 300, 250, 175) # self.ui.setWindowTitle(info) # # 顯示這個Label # self.appLabel.show() self.msgbox = QMessageBox() msgBox = self.msgbox msgBox.setText(info) # msgBox.setStandardButtons(QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel) # msgBox.setDefaultButton(QMessageBox.Save) msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Discard | QMessageBox.Cancel) msgBox.setIcon(QMessageBox.Information) msgBox.setDetailedText("Information:" "\nsdfsdfaaa" "\nTestsertsetsetse") msgBox.setInformativeText("sdfsdfasssssss") # msgBox.show() # MessageBox = QMessageBox() # Ret = MessageBox.question(self.ui, "標題", "內容") #Critical對話方塊 # print(Ret) self.msgbox2 = QMessageBox() msgBox2 = self.msgbox2 connectButton = msgBox2.addButton("Connect", QMessageBox.ActionRole) disconnectButton = msgBox2.addButton("DisConnect", QMessageBox.ActionRole) msgBox.setText(info) msgBox2.setIcon(QMessageBox.Information) msgBox2.exec() if msgBox2.clickedButton() == connectButton: self.ui.textEdit.append("Connect clicked!") print("Connect pass") elif msgBox2.clickedButton() == disconnectButton: self.ui.textEdit.append("DisConnect clicked!") print("DisConnect pass") def center(self): #Get Screen geometry SrcSize = QScreen.availableGeometry(QApplication.primaryScreen()) #Set X Position Center frmX = (SrcSize.width() - self.ui.width())/2 #Set Y Position Center frmY = (SrcSize.height() - self.ui.height())/2 #Set Form's Center Location self.ui.move(frmX, frmY)
MainWindow.py

介面UI檔案:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QGroupBox" name="groupBox">
    <property name="geometry">
     <rect>
      <x>40</x>
      <y>10</y>
      <width>431</width>
      <height>451</height>
     </rect>
    </property>
    <property name="title">
     <string>GroupBox</string>
    </property>
    <widget class="QRadioButton" name="radioButton">
     <property name="geometry">
      <rect>
       <x>40</x>
       <y>80</y>
       <width>95</width>
       <height>20</height>
      </rect>
     </property>
     <property name="text">
      <string>RadioButton</string>
     </property>
    </widget>
    <widget class="QCheckBox" name="checkBox">
     <property name="geometry">
      <rect>
       <x>40</x>
       <y>20</y>
       <width>81</width>
       <height>20</height>
      </rect>
     </property>
     <property name="text">
      <string>CheckBox</string>
     </property>
    </widget>
    <widget class="QTabWidget" name="tabWidget">
     <property name="geometry">
      <rect>
       <x>40</x>
       <y>110</y>
       <width>351</width>
       <height>261</height>
      </rect>
     </property>
     <property name="currentIndex">
      <number>0</number>
     </property>
     <widget class="QWidget" name="tab">
      <attribute name="title">
       <string>Tab 1</string>
      </attribute>
      <widget class="QTextEdit" name="textEdit">
       <property name="geometry">
        <rect>
         <x>10</x>
         <y>30</y>
         <width>331</width>
         <height>191</height>
        </rect>
       </property>
      </widget>
     </widget>
     <widget class="QWidget" name="tab_2">
      <attribute name="title">
       <string>Tab 2</string>
      </attribute>
     </widget>
    </widget>
    <widget class="QPushButton" name="pushButton">
     <property name="geometry">
      <rect>
       <x>330</x>
       <y>410</y>
       <width>93</width>
       <height>28</height>
      </rect>
     </property>
     <property name="text">
      <string>PushButton</string>
     </property>
    </widget>
    <widget class="QRadioButton" name="radioButton_2">
     <property name="geometry">
      <rect>
       <x>40</x>
       <y>50</y>
       <width>95</width>
       <height>20</height>
      </rect>
     </property>
     <property name="text">
      <string>RadioButton</string>
     </property>
    </widget>
   </widget>
   <widget class="QToolBox" name="toolBox">
    <property name="geometry">
     <rect>
      <x>480</x>
      <y>20</y>
      <width>291</width>
      <height>201</height>
     </rect>
    </property>
    <property name="currentIndex">
     <number>1</number>
    </property>
    <widget class="QWidget" name="page">
     <property name="geometry">
      <rect>
       <x>0</x>
       <y>0</y>
       <width>291</width>
       <height>141</height>
      </rect>
     </property>
     <attribute name="label">
      <string>Page 1</string>
     </attribute>
    </widget>
    <widget class="QWidget" name="page_2">
     <property name="geometry">
      <rect>
       <x>0</x>
       <y>0</y>
       <width>291</width>
       <height>141</height>
      </rect>
     </property>
     <attribute name="label">
      <string>Page 2</string>
     </attribute>
    </widget>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>22</height>
    </rect>
   </property>
   <widget class="QMenu" name="menuMenu">
    <property name="title">
     <string>File</string>
    </property>
    <addaction name="actionOpen"/>
    <addaction name="actionSave"/>
    <addaction name="actionClose"/>
   </widget>
   <widget class="QMenu" name="menuEdit">
    <property name="title">
     <string>Edit</string>
    </property>
    <addaction name="actionSettings"/>
    <addaction name="actionReload"/>
   </widget>
   <addaction name="menuMenu"/>
   <addaction name="menuEdit"/>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
  <action name="actionOpen">
   <property name="text">
    <string>Open</string>
   </property>
  </action>
  <action name="actionSave">
   <property name="text">
    <string>Save</string>
   </property>
  </action>
  <action name="actionClose">
   <property name="text">
    <string>Close</string>
   </property>
  </action>
  <action name="actionSettings">
   <property name="text">
    <string>Settings</string>
   </property>
  </action>
  <action name="actionReload">
   <property name="text">
    <string>Reload</string>
   </property>
  </action>
 </widget>
 <resources/>
 <connections/>
</ui>
mainPage.ui

以下檔案用於擴充套件相關功能,但是入口檔案中會用到,需要import:

PyQt6和PySide6相容設定 qt.py:

import sys

if 'PyQt6' in sys.modules:
    # PyQt6
    from PyQt6 import QtGui, QtWidgets, QtCore
    from PyQt6.QtCore import pyqtSignal as Signal, pyqtSlot as Slot


else:
    # PySide6
    from PySide6 import QtGui, QtWidgets, QtCore
    from PySide6.QtCore import Signal, Slot
    
    from PySide6.QtWidgets import QApplication
    from PySide6.QtGui import QIcon
    

def _enum(obj, name):
    parent, child = name.split('.')
    result = getattr(obj, child, False)
    if result:  # Found using short name only.
        return result

    obj = getattr(obj, parent)  # Get parent, then child.
    return getattr(obj, child)


def _exec(obj):
    if hasattr(obj, 'exec'):
        return obj.exec()
    else:
        return obj.exec_()
qt.py

打包部署需要用到的,實現dll檔案整理到dist\lib資料夾下(試了一下功能未實現,僅做記錄,尋找解決方案,如有解決方案的朋友請不吝賜教)

import sys
import os

currentdir = os.path.dirname(sys.argv[0]).replace("/","\\")

libdir = os.path.join(currentdir, "lib")

sys.path.append(libdir)
os.environ['path'] += './lib'
print(sys.path)
print(f"\n{os.environ['path']}")
runtimehook.py

呼叫命令,結束後需要拷貝相應的UI檔案到生成的目錄:

pyinstaller simpleapp.py --noconsole --hidden-import PySide6.QtXml --workpath D:\Projects\PythonAPP\SimpleAPP\build --distpath D:\Projects\PythonAPP\SimpleAPP\build\dist --runtime-hook="runtimehook.py"
Command line