Qt 快速上手#

参考:qtforpython-6/quickstart

创建简单的 Qt Widgets 应用程序#

通过开发简单的应用程序来进一步探索它,该应用程序用多种语言打印“Hello World”。

PySide6 Python 模块作为其子模块提供对 Qt API 的访问。在这种情况下,你正在导入 QtCoreQtWidgetsQtGui 子模块。

import sys
import random
from PySide6 import QtCore, QtWidgets, QtGui
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
Cell In[1], line 3
      1 import sys
      2 import random
----> 3 from PySide6 import QtCore, QtWidgets, QtGui

ImportError: libEGL.so.1: cannot open shared object file: No such file or directory

定义名为 MyWidget 的类,该类扩展了 QWidget 并包含 QPushButtonQLabel

class MyWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()

        self.hello = ["Hallo Welt", "Hei maailma", "Hola Mundo", "Привет мир"]

        self.button = QtWidgets.QPushButton("Click me!")
        self.text = QtWidgets.QLabel("Hello World",
                                     alignment=QtCore.Qt.AlignCenter)

        self.layout = QtWidgets.QVBoxLayout(self)
        self.layout.addWidget(self.text)
        self.layout.addWidget(self.button)

        self.button.clicked.connect(self.magic)

    @QtCore.Slot()
    def magic(self):
        self.text.setText(random.choice(self.hello))
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[2], line 1
----> 1 class MyWidget(QtWidgets.QWidget):
      2     def __init__(self):
      3         super().__init__()

NameError: name 'QtWidgets' is not defined

MyWidget 类有 magic() 成员函数,它从 hello 列表中随机选择一项。当你点击按钮时,会调用 magic() 函数。

添加 main 函数,在其中实例化 MyWidget 并显示它。

if __name__ == "__main__":
    app = QtWidgets.QApplication([])

    widget = MyWidget()
    widget.resize(800, 600)
    widget.show()

    sys.exit(app.exec())

完整代码见 tests/hello.py

为了支持 Jupyter 运行 Qt 应用,需要:

conda install qtconsole

切换 jupyter 前端:

jupyter qtconsole

使用 Qt Quick 创建 Qt 应用程序#

import sys
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
Cell In[3], line 2
      1 import sys
----> 2 from PySide6.QtGui import QGuiApplication
      3 from PySide6.QtQml import QQmlApplicationEngine

ImportError: libEGL.so.1: cannot open shared object file: No such file or directory

Qt 声明式用户界面#

可以使用 QML 语言来描述 UI:

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

Window {
    width: 300
    height: 200
    visible: true
    title: "Hello World"

    readonly property list<string> texts: ["Hallo Welt", "Hei maailma",
                                           "Hola Mundo", "Привет мир"]

    function setText() {
        var i = Math.round(Math.random() * 3)
        text.text = texts[i]
    }

    ColumnLayout {
        anchors.fill:  parent

        Text {
            id: text
            text: "Hello World"
            Layout.alignment: Qt.AlignHCenter
        }
        Button {
            text: "Click me"
            Layout.alignment: Qt.AlignHCenter
            onClicked:  setText()
        }
    }
}

将以下内容放入名为 Main.qml 的文件中,并将该文件放置在名为 Main 的目录中,同时在该目录中创建名为 qmldir 的文件以描述基本的 QML 模块:

module Main
Main 254.0 Main.qml

QML 应用执行#

现在,添加主函数,在其中实例化 QQmlApplicationEngine 并加载 QML

import sys
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine

if __name__ == "__main__":
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()
    engine.addImportPath(sys.path[0])
    engine.loadFromModule("Main", "Main")
    if not engine.rootObjects():
        sys.exit(-1)
    exit_code = app.exec()
    del engine
    sys.exit(exit_code)