I have a PySide2
GUI application with a QPushButton
button with a @Slot
function connected to it. How can I share data with the function?
from PySide2.QtCore import Slot
from PySide2.QtWidgets import QApplication, QMainWindow, QWidget, QPushButton, QVBoxLayout
@Slot()
def button_XYZ_callback():
# Function which is executed when the button XYZ is clicked.
# I'd like to access the __main__s context data "parent_data" here.
pass
if __name__ == '__main__':
# parent context data what I want to access (read only)
parent_data = "blub"
application = QApplication(sys.argv)
window = QMainWindow()
central_widget = QWidget()
xyz_button = QPushButton("XYZ", central_widget)
xyz_button.clicked.connect(button_xyz_callback)
layout = QVBoxLayout(central_widget)
layout.addWidget(xyz_button)
window.show()
sys.exit(application.exec_())
Per Python's LEGB rule, the global variable parent_data
is accessible from within the button_XYZ_callback
function.
If, however, you wish to reduce the function's dependence on global variables, the standard technique is to define a class, and use class or instance attributes to store what was before global values:
# based on code from https://wiki.qt.io/Qt_for_Python_Tutorial_ClickableButton
import sys
from PySide2 import QtCore, QtWidgets, QtGui
class MyWidget(QtWidgets.QWidget):
def __init__(self, data):
QtWidgets.QWidget.__init__(self)
self.data = data
self.button = QtWidgets.QPushButton("Click me!")
self.text = QtWidgets.QLabel("Hello World")
self.text.setAlignment(QtCore.Qt.AlignCenter)
self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.text)
self.layout.addWidget(self.button)
self.setLayout(self.layout)
self.button.clicked.connect(self.button_XYZ_callback)
@QtCore.Slot()
def button_XYZ_callback(self):
print(self.data)
if __name__ == "__main__":
parent_data = "blub"
app = QtWidgets.QApplication(sys.argv)
widget = MyWidget(data=parent_data)
widget.show()
sys.exit(app.exec_())
Alternatively, if the data is known before the callback is to be defined, you could use a function factory to place the data in the enclosing scope of the callback:
import sys
from PySide2.QtCore import Slot
from PySide2.QtWidgets import QApplication, QPushButton
def make_callback(data):
@Slot()
def button_XYZ_callback():
print(data)
return button_XYZ_callback
if __name__ == "__main__":
parent_data = "blub"
# https://wiki.qt.io/Qt_for_Python_Tutorial_ClickableButton
app = QApplication(sys.argv)
button = QPushButton("Click me")
button.clicked.connect(make_callback(parent_data))
button.show()
app.exec_()