Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Access a label from main
Forum Updated to NodeBB v4.3 + New Features

Access a label from main

Scheduled Pinned Locked Moved Solved Qt for Python
11 Posts 3 Posters 1.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • I Offline
    I Offline
    Igor86
    wrote on last edited by
    #1

    Hello everybody!
    I am completely new to python and also to QT.
    Below is part of my code. I would like to set the label (marked by an arrow) to the value returned by the function executed in the main class. my code returns AttributeError: type object 'MainTab' has no attribute 'label'.

    Could somebody please help me out on this?

    Any help appreciated!

    Thank you!

    class App(QMainWindow):
        def __init__(self):
            super().__init__()
            self.setMinimumSize(800, 500)
            self.tab_widget = TabWidget(self)
            self.setCentralWidget(self.tab_widget)
            self.show()
    
    class TabWidget(QWidget):
        def __init__(self, parent):
            super(QWidget, self).__init__(parent)
            self.layout = QVBoxLayout(self)
            self.tabs = QTabWidget()
            self.tabs.addTab(MainTab(), "Main")
            self.tabs.resize(500, 200)
    
            # Add tabs to widget
            self.layout.addWidget(self.tabs)
            self.setLayout(self.layout)
    
    class MainTab(QDialog):
        def __init__(self, parent=None):
            super().__init__()
            self.originalPalette = QApplication.palette()
    
            self.mainLayout = QHBoxLayout()
    
            self.buttonLayout = QVBoxLayout()
            buttonMsg = QPushButton("test button")
    
            self.buttonLayout.addWidget(buttonMsg)
            self.mainLayout.addLayout(self.buttonLayout)
    
            self.label = QLabel(self)       # <--------------------------------------------
    
      #  pixmap = QPixmap('test.jpg')
      #  self.label.setPixmap(pixmap)
        self.label.setStyleSheet("border: 1px solid black;")
        self.label.setAlignment(Qt.AlignCenter)
    
        self.mainLayout.addWidget(self.label)
        self.setLayout(self.mainLayout)
    
    
    def main():
        check_requirements(exclude=('tensorboard', 'thop'))
    
        im0 = yoloRun.run()
        height, width, channel = im0.shape
        bytesPerLine = 3 * width
        qImg = QImage(im0.data, width, height, bytesPerLine, QImage.Format_RGB888)
        pixmap = QPixmap(qImg)
        MainTab.label.setPixmap(pixmap)  # <--------- FROM HERE I WOULD LIKE TO PUT PIXMAP AS BACKGROUND
    
    if __name__ == '__main__':
        t1 = threading.Thread(target=main)
        t1.start()
        app = QApplication([])
        app.setStyle('Fusion')
        app.setApplicationName('KiTest')
        ex = App()
        app.exec()
    
    jsulmJ 1 Reply Last reply
    0
    • I Igor86

      Hello everybody!
      I am completely new to python and also to QT.
      Below is part of my code. I would like to set the label (marked by an arrow) to the value returned by the function executed in the main class. my code returns AttributeError: type object 'MainTab' has no attribute 'label'.

      Could somebody please help me out on this?

      Any help appreciated!

      Thank you!

      class App(QMainWindow):
          def __init__(self):
              super().__init__()
              self.setMinimumSize(800, 500)
              self.tab_widget = TabWidget(self)
              self.setCentralWidget(self.tab_widget)
              self.show()
      
      class TabWidget(QWidget):
          def __init__(self, parent):
              super(QWidget, self).__init__(parent)
              self.layout = QVBoxLayout(self)
              self.tabs = QTabWidget()
              self.tabs.addTab(MainTab(), "Main")
              self.tabs.resize(500, 200)
      
              # Add tabs to widget
              self.layout.addWidget(self.tabs)
              self.setLayout(self.layout)
      
      class MainTab(QDialog):
          def __init__(self, parent=None):
              super().__init__()
              self.originalPalette = QApplication.palette()
      
              self.mainLayout = QHBoxLayout()
      
              self.buttonLayout = QVBoxLayout()
              buttonMsg = QPushButton("test button")
      
              self.buttonLayout.addWidget(buttonMsg)
              self.mainLayout.addLayout(self.buttonLayout)
      
              self.label = QLabel(self)       # <--------------------------------------------
      
        #  pixmap = QPixmap('test.jpg')
        #  self.label.setPixmap(pixmap)
          self.label.setStyleSheet("border: 1px solid black;")
          self.label.setAlignment(Qt.AlignCenter)
      
          self.mainLayout.addWidget(self.label)
          self.setLayout(self.mainLayout)
      
      
      def main():
          check_requirements(exclude=('tensorboard', 'thop'))
      
          im0 = yoloRun.run()
          height, width, channel = im0.shape
          bytesPerLine = 3 * width
          qImg = QImage(im0.data, width, height, bytesPerLine, QImage.Format_RGB888)
          pixmap = QPixmap(qImg)
          MainTab.label.setPixmap(pixmap)  # <--------- FROM HERE I WOULD LIKE TO PUT PIXMAP AS BACKGROUND
      
      if __name__ == '__main__':
          t1 = threading.Thread(target=main)
          t1.start()
          app = QApplication([])
          app.setStyle('Fusion')
          app.setApplicationName('KiTest')
          ex = App()
          app.exec()
      
      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @Igor86 said in Access a label from main:

      MainTab.label.setPixmap(pixmap)

      How should this work? MainTab is a class, you need an instance of it to set the label.
      Your main() function (strange name for a function by the way) should rather return the pixmap and not set anything. Then call this method in MainTab constructor and set the pixmap it returns in the label.

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • I Offline
        I Offline
        Igor86
        wrote on last edited by
        #3

        Thank you, not sure I understood completely what you mean.

        the idea was this: "main" is the main program thread that runs on its own thread, and awaits for a external trigger. the trigger starts a image aquisition that is returned by yoloRun.run() and stored into im0. this will then all be inside a whie loop to start again. the task should not end, it should always be waiting for some images...

        so if my main() function is not going to return as long as the software runs, is there a workaround?

        THANK YOU!

        JonBJ 1 Reply Last reply
        0
        • I Igor86

          Thank you, not sure I understood completely what you mean.

          the idea was this: "main" is the main program thread that runs on its own thread, and awaits for a external trigger. the trigger starts a image aquisition that is returned by yoloRun.run() and stored into im0. this will then all be inside a whie loop to start again. the task should not end, it should always be waiting for some images...

          so if my main() function is not going to return as long as the software runs, is there a workaround?

          THANK YOU!

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @Igor86

          @jsulm said in Access a label from main:

          @Igor86 said in Access a label from main:

          MainTab.label.setPixmap(pixmap)

          How should this work? MainTab is a class, you need an instance of it to set the label.

          You do need to understand what @jsulm said! You need to understand the difference between a class and an instance in Python to achieve anything. (Google it if you don't.)

          You do not create any instance of your class MainTab, so there is no dialog created to do anything on or show.

              t1 = threading.Thread(target=main)
              t1.start()
          

          I have no idea what you are intending to do or why. Threading is the very last thing you should be trying to use. Also in Qt you cannot access any UI elements from anything but the main thread (where you create your QApplication here). I would doubt you could any of what you have to work as it is even if you sort out e.g. your dialog issue. You will not be able to do at least these lines in your thread:

              pixmap = QPixmap(qImg)
              MainTab.label.setPixmap(pixmap)  # <--------- FROM HERE I WOULD LIKE TO PUT PIXMAP AS BACKGROUND
          

          At best you could perhaps get your QImage in a thread; you would then need to send that as a parameter in a signal from the thread which the main UI/application thread receives in a slot and does the QPixmap manipulation and display there.

          1 Reply Last reply
          2
          • I Offline
            I Offline
            Igor86
            wrote on last edited by
            #5

            Thank you JonB, will google it right away and try to understand this.

            I used threads because run() starts a camera aquisition, and then waits for a hardware trigger. without threads the whole app freezes until the trigger arrives. (sometimes it takes a few ms, sometimes 30 minutes.. its a external signal going to the camera not controlled by me..) the IDEA (looks like my idea is not the best.. :D ) would be that this second thread works in background and does nothing but waitig for a trigger and sending the image back. once sent back it restarts and waits for the next trigger. the base thread would do all the rest such as the UI, the TCP comunication etc..

            JonBJ 1 Reply Last reply
            0
            • I Igor86

              Thank you JonB, will google it right away and try to understand this.

              I used threads because run() starts a camera aquisition, and then waits for a hardware trigger. without threads the whole app freezes until the trigger arrives. (sometimes it takes a few ms, sometimes 30 minutes.. its a external signal going to the camera not controlled by me..) the IDEA (looks like my idea is not the best.. :D ) would be that this second thread works in background and does nothing but waitig for a trigger and sending the image back. once sent back it restarts and waits for the next trigger. the base thread would do all the rest such as the UI, the TCP comunication etc..

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #6

              @Igor86
              Yes, I understand you may indeed need to use a background thread for your camera acquisition here. I just drew attention to the fact that using threads in Qt UIs is one of the hardest things to get right.

              You will indeed need to do some reading about "Qt and threads"; there are various approaches to designing them.

              What remains true, however, is that they cannot access UI elements. That would include your dialog or label, when you get those sorted out. They can access/use QImages, because those are not UI-dependent, but not QPixmaps, which are UI-dependent. The usual technique is for a thread to emit a signal with whatever necessary as a parameter, with the UI thread reacting that by doing whatever needs to be done with it on the UI side.

              1 Reply Last reply
              0
              • I Offline
                I Offline
                Igor86
                wrote on last edited by
                #7

                Thank you JonB, I am already reading into it and watching vids,will report back when it works. you helped me a lot.. thank you again for your time!

                1 Reply Last reply
                0
                • I Offline
                  I Offline
                  Igor86
                  wrote on last edited by
                  #8

                  Hello! It works now! :) i replaced the Thread with QtThread and implemented the signals to pass the iamge and some values to a function that sets everything on the UI.

                  The only problem I am facing now, is that I cannot set a label's text. I have 2 labels, one contains a text and a float (managed to do this one by converting the float to string) and the second has a text + a str variable.

                  The second one is not working. the program crashes as soon as it arrives there. I tried to print str and it has the correct value in it. What am I doing wrong here?

                      def setImage(self, img, classname = str, score = float):
                          height, width, channel = img.shape
                          bytesPerLine = 3 * width
                          qImg = QImage(img.data, width, height, bytesPerLine, QImage.Format_RGB888)
                          pixmap = QPixmap(qImg)
                          self.labeledPic.setPixmap(pixmap)
                          self.scoreText.setText("Score: " + f'{score:0.2f}')        
                          print(classname) 
                          self.modeltext.setText("Model: " + classname) <---- crash
                  
                  also tried: 
                          self.modeltext.setText(classname) <---- crash
                  
                  JonBJ 1 Reply Last reply
                  0
                  • I Igor86

                    Hello! It works now! :) i replaced the Thread with QtThread and implemented the signals to pass the iamge and some values to a function that sets everything on the UI.

                    The only problem I am facing now, is that I cannot set a label's text. I have 2 labels, one contains a text and a float (managed to do this one by converting the float to string) and the second has a text + a str variable.

                    The second one is not working. the program crashes as soon as it arrives there. I tried to print str and it has the correct value in it. What am I doing wrong here?

                        def setImage(self, img, classname = str, score = float):
                            height, width, channel = img.shape
                            bytesPerLine = 3 * width
                            qImg = QImage(img.data, width, height, bytesPerLine, QImage.Format_RGB888)
                            pixmap = QPixmap(qImg)
                            self.labeledPic.setPixmap(pixmap)
                            self.scoreText.setText("Score: " + f'{score:0.2f}')        
                            print(classname) 
                            self.modeltext.setText("Model: " + classname) <---- crash
                    
                    also tried: 
                            self.modeltext.setText(classname) <---- crash
                    
                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by JonB
                    #9

                    @Igor86
                    Then I don't believe you have a self.modeltext which exists, hence the "crash". What does print(self.modeltext) say? Judging by self.scoreText.... I would guess it's spelt self.modelText?! [This is why I don't like Python....]

                    I 1 Reply Last reply
                    1
                    • JonBJ JonB

                      @Igor86
                      Then I don't believe you have a self.modeltext which exists, hence the "crash". What does print(self.modeltext) say? Judging by self.scoreText.... I would guess it's spelt self.modelText?! [This is why I don't like Python....]

                      I Offline
                      I Offline
                      Igor86
                      wrote on last edited by
                      #10

                      @JonB you are absolutely right.. feeling dumb right now.. have been looking at it for over an hour... thank you sooo much all is working as expected now..

                      JonBJ 1 Reply Last reply
                      0
                      • I Igor86

                        @JonB you are absolutely right.. feeling dumb right now.. have been looking at it for over an hour... thank you sooo much all is working as expected now..

                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote on last edited by
                        #11

                        @Igor86 Use C++ for better compile-time support ;-)

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved