基于Python的QT(二)
发表于:2022-08-24 |
字数统计: 1.1k | 阅读时长: 4分钟 | 阅读量:

Qt

首先,Qt原来是用C++写的一个框架,作为一个框架,Qt包含了很多的组件,这些组件是按照模块和组件来分布的。

qtbase就是大多数模块的基础组件,比例qtcore、qtgui、qtwidgets、qtnetworks,这些模块里当然都有一些直接可以实例化的类。

因此在编程中,我们可以直接使用他们,用他们来创建应用程序、处理文件、网络连接、正则表达式、文本编码等。

值得一提的是qtwidgets模块,该模块用于图形化程序,这在qt中是核心的部分。

当然还有一些其他的模块,在qt中,有着qml的存在,使得我们可以使用javascript来处理一些命令式的部分,官网是这样描述的,所谓的命令式,即计算机how的过程。之所以用到js,在我看来是为了更好的兼容与扩展,这一点在qt可以使用c++扩展和连接代码就可以看出。

文件类型

在qt中,除了py文件之外,还存在着用户界面定义文件ui文件,以及资源收集的qrc文件和qt建模语言文件qml。

当然还有项目文件pyproject。

信号和槽

这其实直接放在helloworld后面会好一些。

import sys

from PySide6 import QtWidgets, QtCore,QtGui
from PySide6.QtCore import Slot


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

        self.hello = 'hello Tom'

        self.button = QtWidgets.QPushButton('点我')

        self.text = QtWidgets.QLabel('helloworld', alignment=QtCore.Qt.AlignCenter)

        self.layout = QtWidgets.QVBoxLayout(self)

        self.layout.addWidget(self.text)

        self.layout.addWidget(self.button)

        self.button.clicked.connect(self.say)

    @Slot()
    def magic(self):
        self.text.setText(self.hello)

    @Slot()
    def say(self):
        print("Button clicked")


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

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

    sys.exit(app.exec())

这是helloworld的代码,我们忽略那些定义和创建的内容,我们会发现,程序本质上定义了一个按钮,并且在按钮按下的时候,调用了一个方法。

这看起来似乎很简单,但是在qt中,在按钮按下到执行对应内容的机制,被称为信号和槽,同时这也是qt的核心特性。

信号,在上述代码中,当我们单击按钮的时候,这就是一个信号,所谓的槽也就是信号传出时发生的情况,或者说信号的接收者。

信号和插槽不是按钮的专属,事实上所有继承了qobject的子类都可以包含信号和插槽,信号由对象发出。要注意的是,信号仅仅承担发出,并不关心接受的问题。这看起来似乎有点不负责任,但是封装的很好。

插槽用来接受信号,但实际上他们本质上只是最普通的函数,槽同样的只负责接受,他不知道有什么信号能连接到它。

这样的看起来紧密,却随时可以断开连接,互相连接就导致了qt可以创建真正的独立组件。

一个例子,我们可以创建很多的信号,这些信号都连接到一个插槽,或者多个插槽,甚至我们可以把一个信号连接到一个信号。

当然在qt中,有一些预定义的信号和插槽。

关于信号,在 Python 中编写类时,信号被声明为 class 的类级变量QtCore.Signal()

关于槽,由装饰器指示 @QtCore.Slot()Slot()也接受一个name和一个result关键字。result关键字定义将返回的类型,可以是 C 或 Python 类型。关键字的name行为方式与Signal(). 如果没有作为名称传递,则新插槽将与正在装饰的函数具有相同的名称。

在例子中,我们能发现,我们自定义了一个插槽,却没有定义信号,其实此处是利用了qt的预定义信号。

下面自定义信号,并且实现信号与槽的连接。

import sys


from PySide6 import QtWidgets, QtCore,QtGui
from PySide6.QtCore import Slot,Signal


class MyWidget(QtWidgets.QWidget):

    signal1 = Signal()

    def __init__(self):
        super().__init__()

        self.hello = 'hello Tom'

        self.button = QtWidgets.QPushButton('点我')

        self.text = QtWidgets.QLabel('helloworld', 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)

        self.signal1.connect(self.say)

    @Slot()
    def magic(self):
        self.text.setText(self.hello)
        sign = MyWidget()
        sign.signal1.emit()


    def say(self):
        print("Button clicked")


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

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

    sys.exit(app.exec())
上一篇:
springboot+vue(1)
下一篇:
基于python的QT(一)