I've written a simple "proxy widget" class in Qt; the idea is that this widget will hold a single child QWidget and represent that widget in the QWidget
hierarchy. (FWIW, the motivation for doing this is to make it easy to move the child widget around the hierarchy without having to directly disturb the state of various other container-QWidgets
to do so).
This seems to work fairly well; the only problem I've run into is that I want my ProxyWidget
to always be laid-out the same way as its child-QWidget
would be (if the child had been added to the widget hierarchy directly); but instead I find that the ProxyWidget
is often sized larger than its child would be, leading to wasted space in the GUI.
Therefore, is there some way I can craft my ProxyWidget
class so that Qt's layout managers to move/size it exactly the same as if its child widget was added directly?
As a minimal test/example, you can compile the following code and run it with or without the "proxy" command line argument -- my goal is that the visual results would be the same either way, and in particular that you would never see any red pixels in the window (since red pixels indicate areas where the ProxyWidget
has been sized larger than the blue child widget it contains)
#include <QApplication>
#include <QStackedLayout>
#include <QWidget>
class ProxyWidget : public QWidget
{
public:
ProxyWidget(QWidget * childWidget)
: _childWidget(childWidget)
, _layout(new QStackedLayout(this))
{
_layout->addWidget(childWidget);
setSizePolicy(childWidget->sizePolicy());
}
virtual QSize sizeHint() const {return _childWidget->sizeHint();}
virtual QSize minimumSizeHint() const {return _childWidget->minimumSizeHint();}
private:
QWidget * _childWidget;
QStackedLayout * _layout;
};
static void SetWidgetBackgroundColor(QWidget * w, const QColor bc)
{
QPalette p = w->palette();
p.setColor(QPalette::Window, bc);
w->setAutoFillBackground(true);
w->setPalette(p);
}
int main(int argc, char ** argv)
{
QApplication app(argc, argv);
QWidget * win = new QWidget;
win->setWindowTitle("Proxy Widget test");
QWidget * proxyMe = new QWidget;
proxyMe->setFixedSize(100, 50);
SetWidgetBackgroundColor(proxyMe, Qt::blue);
QBoxLayout * winLayout = new QBoxLayout(QBoxLayout::TopToBottom, win);
if ((argc >= 2)&&(strcmp(argv[1], "proxy") == 0))
{
ProxyWidget * proxyWidget = new ProxyWidget(proxyMe);
SetWidgetBackgroundColor(proxyWidget, Qt::red);
winLayout->addWidget(proxyWidget);
}
else winLayout->addWidget(proxyMe);
win->show();
return app.exec();
}
I guess minimumSize
and maximumSize
of ProxyWidget
is different from its child widget and setting them fix things in your particular example :
ProxyWidget(QWidget * childWidget)
: _childWidget(childWidget)
, _layout(new QStackedLayout(this))
{
_layout->addWidget(childWidget);
setSizePolicy(childWidget->sizePolicy());
this->setMinimumSize(childWidget->minimumSize());
this->setMaximumSize(childWidget->maximumSize());
}
However i am not sure it's the best solution but it might gives you a hint to a better one.