1. 程式人生 > >PyQt5信號-槽機制

PyQt5信號-槽機制

previous iou find tde 信號和槽 qt5 獲取 cat utf-8

signal -> emit -> slot

signal.connect(slot)

signal.disconnect(slot)

信號 (singal) 可以連接無數多個槽 (slot),或者沒有連接槽也沒有問題,信號也可以連接其他的信號。

連接的基本語句形式如下: who.singal.connect(slot)

信號是 QObject 的一個屬性。只有通過 connect方法連接起來,信號-槽機制就建立起來了。類似的信號還有 disconnect 方法和emit 方法。

disconnect 就是斷開信號-槽機制,而 emit 就是激活信號。

信號都是類的一個屬性,新的信號必須繼承自 QObject,然後由 PyQt5.QtCore.pyqtSingal(在 pyqt4 下是 PyQt4.QtCore.pyqtSingal)方法創建,這個方法接受的參數中最重要的是 types 類型,比如 int, bool 之類的,你可以認為這是信號傳遞的參數類型,但實際傳遞這些參數值的是 emit 方法。然後槽實際上就是經過特殊封裝的函數,這些函數當然需要接受一些參數或者不接受參數,而這些參數具體的值傳進來的是由 emit 方法執行的,然後我們通過 who.singal.connect(slot) 這樣的形式將某個信號和某個槽連接起來, who 的信號,然後信號類自帶的連接方法,然後連接到 slot 某個函數上,在這裏隱藏的一個重要細節就是 emit 方法,比如說你定義一個新的信號,需要將點擊屏幕的具體 x,y 坐標發送出去,內置的信號-槽將這一機制都完成了,如果你自己定義的信號和槽的話,比如 pyqtSingal(int,int) ,發送給 func(x,y),具體 x 和 y 的值你需要通過 emit(x,y) 來發送。至於什麽時候發送,已經發送的 x,y 值的獲取,這應該又是另外一個信號-槽機制的細節。

1. 自定義信號

from PyQt5.QtCore import *
from PyQt5.QtGui import *

class FindDialog(QDialog):
    findNext = pyqtSignal(str, Qt.CaseSensitivity)
    findPrevious = pyqtSignal(str, Qt.CaseSensitivity)

2. 自定義槽

class FindDialog(QDialog):
    ......
@pyqtSlot() def findClicked(self): text
= self.lineEdit.text() if self.caseCheckBox.isChecked(): cs = Qt.CaseSensitive else: cs = Qt.CaseInsensitive if self.backwardCheckBox.isChecked(): self.findPrevious.emit(text, cs) else: self.findNext.emit(text, cs)

3. 發射信號

class FindDialog(QDialog):
    ......

    @pyqtSlot()
    def findClicked(self):
        ......
        if self.backwardCheckBox.isChecked():
            self.findPrevious.emit(text, cs)
        else:
            self.findNext.emit(text, cs)

4. 以下是完整的示例:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
‘‘‘
    查找對話框示例, 自定義信號槽
‘‘‘

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

class FindDialog(QDialog):
    findNext = pyqtSignal(str, Qt.CaseSensitivity)
    findPrevious = pyqtSignal(str, Qt.CaseSensitivity)
    
    def __init__(self, parent = None):
        super().__init__(parent)
        label = QLabel(self.tr(Find &what:))
        self.lineEdit = QLineEdit()
        label.setBuddy(self.lineEdit)
        self.caseCheckBox = QCheckBox(self.tr(Match &case))
        self.backwardCheckBox = QCheckBox(self.tr(Search &backward))
        self.findButton = QPushButton(self.tr(&Find))
        self.findButton.setDefault(True)
        self.findButton.setEnabled(False)
        closeButton = QPushButton(self.tr(Close))
        self.lineEdit.textChanged.connect(self.enableFindButton)
        self.findButton.clicked.connect(self.findClicked)
        closeButton.clicked.connect(self.close)
        topLeftLayout = QHBoxLayout()
        topLeftLayout.addWidget(label)
        topLeftLayout.addWidget(self.lineEdit)
        leftLayout = QVBoxLayout()
        leftLayout.addLayout(topLeftLayout)
        leftLayout.addWidget(self.caseCheckBox)
        leftLayout.addWidget(self.backwardCheckBox)
        rightLayout = QVBoxLayout()
        rightLayout.addWidget(self.findButton)
        rightLayout.addWidget(closeButton)
        rightLayout.addStretch()
        mainLayout = QHBoxLayout()
        mainLayout.addLayout(leftLayout)
        mainLayout.addLayout(rightLayout)
        self.setLayout(mainLayout)
        self.setWindowTitle(self.tr(Find))
        self.setFixedHeight(self.sizeHint().height())
        
    def enableFindButton(self, text):
        self.findButton.setEnabled(bool(text))
        
    @pyqtSlot()
    def findClicked(self):
        text = self.lineEdit.text()
        if self.caseCheckBox.isChecked():
            cs = Qt.CaseSensitive
        else:
            cs = Qt.CaseInsensitive
        if self.backwardCheckBox.isChecked():
            self.findPrevious.emit(text, cs)
        else:
            self.findNext.emit(text, cs)
            
if __name__ ==  __main__:
    import sys
    app = QApplication(sys.argv)
    findDialog = FindDialog()
    
    def find(text, cs):
        print(find:, text, cs, cs)
        
    def findp(text, cs):
        print(findp:, text, cs, cs)
        
    findDialog.findNext.connect(find)
    findDialog.findPrevious.connect(findp)
    findDialog.show()
    sys.exit(app.exec_())    

d

PyQt5信號-槽機制