6

I have a big layout that contains widgets and layouts of the following structure:

QVBoxLayout
  QTableView
  QPushButton

I set the margins, padding, and spacing on the layout to 0. The way this renders on Mac OS X, the button doesn't fill all of its space. Instead, there is some padding around it. Magically, the layout seems to know this, and makes sure the table view is exactly as wide as the button is wide:

Magic padding caused by QPushButton

When I remove the button, the table view returns to its full width:

No magic padding here

How can I change it so the button, as well as the table view, become as wide as the layout?

I've played with stylesheet's padding and margin, and while I can use those to make the button wider, the extra padding around the tree view remains. The only solution I have so far is to wrap the button in another widget, and then set its margin and padding to 0 via stylesheet, but then I lose the rounded look.

Dirk Groeneveld
  • 2,547
  • 2
  • 22
  • 23

4 Answers4

1

you have to set layout margins to 0, not QPushButton's margins.

Take a look. this is designer look&feel:

enter image description here

This is QWidget's layout properties:

enter image description here

And this is final widget:

enter image description here

Alberto
  • 718
  • 4
  • 20
  • Sadly I can't test it on mac, but if you say that it doesn't work maybe it something related with Mac style.Qt [says](http://doc.qt.digia.com/qt/qstyle.html#details):`There are two approaches to creating a custom style. In the static approach, you either choose an existing QStyle class, subclass it, and reimplement virtual functions to provide the custom behavior, or you create an entire QStyle class from scratch. In the dynamic approach, you modify the behavior of your system style at runtime. The static approach is described below. The dynamic approach is described in QProxyStyle.` – Alberto Oct 22 '12 at 08:16
  • 1
    QPushButton (and QCheckBox) breaks margins on Mac OS. So it's Mac related problem. Question should has something #mac tag. – Ivan Romanov Apr 13 '17 at 08:30
  • 1
    I added the #osx tag. – Dirk Groeneveld Apr 13 '17 at 23:24
0

After some more experimentation, I found that it works as expected with a QToolButton instead of a QPushButton. That's not an explanation, but it's a solution.

Dirk Groeneveld
  • 2,547
  • 2
  • 22
  • 23
0

Hmm. interesting. The following code is for testing your problem but could not find any. it just works as it is.(using Qt 4.8.2 on Mac OSX). The code is self containing. just put it as main.cpp to build application and click show and hide button to test.

#include <QtGui>

class FramedWidget : public QFrame
{
public:
    FramedWidget(QWidget* inner, QWidget* parent=0)
        : QFrame(parent)
    {
        setFrameStyle(QFrame::Panel | QFrame::Sunken);
        QVBoxLayout* lay = new QVBoxLayout(this);
        lay->setContentsMargins(0,0,0,0);
        lay->setSpacing(0);
        lay->addWidget(inner);
    }
};

class LayoutWidget : public QSplitter
{
public:
    LayoutWidget(QWidget* parent=0)
        : QSplitter(parent)
    {
        QTableWidget* table = new QTableWidget;
        m_button = new QPushButton("Testing...");
        QPushButton* showButton = new QPushButton("Show");
        QPushButton* hideButton = new QPushButton("Hide");
        connect(showButton, SIGNAL(clicked()),
                m_button, SLOT(show()));
        connect(hideButton, SIGNAL(clicked()),
                m_button, SLOT(hide()));

        QWidget* tester = new QWidget;
        QVBoxLayout* testerLay = new QVBoxLayout(tester);
        testerLay->addWidget(table);
        testerLay->addWidget(m_button);

        QWidget* controller = new QWidget;
        QVBoxLayout* controllerLay = new QVBoxLayout(controller);
        controllerLay->addWidget(showButton);
        controllerLay->addWidget(hideButton);
        controllerLay->addWidget(new QTextEdit);

        this->addWidget(new FramedWidget(controller));
        this->addWidget(new FramedWidget(tester));
    }
protected:
    QPushButton* m_button;
};

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    LayoutWidget* editor = new LayoutWidget;
    editor->show();
    editor->raise();
    return app.exec();
}
Joonhwan
  • 495
  • 5
  • 11
  • 1
    Add `testerLay->setContentsMargins(0,0,0,0);` and `controllerLay->setContentsMargins(0,0,0,0);` to see the problem. – Ivan Romanov Apr 13 '17 at 08:57
0

Another workaround that preserves the look of a push button is to put the layout in a QFrame container widget and set negative padding in the stylesheet. The container has to be a QFrame or padding won't work.

Jason Haslam
  • 2,617
  • 13
  • 19