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. Applying a style sheet to a QPushButton and a QToolButton
QtWS25 Last Chance

Applying a style sheet to a QPushButton and a QToolButton

Scheduled Pinned Locked Moved General and Desktop
qpushbuttonstylesheetqtoolbutton
1 Posts 1 Posters 2.2k Views
  • 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.
  • E Offline
    E Offline
    eos pengwern
    wrote on 4 Jun 2015, 06:25 last edited by eos pengwern 6 Apr 2015, 14:08
    #1

    I'm trying to create a widget which will have similar behaviour to a QComboBox, but with different behaviours depending on whether the user clicks on the arrow or elsewhere on the widget. For starters, I'm modelling the widget itself as a wide QPushButton with a QToolButton superimposed on it. Once I have this looking as I want it to, I'll add a QListView to provide the drop-down menu and make it appear whenever the unit presses the QToolButton (but not the QPushButton). My basic test code so far looks like this:

        #include <QtWidgets/QApplication>
    
        #include <QDialog>
        #include <QPushButton>
        #include <QToolButton>
        #include <QPushButton>
        #include <QGridLayout>
    
        class StylesheetTest : public QDialog
        {
            Q_OBJECT
        public:
            StylesheetTest(QWidget * parent = nullptr) : QDialog(parent)
            {
                // Create the widgets and layouts
                itsLayout = new QGridLayout;
                itsMainButton = new QPushButton;
                itsDropdownButton = new QToolButton;
    
                // Place the widgets in the layout:
                itsLayout -> addWidget(itsMainButton, 0, 0, 1, 2);
                itsLayout -> addWidget(itsDropdownButton, 0, 1, 1, 1);
                itsLayout -> setSpacing(0);
                itsLayout -> setColumnStretch(0, 1);
                itsMainButton -> setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
                itsDropdownButton -> setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
                itsDropdownButton -> setArrowType(Qt::DownArrow);
    
                // Formally appoint the layout
                setLayout(itsLayout);
    
                // Now the stylesheet settings
                setStyleSheet("QToolButton { border: none; } ");
    
    	        // Give the button a label
                itsMainButton -> setText("An extraordinarily long label for a button");
            }
    
        private:
            QPushButton *itsMainButton;
            QToolButton *itsDropdownButton;
            QGridLayout *itsLayout;
        };
    
        int main(int argc, char *argv[])
        {
            QApplication a(argc, argv);
            StylesheetTest t;
            t.show();
            return a.exec();
        }
    
        #include "main.moc"
    

    This gets me most of the way there; the resulting button looks like this:

    First attempt

    It looks very much like a QComboBox, but I get the independent behaviours of the QPushButton and the QToolButton, just as I want. However, I'd like to make it even better:

    • I'd like to set a bit of a margin on the right-hand side of the QPushButton, so that the text doesn't overlap the arrow
    • I'd like the arrow itself to be a bit smaller

    Everything I know about style sheets (which admittedly isn't much) tells me that to achieve this I need something resembling

            // Now the stylesheet settings
            setStyleSheet("QPushButton { padding-right: 20px; }");
            setStyleSheet("QToolButton { border: none; } "
                          "QToolButton::down-arrow { width: 8px; height: 8px; }" );
    

    but in fact the result of this is a mess:

    Second attempt - much worse

    Further experimentation shows that trying to set the 'padding-right' parameter of the QPushButton to any value at all leads to its vertical height getting squeezed in this way, while all attempts to modify the size of the down-arrow fail. I'm obviously doing something wrong, but I can't see what. Any hints would be gratefully received.

    UPDATE

    I've decided that a better approach is, rather than using a QToolButton in front of a QPushButton and having manually to implement the QListView behaviour, to put a QPushButton in front of a QComboBox leacing just the latter's arrow exposed. Like this:

        #include <QtWidgets/QApplication>
        #include <QDialog>
        #include <QPushButton>
        #include <QComboBox>
        #include <QGridLayout>
    
        class StylesheetTest : public QDialog
        {
            Q_OBJECT
        public:
            StylesheetTest(QWidget * parent = nullptr) : QDialog(parent)
            {
                // Create the widgets and layouts
                itsLayout = new QGridLayout;
                itsMainButton = new QPushButton;
                itsHiddenComboBox = new QComboBox;
    
                // Place the widgets in the layout:
                itsLayout -> addWidget(itsHiddenComboBox, 0, 0, 1, 3);
                itsLayout -> addWidget(itsMainButton,     0, 0, 1, 2);
                itsLayout -> setSpacing(0);
                itsLayout -> setColumnStretch(0, 1);
                itsLayout -> setColumnMinimumWidth(2, 20);
                itsMainButton -> setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
                itsHiddenComboBox -> setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
                setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
    
                // Formally appoint the layout
                setLayout(itsLayout);
    
                // Now the stylesheet settings
                setStyleSheet("QPushButton { border: none; padding-left: 10px; } ");
                itsMainButton -> setText("An extraordinarily long label for a button");
            }
    
        private:
            QPushButton *itsMainButton;
            QComboBox   *itsHiddenComboBox;
            QGridLayout *itsLayout;
        };
    
        int main(int argc, char *argv[])
        {
            QApplication a(argc, argv);
            StylesheetTest t;
            t.show();
            return a.exec();
        }
    
        #include "main.moc"
    

    The one shortcoming of this solution is that, having eliminated the border from the QPushButton, it no longer responds visibly to being clicked (even though the usual signals are sent). As it happens I can cope with this, as my ultimate intention is for pressing the QPushButton to cause a change of the cursor and this will make it obvious enough to the user that the button has been successfully clicked.

    1 Reply Last reply
    0

    1/1

    4 Jun 2015, 06:25

    • Login

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