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

QPushButton is in QToolBar, but misplaced



  • Just for practicing PySide2/Qt, I set myself a task: To create a function in a module, which would add buttons (QPushButtons) to the MainToolBar.

    It all went OK and it works - kind-of. I had to make some sort of mistake, because the result is wierd: The added "Item" button is placed within the MainToolBar, but not added to the other buttons, but it is rather added to the container of the MainToolBar itself, so it is above both the grabbing header of the toolbar and the existing buttons. In the next screenshot, I show the toolbar while moving it, so you could see it's really sitting there:

    Misplaced QPushButton

    Code in the main.py:

    from Interface import DefaultInit
    
    class Form(QObject):
    
        def __init__(self, ui_file, parent=None):
            super(Form, self).__init__(parent)
            ui_file = QFile(ui_file)
            ui_file.open(QFile.ReadOnly)
    
            loader = QUiLoader()
            self.window = loader.load(ui_file)
            ui_file.close()
    
            # Toolbar
            self.MainToolBar = self.window.findChild(QToolBar, 'MainToolBar')
    
    ...
            DefaultInit.InterfaceLoader.__init__(self, self.MainToolBar)     # <<<<<<<<<<<<
    ...
            self.window.show()
    

    Code in the Interface/Dfaultinit.py:

    class InterfaceLoader():
        def __init__(self, ToolBar):
            MainToolbar = QToolBar(ToolBar)
    
            ItemBtn = QPushButton()
            ItemBtn.setText("Item")
            ItemBtn.setIconSize(QSize(24, 24))
            ItemBtn.setIcon(QIcon(QPixmap("./icons/item.png")))
            MainToolbar.addWidget(ItemBtn)
    
            Test2Btn = QPushButton()
            Test2Btn.setText("Test2 Test2 Test2")
            Test2Btn.setIconSize(QSize(24, 24))
            Test2Btn.setIcon(QIcon(QPixmap("./Resources/tools.png")))
            MainToolbar.addWidget(Test2Btn)
    

    By the way, the second button is not shown, instead a ">" symbol appears indicating, that the button couldn't be shown.

    Anyone knows what I did wrong, please?



  • @Oak77 said in QPushButton is in QToolBar, but misplaced:

    MainToolbar = QToolBar(ToolBar)

    Hi @Oak77
    What is the reason below line?

    MainToolbar = QToolBar(ToolBar)
    


  • I tried it to write code like below and it is working.

    interface.py

    # This Python file uses the following encoding: utf-8
    
    # if__name__ == "__main__":
    #     pass
    from PySide2.QtWidgets import QApplication,QToolBar,QPushButton
    from PySide2.QtCore import QObject,QFile,QSize
    from PySide2.QtUiTools import QUiLoader
    from PySide2.QtGui import QIcon,QPixmap
    class InterfaceLoader():
        def __init__(self, ToolBar:QToolBar):
            MainToolbar = ToolBar
    
            ItemBtn = QPushButton()
            ItemBtn.setText("Item")
            ItemBtn.setIconSize(QSize(24, 24))
            ItemBtn.setIcon(QIcon(QPixmap("./icons/item.png")))
            MainToolbar.addWidget(ItemBtn)
            ItemBtn.show()
    
            Test2Btn = QPushButton()
            Test2Btn.setText("Test2 Test2 Test2")
            Test2Btn.setIconSize(QSize(24, 24))
            Test2Btn.setIcon(QIcon(QPixmap("./Resources/tools.png")))
            MainToolbar.addWidget(Test2Btn)
    

    main.py

    # This Python file uses the following encoding: utf-8
    import sys
    from PySide2.QtWidgets import QApplication,QToolBar
    from PySide2.QtCore import QObject,QFile
    from PySide2.QtUiTools import QUiLoader
    from interface import InterfaceLoader
    
    class Form(QObject):
    
        def __init__(self, ui_file, parent=None):
            super(Form, self).__init__(parent)
            ui_file = QFile(ui_file)
            ui_file.open(QFile.ReadOnly)
    
            loader = QUiLoader()
            self.window = loader.load(ui_file)
            ui_file.close()
            self.MainToolBar = self.window.findChild(QToolBar, 'MainToolBar')
            if self.MainToolBar:
                self.loader = InterfaceLoader(self.MainToolBar)
            else:
                print("no maintoolbar")
            #InterfaceLoader.__init__(self, self.MainToolBar)     # <<<<<<<<<<<<
            self.window.show()
    
    if __name__ == "__main__":
        app = QApplication([])
        form = Form("main.ui")
    
        # ...
        sys.exit(app.exec_())
    
    

    result
    Capture.PNG



  • @CKurdu Why the line - Well, unless I messed up the logic, I am creating a MainToolBar object of which I have to be sure it is of QToolBar type and assigning it a ToolBar, the main one from the main window (to be filled with QPushButtons). I will now look at you code, I'm sure it will work and hopefully I'll get the tricks. I see ToolBar:QToolBar, that's new to me (just learning) and I guess this defines the type of the parameter. I will study it and try and get back how I succeeded.



  • @CKurdu Thank you very much, that was very helpful. I applied your changes, the key one is really replacing:

    class InterfaceLoader():
        def __init__(self, ToolBar):
            MainToolbar = QToolBar(ToolBar)
    

    With:

    class InterfaceLoader():
        def __init__(self, ToolBar:QToolBar):
            MainToolbar = ToolBar
    

    So to enforce the type of parametr of the function, rather than define a new variable and make the input object of the desired type.



  • @Oak77 said in QPushButton is in QToolBar, but misplaced:

    @CKurdu Thank you very much, that was very helpful. I applied your changes, the key one is really replacing:

    You are welcome.


Log in to reply