QGraphicsScene does not have a function to remove QWidget - c++

QGraphicsScene has an addWidget(QWidget *) function, but no corresponding removeWidget(QWidget *). It has only removeItem(QGraphicsItem *).
How do I remove a QWidget?

Here's a basic sample, see if it works for you.
QGraphicsScene scene;
QPushButton *button = new QPushButton;
//Add item and obtain QGraphicsProxyWidget
QGraphicsProxyWidget *proxy = scene.addWidget(button);
//Remove item
scene.removeItem(proxy);
Just remember to delete any memory you allocate.
Edit: After OP's comments, maybe this is what you want
//add item
QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget;
proxy = scene.addWidget(button);
//remove item
scene.removeItem(button->graphicsProxyWidget());
Again, remember to delete proxy, or use a smart pointer.

I have a working solution figured out, but I do have some warnings appearing in the console. Here's a basic approximation of what I'm doing:
QGraphicsScene *scene = new QGraphicsScene();
// Add button
QPushButton button = new QPushButton( "Test", this );
scene->addWidget( button );
// Remove button
QGraphicsProxyWidget *proxy;
proxy = proxy->createProxyForChildWidget( button );
scene_->removeItem( proxy );
delete proxy;
proxy = NULL;
delete button;
button = NULL;
Here are the warnings I see though:
QGraphicsProxyWidget::setWidget: cannot embed widget 0x604a2c8 which is not a toplevel widget, and is not a child of an embedded widget
QGraphicsProxyWidget::createProxyForChildWidget: top-level widget not in a QGraphicsScene
QGraphicsScene::removeItem: cannot remove 0-item

Related

Qt layouts, difference between passing and not passing QWidget as parent

I have created a simple QHBoxLayout (horizontal) that is pushed to the bottom of the QVBoxLayout (Vertical) and it contains two buttons. See code:
QWidget* create_ver_and_horizontal_box() {
QWidget* temp = new QWidget();
// Add buttons to the horizontal box
QHBoxLayout* hbox = new QHBoxLayout();
QPushButton *ok = new QPushButton("OK");
QPushButton *cancel = new QPushButton("Cancel");
hbox->addWidget(ok);
hbox->addWidget(cancel);
// Create a vertical box and add the horizontal box to
// the end of it
QVBoxLayout* vbox = new QVBoxLayout();
vbox->addStretch(1);
vbox->addLayout(hbox);
// set the layout and return
temp->setLayout(vbox);
return temp;
}
and the resulting UI is the following.
But when I add the QWidget temp to be the parent of the QHBoxLayout, like so:
// Add buttons to the horizontal box
QHBoxLayout* hbox = new QHBoxLayout(temp);
This is what I get:
I want to understand what is going on here. And in which cases I want the QWidget to be the parent of a layout or any other QWidget(s) and in which cases I don't the containing QWidget to be the parent of the containing QWidgets. For example, I could've added temp to be the parent of the two Push buttons but I didn't. What is the implication of not adding vs adding.
Thanks,
QHBoxLayout* hbox = new QHBoxLayout(temp);
is equivalent to
QHBoxLayout* hbox = new QHBoxLayout();
temp->setLayout(hbox);
I.e. you are making the horizontal layout responsible for temp.
The call to setLayout(vbox) should have generated a runtime warning message, that temp already has a layout, hinting at that.
Since you want the vertical layout to be responsible for that widget, either keep the temp->setLayout(vbox) or pass temp to the constructor of QVBoxLayout.

Center children widget in parent widget(parent widget was added in layout)

I created a layout contain a parent widget. In that parent widget i created another widget.
My code is similarly to this:
QGridLayout *layout = new QGridLayout();
QWidget *parentWidget = new QWidget();
layout->addWidget(parentWidget );
QWidget *childWidget = new QWidget(parentWidget);
How can i center the child widget in parent widget ?
The problem is we cannot get the true size of parent widget because it's in a layout.
Move the child inside the parent's showeEvent. You can use a bool flag to do it only when the parent is shown for the first time.
void Parent::showEvent(QShowEvent *)
{
if(_first_show)
{
_first_show = false;
_child->move(this->rect().center() - _child->rect().center());
}
}
Proof that it works (red is the parent, and blue is the child):
You can do this by setting fixed size of child widget and placing it inside grid layout of parent widget.
QGridLayout *layout = new QGridLayout();
QWidget *parentWidget = new QWidget();
layout->addWidget(parentWidget );
QWidget *childWidget = new QWidget(parentWidget);
QGridLayout *parentLayout = new QGridLayout();
parentWidget->setLayout(parentLayout);
parentLayout->addWidget(childWidget);
childWidget->setFixedSize(/*some fixed size for child widget*/);

QGraphicsProxyWidget animations not working

I'm trying to perform some animations using a QGraphicsProxyWidget but am not seeing any being applied. For example if I want to just rotate a QGraphicsTextItem this code works:
QGraphicsView *view_ = new QGraphicsView(this);
QGraphicsScene *scene_ = new QGraphicsScene(view);
QGraphicsTextItem *text_item_ = new QGraphicsTextItem("This is some sample text to\ntest if we can rotate the\nimage correctly");
scene_->addItem(text_item_);
text_item_->rotate(180);
view->setScene(scene_);
However this doesn't actually seem to do anything:
QLabel* label = new QLabel(this);
label->setText("This is some sample text to\ntest if we can rotate the\nimage correctly");
QGraphicsView *view_ = new QGraphicsView(this);
QGraphicsScene *scene_ = new QGraphicsScene(view);
QGraphicsProxyWidget *proxy_widget_ = new QGraphicsProxyWidget();
proxy_widget_->setWidget(label);
scene_->addItem(proxy_widget__);
proxy_widget_->rotate(180);
view->setScene(scene_);
Nor does doing it like this:
QGraphicsProxyWidget *proxy_widget_ = scene_->addWidget(label).
Any suggestions?
Your code adds the proxy widget and calls: -
proxy_widget->rotate(180);
If you look at the QGraphicsProxyWidget documentation, you'll see that it inherits from QGraphicsItem and that you should call the function setRotation
proxy_widget->setRotation(180);
Thanks Merlin. Figured out the issue. If you remove the parenting from the QLabel it works.
So change this:
QLabel* label = new QLabel(this);
To this:
QLabel* label = new QLabel();

Qt C++ Display new window centered on old window

I have QWidget with button. When button is pressed, show new smaller window (Qwidget too). I want then new window is centered horizontal and veritcal on main window. Code which display new window is:
QWidget *wdg = new QWidget;
QPushButton *closeBtn = new QPushButton("Close");
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(closeBtn);
wdg->setLayout(layout);
wdg->show();
wdg->resize(400,200);
Use the move slot. For example:
QPoint centerPoint = oldWidget->geometry()->center();
newWidget->adjustSize();
newWidget->move(centerPoint.x() - newWidget->width()/2, centerPoint.y() - newWidget->height()/2);
You may consider using frameGeometry() instead of geometry().
http://qt-project.org/doc/qt-5/application-windows.html#window-geometry
Hope that helps.

Want to place a QPushButton onto a GraphicView... but no button is displayed?

Want to place a QPushButton onto a GraphicView... but no button is displayed?
I am creating a new window for each plot. On each plot I want to put some buttons for functionality. I don't know if I should put the view on another type of window... if so how? thx
QGraphicsScene *scene = new QGraphicsScene();
QPixmap image;
image.load(fileInfo.filePath(), 0);
scene->addPixmap(image);
scene->setSceneRect(image.rect());
QGraphicsView *view = new QGraphicsView();
view->setScene(scene);
view->setWindowTitle(QT_TRANSLATE_NOOP(QGraphicsView, "My Plot"));
view->resize(1000, 1000);
view->show();
QPushButton *m_button6 = new QPushButton("ok", view);
m_button6->setGeometry(QRect(QPoint(50, 50), QSize(50, 50)));
connect(m_button6, SIGNAL(released()), this, SLOT(handleButton5()));
wrap it around QGraphicsWidget.
QGraphicsWidget *pBtn = scene->addWidget(m_button6);
scene->addItem(pBtn)
oh! don't forget:
m_button6->show();
widgets are hidden by default!