日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

pyqt 槽任意参数_PyQt5快速入门(二)PyQt5信号槽机制

發布時間:2025/5/22 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pyqt 槽任意参数_PyQt5快速入门(二)PyQt5信号槽机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

PyQt5快速入門(二)PyQt5信號槽機制

一、信號槽機制簡介

1、信號槽簡介

信號槽是Qt的核心機制,也是PyQt編程中對象進行通信的機制。在Qt中,QObject對象和PyQt中所有繼承自QWidget的控件都支持信號槽機制。當信號發射時,連接的槽函數會自動執行。在PyQt5中,信號與槽函數通過object.signal.connect()方法進行連接。

信號槽特點如下:

(1)一個信號可以連接多個槽

(2)一個信號可以連接另一個信號

(3)信號參數可以是任意Python類型

(4)一個槽可以監聽多個信號

(5)信號與槽的連接方式可以是同步連接,也可以是異步連接。

(6)信號與槽的連接可以跨線程

(7)信號可以斷開

在編寫一個類時,要首先定義的類的信號與槽,在類中信號與槽進行連接,實現對象之間的數據傳輸。當事件或狀態發生變化時,會發出信號,進而觸發執行事件或信號關聯的槽函數。信號槽機制示意如下:

2、定義信號

PyQt的內置信號是自動定義的,使用PyQt5.QtCore.pyqtSignal函數可以為QObject對象創建一個信號,使用pyqtSignal函數可以把信號定義為類的屬性。

class pyqtSignal:

def __init__(self, *types, name: str = ...) -> None: ...

types參數表示定義信號時參數的類型,name參數表示信號的名稱,默認使用類的屬性名稱。

使用pyqtSignal函數創建一個或多個重載的未綁定的信號作為類的屬性,信號只能在QObject的子類中定義。信號必須在類創建時定義,不能在類創建后作為類的屬性動態添加進來。使用pyqtSignal函數定義信號時,信號可以傳遞多各參數,并指定信號傳遞參數的類型,參數類型是標準的Python數據類型,包括字符串、日期、布爾類型、數字、列表、字典、元組。

from PyQt5.QtCore import pyqtSignal, QObject

class StandardItem(QObject):

# 定義信號,信號有兩個參數,兩個參數的類型分別為str,str,信號名稱為dataChanged

data_changed = pyqtSignal(str, str, name="dataChanged")

# 更新信息,發送信號

def update(self):

self.dataChanged.emit("old status", "new status")

3、操作信號

使用connect函數可以將信號綁定到槽函數上,使用disconnect函數可以解除信號與槽函數的綁定,使用emit函數可以發射信號。

QObject.signal.connect(self, slot, type=None, no_receiver_check=False)

建立信號到槽函數的連接,type為連接類型。

QObject.signal.disconnect(self, slot=None)

斷開信號到槽的連接

emit(self, *args)

發送信號,args為可變參數。

import sys

from PyQt5.QtCore import pyqtSignal, QObject, QCoreApplication

class StandardItem(QObject):

# 定義信號,信號有兩個參數,兩個參數的類型分別為str,str,信號名稱為dataChanged

data_changed = pyqtSignal(str, str, name="dataChanged")

# 更新信息,發送信號

def update(self):

self.dataChanged.emit("old status", "new status")

# 定義槽函數

def onDataChanged(self, old, new):

print(old)

print(new)

if __name__ == "__main__":

app = QCoreApplication(sys.argv)

item = StandardItem()

item.dataChanged.connect(item.onDataChanged)

item.update()

sys.exit(app.exec_())

# OUTPUT:

# old status

# new status

二、信號與槽應用

1、內置信號與槽函數

內置信號是QObject對象自動定義的信號,內置槽函數是QObject對象自動定義的槽函數,可以通過QObject.signal.connect函數將QObject對象的內置信號連接到QObject對象的槽函數。

2、內置信號與自定義槽函數

import sys

from PyQt5.QtWidgets import QWidget, QApplication, QPushButton

class MainWindow(QWidget):

def __init__(self, parent=None):

super().__init__(parent)

self.setWindowTitle("MainWindow Demo")

self.resize(800, 600)

button = QPushButton("close", self)

# 連接內置信號與自定義槽

button.clicked.connect(self.onClose)

# 自定義槽函數

def onClose(self):

self.close()

if __name__ == "__main__":

app = QApplication(sys.argv)

window = MainWindow()

window.show()

sys.exit(app.exec_())

點擊按鈕時觸發按鈕內置的clicked信號,執行綁定的自定義槽函數onClose。

3、自定義信號與內置槽函數

import sys

from PyQt5.QtCore import pyqtSignal

from PyQt5.QtWidgets import QWidget, QApplication, QPushButton

class MainWindow(QWidget):

closeSignal = pyqtSignal()

def __init__(self, parent=None):

super().__init__(parent)

self.setWindowTitle("MainWindow Demo")

self.resize(800, 600)

button = QPushButton("close", self)

# 連接內置信號與自定義槽

button.clicked.connect(self.onClose)

# 連接自定義信號closeSignal與內置槽函數close

self.closeSignal.connect(self.close)

# 自定義槽函數

def onClose(self):

# 發送自定義信號

self.closeSignal.emit()

if __name__ == "__main__":

app = QApplication(sys.argv)

window = MainWindow()

window.show()

sys.exit(app.exec_())

通過連接內置信號clicked到自定義槽函數onClose,在自定義槽函數onClose內發送自定義信號closeSignal,并將自定義信號closeSignal與內置槽函數close連接。

4、自定義信號與自定義槽函數

import sys

from PyQt5.QtCore import pyqtSignal

from PyQt5.QtWidgets import QWidget, QApplication, QPushButton

class MainWindow(QWidget):

closeSignal = pyqtSignal()

def __init__(self, parent=None):

super().__init__(parent)

self.setWindowTitle("MainWindow Demo")

self.resize(800, 600)

button = QPushButton("close", self)

# 連接內置信號與自定義槽

button.clicked.connect(self.onClicked)

# 連接自定義信號closeSignal與內置槽函數close

self.closeSignal.connect(self.onClose)

# 自定義槽函數

def onClicked(self):

# 發送自定義信號

self.closeSignal.emit()

# 自定義槽函數

def onClose(self):

self.close()

if __name__ == "__main__":

app = QApplication(sys.argv)

window = MainWindow()

window.show()

sys.exit(app.exec_())

三、信號槽應用進階

1、自定義信號槽

通常通過類變量定義信號對象,在__init__函數前定義自定義信號。

class TestObject(QObject):

# 定義無參的信號

noParametersSignal = pyqtSignal()

# 定義一個參數的信號,參數類型為int

oneParameterSignal = pyqtSignal(int)

# 定義一個參數的重載版本的信號,參數類型可以為int或str

oneParameterOverloadSignal = pyqtSignal([int], [str])

# 定義兩個參數的重載版本的信號,參數類型為int,str或int,int

twoParametersOverloadSignal = pyqtSignal([int, str], [int, int])

# 定義一個list參數類型的信號

oneParameterSignalList = pyqtSignal(list)

# 定義一個dict參數類型的信號

oneParameterSignalDict = pyqtSignal(dict)

類的槽函數定義與類的普通方法定義相同。

class TestObject(QObject):

# 定義無參的信號

noParametersSignal = pyqtSignal()

# 定義一個參數的信號,參數類型為int

oneParameterSignal = pyqtSignal(int)

# 定義一個參數的重載版本的信號,參數類型可以為int或str

oneParameterOverloadSignal = pyqtSignal([int], [str])

# 定義兩個參數的重載版本的信號,參數類型為int,str或int,int

twoParametersOverloadSignal = pyqtSignal([int, str], [int, int])

# 定義無參的槽函數

def onNoParameterSlot(self):

pass

# 定義一個參數的槽函數,參數為整型nIndex

def onOneParameterSlot(self, nIndex):

pass

# 定義兩個參數的槽函數,參數為整型nIndex,字符串型sStatus

def onTwoParametersSlot(self, nIndex, sStatus):

pass

通過connect方法連接信號與槽函數,信號與槽函數可以屬于同一個QObject對象,也可以是不同的QObject對象。

test = TestObject()

test.noParametersSignal.connect(test.onNoParameterSlot)

test.oneParameterSignal.connect(test.onOneParameterSlot)

test.twoParametersOverloadSignal.connect(test.onTwoParametersSlot)

信號的發送通過emit方法進行發送。

def update(self):

self.noParametersSignal.emit()

self.oneParameterSignal.emit(100)

self.oneParameterOverloadSignal("Hello, PyQt5")

self.twoParametersOverloadSignal(100, "Hello, PyQt5")

2、信號槽傳遞自定義參數

Qt中信號發出的參數個數必須大于等于槽函數的參數個數,PyQt使用自定義參數傳遞解決槽函數參數比信號參數多的問題。使用Lambda表達式或functools的partial函數可以傳遞自定義參數給槽函數,自定義參數類型可以是Python任意類型。

import sys

from PyQt5.QtWidgets import QWidget, QApplication, QPushButton, QHBoxLayout

from functools import partial

class MainWindow(QWidget):

def __init__(self, parent=None):

super().__init__(parent)

button1 = QPushButton("Button1", self)

button2 = QPushButton("Button2", self)

layout = QHBoxLayout()

layout.addWidget(button1)

layout.addWidget(button2)

self.setLayout(layout)

self.setWindowTitle("MainWindow Demo")

self.resize(800, 600)

# lambda

button1.clicked.connect(lambda: self.onButtonClicked(1))

button2.clicked.connect(lambda: self.onButtonClicked(2))

# partial

button1.clicked.connect(partial(self.onButtonClicked, 1))

button2.clicked.connect(partial(self.onButtonClicked, 2))

# 自定義槽函數

def onButtonClicked(self, n):

print("Button {0} is Clicked".format(n))

if __name__ == "__main__":

app = QApplication(sys.argv)

window = MainWindow()

window.show()

sys.exit(app.exec_())

3、信號槽與裝飾器

PyQt中可以通過Python裝飾器定義信號與槽函數,使用方法如下:

@PyQt5.QtCore.pyqtSlot(bool)

def on_發送者對象名稱_發射信號名稱(self, parameter):

pass

發送者對象名稱是使用setObjectName為QObject對象設置的對象名稱,通過信號名稱連接到槽函數的connectSlotsByName函數如下:

QtCore.QMetaObject.connectSlotsByName(self, QObject)

connectSlotsByName用于將QObject子孫對象的某些信號根據名稱連接到某些QObject對象的相應槽函數。

import sys

from PyQt5 import QtCore

from PyQt5.QtWidgets import QWidget, QApplication, QPushButton, QHBoxLayout

class MainWindow(QWidget):

def __init__(self, parent=None):

super().__init__(parent)

button1 = QPushButton("Button1", self)

button1.setObjectName("Button1")

button2 = QPushButton("Button2", self)

button2.setObjectName("Button2")

layout = QHBoxLayout()

layout.addWidget(button1)

layout.addWidget(button2)

self.setLayout(layout)

self.setWindowTitle("MainWindow Demo")

self.resize(800, 600)

QtCore.QMetaObject.connectSlotsByName(self)

@QtCore.pyqtSlot()

def on_Button1_clicked(self):

print("Button1 is clicked")

@QtCore.pyqtSlot()

def on_Button2_clicked(self):

print("Button2 is clicked")

if __name__ == "__main__":

app = QApplication(sys.argv)

window = MainWindow()

window.show()

sys.exit(app.exec_())

四、事件處理機制

1、事件機制與信號槽機制的區別

PyQt為事件處理提供了高級別的信號槽機制和低級別的事件處理機制,信號槽機制是事件處理機制的高級封裝。使用控件時,不用考慮事件處理機制,只需要關心信號槽即可;對于自定義派生控件,必須考慮事件處理機制,根據控件的行為需求重新實現相應的事件處理函數。

2、事件處理的方法

PyQt提供了5種事件處理和過濾方法,分別為:

(1)重新實現事件處理函數

常用的事件處理函數如paintEvent、mouseMoveEvent、mousePressEvent、mouseReleaseEvent等。

(2)重新實現QObject.event事件分發函數

在增加新的事件時,需要重新實現QObject.event方法,并增加新事件的分發路由。

(3)安裝事件過濾器

如果對QObject對象調用installEventFilter方法,則為QObject對象安裝事件過濾器。QObject對象的所有事件都會先傳遞到事件過濾器eventFilter函數,在事件過濾器eventFilter函數中可以丟棄或修改某些事件,對感興趣的事件使用自定義的事件處理機制,對其它事件使用默認事件處理機制。事件過濾機制會對QObject的所有事件進行過濾,因此如果要過濾的事件比較多則會影響程序性能。

(4)在QApplication安裝事件過濾器

在QApplication對象安裝事件過濾器將會對所有QObject對象的所有事件進行過濾,并且會首先獲得事件,即將事件發送給其它任何一個事件過濾器前,都會首先發送給QApplication的事件過濾器。

(5)重新QApplication的notify方法

PyQt使用QApplication對象的notify方法進行分發事件,要想在任何事件過濾器前捕獲事件唯一的方法就是重新實現QApplication的notify方法。

3、事件處理實例

QDialog對話框在ESC按鍵按下時會自動退出,使用事件處理和過濾對按下ESC按鍵進行處理。

(1)重新實現事件處理函數

import sys

from PyQt5.QtWidgets import QDialog, QApplication

from PyQt5.QtCore import Qt

class Dialog(QDialog):

def __init__(self, parent=None):

super().__init__(parent)

# 重新實現keyPressEvent

def keyPressEvent(self, event):

if event.key() != Qt.Key_Escape:

QDialog.keyPressEvent(self, event)

if __name__ == "__main__":

app = QApplication(sys.argv)

dialog = Dialog()

dialog.exec_()

sys.exit(app.exec_())

(2)重新實現event函數

import sys

from PyQt5.QtWidgets import QDialog, QApplication

from PyQt5.QtCore import Qt

from PyQt5.QtGui import QKeyEvent

class Dialog(QDialog):

def __init__(self, parent=None):

super().__init__(parent)

# 重新實現keyPressEvent

def event(self, event):

if event.type() == QKeyEvent.KeyPress and event.key() == Qt.Key_Escape:

return True

else:

return QDialog.event(self, event)

if __name__ == "__main__":

app = QApplication(sys.argv)

dialog = Dialog()

dialog.exec_()

sys.exit(app.exec_())

(3)QObject安裝事件過濾器

import sys

from PyQt5.QtWidgets import QDialog, QApplication

from PyQt5.QtCore import Qt

from PyQt5.QtGui import QKeyEvent

class Dialog(QDialog):

def __init__(self, parent=None):

super().__init__(parent)

self.installEventFilter(self)

def eventFilter(self, watched, event):

if event.type() == QKeyEvent.KeyPress and event.key() == Qt.Key_Escape:

return True

else:

return QDialog.eventFilter(self, watched, event)

if __name__ == "__main__":

app = QApplication(sys.argv)

dialog = Dialog()

dialog.exec_()

sys.exit(app.exec_())

(4)QApplication安裝事件過濾器

import sys

from PyQt5.QtWidgets import QDialog, QApplication

from PyQt5.QtCore import Qt

from PyQt5.QtGui import QKeyEvent

class Dialog(QDialog):

def __init__(self, parent=None):

super().__init__(parent)

def eventFilter(self, watched, event):

if event.type() == QKeyEvent.KeyPress and event.key() == Qt.Key_Escape:

return True

else:

return QDialog.eventFilter(self, watched, event)

if __name__ == "__main__":

app = QApplication(sys.argv)

dialog = Dialog()

app.installEventFilter(dialog)

dialog.exec_()

sys.exit(app.exec_())

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的pyqt 槽任意参数_PyQt5快速入门(二)PyQt5信号槽机制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。