Can you hide a QGroupBox frame but preserve it's content visible? - qt

I have a QGroupBox. Depending on the context, it's title may be redundent (displayed in another place of the GUI), so I then need to make as if the QGroupBox was not here....but I must preserve it's content visible (so I don't want to call QGroupBox::hide())!
I need to do this dynamically at runtime and would like to avoid creating/destroying the QGroupBox + reparenting it's content....there must be an easier way to do this.
What I tried so far:
QGroupBox visible:
QGroupBox::setTitle("") removes the text.
QGroupBox::setFlat(true) makes the frame be a single line.
I end up with this:
Not too bad...but a line remains....is there a way to completely hide the QGroupBox frame but preserve it's content visible?

My option:
QGroupBox theBox;
theBox.setFlat(true);
//This removes the border from a QGroupBox named "theBox".
theBox.setStyleSheet("QGroupBox#theBox {border:0;}");
//This removes the border from the group box and all of its children
theBox.setStyleSheet("border:0;");

You can derive your own Group Box from the QGroupBox and reimplement the paintEvent() method. It should be very simple. Original QGroupBox::paintEvent() looks like this:
void QGroupBox::paintEvent(QPaintEvent *)
{
QStylePainter paint(this);
QStyleOptionGroupBox option;
initStyleOption(&option);
paint.drawComplexControl(QStyle::CC_GroupBox, option);
}
What you need to do is just to modify the style option right before the widget is painted:
void CMyGroupBox::paintEvent(QPaintEvent *)
{
QStylePainter paint(this);
QStyleOptionGroupBox option;
initStyleOption(&option);
// This should disable frame painting.
option.features = QStyleOptionFrame::None;
paint.drawComplexControl(QStyle::CC_GroupBox, option);
}

You can use QFrame + QGridLayout (or some more complex combination of layouts) + QSS instead of a QGroupBox.
Considering a QGroupBox only, a trivial solution via QSS could be:
static const char kSavedTitle[] = "_savedTitle";
void hideBoxFrame(QGroupBox * box) {
box->setProperty(kSavedTitle, box->title());
box->setTitle(QString());
box->setStyleSheet("border:none");
}
void showBoxFrame(QGroupBox * box) {
box->setTitle(box->property(kSavedTitle).toString());
box->setStyleSheet(QString());
}

Here's an example that does it by swapping the widgets and reparenting the children. It works for any widget that has direct children, not only QGroupBox. It would require special case handling for widgets such as QScrollArea and QMainWindow that wrap children in a special sub-widget.
See this question for a related discussion of programmatically promoting widgets.
// https://github.com/KubaO/stackoverflown/tree/master/questions/group-reparent-36603051
#include <QtWidgets>
/// Replaces the visible widget with a hidden widget, preserving the layout of the
/// children, and making the new widget visible.
void swapWidgets(QWidget * a, QWidget * b)
{
auto src = a->isVisible() ? a : b;
auto dst = a->isVisible() ? b : a;
Q_ASSERT(dst->isHidden());
/// Move the children to the destination
dst->setLayout(src->layout());
/// Replace source with destination in the parent
auto layout = src->parentWidget()->layout();
delete layout->replaceWidget(src, dst);
/// Unparent the source, otherwise it won't be reinsertable into the parent.
src->setParent(nullptr);
/// Only the destination should be seen.
src->hide();
dst->show();
}
int main(int argc, char ** argv) {
QApplication app{argc, argv};
QWidget w;
QGridLayout wLayout{&w};
QPushButton swapBtn{"Swap"};
wLayout.addWidget(&swapBtn);
QWidget noBox;
QGroupBox box{"Group"};
wLayout.addWidget(&box);
QGridLayout boxLayout{&box};
for (int i = 0; i < 16; ++i)
boxLayout.addWidget(new QLabel(QString("Tr%1").arg(i)), i/8, i%8);
swapBtn.connect(&swapBtn, &QPushButton::clicked, [&] { swapWidgets(&box, &noBox); });
w.show();
return app.exec();
}

Yes there is a alternative that you can Try.
You can morph into a QFrame which will keep the behavior But make the container boundaryless
You can simply right click on the Group Box in the QDesigner and Select the 'Morph Into' option to select from

Related

How to change the font of the qcombobox label/header only?

When I change the font of my QComboBox comboBox->setFont(whateverQFont); it is applied on the dropdown menu as well (all the items), and it overrides the Qt::FontRole data I have set on my items with comboBox->setItemData(index, itemSpecificFont, Qt::FontRole);
I'd like to set a font on the QComboBox label only and leave the dropdown displayed as it was. Or even better : to have directly the same font as the selected item.
Is there an easy way to do that ?
Edit: Solution of Jasonhan works fine for an editable QComboBox (-> setting the font on the QLineEdit) but is not applicable for a regular QComboBox, as the QLabel is private.
Before starting implement a custom model you could try with QListView.
It just applies to the drop-down menu and you can change its font with the usual setFont function; the you have to apply it to your QComboBox thorugh routine setView.
Something like this (it's not Qt C++ code, I've skipped all arguments in function calls):
QComboBox *combobox = new QComboBox();
combobox->setFont();
...
QListView *listview = new QListView();
listview->setFont();
combobox->setView(listview);
After 2 years, I saw this question. I don't know whether you have found a better method or not. If not, following code may give you a hint.
QComboBox label as you said is actually a QLineEdit, so you just need to set this component's font, and it will solve your problem.
QComboBox *box = new QComboBox();
//add some list items to box
if (box->lineEdit())
box->lineEdit()->setFont(font);//font is your desirable font
Something that works for a non-editable QComboBox is to install a QProxyStyle that sets the font when a CE_ComboBoxLabel control element is drawn.
Here's an example that sets the label font to italic:
#include <QApplication>
#include <QProxyStyle>
#include <QPainter>
#include <QComboBox>
class MyProxyStyle : public QProxyStyle
{
public:
void drawControl(QStyle::ControlElement element, const QStyleOption *option,
QPainter *painter, const QWidget *widget = nullptr) const override
{
if (element == QStyle::CE_ComboBoxLabel)
{
auto fnt = painter->font();
fnt.setItalic(true);
painter->setFont(fnt);
}
QProxyStyle::drawControl(element, option, painter, widget);
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
app.setStyle(new MyProxyStyle);
QComboBox cb;
cb.addItem("Option 1");
cb.addItem("Option 2");
cb.addItem("Option 3");
cb.show();
app.exec();
}

QTabWidget how to hide pane only?

I have added a QToolButton as corner widget in QTabWidget which is checkable. I want to hide all tabs (panes only) when the tool button is unchecked. I tried to connect button's signal clicked(bool) with all tab's setVisible(bool) slot not working but. I also connected tabwidget's setvisible to the signal but complete widget became invisible(it was a silly trial). Is there any way to make only pane invisible and tab bar will not disappear ?
Edit: Code (ui have a tabwidget and two tabs namely tab and tab_2)
ui->setupUi(this);
QToolButton * b = new QToolButton;
b->setCheckable(true);
b->setChecked(true);
b->setAutoRaise(true);
b->setText("Hide Tabs");
ui->tabWidget->setCornerWidget(b);
connect(b,SIGNAL(clicked()),ui->tab,SLOT(hide()));
connect(b,SIGNAL(clicked()),ui->tab_2,SLOT(hide()));
Use qFindChild to find the QTabBar within the QTabWidget:
QTabBar *tabBar = qFindChild<QTabBar *>(ui->tabWidget);
tabBar->hide();
For Qt5:
QTabBar *tabBar = ui->tabWidget->findChild<QTabBar *>();
tabBar->hide();
so I understand it like this, you want to hide the TabBar and let the tab visible. Or at least that's what I get from your question
Well if that the case all you have to do it's this:
connect(ui->pushButton,SIGNAL(clicked()),ui->tabWidget->tabBar(),SLOT(hide()));
I hope this was helpful, even do the questions in a little old, I though it may help new viewers.
Here is my take on this. I've created a class that inherits QTabWidget. What I do is; set the "maximum vertical size of QTabWidget" to its tabBars height to hide the panels.
It is a hacky solution and I had to add some extra lines to deal with quirks.
file: hidabletabwidget.h
#ifndef HIDABLETABWIDGET_H
#define HIDABLETABWIDGET_H
#include <QTabWidget>
#include <QAction>
class HidableTabWidget : public QTabWidget
{
Q_OBJECT
public:
explicit HidableTabWidget(QWidget *parent = 0);
QAction hideAction;
private slots:
void onHideAction(bool checked);
void onTabBarClicked();
};
#endif // HIDABLETABWIDGET_H
file: hidablewidget.cpp
#include "hidabletabwidget.h"
#include <QTabBar>
#include <QToolButton>
HidableTabWidget::HidableTabWidget(QWidget *parent) :
QTabWidget(parent),
hideAction("▾", this)
{
hideAction.setCheckable(true);
hideAction.setToolTip("Hide Panels");
QToolButton* hideButton = new QToolButton();
hideButton->setDefaultAction(&hideAction);
hideButton->setAutoRaise(true);
this->setCornerWidget(hideButton);
connect(&hideAction, SIGNAL(toggled(bool)), this, SLOT(onHideAction(bool)));
connect(this, SIGNAL(tabBarClicked(int)), this, SLOT(onTabBarClicked()));
}
void HidableTabWidget::onHideAction(bool checked)
{
if (checked)
{
this->setMaximumHeight(this->tabBar()->height());
this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
}
else
{
this->setMaximumHeight(QWIDGETSIZE_MAX); // by default widgets can expand to a maximum sized defined by this macro
this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
}
}
void HidableTabWidget::onTabBarClicked()
{
hideAction.setChecked(false);
}
To use this, you can simply "promote" your QTabWidget to "HidableTabWidget" using qt designer.
And here is how it looks on my system:
You usually want to remove the Tab from the QTabWidget:
void QTabWidget::removeTab ( int index )
The Tab removed will not be deleted and can be reinserted!
So you would connect your QToolButton b to a slot which simply removes the Tabs like this:
connect( b, SIGNAL(clicked()), this, SLOT(hideTabs() );
..
void Foobar::hideTabs( void )
{
for( int i = 0; i < ui->tabWidget->count(); ++i )
ui->tabWidget->removeTab(i);
}
I can not comment due to my low "reputation" so far. If I could I'd just add a comment to Anatoli's answer: the goal is to hide "page area", not "tab bar". So if we imply they always use QStackedWidget for that then the answer should be more like:
auto * tab_pane = qFindChild<QStackedWidget *>(ui->tabWidget);
tab_pane->hide();
or for Qt5:
auto * tab_pane = ui->tabWidget->findChild<QStackedWidget *>();
tab_pane->hide();

Can you set a QWidget to take up an entire column of a QTreeWidget?

I have a custom QTreeWidget subclass that I'm using to display track names/etc. in my MIDI editor project (https://github.com/waddlesplash/ragingmidi). I'd like to add another column to this tree widget, but with one widget taking up the whole column and not per-item widgets.
Is this possible or will I have to figure out some other solution?
EDIT: I'm trying to accomplish something like this: http://www.anvilstudio.com/compose.jpg - see the last "column" in the header view (3rd after "L/R Balance") showing all the lines/notes (which is entirely custom, and written in VB.NET and closed-source anyway).
EDIT 2: You can't see it, but the last column scrolls without the other columns scrolling in the above picture. In their method, you have to scroll using the mouse. I want a scrollbar.
Looking at the Qt documentation, there seems to be a few options to accomplish this, however there are a few important factors to address before you can decide what approach best suits your needs.
Is the content being displayed in this custom tree column static or dynamic?
Is there a one to one mapping of rows from your QTreeWidget to your custom tree column?
If your custom tree column content IS static and there IS a one to one mapping of rows , use of the QTreeWidget::setItemWidget ( QTreeWidgetItem * item, int column, QWidget * widget ) function should suffice.
However, if the content of your custom tree column is dynamic OR there is not a one to one mapping of rows, this will require a more complex approach.
As described in the documentation for QTreeWidget; "If you want to display custom dynamic content or implement a custom editor widget, use QTreeView and subclass QItemDelegate. "
QItemDelegate, and its sub classes, perform all drawing facilities for items inserted into Qt item views (like QTreeView, QListView, QTableView, etc..). This essentially allows you to control ALL drawing operations for any item inserted into a QTreeView class, letting you draw dynamic content in addition to being able to extend content across multiple rows.
Having implemented a similar approach for a QListWidget, I recommend using QStyledItemDelegate in lieu of QItemDelegate as it allows you to more easily integrate this widget with your application's style layout. As you did not detail the exact use of this custom QWidget, you also might need the additional facilities provided by QItemEditorCreator, QItemEditorCreatorBase and QItemEditorFactory. I would post the similar widget I developed here if I could, but sadly it is part of a proprietary software suite.
This is not completely pretty, because it got it's problems when the custom widget is in the right-most column and the column is made narrow, but it's a start:
#include <QtGui>
class TreeWidget : public QTreeWidget
{
Q_OBJECT
public:
TreeWidget();
QRect columnRect(int column) const;
private slots:
void repositionColumnWidget();
private:
QPushButton * mColumnWidget;
};
TreeWidget::TreeWidget()
: mColumnWidget(new QPushButton("Custom Column Button", viewport()))
{
const int COLUMN_COUNT = 6;
setColumnCount(COLUMN_COUNT);
for (int row = 0; row < 400; ++row)
{
QStringList columns;
for (int column = 0; column < COLUMN_COUNT; ++column)
{
columns << QString("row %1, column %2").arg(row + 1).arg(column + 1);
}
addTopLevelItem(new QTreeWidgetItem(columns));
}
for (int column = 0; column < COLUMN_COUNT; ++column)
{
resizeColumnToContents(column);
}
repositionColumnWidget();
mColumnWidget->show();
connect(header(), SIGNAL(sectionResized(int,int,int)), this, SLOT(repositionColumnWidget()));
connect(header(), SIGNAL(sectionMoved(int,int,int)), this, SLOT(repositionColumnWidget()));
connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(repositionColumnWidget()));
connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(repositionColumnWidget()));
}
QRect TreeWidget::columnRect(int column) const
{
int itemCount = topLevelItemCount();
if (!itemCount)
{
return QRect();
}
int columnX = header()->sectionViewportPosition(column);
int columnY = visualItemRect(topLevelItem(0)).top();
int columnWidth = header()->sectionSize(column);
int columnHeight = visualItemRect(topLevelItem(itemCount-1)).bottom() - columnY + 1;
return QRect(columnX, columnY, columnWidth, columnHeight);
}
void TreeWidget::repositionColumnWidget()
{
mColumnWidget->setGeometry(columnRect(3));
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setQuitOnLastWindowClosed(true);
TreeWidget treeWidget;
treeWidget.resize(800, 600);
treeWidget.show();
return a.exec();
}
#include "main.moc"
The though that has come to my mind after a week is to hijack the H-scrollbar for the QTreeWidget, and then make that scrollbar scroll only the final column. Because right now, all the columns fit when the window is 620x670px, and who has a screen that small anymore?
Unless anyone has a better solution or objections as to why this is a bad idea, this is the way I'm going to do it.

C++ Qt - How can (virtual) QWidget points to its children?

I am trying to change the border of a QFrame. BUT.
There is a Window::ui, inside of which there is a class inheriting from QWidget.
In that class, there is a QFrame, set with a vertical Layout, which holds 2 other QFrame and do their QFrame business.
Now, this structure is repeated a lot in Window::ui, so I simply added it to a vertical layout named kingdom_decks.
So far, so good.
Let's say, I want to select one of those element. To mark the selection, I want to change the border, from black to red, or just make it thicker. With a QFrame, very easy. BUT
My event handler is a slot in Window::ui. ui goes to kingdom_decks layout, and go to the item selected. itemAt retourn a QLayoutItem, that I can cast as QWidget with widget()... but then?
ui->kingdom_decks->itemAt(idx_prev)->widget()
I tried unsuccessfully
ui->kingdom_decks->itemAt(idx_prev)->widget()->childAt(0,0)
I believe it failed because there is a Qframe in a Layout, instead of a geometry form with real coordonates, or maybe I didn't go deep enough?
Anyway, thank you very much in advance for any ideas on that! Thanks for your time.
EDIT
Code for window.cpp
#include "window.h"
#include "ui_window.h"
Window::Window(Game_state * p, Card_generator * d, QWidget *parent) :
QDialog(parent),
ui(new Ui::Window)
{
ui->setupUi(this);
/*Stuff happen here*/
/* Display cards*/
for (int i = 0; i < 10; ++i){
/*Add widget to layout*/
ui->kingdom_decks->addWidget(new Cards_kingdom(decks->decks_kingdom[i]),0,i);
/*Connect widget to map*/
connect(ui->kingdom_decks->itemAt(i)->widget(), SIGNAL(mousePressEvent()), signal_mapper, SLOT(map()));
/*Map widget and data*/
signal_mapper->setMapping(ui->kingdom_decks->itemAt(i)->widget(), i);
}
/* Action "Select cards" */
connect(signal_mapper, SIGNAL(mapped(int)), this, SLOT(card_kingdom_selected(int)));
}
Window::~Window()
{
delete ui;
}
/*Implementation of SLOT*/
void Window::card_kingdom_selected(int idx){
/*...*/
//?????????????? What to do here???????????
//ui->findChild<QLabel *>("img");
//ui->kingdom_decks->itemAt(idx)->widget()->????;
}
So what happen here is that I have a layout kingdom_decks, in which I loop to add a widget Cards_kingdom, overloading the function addWidget.
ui->kingdom_decks->addWidget(new Cards_kingdom(decks->decks_kingdom[i]),0,i);
This Object Cards_kingdom is a class, such that:
cards_kingdom.h :
class Cards_kingdom : public QWidget {
public:
Cards_kingdom(Deck_kingdom * input_deck); /* Constructor */
bool isSelected();
QLabel * get_img();
/*
* Price and Counter are display in the same label, then are wrapped with Icon in a vertical layout, inside a frame.
*/
private:
QLabel *img; /* Icon */
QLabel *info; /* Nb Cards left*/
QVBoxLayout *layout; /* Layout */
QFrame *pack; /* Frame */
Deck_kingdom *deck; /* Type Deck */
bool select;
};
In window.cpp, i try to retrieve the QLabel * img, to put a border on this image, such that the user sees that it has been selected.
To answer to #Nicholas Smith, how can findChild, find the exact instanciation of Card_kingdom?
EDIT:
OK, I could change my architecture to something like this:
Create a vector of Cards_kingdom * vec
In the for loop,
vec.push_back(new Card_kingdom *);
ui->layout->addWIdget(vec[i])
So now, I think that would work, because layout is holding a pointer to my widget, so I pass by reference, therefore, if I change something in my object, it will appear in the GUI even if I didn't pass by there...
Right? :)
The fun thing with Qt is layouts can become nests and layers and mazes, but I've just had this exact issue with a different twist, I'd personally go for something along the lines of ui->findChild<QFrame *>("frameObjectName") (if you've created QFrame as pointer, if not just drop the *) and access it from there. You'll need to make sure you have an object name filled it for the frame, but that's not too hard and has other benefits.

How to make a Qt widget invisible without changing the position of the other Qt widgets?

I've got a window full of QPushButtons and QLabels and various other fun QWidgets, all layed out dynamically using various QLayout objects... and what I'd like to do is occasionally make some of those widgets become invisible. That is, the invisible widgets would still take up their normal space in the window's layout, but they wouldn't be rendered: instead, the user would just see the window's background color in the widget's rectangle/area.
hide() and/or setVisible(false) won't do the trick because they cause the widget to be removed from the layout entirely, allowing other widgets to expand to take up the "newly available" space; an effect that I want to avoid.
I suppose I could make a subclass of every QWidget type that override paintEvent() (and mousePressEvent() and etc) to be a no-op (when appropriate), but I'd prefer a solution that doesn't require me to create three dozen different QWidget subclasses.
This problem was solved in Qt 5.2. The cute solution is:
QSizePolicy sp_retain = widget->sizePolicy();
sp_retain.setRetainSizeWhenHidden(true);
widget->setSizePolicy(sp_retain);
http://doc.qt.io/qt-5/qsizepolicy.html#setRetainSizeWhenHidden
The only decent way I know of is to attach an event filter to the widget, and filter out repaint events. It will work no matter how complex the widget is - it can have child widgets.
Below is a complete stand-alone example. It comes with some caveats, though, and would need further development to make it complete. Only the paint event is overridden, thus you can still interact with the widget, you just won't see any effects.
Mouse clicks, mouse enter/leave events, focus events, etc. will still get to the widget. If the widget depends on certain things being done upon an a repaint, perhaps due to an update() triggered upon those events, there may be trouble.
At a minimum you'd need a case statement to block more events -- say mouse move and click events. Handling focus is a concern: you'd need to move focus over to the next widget in the chain should the widget be hidden while it's focused, and whenever it'd reacquire focus.
The mouse tracking poses some concerns too, you'd want to pretend that the widget lost mouse tracking if it was tracking before. Properly emulating this would require some research, I don't know off the top of my head what is the exact mouse tracking event protocol that Qt presents to the widgets.
//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"
You can use a QStackedWidget. Put your button on the first page, a blank QWidget on the second, and change the page index to make your button vanish while retaining its original space.
I've 3 solutions in my mind:
1) Subclass your QWidget and use a special/own setVisible() replacement method witch turns on/off the painting of the widget (if the widget should be invisible simply ignore the painting with an overridden paintEvent() method). This is a dirty solution, don't use it if you can do it other ways.
2) Use a QSpacerItem as a placeholder and set it's visibility to the opposite of the QWidget you want to hide but preserve it's position+size in the layout.
3) You can use a special container widget (inherit from QWidget) which gets/synchronizes it's size based on it's child/children widgets' size.
I had a similar problem and I ended up putting a spacer next to my control with a size of 0 in the dimension I cared about and an Expanding sizeType. Then I marked the control itself with an Expanding sizeType and set its stretch to 1. That way, when it's visible it takes priority over the spacer, but when it's invisible the spacer expands to fill the space normally occupied by the control.
May be QWidget::setWindowOpacity(0.0) is what you want? But this method doesn't work everywhere.
One option is to implement a new subclass of QWidgetItem that always returns false for QLayoutItem::isEmpty. I suspect that will work due to Qt's QLayout example subclass documentation:
We ignore QLayoutItem::isEmpty(); this means that the layout will treat hidden widgets as visible.
However, you may find that adding items to your layout is a little annoying that way. In particular, I'm not sure you can easily specify layouts in UI files if you were to do it that way.
Here's a PyQt version of the C++ Hider class from Kuba Ober's answer.
class Hider(QObject):
"""
Hides a widget by blocking its paint event. This is useful if a
widget is in a layout that you do not want to change when the
widget is hidden.
"""
def __init__(self, parent=None):
super(Hider, self).__init__(parent)
def eventFilter(self, obj, ev):
return ev.type() == QEvent.Paint
def hide(self, widget):
widget.installEventFilter(self)
widget.update()
def unhide(self, widget):
widget.removeEventFilter(self)
widget.update()
def hideWidget(self, sender):
if sender.isWidgetType():
self.hide(sender)
I believe you could use a QFrame as a wrapper. Although there might be a better idea.
Try void QWidget::erase (). It works on Qt 3.

Resources