Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Help overwriting a PyQT widget class and adding a new property



  • I'm trying to create my own "ComboBox" class that inherits the QCombobox widget so I can overwrite and specifically control the pop up events. When I do that alone, the app works fine. However, when I try to add the ability to pass in a property(position) to the ComboBox class, the window opens, but the widget does not show within. I believe it has something to do with my init constructor and how I'm inheriting things incorrectly, but I don't truly know for sure. Any help?

    from PyQt5 import QtCore, QtWidgets,QtGui
    
    class ComboBox(QtWidgets.QComboBox):
        popupAboutToBeShown = QtCore.pyqtSignal()
    
        def __init__(self,position):
            super(QtWidgets.QComboBox,self).__init__()
            self.position = position
    
        def showPopup(self):
            self.setGeometry(QtCore.QRect(10, 10, 480, 41))
            self.popupAboutToBeShown.emit()
            super(ComboBox, self).showPopup()
    
        def hidePopup(self):
            self.setGeometry(QtCore.QRect(10, 10, 21, 41))
            self.popupAboutToBeShown.emit()
            super(ComboBox, self).hidePopup()
    
    class Window(QtWidgets.QWidget):
        def __init__(self):
            super(Window, self).__init__()
            self.resize(916, 916)
            self.combo = ComboBox(9)
            self.combo.setGeometry(QtCore.QRect(10, 10, 21, 41))
            self.combo.addItems(["ITEM 1","ITEM 2","ITEM 3"])
    
    if __name__ == '__main__':
        import sys
        app = QtWidgets.QApplication(sys.argv)
        window = Window()
        window.show()
        sys.exit(app.exec_())


  • @Mike-Taco I don't understand your question or what you want to get. "position" you just store it in a variable and nothing else. What do you want to get?



  • @Mike-Taco
    Are you really sure this has anything to do with your position parameter at all? You simply do not use it. If you remove that parameter (and self.position = position), and do not pass it from caller, are you saying this code does work?

    I'm confused by your/Python's use of super(ComboBox, self).... If you change all of your super(..., self)s to plain super() does it work?

    Normally, a QWidget like QComboBox takes an extra optional parameter of a QWidget for the parent. Just maybe there is some issue with your alternative definition of the second parameter. Does declaring it like

    def __init__(self, position, parent=None):
    

    make any difference?



  • @JonB Sorry for not clarifying. I am not currently using the position parameter in the above code, but I want to be able to in the future . I also go as far as pass the number 9 to combo when I instantiate the object in the window class init. Unfortunately, changing to

    def __init__(self, position, parent=None):
    

    does not work, nor does removing any parameters from super

    super().__init__()
    

    I've also tried other variations including

    def __init__(self, position, parent=None,*args, **kwargs):  
            super().__init__(*args, **kwargs)
            self.position = position
    


  • @Mike-Taco
    Since position should be irrelevant at present, can you please confirm properly that by just removing that parameter, and keeping rest of code the same, it all really works?

    If so, go back in on restored code with position and just make 100% sure --- with a print() statement in your __init__() --- that is being called. just in case it is picking up the base QComboBox with the optional parent parameter instead of your constructor.



  • @JonB the print statement with the position executes just fine when placed after the self.position = position line, but the widget still does not appear in the window. i.e.

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


  • @eyllanesc Although it is not represented in my code above, I want to be able to use the position variable later. For whatever reason how I have the init function written, upon running it, the widget wont appear in the window. If I add a print statement at the end of the init function, it executes just fine, but still no widget appearance in the window,

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


  • @Mike-Taco For a widget to appear as part of another widget then the widget must be a child of the other widget or one of its children. The layouts apart from establishing the size and position also establish that relationship, as you do not use it then you must use the parent that they already indicated:

    def __init__(self, position, parent=None):  
         super().__init__(parent) # <---
         self.position = position
         print(self.position)
    


  • Found a solution from a user in another forum

    from PyQt5 import QtCore, QtWidgets, QtGui
    
    class ComboBox(QtWidgets.QComboBox):
        popupAboutToBeShown = QtCore.pyqtSignal()
    
    
        def __init__(self, window, position):
            super().__init__(window)
            self.position = position
            print(self.position)
    
        def showPopup(self):
            self.setGeometry(QtCore.QRect(10, 10, 480, 41))
            self.popupAboutToBeShown.emit()
            super().showPopup()
    
        def hidePopup(self):
            self.setGeometry(QtCore.QRect(10, 10, 21, 41))
            self.popupAboutToBeShown.emit()
            super().hidePopup()
    
    class Window(QtWidgets.QWidget):
        def __init__(self):
            super().__init__()
            self.resize(916, 916)
            self.combo = ComboBox(self, 9)
            self.combo.setGeometry(QtCore.QRect(10, 10, 21, 41))
            self.combo.addItems(["ITEM 1","ITEM 2","ITEM 3"])
    
    if __name__ == '__main__':
        import sys
        app = QtWidgets.QApplication(sys.argv)
        window = Window()
        window.show()
        sys.exit(app.exec_())


  • @Mike-Taco Don't use window as it can be confused with the global variable assigned to Window. In my previous comment you must change self.combo = ComboBox(9, self).



  • @JonB said in Help overwriting a PyQT widget class and adding a new property:

    @Mike-Taco
    Since position should be irrelevant at present, can you please confirm properly that by just removing that parameter, and keeping rest of code the same, it all really works?

    I still don't see that any of this has to do with you adding a position parameter, which is what you said caused the code not to work.


Log in to reply