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. QPushButton vertical alignment in QToolBar
Forum Updated to NodeBB v4.3 + New Features

QPushButton vertical alignment in QToolBar

Scheduled Pinned Locked Moved Unsolved Qt for Python
8 Posts 4 Posters 1.0k 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.
  • S Offline
    S Offline
    Strangelove
    wrote on 9 Aug 2021, 07:57 last edited by
    #1

    I'm adding QActions, QLabels, QSpinBoxes and a QPushButton to a QToolBar in a QMainWindow. Minimal styling is involved (only some padding on the QLabels via CSS).

    I've spent the last 30 minutes trying to make the QPushButton vertically aligned with the other widgets, without success. I've tried CSS margins, padding, setContentMargins and setAlignment, nothing works.

    Any ideas?

    Screenshot 2021-08-09 at 09.50.13.jpg

    Thanks.

    # This is part of QMainWindow
    
    # Command buttons
    toolbar = self.addToolBar('Main')
    toolbar.setIconSize(QSize(25, 25))
    toolbar.setMovable(False)
    toolbar.setContextMenuPolicy(Qt.PreventContextMenu)
    
    toolbar.addAction(self.act_reload)
    toolbar.addAction(self.act_reset_zoom)
    toolbar.addAction(self.act_toggle_grid)
    
    toolbar.addSeparator()
    
    # Depth spin boxes
    lbl_spin_min = QLabel('Min depth')
    lbl_spin_min.setStyleSheet('QLabel {padding: 0 10}')
    toolbar.addWidget(lbl_spin_min)
    
    self.spin_min = DepthSpinBox()
    toolbar.addWidget(self.spin_min)
    
    lbl_spin_max = QLabel('Max depth')
    lbl_spin_max.setStyleSheet('QLabel {padding: 0 10}')
    toolbar.addWidget(lbl_spin_max)
    
    self.spin_max = DepthSpinBox()  # Minimal changes to QSpinBox, see below
    toolbar.addWidget(self.spin_max)
    
    self.spin_min.valueChanged.connect(self.spin_value_changed)
    self.spin_max.valueChanged.connect(self.spin_value_changed)
            
    self.btn_reset_spin = QPushButton('Reset')
    toolbar.addWidget(self.btn_reset_spin)
    
    self.btn_reset_spin.clicked.connect(self.depth_spin_reset)
    
    # Somewhere else...
    
    class DepthSpinBox(QSpinBox):
        def __init__(self):
            super().__init__()
            self.setSingleStep(5)
            self.setAlignment(Qt.AlignRight)
            self.setFixedWidth(60)
    
    
    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 9 Aug 2021, 19:06 last edited by
      #2

      Hi,

      Why not build a widget to contain all of these and then add that widget to the toolbar ?

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

      S 1 Reply Last reply 10 Aug 2021, 09:33
      1
      • S SGaist
        9 Aug 2021, 19:06

        Hi,

        Why not build a widget to contain all of these and then add that widget to the toolbar ?

        S Offline
        S Offline
        Strangelove
        wrote on 10 Aug 2021, 09:33 last edited by
        #3

        @SGaist Pardon me if I'm wrong, but do you mean create a subclass of QWidget, with a QHBoxLayout and everything, add the controls to that layout with self as the parent and then add the subclassed QWidget to the toolbar?

        J 1 Reply Last reply 10 Aug 2021, 09:38
        0
        • S Strangelove
          10 Aug 2021, 09:33

          @SGaist Pardon me if I'm wrong, but do you mean create a subclass of QWidget, with a QHBoxLayout and everything, add the controls to that layout with self as the parent and then add the subclassed QWidget to the toolbar?

          J Offline
          J Offline
          JonB
          wrote on 10 Aug 2021, 09:38 last edited by
          #4

          @Strangelove
          Yes, that is exactly what @SGaist means :) It would give you a nice, self-contained widget with all your sub-widgets nicely laid out. For use here, or elsewhere.

          You do not have to sub-class QWidget for this --- you could just use a plain QWidget. However, it is probably a good idea to do so as it makes it neater, explicable and even more self-contained.

          S 1 Reply Last reply 10 Aug 2021, 09:58
          0
          • J JonB
            10 Aug 2021, 09:38

            @Strangelove
            Yes, that is exactly what @SGaist means :) It would give you a nice, self-contained widget with all your sub-widgets nicely laid out. For use here, or elsewhere.

            You do not have to sub-class QWidget for this --- you could just use a plain QWidget. However, it is probably a good idea to do so as it makes it neater, explicable and even more self-contained.

            S Offline
            S Offline
            Strangelove
            wrote on 10 Aug 2021, 09:58 last edited by Strangelove 8 Oct 2021, 10:00
            #5

            @JonB Thank you. While waiting for an answer I tried subclassing QWidget and indeed it solves the alignment issue. It has good sides and bad sides, though, and I'm wondering what's the best practice here.

            Good

            • It is indeed a self-contained widget which could be used elsewhere (although it's very specific to this application...)
            class ToolbarFilterWidget(QWidget):
                def __init__(self):
                    super().__init__()
            
                    layout = QHBoxLayout()
            
                    lbl_spin_min = QLabel('Min depth', self)
                    lbl_spin_min.setStyleSheet('QLabel {padding: 0 10}')
                    layout.addWidget(lbl_spin_min)
            
                    self.spin_min = DepthSpinBox(self)
                    layout.addWidget(self.spin_min)
            
                    lbl_spin_max = QLabel('Max depth', self)
                    lbl_spin_max.setStyleSheet('QLabel {padding: 0 10}')
                    layout.addWidget(lbl_spin_max)
            
                    self.spin_max = DepthSpinBox(self)
                    layout.addWidget(self.spin_max)
            
                    self.category_checkbox = {}
                    for cat in config.categories:
                        self.category_checkbox[cat] = QCheckBox(cat.capitalize())
                        layout.addWidget(self.category_checkbox[cat])
            
                    self.checkbox_include_done = QCheckBox('Include Done')
                    layout.addWidget(self.checkbox_include_done)
            
                    self.btn_reset_filters = QPushButton('Reset Filters')
                    layout.addWidget(self.btn_reset_filters)
            
                    self.setLayout(layout)
            
            • My Reset button is finally where it should be :)

            Not so good

            • Seems like a lot of work just to have a button stay vertically centered.
            • Because the widget is now a class independent of my QMainWindow, all the controls inside the widget have to be accessed through an additional variable which makes the code a mouthful (and IMHO rather ugly), since I have to prefix everything with filter_widget:
            def reset_filters(self):
                    min_loc_depth, max_loc_depth = self.map.extents
                    self.filter_widget.spin_min.setMinimum(min_loc_depth)
                    self.filter_widget.spin_min.setMaximum(max_loc_depth)
                    self.filter_widget.spin_max.setMinimum(min_loc_depth)
                    self.filter_widget.spin_max.setMaximum(max_loc_depth)
                    self.filter_widget.spin_min.setValue(min_loc_depth)
                    self.filter_widget.spin_max.setValue(max_loc_depth)
                    for checkbox in self.filter_widget.category_checkbox.values():
                        checkbox.blockSignals(True)
                        checkbox.setChecked(True)
                        checkbox.blockSignals(False)
                    self.filter_widget.checkbox_include_done.setChecked(True)
                    self.set_filter()
            
            

            BTW, how would you go about doing this without subclassing QWidget?

            Thanks a lot.

            1 Reply Last reply
            0
            • S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 10 Aug 2021, 19:19 last edited by
              #6

              It's up to you to add appropriate getter and setter to not have to worry about the internals of your custom widget.

              In your case, you could have done as I suggested and just create that "container widget". The rest of your code would have not changed.

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

              1 Reply Last reply
              0
              • JoeCFDJ Offline
                JoeCFDJ Offline
                JoeCFD
                wrote on 10 Aug 2021, 20:48 last edited by JoeCFD 8 Oct 2021, 20:49
                #7

                Try QToolButton which is made for QToolBar

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  Strangelove
                  wrote on 11 Aug 2021, 17:33 last edited by
                  #8

                  I believe I figured out the "container widget" approach, which is just to instantiate each widget with a second argument pointing to an empty parent widget, then adding the parent widget to the toolbar.

                  FWIW, I've attached screenshots of the results. It seems that — at least on my machine (macOS Catalina) — a subclass of QWidget still centers the button better than the container widget does. No idea why.

                  center.png

                  @JoeCFD said in QPushButton vertical alignment in QToolBar:

                  Try QToolButton which is made for QToolBar

                  Thank you, I already have several QToolButtons in the toolbar but I really needed this one to stand out.

                  1 Reply Last reply
                  0

                  1/8

                  9 Aug 2021, 07:57

                  • Login

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