0

First, please let me explain the situation.

I have a QVBoxLayout, which contains two QHBoxLayout, one of them has a QLineEdit and a QPushButton, another has a single QLabel, which should be filled with the text of QLineEdit when button is pressed. That's it.

I know, how to handle buttonClicked event, how to get the value of QEditText and all that.

The main problem here is, how do I access the QLabel and QLineEdit instance inside the buttonClicked event handler, specially when they are child of separate BoxLayout.

I have already solved this problem by defining them as class variables, so can access them from anywhere. But this is not a good design apparently. So, I am looking for a recommended way to solve this particular problem.

My Code:

import sys
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QHBoxLayout, QLabel, QWidget, QPushButton, QLineEdit

class Example(QWidget):

    def __init__(self):
        super().__init__()
        self.setUI()

    def setUI(self):
        h1box = QHBoxLayout()

        line_edit = QLineEdit()
        button = QPushButton("Submit")
        button.clicked.connect(self.buttonClicked)            

        h1box.addWidget(line_edit)
        h1box.addWidget(button)

        h2box = QHBoxLayout()
        label = QLabel("0")
        h2box.addWidget(label)

        vbox = QVBoxLayout()

        vbox.addLayout(h1box)
        vbox.addLayout(h2box)
        self.setLayout(vbox)
        self.show()

    def buttonClicked(self):
        # label needs to be filled with LineEdit value 

app = QApplication(sys.argv)
ex = Example()

sys.exit(app.exec_())
Ahsanul Haque
  • 10,676
  • 4
  • 41
  • 57
  • 1
    Why do you say that by placing these elements as class variables, it is not a part of a good design? – eyllanesc Dec 10 '16 at 15:40
  • use `self.` to creat instance variables and then you will have access in other method. it is recomended way. – furas Dec 10 '16 at 15:42
  • @furas, Okay, I have already solved it with the exactly same way as yours. I just got the feeling that things are gettinging dirty if my UI is too complex and I end up with bunch of instance variable. Actually I thought there is some way (may be some dot notation like things) to access the childs from the parent widget/layout, that's it. Thanks to both of you. – Ahsanul Haque Dec 10 '16 at 15:53
  • probably you can use dot notation to get parent and later its child but this child still may need `self.` - without `self.` is it only local variable which doesn't exists after you run `setUI`. And it will be long line - direct access can be more readable. Or maybe you could send label as line_edit as arguments to `buttonClicked` – furas Dec 10 '16 at 15:55
  • Can you give a reference for "this is not a good design apparently"? I have my doubts that someone actually said that. – ImportanceOfBeingErnest Dec 10 '16 at 17:45

2 Answers2

0

You seem to be confusing the terms class variable and instance variable.

The former is an attribute of the class, and is potentially shared between all instances of the class; whereas the latter is an attribute of the instance, and is normally unique to each instance. A class attribute can be accessed directly via the class object itself (meaning it is usually available in the global namespace); whereas an instance attribute must be accessed via a specific instance (and thus is not normally globally available).

In PyQt/PySide applications, it is completely normal and accepted practice to use instance variables. Pretty much every example and tutorial you will see uses them, and that is what you should also use to solve your own current problem.

Class variables are most commonly used as global constants. So for example in Qt there are many enums that are accessible via the class (e.g. QPalette.Background). If you've read that defining class variables is bad design, it's probably in the context of using them as global state variables - which is generally considered to be bad practice in most programming languages.

Community
  • 1
  • 1
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
0

Sir, there are a million ways of doing that. I don't know if you want in this way, but here is a little example.

import sys
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QHBoxLayout, QLabel, QWidget, QPushButton, QLineEdit

class Example(QWidget):
    line_edit = None
    button = None
    h1box = None
    h2box = None
    vbox = None
    label = None

    def __init__(self):
        super().__init__()
        self.setUI()

    def setUI(self):
        self.h1box = QHBoxLayout()

        self.line_edit = QLineEdit()
        self.button = QPushButton("Submit")
        self.button.clicked.connect(self.buttonClicked)

        self.h1box.addWidget(self.line_edit)
        self.h1box.addWidget(self.button)

        self.h2box = QHBoxLayout()
        self.label = QLabel("0")
        self.h2box.addWidget(self.label)

        self.vbox = QVBoxLayout()

        self.vbox.addLayout(self.h1box)
        self.vbox.addLayout(self.h2box)
        self.setLayout(self.vbox)
        self.show()

    def buttonClicked(self):
        self.label.setText(self.line_edit.text())
        pass

if __name__ == '__main__':

    app = QApplication(sys.argv)
    exemp = Example()
    exemp.showMaximized()
    sys.exit(app.exec_())
yurisnm
  • 1,630
  • 13
  • 29
  • You could also subclass each of your items and handle the events inside of itself what would make your code much more organized and all that.. ") – yurisnm Dec 12 '16 at 12:05