Python版本3.7
PySide2 Version: 5.14.1
官方文档:http://doc.qt.io/qtforpython/index.html
当Qt给我们提供的信号与槽不够用,或者需要自己封装某些控件,并向外提供改变内部控件的接口时,就要自定义信号与槽了。
from PySide2.QtWidgets import QLCDNumber, QSlider, QWidget, QVBoxLayout, QApplication, QGridLayout, QPushButton
from PySide2.QtCore import Qt
from PySide2.QtCore import Signal, Slot
class MyLCDNumber(QWidget):
# 自定义一个信号,需要传入一个int类型的参数
slider_valueChanged_signal = Signal(int)
def __init__(self, parent=None):
super().__init__(parent)
self.lcd_number = QLCDNumber()
# 初始化一个水平的slider,默认是垂直的
self.slider = QSlider(Qt.Horizontal)
self.btn_add = QPushButton('加一')
# 垂直布局
self.layout = QVBoxLayout()
self.layout.addWidget(self.lcd_number)
self.layout.addWidget(self.slider)
self.layout.addWidget(self.btn_add)
self.setLayout(self.layout)
# 设置整个控件的固定大小
self.setFixedSize(120, 140)
# 设置最多显示两位数
self.lcd_number.setDigitCount(2)
# 设置可以调节的范围大小
self.slider.setRange(0, 99)
# 信号与信号的连接
self.slider.valueChanged.connect(self.slider_valueChanged_signal)
# 信号与槽点连接
self.btn_add.clicked.connect(self.add)
# 自定义一个槽
@Slot()
def setLCDNumberValue(self, val):
self.lcd_number.display(val)
@Slot()
def add(self):
v = self.slider.value() + 1
self.slider.setValue(v)
# 主动发送信号
self.slider_valueChanged_signal.emit(v)
app = QApplication()
window = QWidget()
# 网格布局
layout = QGridLayout()
mylcdnumber01 = MyLCDNumber()
mylcdnumber02 = MyLCDNumber()
mylcdnumber01.slider_valueChanged_signal.connect(mylcdnumber01.setLCDNumberValue)
mylcdnumber02.slider_valueChanged_signal.connect(mylcdnumber02.setLCDNumberValue)
layout.addWidget(mylcdnumber01, 1, 1)
layout.addWidget(mylcdnumber02, 1, 2)
window.setLayout(layout)
window.show()
app.exec_()
运行结果:
图1代码中涉及到了信号与槽的自定义,信号的传递和信号的发送。
首先是信号的自定义slider_valueChanged_signal = Signal(int)
,使用Qt
给我们提供的Signal
类来创建一个信号,可以传入需要传递的参数类型,注意信号需要在类里面定义,不要放在__init__
里面定义。
定义完信号后就可以使用emit()
来进行信号的发送,可以传入需要传递的参数,前提是要与定义的信号参数类型一致。
然后就是自定义槽,槽的自定义就是定义一个函数,然后使用Qt
为我们提供的Slot
装饰器进行装饰,然后就可以进行信号与槽的连接
信号不仅仅可以连接到槽,还可以连接到信号,即信号的传递。当我们封装一个控件的时候,往往需要将这个控件的信号暴露出来,但是又不能在外面直接操作这个控件,如果这样的话就破坏了封装性,所以我们可以将这个控件的信号连接到我们自定义的另一个信号,从而不用直接操作内部控件。
网友评论