我有一个充满了QPushButtons和QLabels以及其他各种有趣的QWidgets的窗口,所有这些都是使用各种QLayout对象动态布局的......而我想要做的是偶尔让一些小部件变得不可见.也就是说,隐形窗口小部件仍会占用窗口布局中的正常空间,但它们不会被渲染:相反,用户只会在窗口小部件的矩形/区域中看到窗口的背景颜色.
hide()和/或setVisible(false)不会这样做,因为它们会导致小部件完全从布局中删除,允许其他小部件扩展以占用"新可用"空间; 我想避免的效果.
我想我可以创建一个QWidget覆盖paintEvent()(和mousePressEvent()等)的每个类型的子类为无操作(在适当的时候),但我更喜欢一个不需要我创建三十个不同QWidget子类的解决方案.
Tho*_*sum 55
这个问题在Qt 5.2中得到了解决.可爱的解决方案是:
QSizePolicy sp_retain = widget->sizePolicy();
sp_retain.setRetainSizeWhenHidden(true);
widget->setSizePolicy(sp_retain);
Run Code Online (Sandbox Code Playgroud)
http://doc.qt.io/qt-5/qsizepolicy.html#setRetainSizeWhenHidden
Rei*_*ica 14
我所知道的唯一不错的方法是将事件过滤器附加到窗口小部件,并过滤掉重绘事件.无论窗口小部件有多复杂,它都可以工作 - 它可以有子窗口小部件.
以下是一个完整的独立示例.但是,它有一些警告,需要进一步开发才能完成.只覆盖绘制事件,因此您仍然可以与窗口小部件进行交互,您将看不到任何效果.
鼠标点击,鼠标进入/离开事件,焦点事件等仍将进入窗口小部件.如果窗口小部件依赖于在重新绘制时执行的某些操作,可能是由于在这些事件上触发的update(),则可能存在问题.
至少你需要一个case语句来阻止更多的事件 - 比如鼠标移动和点击事件.处理焦点是一个值得关注的问题:如果小部件在焦点处于隐藏状态时以及重新获得焦点时,您需要将焦点移至链中的下一个小部件.
鼠标跟踪也提出了一些问题,你想假装小部件在之前跟踪时丢失鼠标跟踪.正确地模拟这将需要一些研究,我不知道Qt向小部件提供的确切鼠标跟踪事件协议.
//main.cpp
#include <QEvent>
#include <QPaintEvent>
#include <QWidget>
#include <QLabel>
#include <QPushButton>
#include <QGridLayout>
#include <QDialogButtonBox>
#include <QApplication>
class Hider : public QObject
{
Q_OBJECT
public:
Hider(QObject * parent = 0) : QObject(parent) {}
bool eventFilter(QObject *, QEvent * ev) {
return ev->type() == QEvent::Paint;
}
void hide(QWidget * w) {
w->installEventFilter(this);
w->update();
}
void unhide(QWidget * w) {
w->removeEventFilter(this);
w->update();
}
Q_SLOT void hideWidget()
{
QObject * s = sender();
if (s->isWidgetType()) { hide(qobject_cast<QWidget*>(s)); }
}
};
class Window : public QWidget
{
Q_OBJECT
Hider m_hider;
QDialogButtonBox m_buttons;
QWidget * m_widget;
Q_SLOT void on_hide_clicked() { m_hider.hide(m_widget); }
Q_SLOT void on_show_clicked() { m_hider.unhide(m_widget); }
public:
Window() {
QGridLayout * lt = new QGridLayout(this);
lt->addWidget(new QLabel("label1"), 0, 0);
lt->addWidget(m_widget = new QLabel("hiding label2"), 0, 1);
lt->addWidget(new QLabel("label3"), 0, 2);
lt->addWidget(&m_buttons, 1, 0, 1, 3);
QWidget * b;
b = m_buttons.addButton("&Hide", QDialogButtonBox::ActionRole);
b->setObjectName("hide");
b = m_buttons.addButton("&Show", QDialogButtonBox::ActionRole);
b->setObjectName("show");
b = m_buttons.addButton("Hide &Self", QDialogButtonBox::ActionRole);
connect(b, SIGNAL(clicked()), &m_hider, SLOT(hideWidget()));
QMetaObject::connectSlotsByName(this);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Window w;
w.show();
return a.exec();
}
#include "main.moc"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
32176 次 |
| 最近记录: |