0

I have a button in widget widget which is a central widget of MyApp class, which inherits from QMainWindow. I have connected widget's button to MyApp's method called logic. This is fine, because if I write a method in my main class MyApp(QMainWindow):

def logic(self):
    sender = self.sender()
    print(sender)

... and click the button I get a message:

PyQt5.QtWidgets.QPushButton object at 0x7ff92e19eaf8

My question is how can I from MyApp's method called logic access to its child object like MyApp.widget.saltLine which is a QLineEdit object? I need to read that line.

class MyApp(QMainWindow):

    def __init__(self, parent=None):
        super().__init__(parent)
        self.initui()

    def initui(self):
        self.setMinimumSize(500, 150)

        # create central widget
        widget = QWidget()

        # lines for entering data
        widget.saltLabel = QLabel("Salt:")
        widget.hashSunkenLabel = QLabel()
        widget.passwordLine = QLineEdit()
        widget.resultButton = QPushButton("&Calculate", self)

        # set layout
        grid = QGridLayout()
        grid.addWidget(widget.saltLabel, 0, 0)
        grid.addWidget(widget.passwordLine, 1, 0)
        grid.addWidget(widget.hashSunkenLabel, 2, 0)
        grid.addWidget(widget.resultButton, 2, 1)

        # set widget a grid layout and set widget
        # as central widget of QMainWindows
        widget.setLayout(grid)
        self.setCentralWidget(widget)

        # don't know how should this look like
        widget.resultButton.clicked.connect(self.logic)

    def logic(self):
        salt = self.saltLine.text()
        password = self.passwordLine.text()
        resulting_hash = crypt.crypt(password, salt)
        self.hashSunkenLabel.setText(resulting_hash)

Or am I definig centralwidget widget wrong? If I do it without a central widget it works fine:

#!/usr/bin/env python3


import sys
import crypt
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QMainWindow, QLabel, QLineEdit, QPushButton,
    QWidget, QApplication, QSystemTrayIcon, QFrame, QGridLayout)



class MyApp(QWidget):

    def __init__(self, parent=None):
        super().__init__(parent)

        self.saltLabel = QLabel("Salt:")
        self.saltLine = QLineEdit()
        self.saltLine.setPlaceholderText("e.g. $6$xxxxxxxx")
        self.passwordLabel = QLabel("Password:")
        self.passwordLine = QLineEdit()
        self.hashLabel = QLabel("Hash:")
        self.hashSunkenLabel = QLabel()
        # widget.hashSunkenLabel.setFrameStyle(QFrame.Box | QFrame.Sunken)
        self.hashSunkenLabel.setFrameShadow(QFrame.Sunken)
        self.resultButton = QPushButton("&Calculate", self)
        self.resultButton.setMaximumSize(100, 50)

        self.initui()

    def initui(self):
        # main window size, title and icon
        self.setGeometry(300, 300, 500, 150)
        self.setWindowTitle("Password hash calculator | Linux")

        # set layout
        grid = QGridLayout()
        grid.addWidget(self.passwordLabel, 0, 0)
        grid.addWidget(self.passwordLine, 0, 1)
        grid.addWidget(self.saltLabel, 1, 0)
        grid.addWidget(self.saltLine, 1, 1)
        grid.addWidget(self.resultButton, 2, 1)
        grid.addWidget(self.hashLabel, 3, 0)
        grid.addWidget(self.hashSunkenLabel, 3, 1)
        self.setLayout(grid)

        self.resultButton.clicked.connect(self.logic)


    def logic(self):
        """
        Calculates hash from salt and password
        """
        salt = self.saltLine.text()
        password = self.passwordLine.text()
        resulting_hash = crypt.crypt(password, salt)
        self.hashSunkenLabel.setText(resulting_hash)
        # sender = self.sender()
        # print(sender)
        # print(dir(MyApp))


def main():
    app = QApplication(sys.argv)
    instance = MyApp()
    instance.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()
Hrvoje T
  • 3,365
  • 4
  • 28
  • 41
  • So - did you try it? What happened? – ekhumoro Feb 08 '17 at 23:47
  • When I press the button I get: `AttributeError: 'MyApp' object has no attribute 'saltLine'`. And I know it doesn't have. Widget object has it. – Hrvoje T Feb 09 '17 at 06:26
  • 1
    The `widget` doesn't have it either. I think you are confusing yourself by making the other widgets attributes of the central widget. It's much simpler if you make eveything an attribute of `MyApp`. Then you can access eveything via `self`. – ekhumoro Feb 09 '17 at 17:24
  • @ekhumoro Thanks. Now I see it that naming widget.Label something doesn't make it its attribute. I made it without a central widget, but stil curious how to make it with it. – Hrvoje T Feb 09 '17 at 17:53
  • Actually, it *does* make it the widget's attribute. But then you can't acces it via `self`, because `self` isn't the widget. In your first example, there is no attribute called `saltLine` anywhere. Did you perhaps mean to use `saltLabel`? But even so, it is unwise to make `saltLabel` an attribute of `widget`, because you can't then access it via `self`. – ekhumoro Feb 09 '17 at 18:38
  • @ekhumoro It is there I just didn't copy everything in the example. So, widget=QWidget() is an independent object. How to call then its attribute inside MyApp logic method, widget.saltLabel? If this is true, then how to connect it widget.resultButton.clicked.connect(self.logic)? – Hrvoje T Feb 09 '17 at 18:50
  • As I've said twice before, **do not** make `saltLabel` (or whatever) an attribute of `widget` - make it an attribute of `self` (i.e. `MyApp`). It really is as a simple as that. – ekhumoro Feb 09 '17 at 19:03
  • Actually, I did `saltLabel` an attribute of `widget`. Then I added widget as a central widget of `QMainWindow`. I need QMainWindow because of `menuBar()`. And I can connect widget button with a logic function like this `self.widget.resultButton.clicked.connect(self.logic)`. I had gotcha moment today with a scope of a variable. This helped me http://stackoverflow.com/questions/5690888/variable-scopes-in-python-classes – Hrvoje T Feb 11 '17 at 23:05

0 Answers0