Make it change QLabel

1

I am practicing with PyQt and I have done an exercise that prints on the console which button I press, then I wanted to change it so that it appears in QLabel , pro gives me an error

  

File "call.pyw", line 30, in b1_clicked       self.txt1.setText ("You pressed the First Button") NameError: name 'self' is not defined

This is the code:

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

def window() :
   app = QApplication(sys.argv)
   win = QDialog()
   #label
   txt1 = QLabel(win)
   txt1.setGeometry(30,10,150,30)
   txt1.setText("Presione un Boton...")

   #primer boton
   b1 = QPushButton(win)
   b1.setText("Button1")
   b1.move(70,50)
   b1.clicked.connect(b1_clicked)
   #segundo boton
   b2 = QPushButton(win)
   b2.setText("Button2")
   b2.move(70,70)
   QObject.connect(b2,SIGNAL("clicked() "),b2_clicked)

   win.setGeometry(100,100,300,200)
   win.setWindowTitle("PyQt")
   win.show()
   sys.exit(app.exec_() )

def b1_clicked() :
   txt1.setText("Presionaste el Primer Boton")

def b2_clicked() :
   txt1.setText("Presionaste el Segundo Boton")

if __name__ == '__main__':
   window()
    
asked by Marco Salazar 06.10.2017 в 17:46
source

1 answer

0

The problem is that your object tex1 is a local variable, belonging to your function window , which can only be accessed from this function. So that your b1_clicked and b2_clicked functions can access this object and use its methods you must make it accessible to these functions. There are several options, one of them is to use global variables (usually better avoid them), the other option is to pass these two functions as an argument to the object tex1 (using functions lambda or functools.partial ):

import sys
from functools import partial
from PyQt4.QtCore import *
from PyQt4.QtGui import *

def window() :
   app = QApplication(sys.argv)
   win = QDialog()
   #label
   txt1 = QLabel(win)
   txt1.setGeometry(30,10,150,30)
   txt1.setText("Presione un Boton...")

   #primer boton
   b1 = QPushButton(win)
   b1.setText("Button1")
   b1.move(70,50)
   b1.clicked.connect(partial(b1_clicked,  txt1))
   #segundo boton
   b2 = QPushButton(win)
   b2.setText("Button2")
   b2.move(70,70)
   b2.clicked.connect(partial(b2_clicked,  txt1))

   win.setGeometry(100,100,300,200)
   win.setWindowTitle("PyQt")
   win.show()
   sys.exit(app.exec_() )

def b1_clicked(widget) :
   widget.setText("Presionaste el Primer Boton")

def b2_clicked(widget) :
   widget.setText("Presionaste el Segundo Boton")

if __name__ == '__main__':
   window()

Although it works, using structured programming complicates life a lot when the app is moderately complex. Using object-oriented programming is in principle ideal, and in many cases, almost essential if we do not want to complicate our lives unnecessarily.

You must always avoid (only in very specific cases they should be used) the import of the form from modulo import* . It hinders the readability of the code, populates the namespace unnecessarily and opens up the possibility of collisions between imported modules or with identifiers of the module itself.

Using POO and keeping the above in mind, the code could be like this:

# Importamos modulos necesarios
import sys
from PyQt4 import QtGui 


# Creamos nuestra clase Window que en este caso hereda de QtDialog   
class Window(QtGui.QDialog):

    # Metodo especiar __init__, inicializador que es ejecutado nada mas instanciar
    def __init__(self,  parent = None):

        # usamos super para llamar al __init__ de la clase padre
        super(Window, self).__init__(parent)
        self.parent = parent
        self.setGeometry(100,100,300,200)
        self.setWindowTitle("PyQt")

        #label
        self.txt1 = QtGui.QLabel(self)
        self.txt1.setGeometry(30,10,150,30)
        self.txt1.setText("Presione un Boton...")
        self.txt1.adjustSize()
        #primer boton
        self.b1 = QtGui.QPushButton(self)
        self.b1.setText("Button1")
        self.b1.move(70,50)
        self.b1.clicked.connect(self.b1_clicked)
        #segundo boton
        self.b2 = QtGui.QPushButton(self)
        self.b2.setText("Button2")
        self.b2.move(70,80)
        self.b2.clicked.connect(self.b2_clicked)
        self.show()

    def b1_clicked(self) :
        self.txt1.setText("Presionaste el Primer Boton")
        self.txt1.adjustSize() 

    def b2_clicked(self) :
        self.txt1.setText("Presionaste el Segundo Boton")
        self.txt1.adjustSize() 

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    ui = Window()
    sys.exit(app.exec_())

self refers to the instance of the class, in our case it will be an instance of our class Window , which when inheriting from QtDialog inherits all its methods and attribute.

More information about self and super :

What is the difference? between self and super (Class, self)?

And about __init__ :

Hesitate with classes. What is the use of __init__?

    
answered by 06.10.2017 / 20:24
source