umrpedrod
umrpedrod

Reputation: 65

How to change the text in QPushbutton within a QButtongroup element after some user input?

I'm currently switching from using Tk in my Python scripts to PyQt to run some simple GUIs. They are intended to provide features that will be saved later in a file together with some data which will be collected after a different script is started (separate PushButton which I left out for the time being). Right now, I cannot get my head around how to change the text of some Pushbottons depending on the user's input. To be more precise I would like to display the same buttons but either with BTNS = ["1", "2", ... "8"] or BTNS = ["9", "10", ... "16"], depending upon the input of a different Pushbutton ("Right" vs. "Left"). I have tried different approaches (fetching information from findChildren within the group, using deleteLater, using the clicked argument and so on) but nothing gives the result I am looking for.

Here is a MWE of my problem.

# -*- coding: utf-8 -*-

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QFont

class App(QMainWindow):

    def __init__(self):
        super().__init__()
        self.setGeometry(50, 50, 600, 500)
        self.initUI()

    def initUI(self):

        self.MainLayout = QVBoxLayout(self)

        self.lbl1 = QLabel(self)
        self.lbl1.setText('Test1:')
        self.lbl1.move(50, 80)
        self.MainLayout.addWidget(self.lbl1)

        self.MainLayout.addWidget(self.addSideButtons())

        self.btnGroup2 = QButtonGroup(self)
        self.MainLayout.addWidget(self.StimButtons("left"))

        self.show()

    def addSideButtons(self):

        self.btnGroup1 = QButtonGroup()
        self.button1 = QPushButton(self)
        self.button2 = QPushButton(self)

        self.button1.setGeometry(90, 20, 100, 30)
        self.button1.setText("Left")
        self.button1.setCheckable(True)
        #self.button1.clicked.connect(lambda:self.StimButtons("left"))
        self.button1.setChecked(True)
        self.btnGroup1.addButton(self.button1)

        self.button2.setGeometry(200, 20, 100, 30)
        self.button2.setText("Right")
        self.button2.setCheckable(True)
        #self.button2.clicked.connect(lambda:self.StimButtons("right"))
        self.btnGroup1.addButton(self.button2)
        self.btnGroup1.setExclusive(True)

    def StimButtons(self, btn):

        if btn == "left":
            BTNS = ["1", "2", "3", "4", "5", "6", "7", "8"]
        else:
            BTNS = ["9", "10", "11", "12", "13", "14", "15", "16"]

        coords = [(150, 350), (80, 300), (150, 300), (220, 300),
                    (80, 250), (150, 250), (220, 250), (150, 200)]

        for idx, contact_bts in enumerate(BTNS):
            self.btn = QPushButton(contact_bts, self)
            self.btn.setGeometry(coords[idx][0], coords[idx][1], 60, 45)
            self.btn.setCheckable(True)
            self.btnGroup2.addButton(self.btn)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

Upvotes: 1

Views: 453

Answers (1)

eyllanesc
eyllanesc

Reputation: 244132

You must reuse the buttons instead of deleting them and creating them so you first create the buttons in a method that will only be called once. In another method you must change the text of the buttons depending on the button pressed, and for this you must send a feature that identifies the button, in this case the button pressed will be sent using the buttonClicked signal of the QButtonGroup. On the other hand as a plus I have restructured your code to use layout.

# -*- coding: utf-8 -*-

from PyQt5 import QtCore, QtGui, QtWidgets


class App(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setGeometry(50, 50, 600, 500)
        self.initUI()

    def initUI(self):
        self.m_buttons = []

        group = QtWidgets.QButtonGroup(self)
        left_button = QtWidgets.QPushButton("Left", checkable=True)
        right_button = QtWidgets.QPushButton("Right", checkable=True)
        group.addButton(left_button)
        group.addButton(right_button)
        group.buttonClicked[QtWidgets.QAbstractButton].connect(self.update_text)

        label = QtWidgets.QLabel("Test1:")

        self.m_widget = QtWidgets.QWidget()
        self.create_buttons()

        left_button.click()

        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)
        lay = QtWidgets.QVBoxLayout(central_widget)
        hlay = QtWidgets.QHBoxLayout()
        hlay.addStretch()
        hlay.addWidget(left_button)
        hlay.addWidget(right_button)
        hlay.addStretch()
        lay.addLayout(hlay)
        lay.addWidget(label)
        lay.addWidget(self.m_widget, alignment=QtCore.Qt.AlignCenter)
        lay.addStretch()

    def create_buttons(self):
        coords = [
            (4, 1),
            (3, 0),
            (3, 1),
            (3, 2),
            (2, 0),
            (2, 1),
            (2, 2),
            (0, 1),
        ]
        group = QtWidgets.QButtonGroup(exclusive=True)
        grid = QtWidgets.QGridLayout(self.m_widget)
        for coord in coords:
            btn = QtWidgets.QPushButton(checkable=True)
            btn.setFixedSize(60, 45)
            grid.addWidget(btn, *coord)
            group.addButton(btn)
            self.m_buttons.append(btn)
        self.m_widget.setFixedSize(self.m_widget.sizeHint())

    @QtCore.pyqtSlot(QtWidgets.QAbstractButton)
    def update_text(self, btn):
        text = btn.text()
        texts = {
            "Left": ["1", "2", "3", "4", "5", "6", "7", "8"],
            "Right": ["9", "10", "11", "12", "13", "14", "15", "16"],
        }
        if text in texts:
            for btn, txt in zip(self.m_buttons, texts[text]):
                btn.setText(txt)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)

    w = App()
    w.show()

    sys.exit(app.exec_())

enter image description here

enter image description here

Upvotes: 1

Related Questions