Python Forum
Simple printing the text for a QLineEdit
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Simple printing the text for a QLineEdit
#13
A subclass inherits methods from it's superclass. It does not inherit objects.

Unlike C++, Python inheritance is only about methods. When you declared enterNewHardware is a subclass of hardwareTab, enterNewHardware inherited all the methods defined by hardwareTab which inherited all the methods defined by QWidget and so on an so forth all the way back to class object. No instance variables are inherited.

You are probably wondering "What about all the labels and buttons and stuff in hardwareTab. Don't I inherit those? The answer is no. Inheritance does not make instance variables. For proof I subclassed HardwareTab like this and created an instance of the new class.
class EnhancedHardwareTab(HardwareTab):
    def __init__(self):
        self.x = 5
        print(self.x)
Notice that the __init__ method does not call the __init__ method for the superclass. This is a necessary error to make my point.

I set a breakpoint inside the HardwareTab.__init__ method and inside the EnhancedHardwareTab.__init__ method. This is what was returned when I asked for all the instance variables defined in a HardwareTab.
Output:
self.__dict__ {'enButton': <PySide2.QtWidgets.Q...24715E5C0>, 'snTextBox': <PySide2.QtWidgets.Q...24715E500>}
This is what was returned when I asked for all the instance variables defined in an EnhancedHardwareTab.
Output:
self.__dict__ {'x': 5}
EnhancedHardwareTab does not "inherit" the enButton and snTextBox from HardwareTab. But if, inside the EnhancedHardwareTab.__init__ I had called super().__init__() the HardwareTab.__init__ would create those objects for me. If I modify EnhancedHardwareTab to call super().__init__ the "inherited" attributes magically appear.
Output:
self.__dict__ {'enButton': <PySide2.QtWidgets.Q...D0265EC00>, 'snTextBox': <PySide2.QtWidgets.Q...D0265EB40>, 'x': 5}
The attributes common to HardwareTab and EnhancedHardwareTab are not created by inheritance, but rather by calling an inherited method. You might say this is just semantics, but it is very important semantics. Especially when describing why inheritance does not create shared instance variables.

When you created an instance of hardwareTab and added it to the tab view, the hardwareTab.__init__ method created a bunch of QLabels, QLineEdits and a QButton. This is a method/function calling code that creates instances of QtWidgets. When you press the enButton in your code it created an instance of enterNewHardware class. Creating a new instance resulted in calling hardwareTab.__init__, which created a bunch of QLabels, QLineEdits and QButtons. But these are no the same widgets that appear in the hardwareTab you previously created. These were different widgets. The only similarity between the hardwareTab object widgets and the enterNewHardware object widgets is that their attribute names are the same.

What I did in my code was pass the hardwareTab object that you added to the tab control, as an argument to the newHardware function. I didn't pass a new instance of the class, or a new instance of an inherited class. I passed the actual object that contains the widgets you see on the screen. If you doubt me, try this slightly modified code.
from PySide2.QtWidgets import QPushButton, QLineEdit, QApplication, \
    QMainWindow, QWidget, QVBoxLayout, QTabWidget
import sys
  
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.tabForm = QTabWidget()
        self.tabForm.addTab(HardwareTab(), "Hardware")
        self.tabForm.addTab(HardwareTab(), "Software")
        self.setCentralWidget(self.tabForm)
  
class HardwareTab(QWidget):
    def __init__(self):
        super().__init__()
        self.snTextBox = QLineEdit()
        self.enButton = QPushButton("ENTER NEW HARDWARE")
  
        layout = QVBoxLayout(self)
        layout.addWidget(self.snTextBox)
        layout.addWidget(self.enButton)
  
        self.enButton.clicked.connect(lambda: newHardware(self))
  
def newHardware(tab):
    print(tab.snTextBox.text())
  
if __name__ == "__main__":
    APP = QApplication(sys.argv)
    WINDOW = MainWindow()
    WINDOW.show()
    sys.exit(APP.exec_())
This code creates two instances of the same class. It labels one Hardware and the other Software. Enter text in the Hardware tab and press the button. What get's printed? Do the same thing in the SOftware tab. but enter different text. What get's printed? Switch back and forth between the tabs, pressing the button. Does the print always match the text in the window?

Lambda expressions:
If you want to write GUI programs you need to get comfortable with lambda expressions. Rarely does the signature of a Qt Signal callback match the function I want to call. For example, there is no Qt Signal that I can use for a pushbutton to call a function with a hardwareTab argument. This is where lambda is useful. This code tells the Pushbutton that I want it to call "newHardware" and pass "self" as the first argument.
self.enButton.clicked.connect(lambda: newHardware(self))
Notice that I am using parenthesis and passing an argument. Lambda lets you do this. Normally following the function name with parenthesis would call the function and the return value would be bound to the clicked signal. But the evaluation of a lambda expression is delayed. The expression following the lambda is not evaluated until the button is pressed. This lets me change the signature from what the signal wants to what my function is using. I can describe this in greater detail, but some independent study of lambda expressions and their use would provide greater returns.
thewolf likes this post
Reply


Messages In This Thread
RE: Simple printing the text for a QLineEdit - by deanhystad - Mar-06-2021, 05:55 AM

Possibly Related Threads…
Thread Author Replies Views Last Post
  [PyQt] QLineEdit Caret (Text Cursor) Transparency malonn 5 3,002 Nov-04-2022, 09:04 PM
Last Post: malonn
  How to accept only float number in QLineEdit input ism 5 29,034 Jul-06-2021, 05:23 PM
Last Post: deanhystad
  PyQt5: How to retrieve a QLineEdit by its name ? arbiel 4 8,151 Oct-21-2020, 02:35 PM
Last Post: arbiel
  Two QlineEdit box, which interrelated GMCobraz 1 2,500 Aug-14-2020, 07:15 PM
Last Post: deanhystad
  [PyQt] Dynamically add and remove QLineEdit's GMCobraz 3 7,327 Jun-23-2020, 07:01 PM
Last Post: Yoriz
  prompt for input in qlineedit GMCobraz 3 3,318 Jun-22-2020, 01:51 PM
Last Post: GMCobraz
  [PyQt] display content from left to right in QComboBox or QLineEdit mart79 2 2,401 May-30-2020, 04:38 PM
Last Post: Axel_Erfurt
  How to loop through all QLineEdit widgets on a form JayCee 6 6,894 Apr-03-2020, 12:15 AM
Last Post: JayCee
  [PyQt] How to clear multiple Qlineedit in a loop mart79 6 7,964 Aug-15-2019, 02:37 PM
Last Post: Denni
  How to validate multiple QLineEdit widgets without addressing them separately? mart79 3 4,379 Aug-08-2019, 12:50 PM
Last Post: Denni

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020