当前位置:网站首页>Pyside6 signal, slot
Pyside6 signal, slot
2022-07-06 16:00:00 【Catch the king before the thief】
Introduction to signal and slot applications ( One ):https://blog.csdn.net/jia666666/article/details/81774175
Subdivision of signal and slot ( Two ):https://blog.csdn.net/jia666666/article/details/81774858
Advanced play of signals and slots ( 3、 ... and ):https://blog.csdn.net/jia666666/article/details/81775378
Advanced usage of signals and slots ( Four ):https://blog.csdn.net/jia666666/article/details/81775614
Qt Designer God assists ( 5、 ... and ):https://blog.csdn.net/jia666666/article/details/81780619
Use of signals and slots in multithreading ( 6、 ... and ):https://blog.csdn.net/jia666666/article/details/81780930
Multi window data transmission ( 7、 ... and ):https://blog.csdn.net/jia666666/article/details/81781697
Event handling mechanism ( 8、 ... and ):https://blog.csdn.net/jia666666/article/details/81781992
1、 according to Use To classify
1. Built in signal 、 built-in Slot
Use of built-in signal and slot , When transmitting a signal , Functions using window controls , Not a custom function , This is also the one we used most in the past . Example :
# -*- coding: utf-8 -*-
import sys
from PySide6.QtWidgets import QMessageBox, QPushButton, QApplication, QWidget
def show_msg():
QMessageBox.information(widget, ' Message box ', 'Ok Pop up test information ')
app = QApplication(sys.argv)
widget = QWidget()
btn = QPushButton(' Test click the button ', widget)
btn.clicked.connect(show_msg)
widget.resize(300, 300)
widget.show()
sys.exit(app.exec())
This example will build a button object clicked Signals and custom slot functions show_msg() Connect . Click the button , This slot function will be triggered , Pop up a message box
2. Custom signal 、 Custom slot
Customize the use of signals and slots : When transmitting a signal , Functions that do not use window controls , Instead, use custom functions ,( Simply put, use oyqtsSignal Class instances emit signals ), The reason for using custom signals and slots , Because transmitting signals through built-in functions has its own defects , First , Built in functions only contain some commonly used signals , Some signal transmissions cannot find the corresponding built-in function , Secondly, under certain circumstances , To transmit this signal , Such as the click event of the button , Last , The parameters passed by the built-in function are specific , You can't customize , Using custom signal and slot functions does not have these defects
stay pyqt5 in , The application of customized signals and slots is very flexible , For example, because of business needs , In some places in the program, you need to send a signal , Transfer a variety of data , Then accept the data in the slot function , In this way, you can flexibly implement some business logic
A simple example : Simple custom signal and slot
import sys
from PySide6 import QtCore
# Define a name as say_some_words Of slot, And receive string
@QtCore.Slot(str)
def say_some_words(words):
print(words)
# Signal object
class Communicate(QtCore.QObject):
# Create a name called speak The signal of
speak = QtCore.Signal(str)
some_one = Communicate()
# connect signal and slot
some_one.speak.connect(say_some_words)
# emit 'speak' signal
some_one.speak.emit("Hello everybody!")
Add overloads :
import sys
from PySide6 import QtCore
# define a new slot that receives a C 'int' or a 'str'
# and has 'saySomething' as its name
@QtCore.Slot(int)
@QtCore.Slot(str)
def say_something(stuff):
print(stuff)
class Communicate(QtCore.QObject):
# create two new signals on the fly: one will handle
# int type, the other will handle strings
speakNumber = QtCore.Signal(int)
speakWord = QtCore.Signal(str)
someone = Communicate()
# connect signal and slot properly
someone.speakNumber.connect(say_something)
someone.speakWord.connect(say_something)
# emit each 'speak' signal
someone.speakNumber.emit(10)
someone.speakWord.emit("Hello everybody!")
Use slot overload and some complex signal connection and transmission
import sys
from PySide6 import QtCore
# define a new slot that receives an C 'int' or a 'str'
# and has 'saySomething' as its name
@QtCore.Slot(int)
@QtCore.Slot(str)
def say_something(stuff):
print(stuff)
class Communicate(QtCore.QObject):
# create two new signals on the fly: one will handle
# int type, the other will handle strings
speak = QtCore.Signal((int,), (str,))
someone = Communicate()
# connect signal and slot. As 'int' is the default
# we have to specify the str when connecting the
# second signal
someone.speak.connect(say_something)
someone.speak[str].connect(say_something)
# emit 'speak' signal with different arguments.
# we have to specify the str as int is the default
someone.speak.emit(10)
someone.speak[str].emit("Hello everybody!")
Example :
import sys
from PySide6.QtCore import QObject, Signal, Slot
"""
PyQt Another way is used . In order to PyQt Scripts switch to PySide function
Just use the following code to modify .
from PySide.QtCore import Signal as pyqtSignal
from PySide.QtCore import Slot as pyqtSlot
perhaps
QtCore.pyqtSignal = QtCore.Signal
QtCore.pyqtSlot = QtCore.Slot
"""
# Signal object
class CustomSignal(QObject):
# Define a signal
signal_send_msg = Signal(str, str)
def __init__(self):
super(CustomSignal, self).__init__()
def run(self):
# Send a signal
# self.sendmsg.emit('hell')
# Launch multiple parameters
self.signal_send_msg.emit(' The first parameter ', ' The second parameter ')
# Slot object
class CustomSlot(QObject):
def __init__(self):
super(CustomSlot, self).__init__()
self.temp = None
# Slot function in slot object
# def get( self,msg ):
# print("QSlot get msg => " + msg)
# Multiple parameters
def get_msg(self, msg1, msg2):
self.temp = None
print("QSlot get msg => " + msg1 + ' ' + msg2)
if __name__ == '__main__':
custom_signal = CustomSignal() # Instantiate the signal object
custom_slot = CustomSlot() # Instantiate the slot object
# Bind the signal to the slot function
custom_signal.signal_send_msg.connect(custom_slot.get_msg)
custom_signal.run()
# Unbind the signal from the slot function
custom_signal.signal_send_msg.disconnect(custom_slot.get_msg)
custom_signal.run()
3. The signal of the decorator 、 Slot
The so-called decorator signal and slot , It is through Decorator To define signals and slot functions
Example : adopt @QtCore.Slot(str) Decorate a function , Turn the function into a Slot function
import sys
from PySide6 import QtCore
# Define a name as say_some_words Of slot, And receive string
@QtCore.Slot(str)
def say_some_words(words):
print(words)
# Signal object
class Communicate(QtCore.QObject):
# Create a name called speak The signal of
speak = QtCore.Signal(str)
some_one = Communicate()
# connect signal and slot
some_one.speak.connect(say_some_words)
# emit 'speak' signal
some_one.speak.emit("Hello everybody!")
2、 According to the properties of signal and slot
Built in signal 、 Built in slot function
Demo close window when clicked , Use built-in signal and slot functions
# -*- coding: utf-8 -*-
from PySide6.QtWidgets import *
import sys
class WinForm(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle(' Built in signal / Slot example ')
self.resize(300, 150)
btn = QPushButton(' close ', self)
btn.clicked.connect(self.close)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = WinForm()
win.show()
sys.exit(app.exec())
Built in signal 、 Custom slot function
# -*- coding: utf-8 -*-
from PySide6.QtWidgets import *
import sys
class WinForm(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle(' Examples of built-in signals and custom slot functions ')
self.resize(300, 150)
btn = QPushButton(' close ', self)
btn.clicked.connect(self.btn_close)
def btn_close(self):
# Custom slot function
self.close()
if __name__ == '__main__':
app = QApplication(sys.argv)
win = WinForm()
win.show()
sys.exit(app.exec())
Custom signal 、 Built in slot function
# -*- coding: utf-8 -*-
import sys
from PySide6 import QtCore
from PySide6.QtWidgets import *
class WinForm(QWidget):
# Custom signal , With no arguments
button_clicked_signal = QtCore.Signal()
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle(' Examples of custom signals and built-in slot functions ')
self.resize(300, 150)
btn = QPushButton(' close ', self)
# Connect Signals and slots
btn.clicked.connect(self.btn_clicked)
# Received signal , Connect to slot
self.button_clicked_signal.connect(self.close)
def btn_clicked(self):
# Send custom signal , No parameter
self.button_clicked_signal.emit()
if __name__ == '__main__':
app = QApplication(sys.argv)
win = WinForm()
win.show()
sys.exit(app.exec())
Custom signal 、 Custom slot function
# -*- coding: utf-8 -*-
import sys
from PySide6 import QtCore
from PySide6.QtWidgets import *
class WinForm(QWidget):
# Custom signal , With no arguments
button_clicked_signal = QtCore.Signal()
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle(' Examples of custom signals and slot functions ')
self.resize(300, 150)
btn = QPushButton(' close ', self)
# Connect Signals and slots
btn.clicked.connect(self.btn_clicked)
# Received signal , Connect to the custom slot function
self.button_clicked_signal.connect(self.btn_close)
def btn_clicked(self):
# Send custom signal , No parameter
self.button_clicked_signal.emit()
def btn_close(self):
self.close()
if __name__ == '__main__':
app = QApplication(sys.argv)
win = WinForm()
win.show()
sys.exit(app.exec())
3、 The signal 、 Slot Advanced usage
Advanced , When customizing signals and slots , Parameters can be passed .
Custom signal general process
Defining signals
Define the slot function
Connect the signal to the slot function
Send a signal
Definition The signal
adopt Class member variable Define signal object
signal1 = QtCore.Signal() # Parameterless signal
signal2 = QtCore.Signal(int) # With one parameter ( Integers ) The signal of
signal3 = QtCore.Signal(int, str) # With two parameters ( Integers , character string ) The signal of
signal4 = QtCore.Signal(list) # With one parameter ( list ) The signal of
signal5 = QtCore.Signal(dict) # With one parameter ( Dictionaries ) The signal of
signal6 = QtCore.Signal([int, str], [str]) # belt ( Integers character string ) perhaps ( character string ) The signal of
Definition Slot function
Define a slot function , It has several different input parameters
def signal_call_1(self):
print("signal1 emit")
def signal_call_2(self, val):
print('signal2 emit,value:', val)
def signal_call_3(self, val, text):
print('signall3 emit,value:', val, text)
def signal_call_4(self, val):
print('signal4 emit,value:', val)
def signal_call_5(self, val):
print('signal5 emit,value', val)
def signal_call_6(self, val, text):
print('signal6 emit,value', val, text)
def signal_call_7(self, val):
print('signal6 overload emit', val)
Connecting signals And Slot function
# Link between signal and slot function
self.signal1.connect(self.signal_call_1)
self.signal2.connect(self.signal_call_2)
self.signal3.connect(self.signal_call_3)
self.signal4.connect(self.signal_call_4)
self.signal5.connect(self.signal_call_5)
self.signal6[int,str].connect(self.signal_call_6)
self.signal6[str].connect(self.signal_call_7)
Send a signal
# Signal transmission
self.signal1.emit()
self.signal2.emit(1)
self.signal3.emit(1,' Third ')
self.signal4.emit([1,2,3,4])
self.signal5.emit({"name":'JIA','age':'21'})
self.signal6[int,str].emit(1," The sixth ")
self.signal6[str].emit(' The sixth ')
example : The complete code is as follows
# -*- coding: utf-8 -*-
import sys
from PySide6.QtWidgets import *
from PySide6.QtCore import QObject, Signal, Slot
class CustomSignal(QObject):
signal1 = Signal() # Parameterless signal
signal2 = Signal(int) # With one parameter ( Integers ) The signal of
signal3 = Signal(int, str) # With two parameters ( Integers , character string ) The signal of
signal4 = Signal(list) # With one parameter ( list ) The signal of
signal5 = Signal(dict) # With one parameter ( Dictionaries ) The signal of
signal6 = Signal([int, str], [str]) # belt ( Integers character string ) perhaps ( character string ) The signal of
def __init__(self, parent=None):
super(CustomSignal, self).__init__(parent)
# Link between signal and slot function
self.signal1.connect(self.signal_call_1)
self.signal2.connect(self.signal_call_2)
self.signal3.connect(self.signal_call_3)
self.signal4.connect(self.signal_call_4)
self.signal5.connect(self.signal_call_5)
self.signal6[int, str].connect(self.signal_call_6)
self.signal6[str].connect(self.signal_call_7)
# Signal transmission
self.signal1.emit()
self.signal2.emit(1)
self.signal3.emit(1, ' Third ')
self.signal4.emit([1, 2, 3, 4])
self.signal5.emit({"name": 'JIA', 'age': '21'})
self.signal6[int, str].emit(1, " The sixth ")
self.signal6[str].emit(' The sixth ')
# Slot function
def signal_call_1(self):
print("signal1 emit")
def signal_call_2(self, val):
print('signal2 emit,value:', val)
def signal_call_3(self, val, text):
print('signall3 emit,value:', val, text)
def signal_call_4(self, val):
print('signal4 emit,value:', val)
def signal_call_5(self, val):
print('signal5 emit,value', val)
def signal_call_6(self, val, text):
print('signal6 emit,value', val, text)
def signal_call_7(self, val):
print('signal6 overload emit', val)
if __name__ == '__main__':
custom_signal = CustomSignal()
Transfer of custom parameters
During programming , We often encounter the situation of passing custom parameters to slot functions , For example, the connection between a signal and a slot function is
button.clicked.connect(show_page)
about clicked The signal , It has no parameters , about show_page In terms of functions , I hope he can accept the parameters , hope show_page The function is as follows
def show_page(self,name):
print(name', Click. ’)
Then there will be a problem , The number of parameters sent by the signal is different from the number of parameters accepted by the slot function , So how to solve this problem ? Here are two solutions ;
- The first one is :lamdba expression
- The second kind : Use functools Medium partial function
The two methods , It is written below , You can run it yourself , Pay attention to the notes .
# -*- coding: utf-8 -*-
import sys
from PySide6.QtWidgets import *
from PySide6.QtCore import QObject, Signal, Slot
from functools import partial
class WinForm(QMainWindow):
def __init__(self, parent=None):
super(WinForm, self).__init__(parent)
# Instantiate two buttons
button1 = QPushButton('Button1')
button2 = QPushButton('Button2')
# todo The first method
# Click signal correlation slot function , utilize lambda The expression passes a parameter
# button1.clicked.connect(lambda :self.onButtonClick(1))
# button2.clicked.connect(lambda :self.onButtonClick(2))
#
# todo The second method
button1.clicked.connect(partial(self.btn_click, 1))
button2.clicked.connect(partial(self.btn_click, 2))
# Instantiation window
main = QWidget()
# Set the layout of the window , And add controls to it
layout = QHBoxLayout(main)
layout.addWidget(button1)
layout.addWidget(button2)
# Set as central control
self.setCentralWidget(main)
self.resize(500, 500)
def btn_click(self, n):
# Pop up information prompt box , Output the clicked information
print("Button {0}".format(n))
QMessageBox.information(self, ' Message box ', 'Button {0}'.format(n))
if __name__ == '__main__':
app = QApplication(sys.argv)
form = WinForm()
form.show()
sys.exit(app.exec_())
Use lambda The expression passes the button number to the slot function , Of course, it can also pass on other things , Even the button itself
button1.clicked.connect(lambda :self.onButtonClick(1))
button2.clicked.connect(lambda :self.onButtonClick(2))
Use functools Medium partial Functions can fix function parameters
button1.clicked.connect(partial(self.onButtonClick, 1))
button2.clicked.connect(partial(self.onButtonClick, 2))
Decorator signal and slot
The so-called decorator signal and slot , It is to define signals and slot functions through decorators .
as follows
@PySide6.QtCore.Slot( Parameters )
def on_ Sender object name ) Transmit signal name (self, Parameters ):
pass
The premise of this method is that the following functions have been executed :
QMetaObject.connectSlotsByName(QObject)
In the code above ," Sender object name " Is the use of "setObjectName function " Name of the setting . Therefore, the naming rules of user-defined slot functions can also be seen as :
on + Use setObjectName Name of the setting + Signal name
Specific examples
# -*- coding: utf-8 -*-
import sys
from PySide6.QtWidgets import *
from PySide6.QtCore import QObject, Signal, Slot, QMetaObject
class WinForm(QWidget):
def __init__(self, parent=None):
super(WinForm, self).__init__(parent)
self.btn_ok = QPushButton('ok', self) # Create button , Add to your own window
self.btn_ok.setObjectName('btn_ok') # Use setObjectName Set object name
# Set its layout as horizontal , And add a button control to it
layout = QHBoxLayout(self)
layout.addWidget(self.btn_ok)
self.resize(300, 150)
# TODo The first method
# self.okButton.clicked.connect(self.btn_ok_clicked)
# The second method
QMetaObject.connectSlotsByName(self)
# def btn_ok_clicked(self):
# print(' Click ok Button ')
@Slot()
def on_btn_ok_clicked(self):
print(' Click ok Button ')
if __name__ == '__main__':
app = QApplication(sys.argv)
form = WinForm()
form.show()
sys.exit(app.exec())
QtCore.QMetaObject.connectSlotsByName(self) yes PySide6 According to the The signal name is automatically connected to the core code of the slot function , This line of code is used to put QObject Some objects of the descendant objects in are in accordance with their objectName Connect to the corresponding slot function .
For example, name , Suppose the code QtCore.QMetaObject.connectSlotsByName(self) Has been performed , Then the following code
@QtCore.Slot()
def on_okButton_clicked(self):
print(' Click ok Button ')
It will be automatically recognized as the following code
def __init__(self,parent=None):
self.okButton.clicked.connect(self.okButton_clicked)
def okButton_clicked(self):
print(' Click ok Button ')
Disconnection and connection of signal and slot
Sometimes for some reason , Want to temporarily or permanently disconnect a signal from the slot function , Generally put connect prefix dis It means unbinding : namely disconnect
Examples are as follows
# -*- coding: utf-8 -*-
import sys
from PySide6.QtWidgets import *
from PySide6.QtCore import QObject, Signal, Slot, QMetaObject
class SignalClass(QObject):
signal1 = Signal() # Declare a signal without parameters
signal2 = Signal(int) # The declaration takes a int Signal of type parameter
def __init__(self, parent=None):
super(SignalClass, self).__init__(parent)
# take signal1 The signal is connected to two slot functions
self.signal1.connect(self.sig1Call)
self.signal1.connect(self.sig2Call)
# take signal2 The signal is connected to the signal 1
self.signal2.connect(self.signal1)
# Send a signal
self.signal1.emit()
self.signal2.emit(1)
# Disconnect the relationship between the signal and the slot function
self.signal1.disconnect(self.sig1Call)
self.signal1.disconnect(self.sig2Call)
self.signal2.disconnect(self.signal1)
# Bind signal and slot function
self.signal1.connect(self.sig1Call)
self.signal2.connect(self.sig1Call)
# Signal transmission
self.signal1.emit()
self.signal2.emit(1)
# The output signal 1 launch
def sig1Call(self):
print('signal-1 emit')
# The output signal 2 launch
def sig2Call(self):
print('signal-2 emit')
if __name__ == '__main__':
signal = SignalClass()
4、 The signal And Slot And Qt Designer God assists
The front is the signal of manual input code and the use method of slot , Because it will be simpler to introduce in this way . But in practical application , because Qt Designer It can well realize the separation of interface display and business logic , If it can be used Qt Designer Automatically create some signals and slot mechanisms , So much the better
The function of this example is : The use of signals is explained in detail through an analog printing interface , When printing , You can set the number of copies to print , Paper type , After triggering the print button , Display the execution results on the right , adopt QCheckBox( Full screen preview Check box ) To choose whether to preview in full screen mode , Display the execution results on the right
Press F1 Key can display helpmessage Help information
First step :Qt Designer
First , Use Qt Designer Create a new template named widget Simple window , By way of widget box Drag the control of the area into the window , Realize the interface effect as shown in the figure
Here is a brief description of the window control
Control types | Control name | effect |
QSpinBox | numberSpinBox | Show printed scores |
QComboBox | styleCombo | Displays the type of paper printed , Paper types include A3,A4 etc. |
QPushButton | printButton | Connect emitPrintSiagnal Function binding , Trigger custom signals printSignal The launch of |
QCheckBox | prievewState | Whether to preview in full screen |
QPushButton | priviewButton | Connect emitPreviewSignal Function binding , Trigger custom signals previewSignal The launch of |
QLabel | resultLabel | Show execution results |
The second step : Add the interface file ui Convert to py file
pyuic5 -o xxxxx.py xxxxx.ui
It will generate a py file , In order to separate the display of the window from the business logic , Creating a file displayed in the call window , Add multiple custom signals to the calling class , And bind with slot function , The complete code is as follows
# -*- coding: utf-8 -*-
import sys
from PySide6 import QtCore, QtGui, QtWidgets
from PySide6.QtWidgets import *
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("Form")
MainWindow.resize(715, 225)
self.controlsGroup = QtWidgets.QGroupBox(MainWindow)
self.controlsGroup.setGeometry(QtCore.QRect(10, 20, 451, 151))
self.controlsGroup.setObjectName("controlsGroup")
self.widget = QtWidgets.QWidget(self.controlsGroup)
self.widget.setGeometry(QtCore.QRect(10, 40, 411, 30))
self.widget.setObjectName("widget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.label = QtWidgets.QLabel(self.widget)
self.label.setObjectName("label")
self.horizontalLayout.addWidget(self.label)
self.numberSpinBox = QtWidgets.QSpinBox(self.widget)
self.numberSpinBox.setObjectName("numberSpinBox")
self.horizontalLayout.addWidget(self.numberSpinBox)
self.styleCombo = QtWidgets.QComboBox(self.widget)
self.styleCombo.setObjectName("styleCombo")
self.styleCombo.addItem("")
self.styleCombo.addItem("")
self.styleCombo.addItem("")
self.horizontalLayout.addWidget(self.styleCombo)
self.label_2 = QtWidgets.QLabel(self.widget)
self.label_2.setObjectName("label_2")
self.horizontalLayout.addWidget(self.label_2)
self.printButton = QtWidgets.QPushButton(self.widget)
self.printButton.setObjectName("printButton")
self.horizontalLayout.addWidget(self.printButton)
self.widget1 = QtWidgets.QWidget(self.controlsGroup)
self.widget1.setGeometry(QtCore.QRect(10, 100, 201, 30))
self.widget1.setObjectName("widget1")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.widget1)
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.previewStatus = QtWidgets.QCheckBox(self.widget1)
self.previewStatus.setObjectName("previewStatus")
self.horizontalLayout_2.addWidget(self.previewStatus)
self.previewButton = QtWidgets.QPushButton(self.widget1)
self.previewButton.setObjectName("previewButton")
self.horizontalLayout_2.addWidget(self.previewButton)
self.resultGroup = QtWidgets.QGroupBox(MainWindow)
self.resultGroup.setGeometry(QtCore.QRect(470, 20, 231, 151))
self.resultGroup.setObjectName("resultGroup")
self.resultLabel = QtWidgets.QLabel(self.resultGroup)
self.resultLabel.setGeometry(QtCore.QRect(20, 30, 191, 101))
self.resultLabel.setObjectName("resultLabel")
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("Form", " Print controls "))
self.controlsGroup.setTitle(_translate("Form", " Print control "))
self.label.setText(_translate("Form", " Number of printed copies :"))
self.styleCombo.setItemText(0, _translate("Form", "A3"))
self.styleCombo.setItemText(1, _translate("Form", "A4"))
self.styleCombo.setItemText(2, _translate("Form", "A5"))
self.label_2.setText(_translate("Form", " Paper type :"))
self.printButton.setText(_translate("Form", " Print "))
self.previewStatus.setText(_translate("Form", " Full screen preview "))
self.previewButton.setText(_translate("Form", " preview "))
self.resultGroup.setTitle(_translate("Form", " Operating results "))
self.resultLabel.setText(_translate("Form", "<html><head/><body><p><br/></p></body></html>"))
class MyMainWindow(QMainWindow, Ui_MainWindow):
help_signal = QtCore.Signal(str)
print_signal = QtCore.Signal(list)
# Declare a signal with multiple overloaded versions , Includes a band int and str Signal of type parameter , And the belt str Parameter signal
preview_signal = QtCore.Signal([int, str], [str])
def __init__(self, parent=None):
super(MyMainWindow, self).__init__(parent)
self.setupUi(self)
self.init_signal_and_slot()
def init_signal_and_slot(self):
self.help_signal.connect(self.show_help_message)
self.print_signal.connect(self.print_paper)
self.preview_signal[str].connect(self.preview_paper)
self.preview_signal[int, str].connect(self.preview_paper_with_args)
self.printButton.clicked.connect(self.emit_print_signal)
self.previewButton.clicked.connect(self.emit_preview_signal)
# Send preview signal
def emit_preview_signal(self):
if self.previewStatus.isChecked():
self.preview_signal[int, str].emit(1080, " Full Screen")
elif not self.previewStatus.isChecked():
self.preview_signal[str].emit("Preview")
# Transmit print signal
def emit_print_signal(self):
print_info = [self.numberSpinBox.value(), self.styleCombo.currentText()]
self.print_signal.emit(print_info)
def print_paper(self, print_info):
self.resultLabel.setText(" Print : " + " Additional copies :" + str(print_info[0]) + " paper :" + str(print_info[1]))
def preview_paper_with_args(self, style, text):
self.resultLabel.setText(str(style) + text)
def preview_paper(self, text):
self.resultLabel.setText(text)
# Reload keyboard click events
def keyPressEvent(self, event):
if event.key() == QtCore.Qt.Key_F1:
self.help_signal.emit("help message")
# Show help messages
def show_help_message(self, message):
self.resultLabel.setText(message)
self.statusBar().showMessage(message)
if __name__ == "__main__":
app = QApplication(sys.argv)
win = MyMainWindow()
win.show()
sys.exit(app.exec())
5、 Use of signals and slots in multithreading
The simplest multithreading QThread Use
The way is to use QThread function .
Example :QThread Simple combination of function and signal
# -*- coding: utf-8 -*-
import sys
from PySide6.QtCore import *
from PySide6.QtWidgets import *
class MyThread(QThread):
# The custom signal parameters are str type
custom_signal = Signal(str)
def __init__(self, parent=None):
super(MyThread, self).__init__(parent)
# Initialization name is empty
self.times = None
self.identity = None
def set_identity(self, text):
# Set the multithread name
self.identity = text
def set_val(self, val):
# Receive data , Running multithreading
self.times = int(val)
self.run()
def run(self):
# When the number is greater than 0 And execute code when the name is not empty
while self.times > 0 and self.identity:
# Send a signal , Trigger the print function , frequency -1
self.custom_signal.emit(self.identity + '==>' + str(self.times))
self.times -= 1
class WinForm(QWidget):
def __init__(self, parent=None):
super(WinForm, self).__init__(parent)
# Create a thread instance and set the name Variable Signal and slot
self.thread = MyThread()
self.thread.set_identity('thread1')
self.thread.custom_signal.connect(self.out_text)
self.thread.set_val(6)
# Print out text
def out_text(self, text):
print(text)
if __name__ == '__main__':
app = QApplication(sys.argv)
form = WinForm()
form.show()
sys.exit(app.exec())
pass
Example :
import sys, time
from PySide6.QtCore import (
Signal, Slot, Qt, QThread
)
from PySide6.QtWidgets import (
QWidget, QVBoxLayout, QPushButton, QLabel, QApplication
)
class mainWindow(QWidget):
def __init__(self) -> None:
super().__init__()
self.label = QLabel("Hello!")
self.label.setAlignment(Qt.AlignCenter)
self.but = QPushButton("Click!")
self.but.clicked.connect(self.fun)
self.layout = QVBoxLayout()
self.layout.addWidget(self.label)
self.layout.addWidget(self.but)
self.setLayout(self.layout)
self.setWindowTitle('Signal Example')
self.resize(300, 300)
self.show()
@Slot()
def fun(self):
self.th = Th()
self.th.timer.connect(self.flushlabel)
self.th.finish.connect(self.isFinish)
self.th.start()
@Slot(int)
def flushlabel(self, nu):
self.label.setText(str(nu))
@Slot(bool)
def isFinish(self, bo):
if bo is True:
self.but.setEnabled(True)
else:
self.but.setEnabled(False)
class Th(QThread):
timer = Signal(int)
finish = Signal(bool)
def __init__(self) -> None:
super().__init__()
def run(self):
print('Start Timer')
self.finish.emit(False)
for x in range(5):
self.timer.emit(5 - x)
time.sleep(1)
self.finish.emit(True)
if __name__ == '__main__':
app = QApplication([])
widgets = mainWindow()
sys.exit(app.exec())
Use of main threads and sub threads
Sometimes, some time-consuming operations are often performed when developing programs , This will cause the interface to jam , This is also one of the applications of multithreading , In this way, we can create multithreading , Use the main thread to update the interface , Use sub threads to process data in the background , Finally, the results are displayed on the interface
# -*- coding: utf-8 -*-
import sys
import time
from PySide6.QtCore import *
from PySide6.QtWidgets import *
class BackQthread(QThread):
# The custom signal is str Parameter type
update_date = Signal(str)
def run(self):
while True:
# Get the current system time
data = QDateTime.currentDateTime()
# Set the time display format
current_time = data.toString('yyyy-MM-dd hh:mm:ss dddd')
# Send a signal
self.update_date.emit(str(current_time))
# Sleep for a second
time.sleep(1)
class window(QDialog):
def __init__(self):
super(window, self).__init__()
# Set title and initial size
self.backend = None
self.setWindowTitle('PyQt5 Examples of real-time interface updates ')
self.resize(400, 100)
# Instantiate the text input box and its initial size
self.input = QLineEdit(self)
self.input.resize(400, 100)
self.init_ui()
def init_ui(self):
# Instantiate objects
self.backend = BackQthread()
# The signal is connected to the interface to display the slot function
self.backend.update_date.connect(self.handle_display)
# Multithreading starts
self.backend.start()
def handle_display(self, data):
# Set the text of a single line text box
self.input.setText(data)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = window()
win.show()
sys.exit(app.exec())
6、 Signal and slot multi window data transmission
stay pyqt During programming , We often encounter the problem of entering or selecting multiple parameters , Write multiple parameters to a window , The main window will look bloated , therefore , It is usually to add a button , Call the dialog , Select parameters in the dialog box , Close the dialog box and return the parameters to the main window
pyqt Provides some standard dialog classes , Used to enter data , Modifying data , Change the settings of the application, etc , Common are QFileDialog,QInputDialog,QColorDialog, QFontDialog etc. , There are two common ways to transfer parameters between different windows , One is to transfer parameters between user-defined dialog boxes through attributes , Another way is to use signals and slots between windows
Example 1: Single window data transmission
For programs with a single window , Changes in one control affect changes in another , This change is very easy to solve by using the relationship between signal and slot
# -*- coding: utf-8 -*-
import sys
import time
from PySide6.QtCore import *
from PySide6.QtWidgets import *
class WinForm(QWidget):
def __init__(self):
super(WinForm, self).__init__()
self.init_ui()
def init_ui(self):
# First create a horizontal slider and Lcd Control
lcd = QLCDNumber(self)
slider = QSlider(Qt.Horizontal, self)
# Vertical layout , add controls
vbox = QVBoxLayout()
vbox.addWidget(lcd)
vbox.addWidget(slider)
# Set window layout
self.setLayout(vbox)
# Set the slider value signal to change the connection Lcd Update
slider.valueChanged.connect(lcd.display)
# Set the initial position and initial size , Set title
self.setGeometry(300, 300, 350, 150)
self.setWindowTitle(' Signal and slot : Connecting slider LCd')
if __name__ == '__main__':
app = QApplication(sys.argv)
form = WinForm()
form.show()
sys.exit(app.exec())
Example 2: Multi window data transmission : Call the property
New dialog box sub window properties ,form_QDialog.py
import sys
import time
from PySide6.QtCore import *
from PySide6.QtWidgets import *
class DateDialog(QDialog):
def __init__(self, parent=None):
super(DateDialog, self).__init__(parent)
self.setWindowTitle('DateDialog')
# Add controls to layout
layout = QVBoxLayout(self)
self.datetime = QDateTimeEdit(self)
self.datetime.setCalendarPopup(True)
self.datetime.setDateTime(QDateTime.currentDateTime())
layout.addWidget(self.datetime)
buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)
buttons.accepted.connect(self.accept)
buttons.rejected.connect(self.reject)
layout.addWidget(buttons)
def date_time(self):
return self.datetime.dateTime()
@staticmethod
def get_datetime(parent=None):
dialog = DateDialog(parent)
result = dialog.exec_()
date = dialog.date_time()
return date.date(), date.time(), result == QDialog.Accepted
Create a new main window file form_main.py , Used to call form_QDialog.py
# -*- coding: utf-8 -*-
# @Author : The Buddha bless , never bug
# @Date :
# @File : form_main.py.py
# @Software: PyCharm
# @description : XXX
import sys
from PySide6.QtWidgets import *
from form_QDialog import DateDialog
class WinForm(QWidget):
def __init__(self, parent=None):
super(WinForm, self).__init__(parent)
self.resize(400, 90)
self.setWindowTitle(' An example of returning a value to the main window when the dialog box closes ')
self.lineEdit = QLineEdit(self)
self.btn1 = QPushButton(' Pop-up dialog box 1')
self.btn1.clicked.connect(self.on_btn1_clicked)
self.btn2 = QPushButton(' Pop-up dialog box 2')
self.btn2.clicked.connect(self.on_btn2_clicked)
grid_layout = QGridLayout(self)
grid_layout.addWidget(self.lineEdit)
grid_layout.addWidget(self.btn1)
grid_layout.addWidget(self.btn2)
def on_btn1_clicked(self):
dialog = DateDialog(self)
result = dialog.exec()
date = dialog.date_time()
self.lineEdit.setText(date.date().toString())
print('\n The return value of the date dialog ')
print('date=%s' % str(date.date))
print('time=%s' % str(date.time()))
print('result=%s' % result)
def on_btn2_clicked(self):
date, time, result = DateDialog.get_datetime()
self.lineEdit.setText(date.toString())
print('\n The return value of the date dialog ')
print('date=%s' % str(date))
print('time=%s' % str(time))
print('result=%s' % result)
if __name__ == '__main__':
app = QApplication(sys.argv)
form = WinForm()
form.show()
sys.exit(app.exec())
pass
Running results :
Example 3: Multi window data transmission : Signal and slot
For multi window data transfer , Generally, the signal is transmitted through the sub window , The main window captures this signal through the slot function , Then get the data in the signal .
There are two kinds of signals transmitted by the sub window :
- One is the launch built-in pyqt The signal .
- One is to transmit customized signals . The advantage of transmitting customized signals is that its parameters can be customized , It can be for int list dict Various types and multiple parameters
Create a sub dialog file , The name here is :form_QDialog.py
# -*- coding: utf-8 -*-
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import *
class DateDialog(QDialog):
Signal_OneParameter = Signal(str)
def __init__(self, parent=None):
super(DateDialog, self).__init__(parent)
self.setWindowTitle(' child window : Used to transmit signals ')
# Adding subassemblies to a layout
layout = QVBoxLayout(self)
self.label = QLabel(self)
self.label.setText(' The former transmits a built-in signal \n The latter transmits custom signals ')
self.datetime_inner = QDateTimeEdit(self)
self.datetime_inner.setCalendarPopup(True)
self.datetime_inner.setDateTime(QDateTime.currentDateTime())
self.datetime_emit = QDateTimeEdit(self)
self.datetime_emit.setCalendarPopup(True)
self.datetime_emit.setDateTime(QDateTime.currentDateTime())
layout.addWidget(self.label)
layout.addWidget(self.datetime_inner)
layout.addWidget(self.datetime_emit)
# Use two button(ok and cancel) Separate connection accept() and reject() Slot function
buttons = QDialogButtonBox(
QDialogButtonBox.Ok | QDialogButtonBox.Cancel,
Qt.Horizontal, self)
buttons.accepted.connect(self.accept)
buttons.rejected.connect(self.reject)
layout.addWidget(buttons)
self.datetime_emit.dateTimeChanged.connect(self.emit_signal)
def emit_signal(self):
date_str = self.datetime_emit.dateTime().toString()
self.Signal_OneParameter.emit(date_str)
Create main window form_main.py, Call dialog file form_QDialog.py
import sys
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import *
from form_QDialog import DateDialog
class WinForm(QWidget):
def __init__(self, parent=None):
super(WinForm, self).__init__(parent)
self.resize(400, 90)
self.setWindowTitle(' Examples of signal and slot transfer parameters ')
self.open_btn = QPushButton(' Acquisition time ')
self.lineEdit_inner = QLineEdit(self)
self.lineEdit_emit = QLineEdit(self)
self.open_btn.clicked.connect(self.open_dialog)
self.lineEdit_inner.setText(' Time to receive the built-in signal in the sub window ')
self.lineEdit_emit.setText(' Time of receiving custom signal of sub window ')
grid = QGridLayout()
grid.addWidget(self.lineEdit_inner)
grid.addWidget(self.lineEdit_emit)
grid.addWidget(self.open_btn)
self.setLayout(grid)
def open_dialog(self):
dialog = DateDialog(self)
''' Connect the built-in signal of the sub window with the slot function of the main window '''
dialog.datetime_inner.dateTimeChanged.connect(self.deal_inner_slot)
''' Connect the custom signal of the sub window with the slot function of the main window '''
dialog.Signal_OneParameter.connect(self.deal_emit_slot)
dialog.show()
def deal_inner_slot(self, date):
self.lineEdit_inner.setText(date.toString())
def deal_emit_slot(self, date_str):
self.lineEdit_emit.setText(date_str)
if __name__ == "__main__":
app = QApplication(sys.argv)
form = WinForm()
form.show()
sys.exit(app.exec())
7、 Signal and slot And Event handling mechanism
Signals and slots can be said to be high-level encapsulation of event processing mechanism , If events are used to create window controls , Then the signal and slot are used to use this control , Like a button , When we use buttons , Only care about clicked The signal , As for how this button accepts and controls mouse click events , Then send this signal , Don't care , But if you want to reload a button , It's time to care , For example, it can change its behavior : Trigger when the mouse is pressed clicked The signal , Instead of releasing
Common event types
qt Programs are event driven , Every action of it is triggered by an event behind the scenes ,Qt There are many types of events , The common ones are as follows
- Keyboard events : Press and release the key
- Mouse events : The movement of the mouse pointer , Press and release the mouse button
- Drag and drop Events : Drag and drop with the mouse
- Wheel event : Scroll with the mouse wheel
- Screen drawing event : Redraw some parts of the screen
- Timing events : When the timer expires
- "Event" : Keyboard focus moves
- Entry and exit events : Move the mouse pointer into Widget Inside , Or move out
- Mobile event :Widget The position of
- Size change event :widget Size change of
- Show and hide Events :widget Show and hide
- Window events : Whether the window is the current window
There are also some common qt event , such as Socket event , The shear board event , Font change event , Layout change event
Use the method of event handling
pyqt The following is provided 5 A method of event processing and filtering ( From weak to strong ), Only the first two methods are used most frequently
1. Re implement event functions
such as mousePressEvent(),keyPressEvent(),paintEvent(), This is the most common event handling method
2. Re actualize QObject.event()
Generally used in pyqt Without providing a handler for this event , That is, when a new event is added
3. Install event filter
If the QObject call installEventFilter, Is equivalent to this QObject Installed an event filter , about QObject For all events , They are passed to the event filter function first eventFilter in , In this function , We can discard or modify these events , For example, use a custom processing mechanism for the events you are interested in , Use the default event handling mechanism for other events , Because this method will call installEventFilter All of the QObject To filter events , Therefore, if there are many events to filter , It will reduce the performance of the program
4. stay QApplication Install event filters in
This method is more powerful than the previous one ,QApplication The event filter of will capture all QObject event , And the first to get the event , in other words , Before sending the event to any other event filter , Will be sent to QApplication Event filters
5. Re actualize QApplication Of notify() Method
pyqt Use notify To distribute Events , To capture events before any event handler , The only way is to re implement QApplication Of notify(), In practice , This method is only used in debugging
Example : Classic case
Draw the event
Window resizing Events
Mouse release
Mouse movement events
Keyboard press event
heavy load tab key
import sys
from PySide6.QtCore import (QEvent, QTimer, Qt)
from PySide6.QtWidgets import (QApplication, QMenu, QWidget)
from PySide6.QtGui import QPainter
class Widget(QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
# Initialization data
# Mouse click False
self.justDoubleClicked = False
# Key , The output text , Prompt message is empty
self.key = ""
self.text = ""
self.message = ""
# Set the initial size and position of the window
self.resize(400, 300)
self.move(100, 100)
# Set title
self.setWindowTitle("Events")
# Timer 1 Execute the slot function in seconds
QTimer.singleShot(1000, self.give_help)
# Avoid the effect of window size redrawing Events , You can put the parameters 0 Change to 3000(3 second ), And then it's running , You can understand the meaning of this line of code .
def give_help(self):
self.text = " Please click here to trigger the tracking mouse function "
# Redraw events , That is to trigger paintEvent function .
self.update()
''' Re implement the shutdown event '''
def closeEvent(self, event):
print("Closed")
''' Re implement context menu events '''
def contextMenuEvent(self, event):
# Instantiate menu , Add submenu one two And add shortcut key function , Correlation slot function
menu = QMenu(self)
one_action = menu.addAction("&One")
two_action = menu.addAction("&Two")
one_action.triggered.connect(self.one)
two_action.triggered.connect(self.two)
# If message It's empty , perform
if not self.message:
# Add a split line to the menu
menu.addSeparator()
# Add from menu three, Correlation slot function
threeAction = menu.addAction("Thre&e")
threeAction.triggered.connect(self.three)
# The menu bar appears in the mouse position
menu.exec_(event.globalPos())
''' Context menu slot function '''
def one(self):
self.message = "Menu option One"
self.update()
def two(self):
self.message = "Menu option Two"
self.update()
def three(self):
self.message = "Menu option Three"
self.update()
''' Re implement drawing events '''
def paintEvent(self, event):
text = self.text
i = text.find("\n\n")
if i >= 0:
text = text[0:i]
# If the keyboard button is triggered , Record the button information in the text information .
if self.key:
text += "\n\n You pressed : {0}".format(self.key)
painter = QPainter(self)
painter.setRenderHint(QPainter.TextAntialiasing)
# Draw the content of the message text
painter.drawText(self.rect(), Qt.AlignCenter, text)
# If the message text exists, draw the message in the center at the bottom ,5 After seconds, clear the message text and redraw .
if self.message:
# Displays the text at the given coordinates , coordinate , Alignment mode . Text content
painter.drawText(self.rect(), Qt.AlignBottom | Qt.AlignHCenter,
self.message)
# 5 The function that triggers the clearing of information after seconds , And redraw the event
QTimer.singleShot(5000, self.clear_message)
QTimer.singleShot(5000, self.update)
''' Empty the slot function of message text '''
def clear_message(self):
self.message = ""
''' Re implement the resize window event '''
def resizeEvent(self, event):
self.text = " Size the window to : QSize({0}, {1})".format(
event.size().width(), event.size().height())
self.update()
''' Re implement the mouse release event '''
def mouseReleaseEvent(self, event):
# If the mouse release is double-click release , Does not track mouse movement
if self.justDoubleClicked:
self.justDoubleClicked = False
# If the mouse release is click release , You need to change the state of the tracking function , If you turn on the tracking function, you can track , If you don't turn on the tracking function, you won't track
else:
# Click the mouse
self.setMouseTracking(not self.hasMouseTracking())
if self.hasMouseTracking():
self.text = " Turn on the mouse tracking function .\n" + \
" Please move the mouse !\n" + \
" Click the mouse to turn off this function "
else:
self.text = " Turn off mouse tracking .\n" + \
" Click the mouse to turn on this function "
self.update()
''' Re implement the mouse movement event '''
def mouseMoveEvent(self, event):
# If there is no mouse double click , perform
if not self.justDoubleClicked:
# Convert window coordinates to screen coordinates
global_pos = self.mapToGlobal(event.pos())
self.text = """ Mouse position :
The window coordinates are :QPoint({0}, {1})
The screen coordinates are :QPoint({2}, {3}) """.format(event.pos().x(), event.pos().y(), global_pos.x(), global_pos.y())
self.update()
''' Re implement the mouse double click event '''
def mouseDoubleClickEvent(self, event):
self.justDoubleClicked = True
self.text = " You double clicked the mouse "
self.update()
''' Re implement the keyboard press event '''
def keyPressEvent(self, event):
self.key = ""
if event.key() == Qt.Key_Home:
self.key = "Home"
elif event.key() == Qt.Key_End:
self.key = "End"
elif event.key() == Qt.Key_PageUp:
if event.modifiers() & Qt.ControlModifier:
self.key = "Ctrl+PageUp"
else:
self.key = "PageUp"
elif event.key() == Qt.Key_PageDown:
if event.modifiers() & Qt.ControlModifier:
self.key = "Ctrl+PageDown"
else:
self.key = "PageDown"
elif Qt.Key_A <= event.key() <= Qt.Key_Z:
if event.modifiers() & Qt.ShiftModifier:
self.key = "Shift+"
self.key += event.text()
# If key Have a character , Not empty , Then draw characters
if self.key:
self.key = self.key
self.update()
# Otherwise, continue to monitor this event
else:
QWidget.keyPressEvent(self, event)
''' Re implement other events , Apply to PyQt The event handler is not provided ,Tab Key because it involves focus switching , It will not be passed on to keyPressEvent, therefore , Need to redefine here .'''
def event(self, event):
# If a key is pressed , And the key is tab key
if (event.type() == QEvent.KeyPress and
event.key() == Qt.Key_Tab):
self.key = " stay event() Capture in Tab key "
self.update()
return True
return QWidget.event(self, event)
if __name__ == "__main__":
app = QApplication(sys.argv)
form = Widget()
form.show()
app.exec()
Example 2: Use of filters
The following code means that this filter is only for label1 To deal with the incident , And only handle its mouse press event and mouse release event
import sys
from PySide6.QtGui import *
from PySide6.QtCore import *
from PySide6.QtWidgets import *
class EventFilter(QDialog):
def __init__(self, parent=None):
super(EventFilter, self).__init__(parent)
self.setWindowTitle(' Event filter ')
# Instantiate and set four label texts
self.label1 = QLabel(' Please click on ')
self.label2 = QLabel(' Please click on ')
self.label3 = QLabel(' Please click on ')
self.labelState = QLabel('test')
# Load three pictures
self.image1 = QImage('images\cartoon1.ico')
self.image2 = QImage('images\cartoon2.ico')
self.image3 = QImage('images\cartoon3.ico')
self.width = 600
self.height = 300
# Set the initial size
self.resize(self.width, self.height)
# Use personal leave filter
self.label1.installEventFilter(self)
self.label2.installEventFilter(self)
self.label3.installEventFilter(self)
# Set the window layout and add controls
layout = QGridLayout(self)
layout.addWidget(self.label1, 500, 0)
layout.addWidget(self.label2, 500, 1)
layout.addWidget(self.label3, 500, 2)
layout.addWidget(self.labelState, 600, 1)
def eventFilter(self, watched, event):
# Processing and filtering mechanism for event one
if watched == self.label1:
if event.type() == QEvent.MouseButtonPress:
mouseEvent = QMouseEvent(event)
if mouseEvent.buttons() == Qt.LeftButton:
self.labelState.setText(' Press the left mouse button ')
elif mouseEvent.buttons() == Qt.MidButton:
self.labelState.setText(' Press the middle mouse button ')
elif mouseEvent.buttons() == Qt.RightButton:
self.labelState.setText(' Press the right mouse button ')
# Convert picture size
transform = QTransform()
transform.scale(0.5, 0.5)
tmp = self.image1.transformed(transform)
self.label1.setPixmap(QPixmap.fromImage(tmp))
if event.type() == QEvent.MouseButtonRelease:
self.labelState.setText(' Release the mouse button ')
self.label1.setPixmap(QPixmap.fromImage(self.image1))
return QDialog.eventFilter(self, watched, event)
if __name__ == '__main__':
app = QApplication(sys.argv)
dialog = EventFilter()
app.installEventFilter(dialog)
dialog.show()
app.exec()
边栏推荐
- Opencv learning log 32 edge extraction
- Accounting regulations and professional ethics [1]
- 初入Redis
- Cost accounting [14]
- [exercise 4-1] cake distribution
- Opencv learning log 18 Canny operator
- PySide6 信号、槽
- China exterior wall cladding (EWC) market trend report, technical dynamic innovation and market forecast
- Research Report of cylindrical grinder industry - market status analysis and development prospect forecast
- 入门C语言基础问答
猜你喜欢
Information security - threat detection - detailed design of NAT log access threat detection platform
Nodejs+vue网上鲜花店销售信息系统express+mysql
程序员的你,有哪些炫技的代码写法?
渗透测试 ( 5 ) --- 扫描之王 nmap、渗透测试工具实战技巧合集
【高老师软件需求分析】20级云班课习题答案合集
TCP的三次握手与四次挥手
1010 things that college students majoring in it must do before graduation
PySide6 信号、槽
STM32 learning record: LED light flashes (register version)
MySQL import database error [err] 1273 - unknown collation: 'utf8mb4_ 0900_ ai_ ci’
随机推荐
Opencv learning log 19 skin grinding
Penetration test (1) -- necessary tools, navigation
[teacher Gao UML software modeling foundation] collection of exercises and answers for level 20 cloud class
Research Report on market supply and demand and strategy of geosynthetics industry in China
Find 3-friendly Integers
【练习-1】(Uva 673) Parentheses Balance/平衡的括号 (栈stack)
Cost accounting [14]
Cost accounting [16]
[exercise-2] (UVA 712) s-trees
Research Report on market supply and demand and strategy of Chinese graphic screen printing equipment industry
信息安全-威胁检测引擎-常见规则引擎底座性能比较
Truck History
Cost accounting [14]
HDU - 6024 Building Shops(女生赛)
[exercise-5] (UVA 839) not so mobile (balance)
渗透测试 ( 3 ) --- Metasploit Framework ( MSF )
对iptables进行常规操作
Indonesian medical sensor Industry Research Report - market status analysis and development prospect forecast
数据在内存中的存储&载入内存,让程序运行起来
Opencv learning log 31 -- background difference