Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Qt Academy Launch in California!

    Solved How to override PySide2 widget's method generated by Qt Designer?

    Qt for Python
    qt for python pyside2
    3
    13
    1290
    Loading More Posts
    • 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.
    • J
      johnjml @JonB last edited by

      Hi, @JonB
      Thanks for your reply.

      First,I must say sorry. It's all about 'overriding'. 'overload' is my typo,edited that.Sorry if you feel confused.

      It's my own code. As I mentioned,I'm trying to learn PySide,and my knowledge of C++ is very poor,which is limited to basic syntax(sorry for my stupidity).

      I came across the basic idea from this PySide documentation example.
      I have watched some tutorials about PySide, such as this Zurbrigg PySide tutorial.

      Sorry that I cannot find systematic instructions of learning PySide and I really think the documentation of PySide is a little bit messy for beginners like me.Sometimes I have to navigate to C++ version of the documents to fetch some information of a class or a method (such as return types).

      I know that I can derive a custom QTreeWidget class from the basic QTreeWidget and override the methods there.

      But I do what to know is there a way to override methods of widget generated from Qt Designer?

      And beginner-friendly resources of learning Pyside will be much appreciated.

      Thank you.

      JonB 1 Reply Last reply Reply Quote 0
      • JonB
        JonB @johnjml last edited by JonB

        @johnjml
        The example you used has nothing to say about either overloading or overriding. The way you have chosen to try to achieve that

                self.ui.previewTreeWidget.dragEnterEvent = dragEnterEvent
                self.ui.previewTreeWidget.dropEvent = dropEvent
        

        is a totally Pythonic feature of replacing am existing function pointer, or whatever this is referred to in Python ("monkey-patching?"). It would not be be available in C++, and it's not how we go about overriding an existing virtual method. I do not know whether your way can work in Python/PySide, perhaps not because of the error message you receive.

        The way I have done it in PySide is the same as I would in C++, and corresponds to Python examples I have seen. Basically we must subclass the widget, and the Python would look something like this:

        class PreviewTreeWidget(QTreeWidget):
            def __init__(self, parent=None):
                super().__init__(parent)
        
            def dragEnterEvent(self, evt):
                # your code
        
            def dropEvent(self, evt):
                # your code
        

        An example for PyQt5 is shown in e.g. https://zetcode.com/gui/pyqt5/dragdrop/. Should be same for PySide2.

        When you need to do this against a widget in Qt Designer, you need to use its Promote feature to effectively declare your PreviewTreeWidget class as derived from and usable in place of a standard QTextWidget. I'm not sure how that works or how easy/difficult it is from PySide, Google for e.g. pyside2 designer promote widget (or pyqt5) and have a read.

        I am mentioning @SGaist here, in the hope he will see this and comment as to whether this is right or wrong for PySide. He is a general expert, but I know he has used PySide too. I will also mention @mrjj, who is a Designer UI expert for things like Promote, but I'm not sure if he knows about the PySide requirements for this.

        Finally, when you get past this issue, unless you know better than I this code

                    item.value().setFlags(item.value().flags()|QtCore.Qt.ItemIsUserCheckable)
                    item.value().setCheckState(0,QtCore.Qt.Checked)
        

        does not look right. I don't see you can call these methods on value(). I would have thought you would remove .value() from both of these?

        J 1 Reply Last reply Reply Quote 0
        • SGaist
          SGaist Lifetime Qt Champion last edited by

          Hi,

          Monkey patching can work, no problem with that but at some point it becomes really hard to reason about it.

          Since you are doing several changes, you should follow @JonB´a suggestion and use the promote feature of Designer.

          If you have simple widgets, you might also want to learn to build your UI directly with code.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          J 1 Reply Last reply Reply Quote 2
          • J
            johnjml @JonB last edited by

            @JonB
            Oh,I see.
            Seems the correct way of overriding is to declare and define my custom QTreeWidget and derive from the basic widget.
            The 'monkey-patching' thing is a python way to change function or method in runtime.I was thinking it might have the same effect like overriding,that why I used the term 'overriding' in the question.I can see I'm totally wrong about that.

            As for the .value() issue you mentioned, every item in that snippet is actually a Iterater object in python,so I have to use the .value() to get the actual QTreeWidgetItem to access the methods in QTreeWidgetItem instance.
            If I remove .value(),I will get an AttributeError: 'PySide6.QtWidgets.QTreeWidgetItemIterator' object has no attribute 'setFlags'.The official doc is referenced here.
            I'm also quite confued by this,hope the experts you mentioned can explain it.
            Maybe I should change my code to this so it can be undertood better:

            itemIter = QtWidgets.QTreeWidgetItemIterator(self.ui.previewTreeWidget)
            for iter in itemIter:
                iter.value().setFlags(iter.value().flags()|QtCore.Qt.ItemIsUserCheckable)
                iter.value().setCheckState(0,QtCore.Qt.Checked)
            
            JonB 1 Reply Last reply Reply Quote 0
            • JonB
              JonB @johnjml last edited by JonB

              @johnjml
              For the overriding, see @SGaist's confirmation of my understand above.

              The iterator is a small problem, which you will get right. I respect what you say. However you referred me to the PySide2 reference page and that starts with example:

              it = QTreeWidgetItemIterator(treeWidget)
              while it:
                  if (it).text(0) == itemText:
                      (it).setSelected(True)
                  it = it + 1
              

              Here you can see no use of .value(). However, looking at it I am concerned it might be some straight copy of the required C++ code, and nonsense for Python? I believe some/most/all of the PySide2 examples code may have been left as simple, automated translation from the C++ examples...?

              J 1 Reply Last reply Reply Quote 0
              • J
                johnjml @JonB last edited by

                @JonB
                Right,that example is the confusing point.I noticed the problem too.
                See that is the 'messy' part in PySide doc I was talking about.
                Some examples and descriptions are not so python user friendly.
                Return types are not strictly listed.
                Still,very appreciate your help.

                JonB 1 Reply Last reply Reply Quote 0
                • JonB
                  JonB @johnjml last edited by

                  @johnjml
                  Sadly (depending on your POV!) Python is still very much a second-class citizen in the Qt world.

                  PyQt5 never had its own documentation, you just had to go look up the normal C++ documentation and figure for yourself.

                  PySide2 does have those documentation pages you reference. However, they seem to have been generated automatically by some translation tool from the literal C++ examples in their doc pages. Newer PySide6 docs do not seem to me to have changed in this respect. As we are both saying, I believe that while some of them work some will not. As witness the current case. I found the PySide2 docs useless, and always use the C++ ones, regardless of which language I am programming in. At least be aware that even if C++ is not your favored language it can be worth looking at the standard C++ docs as well as the PySide stuff.

                  1 Reply Last reply Reply Quote 0
                  • J
                    johnjml @SGaist last edited by

                    @SGaist
                    I see,monkey patching is really confusing me.Maybe it will work in some way.
                    I will dig in the promote feature right now.
                    Thanks for your help.

                    Could you please provide some PySide beginner-friendly learning resources,master SGaist?
                    It would help alot.
                    Again,huge thanks.

                    JonB 1 Reply Last reply Reply Quote 0
                    • JonB
                      JonB @johnjml last edited by JonB

                      @johnjml
                      Then don't use your monkey-patching code approach! If you do the Promote route there will be no monkey patching, and it will work by overriding the method in a subclass, like one would have to do in C++. The only issue then is how you get Designer Promote to work right for PySide2, there must be Googlable answers out there.....

                      J 1 Reply Last reply Reply Quote 0
                      • J
                        johnjml @JonB last edited by johnjml

                        @JonB
                        Yeah,I abandoned the monkey patching thing. It's not a good way to edit widgets.
                        I'll follow your promote solution.I'll try google it.I didn't even know there is a promote feature before.
                        I'm not a native english speaker,hope my codes and typos didn't make you angry.

                        Really appreciate the help of yours.Thanks alot.

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post