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())