I am not able to remove a particular widget from a cell in a qgridlayout. I tried several codes found in internet... but i failed!! the way how i did the work was, first i created a qwidget class containing button,qpixmap,qplaintextedit. i then created an object of this class and it was set dynamically on the QGridLayout. the layout was then set on the current widget using this pointer. I am able to addwidgets on the gridlayout, but not able to delete it.. i want to delete the whole widget i created only if the pixmap is null!!! Do anyone knows a suitable remedy for this problem??
To remove a widget without deleting it, call
void QLayout::removeWidget(QWidget*)
To remove and delete a widget, just delete it.
Related
I subclass a QTableWidget class and wanted to display in QTabWidget, something like this:
class Mainwindow:
_tabWidget->addTab(doc, QFileInfo(doc->fileName()).fileName());
class doc:
_tableWidget = new QTableWidget(row, column);
I can debug that "doc" is not NULL.
_tableWidget have values in rows and cells.
But all I can see on my application is the display of tab with correct label,
there are no rows and columns drawn.
I created the _tabWidget programmatically.
What are the reasons why the content of "doc" were not displayed?
Thanks in advance.
I tried to access the QTableWidget object of custom class from the Mainwindow class using a getter function (doc->table()):
_tabWidget->addTab(doc->table(), QFileInfo(doc->fileName()).fileName());
The rows and columns are now displayed.
Is it really the way to do it?
What you are doing in the little piece of code showing is creating a QTabWidget and adding a tab with a QWidget (base class of Doc) object. In your edit (that works), you are no longer adding the QWidget (doc), but adding a QTableWidget object (doc->table()) directly, which works.
I thus can only conclude that you are not setting a layout for QWidget and thus not putting the QTableWidget in the layout.
Im using QListWidget to show names as a type of dropdown when someone
types entries in another QLineEdit field. It hits the database and shows
all possibilities to choose from. As they type, the list changes, so I want
it to delete all entries and re-fill the QListWidget.
When I call the following code, it indeed empties the QListWidget list, but
the screen elements are still visible. Can someone help me figure out why
they arent being removed from the display? Im using Qt 4.8.4. Thank you!
void myClass::clearListWidget()
{
QListWidget * lw = m_ui->db_listWidget;
while(lw->selectedItems().size())
{
delete lw->takeItem(0);
}
lw->update();
lw->repaint();
qApp->processEvents();
}
Use slot void QListWidget::clear() to clear all contents. QListWidget documentation is here.
(I use Qt 4.7, Windows 7, 64bit).
I created a custom table. Each row is a horizontal layout with widgets.
The rows are kept in a QList for easy access, and the children too. The rows are also added inside the parent widget.
If I resize the parent widget, I calculate the new sizes, delete everything, and recreate it again.
My problem is that I don't want to delete any widget. Only when I clear the table, I do it.
Since I have the widgets inside a QList and inside the parent layouts, How can I remove all widgets in each row, delete all layouts, and then add those to new layouts?
If I do: takeAt(0) for every element inside each layout I have a QLayoutItem with a widget inside... How can I delete the layoutItem without deleting the widget?.... How do I remove the widget without killing it, no matter if it's in the parent or the child? Because there are many methods for deleting: removeItem, removeWidget... in a layout, but not takeWidget... just takeAt() and it gives a Qlayoutitem.
I tried several ways, but I still see the widgets no matter what happened to them.
Questions about this:
When does a widget get deleted? If I takeWidget(index) from a layout, is it deleted some time by itself? does it happen if I have a pointer to it in another list?
removeAt(index) does execute the delete method of a widget?
Ok. I got it working.
Let me explain how this Removing, keeping widgets works.
A widget is known by its parent layout. And you remove it through the layout. By doing:
layout()->removeAt(widget);
delete widget;
If you use takeAt(index) in a QLayout (or its children), it gives you a QLayoutItem. To access the widget inside, just use widget(). But there's no way to remove the widget without deleting it. So this approach is non valid.
In the Docs it tells a way to delete the elements:
QLayoutItem *child;
while ((child = layout->takeAt(0)) != 0) {
...
delete child;
}
A special thing to note in Qt is the following:
If you have a hierarchy tree of layouts, added with addLayout() inside layouts, no matter how deep your widget is inserted, you can remove it from the child layouts or any of the parent layouts, if the tree path from the layout and this item is built from child layouts.
The easiest thing is to keep a list of pointers to all the items, in a custom table. When clearing the table to reconstruct it, just do this inside your widget:
CustomTableItem* item;
while ( !items_.isEmpty() && ( (item = items_.takeFirst()) != 0 ) ){
layout()->removeWidget(item);
delete item; // It works no matter where the item is
}
items_.clear(); // clear the list afterwards.
And it works perfectly, updates the layout too by itself.
If you want to keep the elements, just skip the "delete item;" and use them afterwards.
An important thing to note is that different "remove" functions work differently (as i understand on Qt Docs) in QList or similar widgets, and in a QLayout.
In the QList, removeAt actually removes the object.
(Qt 4.7 QList Docs)"Removes the item at index position i. i must be a valid index position in the list (i.e., 0 <= i < size())."
In a QLayout, removeWidget or removeItem don't remove the item/widget, you have the responsability to delete it, as I did before.
(Qt 4.7 QLayout Docs) "Removes the widget widget from the layout. After this call, it is the
caller's responsibility to give the widget a reasonable geometry or to
put the widget back into a layout."
Hope it helps. If you see any error, you could tell me and I will edit the answer!
More on deleting here:
Other stackoverflow post
A widget in Qt is a regular C++ object and can be deleted with the C++ delete operator as any other object:
delete myWidget;
In Qt there is always a parent-child relation between widgets. When the parent widget is destroyed, it will delete all its children. Usually, you do not need to think about explicitly deleting any widgets but the top level widgets, i.e., windows and dialogs. Qt will take care of deleting any child widgets.
QList::removeAt(int) does not delete the object that is removed, it only removes the object from the list. If you also want to delete the object you would have to do something like:
delete myList.takeAt(0);
This applies to all functions such as removeAt(int), takeAt(int), takeFirst(), etc. They never delete objects, they only remove them from the container (list, layout, scrollarea, etc). In most cases the ownership of the widget is then transferred to the caller, (the caller becomes responsible for deleting the widget as the parent-child relation breaks), but do not assume this is always the case, always read the documentation of the function.
i created one QWidget(Parent). in the inside of the parent widget i created another one QWidget(Child). In the run time i need to remove the child widget. how to do that?
i am not using any layout. i am directly putting in the Parent Widget.
Please Help me to fix this.
If you add the widget with e.g.:
QWidget *w = new QWidget(parent);
...then you can remove it with:
delete w;
Another approach would be to just hide it:
w->hide();
This answer is for those arriving from search engines and want an answer to the question as stated in the title.
If you want to remove a child from a parent without deleting it or hiding it (which does NOT remove it from its parent), set the child's parent to NULL.
QWidget::setParent(NULL)
Note that explicitly reparenting a widget like this carries several implications (e.g visibility automatically set to hidden). See QWidgets documentation for more information.
In my app have a window splitted by a QSplitter, and I need to remove an widget.
How can I do that? I can't find useful methods
It's not clear to me if you want to preserve the widget and put it somewhere else, or if you want to destroy the widget.
Destroying the widget: If you can
get a pointer to the widget, you can
simply delete it. The splitter will
safely be notified that its child is
being deleted and will remove it
from itself.
Preserving the widget: If you grab
the pointer to the widget, you can
simply set its parent to some other
widget and add it to another
widget's layout and it will show up
there. This is safe because the
QSplitter will be notified that one
of its children is being reparented.
If you want to set the parent to NULL (cjhuitt's answer) be aware that you are now responsible for cleaning up that memory because the widget no longer has a parent.
Many things in Qt cannot be "traditionally" removed. Instead call hide() on it and destruct it. From QSplitter documentation:
When you hide() a child its space will
be distributed among the other
children. It will be reinstated when
you show() it again.
I like Tuminoid's answer. But if you absolutely need it removed, try getting the widget you want to remove, and calling setParent( NULL ) on that widget. That's my best guess.
If you hold a pointer to the widget, then just delete it, or use deleteLater() if you want to be on the safe side.
If you do not have the widget pointer, use QSplitter::widget(int index) function. Then, you can use invoke its deleteLater() slot.
If you do not have the widget index, but you still know the widget objectName(), then QObject::findChild() is your only way to get the widget pointer.
I ran into the same problem. In Qt 4.8 to temporally hide one of the widget of a QSplitter I simply hide it. However it is not enough, as the splitter handle is still available to move. But the handle can be accessed and hidden as well:
frameA->setVisible(conditionA);
frameB->setVisible(conditionB);
if ( !(conditionA && conditionB) ) // if only 1 frame is visible
{
splitter->handle(0)->setVisible(false);
}
Another easy way to prevent the child widget from getting deleted is to use QSplitter.takeWidget(child). This is also the recommended way of removing the widget from a splitter. (Qt Documentation)