Home > Software engineering >  how to connect to signal to (from ? ) other class(pyside6)
how to connect to signal to (from ? ) other class(pyside6)

Time:07-11

How to connect to myQCustomQWidget.connectButton() to def setNewText(): ?
If is in class exampleQMainWindow i can simple call like this: self.button.clicked.connect(self.setNewText) ,but if it's another class, I have no idea how to call it up.

....................................................................................

                                             .
import sys
from PySide6 import QtGui
from PySide6.QtWidgets import *

class QCustomQWidget(QWidget):
    def __init__(self, parent=None):
        super(QCustomQWidget, self).__init__(parent)
        self.textQVBoxLayout = QVBoxLayout()
        self.textUpQLabel = QLabel()
        self.textDownQLabel = QLabel()
        self.textQVBoxLayout.addWidget(self.textUpQLabel)
        self.textQVBoxLayout.addWidget(self.textDownQLabel)
        self.allQHBoxLayout = QHBoxLayout()
        self.iconQLabel = QLabel()
        self.allQHBoxLayout.addWidget(self.iconQLabel, 0)
        self.allQHBoxLayout.addLayout(self.textQVBoxLayout, 1)
        self.setLayout(self.allQHBoxLayout)
        # setStyleSheet
        self.textUpQLabel.setStyleSheet('''
            color: rgb(0, 0, 255);
        ''')
        self.textDownQLabel.setStyleSheet('''
            color: rgb(255, 0, 0);
        ''')

        self.openButton = QPushButton()
        # self.openButton.setText("open")
        self.allQHBoxLayout.addWidget(self.openButton, 1)

    def setButton(self, index):
        self.openButton.setText(index)

    def connectButton(self, index): # <-----
        self.openButton.clicked.connect()

    def setTextUp(self, text):
        self.textUpQLabel.setText(text)

    def setTextDown(self, text):
        self.textDownQLabel.setText(text)

    def setIcon(self, imagePath):
        self.iconQLabel.setPixmap(QtGui.QPixmap(imagePath))


class exampleQMainWindow(QMainWindow):
    def __init__(self):
        super(exampleQMainWindow, self).__init__()

        # Create QListWidget
        self.table = QTableWidget(self)
        self.table.setColumnCount(3)
        self.setCentralWidget(self.table)
        self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.table.setRowCount(6)
        for index, name, icon, btname in [
            (1, 'text1', 'g:\downloads\coffee-icon.png', "alpha"),
            (2, 'text2', 'g:\downloads\coffee-icon.png', "beta"),
            (3, 'text3', 'g:\downloads\coffee-icon.png', "gamma"),
            (4, 'text4', 'g:\downloads\coffee-icon.png', "delta")
            ]:
            # Create QCustomQWidget
            myQCustomQWidget = QCustomQWidget()
            myQCustomQWidget.setTextUp(str(index))
            myQCustomQWidget.setTextDown(name)
            #myQCustomQWidget.setIcon(icon) #just image can be ignored
            myQCustomQWidget.setButton(str(btname))
            myQCustomQWidget.button_row = index

            myQCustomQWidget.connectButton()# how to connect it to setNewText ?

            self.table.setCellWidget(index, 1, myQCustomQWidget)
            self.table.setRowHeight(index,90)


    def setNewText(self): # <----------
        print("test") 



app = QApplication([])
window = exampleQMainWindow()
window.resize(800,512)
window.show()
sys.exit(app.exec())

CodePudding user response:

Create a custom signal that emits the index, then connect it from the instance that creates the widget, not the other way around.

class QCustomQWidget(QWidget):
    clicked = Signal(int)
    def __init__(self, index, name, icon, btnName, parent=None):
        super(QCustomQWidget, self).__init__(parent)
        self.index = index
        # ...
        self.openButton.clicked.connect(self.emitClicked)
        self.setTextUp(str(index   1))
        self.setTextDown(name)
        self.setIcon(icon)
        self.setButton(btnName)
    # ...

    def emitClicked(self):
        self.clicked.emit(self.index)


class exampleQMainWindow(QMainWindow):
    def __init__(self):
        # ...
        data = [
            ('text1', 'g:\downloads\coffee-icon.png', "alpha"),
            ('text2', 'g:\downloads\coffee-icon.png', "beta"),
            ('text3', 'g:\downloads\coffee-icon.png', "gamma"),
            ('text4', 'g:\downloads\coffee-icon.png', "delta")
            ]
        self.table.setRowCount(len(data))
        for index, (name, icon, btname) in enumerate(data):
            myQCustomQWidget = QCustomQWidget(index, name, icon, btnname)
            myQCustomQWidget.clicked.connect(self.setNewText)

            self.table.setCellWidget(index, 1, myQCustomQWidget)
            self.table.setRowHeight(index, 90)

    def setNewText(self, index):
        print(index)

Note that signal connections of child objects should usually be done by a parent object, not the other way around. Also, you should not use global references, especially for these situations, otherwise you might have unexpected behavior or exceptions caused by missing references.

CodePudding user response:

def connectButton(self): # <-----
    self.openButton.clicked.connect(exampleQMainWindow.setNewText)

And change this method to static since you don't use the instance (self).

@staticmethod
def setNewText(): # <----------
    print("test") 

If this wasn't a staticmethod you would want to pass a instance to the class that you want to connect to in your case it would be:

class QCustomQWidget(QWidget):
    def __init__(self, parent=None):
        super(QCustomQWidget, self).__init__(parent)
        self.main_window = parent  # not required, just to understand better.
    # ...
    def connectButton(self): # <-----
        self.openButton.clicked.connect(self.parent.setNewText)

Considered best practice. Create signals in child and in the parent connect to the method you want.

Example based on your code:

import sys
from PySide6 import QtGui
from PySide6.QtWidgets import *
from PySide6.QtCore import Signal

class QCustomQWidget(QWidget):
    ask_set_new_text = Signal()
    def __init__(self, parent=None):
        super(QCustomQWidget, self).__init__(parent)
        self.textQVBoxLayout = QVBoxLayout()
        self.textUpQLabel = QLabel()
        self.textDownQLabel = QLabel()
        self.textQVBoxLayout.addWidget(self.textUpQLabel)
        self.textQVBoxLayout.addWidget(self.textDownQLabel)
        self.allQHBoxLayout = QHBoxLayout()
        self.iconQLabel = QLabel()
        self.allQHBoxLayout.addWidget(self.iconQLabel, 0)
        self.allQHBoxLayout.addLayout(self.textQVBoxLayout, 1)
        self.setLayout(self.allQHBoxLayout)
        # setStyleSheet
        self.textUpQLabel.setStyleSheet('''
            color: rgb(0, 0, 255);
        ''')
        self.textDownQLabel.setStyleSheet('''
            color: rgb(255, 0, 0);
        ''')

        self.openButton = QPushButton()
        # self.openButton.setText("open")
        self.allQHBoxLayout.addWidget(self.openButton, 1)

    def setButton(self, index):
        self.openButton.setText(index)

    def connectButton(self): # <-----
        self.openButton.clicked.connect(lambda: self.ask_set_new_text.emit())

    def setTextUp(self, text):
        self.textUpQLabel.setText(text)

    def setTextDown(self, text):
        self.textDownQLabel.setText(text)

    def setIcon(self, imagePath):
        self.iconQLabel.setPixmap(QtGui.QPixmap(imagePath))


class exampleQMainWindow(QMainWindow):
    def __init__(self):
        super(exampleQMainWindow, self).__init__()

        # Create QListWidget
        self.table = QTableWidget(self)
        self.table.setColumnCount(3)
        self.setCentralWidget(self.table)
        self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.table.setRowCount(6)
        for index, name, icon, btname in [
            (1, 'text1', 'g:\downloads\coffee-icon.png', "alpha"),
            (2, 'text2', 'g:\downloads\coffee-icon.png', "beta"),
            (3, 'text3', 'g:\downloads\coffee-icon.png', "gamma"),
            (4, 'text4', 'g:\downloads\coffee-icon.png', "delta")
            ]:
            # Create QCustomQWidget
            myQCustomQWidget = QCustomQWidget()
            myQCustomQWidget.setTextUp(str(index))
            myQCustomQWidget.setTextDown(name)
            myQCustomQWidget.ask_set_new_text.connect(self.setNewText)
            #myQCustomQWidget.setIcon(icon) #just image can be ignored
            myQCustomQWidget.setButton(str(btname))
            myQCustomQWidget.button_row = index

            myQCustomQWidget.connectButton()# how to connect it to setNewText ?

            self.table.setCellWidget(index, 1, myQCustomQWidget)
            self.table.setRowHeight(index,90)

    def setNewText(self): # <----------
        print("test") 



app = QApplication(sys.argv)
window = exampleQMainWindow()
window.resize(800,512)
window.show()
sys.exit(app.exec())


  • Related