Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Need Help with OOP/my project, trouble understanding how things "connect" and work together.
Qt 6.11 is out! See what's new in the release blog

Need Help with OOP/my project, trouble understanding how things "connect" and work together.

Scheduled Pinned Locked Moved Unsolved General and Desktop
12 Posts 3 Posters 3.9k Views 1 Watching
  • 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.
  • mrjjM Offline
    mrjjM Offline
    mrjj
    Lifetime Qt Champion
    wrote on last edited by mrjj
    #2

    Hi
    A signal and slot connection are always between instantiated objects.
    The sender and receiver must both be a pointer to an instance of the class.
    ( with the exception of lambdas )

    -if my button (which is of class QPushButton/AbstractButton) can even use the members/functions(?) of other PyQt5 Classes etc.
    well yes they can. but it's not actually the button that needs access, its more the function (slot) you connected to its signal.

    But here is Qt signal & slot concept very handy.

    You can connect it's signal to more than one slot. Also to a slot in another instance of another class.

    You can also easily add a new signal to a class. Like HitPointChanged and use that signal
    to connect other instances of classes that need to know this.
    Then you simply emit this new signal and others will know.

    This allows each class to know very little about others and still "talk".

    R 1 Reply Last reply
    1
    • mrjjM mrjj

      Hi
      A signal and slot connection are always between instantiated objects.
      The sender and receiver must both be a pointer to an instance of the class.
      ( with the exception of lambdas )

      -if my button (which is of class QPushButton/AbstractButton) can even use the members/functions(?) of other PyQt5 Classes etc.
      well yes they can. but it's not actually the button that needs access, its more the function (slot) you connected to its signal.

      But here is Qt signal & slot concept very handy.

      You can connect it's signal to more than one slot. Also to a slot in another instance of another class.

      You can also easily add a new signal to a class. Like HitPointChanged and use that signal
      to connect other instances of classes that need to know this.
      Then you simply emit this new signal and others will know.

      This allows each class to know very little about others and still "talk".

      R Offline
      R Offline
      Romeoo
      wrote on last edited by
      #3

      @mrjj Hey, first off I'd like to say thank you for typing all this out!

      Now.. I want to say I understand what you're telling me, but if you're asking me to now go ahead and implement this new knowledge and edit my code so it all works, I wouldn't be able to do it.

      That's not to say your explanation is bad in any way, it's just that (as you can probably tell) I'm still pretty new to OOP & PyQt5 and I have no idea how to even approach this.

      I watched several OOP-tutorials and can do the stuff they always show off in these (most of them show the Class Person example with multiple other Classes (Manager, Employee etc.) inheriting from Person.. all its methods and properties). Simple enough.

      But when I look at this and try to rewrite my code so it works... or think about how I'd code what you're telling me, I'm just lost & scratching my head, honestly. Sorry

      mrjjM 1 Reply Last reply
      0
      • R Romeoo

        @mrjj Hey, first off I'd like to say thank you for typing all this out!

        Now.. I want to say I understand what you're telling me, but if you're asking me to now go ahead and implement this new knowledge and edit my code so it all works, I wouldn't be able to do it.

        That's not to say your explanation is bad in any way, it's just that (as you can probably tell) I'm still pretty new to OOP & PyQt5 and I have no idea how to even approach this.

        I watched several OOP-tutorials and can do the stuff they always show off in these (most of them show the Class Person example with multiple other Classes (Manager, Employee etc.) inheriting from Person.. all its methods and properties). Simple enough.

        But when I look at this and try to rewrite my code so it works... or think about how I'd code what you're telling me, I'm just lost & scratching my head, honestly. Sorry

        mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by
        #4

        @Romeoo

        Hi
        Thats ok.
        But what exactly do you want to happen?

        Which class has the skillpoint list ?

        For the case of add/reducing skill point assignment for a player, I assume you
        must read the current assignment from some class and add/reduce from it and the write it back.

        Im asking as the data class is the one that is normally shared amount classes/GUI or being hold by say
        MainWindow and other classes use its slots to manipulate its data.

        R 1 Reply Last reply
        0
        • mrjjM mrjj

          @Romeoo

          Hi
          Thats ok.
          But what exactly do you want to happen?

          Which class has the skillpoint list ?

          For the case of add/reducing skill point assignment for a player, I assume you
          must read the current assignment from some class and add/reduce from it and the write it back.

          Im asking as the data class is the one that is normally shared amount classes/GUI or being hold by say
          MainWindow and other classes use its slots to manipulate its data.

          R Offline
          R Offline
          Romeoo
          wrote on last edited by
          #5

          @mrjj Hey,
          I actually don't know how I'm going to structure/build all of this yet as I'm just experimenting with the different PyQt5 possibilities and learning about certain functionalities which I'm going to need for my project later on.

          Right now (for the purpose of learning this), I just want to keep the code as is and manipulate/connect the few methods and attributes the classes/instances have.

          So for example, after testing some more.. I figured out that if I make these changes to the above code:

          old:

          def clicked(self, value):
                  if value == "Button 2":
                      self.button2.setText("I am Button 2")
                  
                  if value == "Button 3":
                      self.button3.setText("I am Button 3")
          

          new:

          def clicked(self, value):
                  t = MyWidget()
                  if value == "Button 2":
                      t.handleButton()
                      self.button2.setText("I am Button 2")
                  
                  if value == "Button 3":
                      self.button3.setText("I am Button 3")
                      t.handleButton()
          

          it will correctly check if either of the 2 buttons in the MainWindowTwo class have been pressed with any of the defined modifiers in MyWidget's handlebutton() method (shift, ctrl, shift+ctrl) and no longer if only the Widget itself has been clicked like that.

          But if I try the same with mousePressEvent (whether it's in the MainWindowTwo Class or MyWidget Class), I get the Error: 'QPushButton' object has no attribute 'button'
          or
          'MainWindowTwo' object has no attribute 'button'

          depending on how I call it.

          I'm sure this seems very silly, I'm sorry. I just want it to also check if the two buttons which are defined in MainWindowTwo have been pressed with either left- or right-click.

          JonBJ 1 Reply Last reply
          0
          • R Romeoo

            @mrjj Hey,
            I actually don't know how I'm going to structure/build all of this yet as I'm just experimenting with the different PyQt5 possibilities and learning about certain functionalities which I'm going to need for my project later on.

            Right now (for the purpose of learning this), I just want to keep the code as is and manipulate/connect the few methods and attributes the classes/instances have.

            So for example, after testing some more.. I figured out that if I make these changes to the above code:

            old:

            def clicked(self, value):
                    if value == "Button 2":
                        self.button2.setText("I am Button 2")
                    
                    if value == "Button 3":
                        self.button3.setText("I am Button 3")
            

            new:

            def clicked(self, value):
                    t = MyWidget()
                    if value == "Button 2":
                        t.handleButton()
                        self.button2.setText("I am Button 2")
                    
                    if value == "Button 3":
                        self.button3.setText("I am Button 3")
                        t.handleButton()
            

            it will correctly check if either of the 2 buttons in the MainWindowTwo class have been pressed with any of the defined modifiers in MyWidget's handlebutton() method (shift, ctrl, shift+ctrl) and no longer if only the Widget itself has been clicked like that.

            But if I try the same with mousePressEvent (whether it's in the MainWindowTwo Class or MyWidget Class), I get the Error: 'QPushButton' object has no attribute 'button'
            or
            'MainWindowTwo' object has no attribute 'button'

            depending on how I call it.

            I'm sure this seems very silly, I'm sorry. I just want it to also check if the two buttons which are defined in MainWindowTwo have been pressed with either left- or right-click.

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

            @Romeoo
            mousePressEvent() is an event, not a signal, and has to be coded quite differently. Show your code which errors if you want help.

            R 1 Reply Last reply
            1
            • JonBJ JonB

              @Romeoo
              mousePressEvent() is an event, not a signal, and has to be coded quite differently. Show your code which errors if you want help.

              R Offline
              R Offline
              Romeoo
              wrote on last edited by Romeoo
              #7

              @JonB Hey, thanks!

              I already posted the code in my first post though?
              The Errors I mentioned like "QPushButton' object has no attribute 'button'" was just me messing around with the code and trying stuff out.. just mentioning nonsense I tried.

              I have not found a way to do what I want. The code in my initial post is the code I have and it works/has no Error messages because I have no idea how to do what I'm asking for here (which is connecting it all to work together).

              That is why I made this post, so someone can hopefully show me how to do it and explain it.

              Again: I want mousePressEvent() to be able to determine if self.button2 and self.button3 have been pressed with a left-click or a right-click.
              Right now all it can do is determine that if I press anywhere in MainWindowTwo's Window, but not if I press on either of the buttons.

              mrjjM 1 Reply Last reply
              0
              • R Romeoo

                @JonB Hey, thanks!

                I already posted the code in my first post though?
                The Errors I mentioned like "QPushButton' object has no attribute 'button'" was just me messing around with the code and trying stuff out.. just mentioning nonsense I tried.

                I have not found a way to do what I want. The code in my initial post is the code I have and it works/has no Error messages because I have no idea how to do what I'm asking for here (which is connecting it all to work together).

                That is why I made this post, so someone can hopefully show me how to do it and explain it.

                Again: I want mousePressEvent() to be able to determine if self.button2 and self.button3 have been pressed with a left-click or a right-click.
                Right now all it can do is determine that if I press anywhere in MainWindowTwo's Window, but not if I press on either of the buttons.

                mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by
                #8

                @Romeoo

                Hi
                For MousePressEvent you must subclass the button.
                something like. (disclaimer. c++ dude. don't know python :)

                class MyButton(QtGui.QPushButton): 
                
                    def mousePressEvent(self, event):
                        // use events button() == Qt::RightButton to know if left or right
                        QtGui.QPushButton.mousePressEvent(self, event) // call the base class which you must do or button stops to function
                
                R 1 Reply Last reply
                1
                • mrjjM mrjj

                  @Romeoo

                  Hi
                  For MousePressEvent you must subclass the button.
                  something like. (disclaimer. c++ dude. don't know python :)

                  class MyButton(QtGui.QPushButton): 
                  
                      def mousePressEvent(self, event):
                          // use events button() == Qt::RightButton to know if left or right
                          QtGui.QPushButton.mousePressEvent(self, event) // call the base class which you must do or button stops to function
                  
                  R Offline
                  R Offline
                  Romeoo
                  wrote on last edited by
                  #9

                  @mrjj ty for being so patient with me lol,

                  hmn, if I try to implement that and mess around with it, it just says
                  "AttributeError: module 'PyQt5.QtGui' has no attribute 'QPushButton'

                  mrjjM 1 Reply Last reply
                  0
                  • R Romeoo

                    @mrjj ty for being so patient with me lol,

                    hmn, if I try to implement that and mess around with it, it just says
                    "AttributeError: module 'PyQt5.QtGui' has no attribute 'QPushButton'

                    mrjjM Offline
                    mrjjM Offline
                    mrjj
                    Lifetime Qt Champion
                    wrote on last edited by mrjj
                    #10

                    "AttributeError: module 'PyQt5.QtGui' has no attribute 'QPushButton'

                    Then it lives in another module, would be my guess.

                    PyQt5 is not the official python binding so not sure where to look it up.

                    Hmm
                    I saw code doing
                    self.pushButton = QtWidgets.QPushButton(self.centralwidget)

                    so it lives in QtWidgets, I guess ?

                    so replace QtGui with QtWidgets and see if it eats it :)

                    R 1 Reply Last reply
                    0
                    • mrjjM mrjj

                      "AttributeError: module 'PyQt5.QtGui' has no attribute 'QPushButton'

                      Then it lives in another module, would be my guess.

                      PyQt5 is not the official python binding so not sure where to look it up.

                      Hmm
                      I saw code doing
                      self.pushButton = QtWidgets.QPushButton(self.centralwidget)

                      so it lives in QtWidgets, I guess ?

                      so replace QtGui with QtWidgets and see if it eats it :)

                      R Offline
                      R Offline
                      Romeoo
                      wrote on last edited by
                      #11

                      @mrjj thanks... been trying everything since your post, but I'm clearly way in over my head and seemingly have no idea what I'm doing.

                      The "best" I was able to do was create new buttons in self.button2 and self.button3 that would properly respond to the mouseclick?!

                      I eventually just ended up throwing lots of nonsense syntax at the wall and hope something would stick... that's how I ended up with:
                      self.button2.clicked.connect(MyButton(self.button2).mousePressEvent)
                      self.button3.clicked.connect(MyButton(self.button3).mousePressEvent)

                      which like I said simply resulted in creating 2 additional buttons inside of my other 2 (one in self.button1 and one in self.button2) which then determined if it was left or rightclick.

                      Everything else just resulted in:
                      AttributeError: 'QPushButton' object has no attribute 'button'
                      AttributeError: 'PyQt5.QtCore.pyqtBoundSignal' object has no attribute 'button'
                      AttributeError: 'MainWindowTwo' object has no attribute 'button'

                      I mean.. I understand these Errors. But I also have no clue how to fix this.
                      Anyway, sorry for wasting your time. thanks for trying to help me ; )

                      mrjjM 1 Reply Last reply
                      0
                      • R Romeoo

                        @mrjj thanks... been trying everything since your post, but I'm clearly way in over my head and seemingly have no idea what I'm doing.

                        The "best" I was able to do was create new buttons in self.button2 and self.button3 that would properly respond to the mouseclick?!

                        I eventually just ended up throwing lots of nonsense syntax at the wall and hope something would stick... that's how I ended up with:
                        self.button2.clicked.connect(MyButton(self.button2).mousePressEvent)
                        self.button3.clicked.connect(MyButton(self.button3).mousePressEvent)

                        which like I said simply resulted in creating 2 additional buttons inside of my other 2 (one in self.button1 and one in self.button2) which then determined if it was left or rightclick.

                        Everything else just resulted in:
                        AttributeError: 'QPushButton' object has no attribute 'button'
                        AttributeError: 'PyQt5.QtCore.pyqtBoundSignal' object has no attribute 'button'
                        AttributeError: 'MainWindowTwo' object has no attribute 'button'

                        I mean.. I understand these Errors. But I also have no clue how to fix this.
                        Anyway, sorry for wasting your time. thanks for trying to help me ; )

                        mrjjM Offline
                        mrjjM Offline
                        mrjj
                        Lifetime Qt Champion
                        wrote on last edited by SGaist
                        #12

                        @Romeoo
                        Hi
                        Ahh, i see where the confusion comes from.
                        https://doc.qt.io/qt-5/eventsandfilters.html

                        Events are not a signal. you cannot connect to them.
                        events are handled by classes in a virtual function.
                        and to customize that we create a sub class so its our own class.

                        so self.button2.clicked.connect(MyButton(self.button2).mousePressEvent)
                        will not work.

                        You should create instances of MyButton and use instead of the std Buttons.
                        Qt will then call your mousePressEvent directly in the sub class.

                        Often one does not wish to handle the processing directly in the mousepRessEvent but
                        tell someone else to do it. that we can do with a new signal to keep the MyButton clean and separate from rest of the app.
                        Disclaimer: I'm just grabbing code from the net. i cannot test it so will have errors:)

                        class MyButton(QtWidgets.QPushButton): 
                          leftclicked=pyqtSignal() // define new signal
                          rightclicked=pyqtSignal()
                        
                            def mousePressEvent(self, event):
                                // use events button() == Qt.RightButton to know if left or right
                               if ( event.button == Qt.RightButton )    self.rightclicked.emit() // send signal
                               if ( event.button == Qt.LeftButton )    self.leftclicked.emit()
                                QtWidgets.QPushButton.mousePressEvent(self, event) // call the base class which you must do or button stops to function
                        

                        [edit: fixed wrong module and syntax SGaist]

                        then from outside, you connect, your instance of MyButton and its new signal leftclicked and rightclicked to slots in main. there you then to the actual skill assignment.

                        1 Reply Last reply
                        1

                        • Login

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