Adding a QWidget to a QGraphicsScene - qt

I have a QGraphicsScene for drawing, where I now want to "add" a QWidget to a QGraphicsItem (display on top of the item, which can of course be moved).
How could this be accomplished? Is there any QGraphicsItem, which may function as a Widget container?

You can use QGraphicsScene::addWidget which creates a new QGraphicsProxyWidget for widget, adds it to the scene, and returns a pointer to the proxy :
QGraphicsProxyWidget * item = myScene->addWidget(myWidget);
item->setParentItem(anOtherItem);
item->setPos(100,100);
item->setZValue(1);

Related

Why QGraphicsPixmapItem do not have setParent()

QGraphicsPixmapItem does not like other qt object which inherited from QObject. It can not be destroyed when its parent destroy. Is the only way to use it is delete the pointer by myself?
......
QGraphicsPixmapItem * backGround = new QGraphicsPixmapItem(QPixmap::fromImage(this->mat2QImage(img)), NULL);
this->scene->addItem(backGround);
ui.imgDisplay->setScene(scene);
ui.imgDisplay->show();
......
// delete by myself
delete backGround;
// why can not I set the parent of the QGraphicsPixmapItem to QGraphicsScene
// when QGraphicsScene destroy, QGraphicsPixmapItem under QGraphicsScene automatically destroy.
QGraphicsPixmapItem inherits from QGraphicsItem, not QObject.
A QgraphicsItem is deleted when the scene is deleted. It will also delete all its children. So, you don't have delete yourself the items.
If you want a graphics item based on QObject, you should take a look to QGraphicsObject.

How to make a list of children widgets on a layout in QT?

A nice simple example would be nice. For my part, I wish to do something like this:
myLayout->addWidget(myButton1);
myLayout->addWidget(myButton2);
myButtonList<QToolButtons*>->append(myLayout->findChildren(QToolButtons));
myButtonList->at(1)->setText("This is 'myButton2'");
Use QList along with using findChildren with QWidget because QLayout does not show QWidgets as its children and a QWidget have a parent QWidget only. Refer this
QWidget w;
QPushButton *p1= new QPushButton;
QPushButton *p2= new QPushButton;
QHBoxLayout l;
l.addWidget(p1);
l.addWidget(p2);
w.setLayout(&l);
QList<QPushButton*> buttons = w.findChildren<QPushButton*>();
buttons.at(0)->setText("Hello I am P1");
buttons.at(1)->setText("Hello I am P2");
w.show();
A lot easier would be the approach to first fill the list and afterwards the layout:
QList<QToolButton *> list;
list.append(new QToolButton);
list.last().setText("1");
myLayout->addWidget(list.last());
This could then also be easily looped for a higher amount of buttons.
You can still use
ParentWidget->findChildren<QToolButtons *>();
edited given vahancho hint for parent is always a widget, not the layout

Qt How to Find Object on a widget using x() and y() position

I have a MainWindow. On MainWindow I have multiple Qlabel's. Now, i need to find the QLabel clicked.
Using MousePressEvent, i can get the X() and Y() position of the mouse clicked.
How can i use this Co-ordinate to identify the QLabel??
Is there any function in QT to find the Object clicked using X() and Y() co-ordinate??
Since QLabel is a subclass of QWidget, you can handle mouse press events in QLabel::mousePressEvent
virtual void mousePressEvent ( QMouseEvent * ev )
But in QMainWindow, you can use childAt to get the child widgets at x,y
QWidget * QWidget::childAt ( int x, int y ) const
QLabel* label= static_cast<QLabel*>(mainWindow->childAt(x,y));
Read more at:
http://doc.qt.io/qt-5/qwidget.html#childAt
In Qt5 this also works
QTabBar *widget =(QTabBar*) qApp->widgetAt(QCursor::pos());
Rather than trying to identify which label has been clicked on from mouse coordinates, you could also alternatively use a label's mousePressEvent() method.
For example, make your own overloaded label class and, on a mousePressEvent() emit a clicked() signal which you can then bind to a slot.
Use the widgetAt function inside QApplication
QWidget *widget = qApp->widgetAt(x,y);
which then you can dynamic_cast into QLabel.

Redefine QPainter options when redrawing QGraphicsItem

I want to redefine the QPainter before drawing earch QGraphicsItem in a QGraphics scene.
void GraphicsScene::drawItems( QPainter * painter, int nbItem, QGraphicsItem *[] items, const QStyleOptionGraphicsItem[] options, QWidget * widget = NULL )
Is now obsolete, what's the "new" method ?
Thx
The QGraphicsScene isn't in charge of the painter... it is in charge of the storage and retrieval of the items. The QGraphicsView is in charge of the painter and transformation of the view.
If you want to set render hints to modify the QPainter behavior, you can do that from the view using QGraphicsView::setRenderHint.
If you just want to do a single render to another special QPainter engine, the documentation shows an example for it to a printer here.
Here is link to the docs on QGraphicsView.

How to Add QListView/QListWidget to QGraphicsScene in Qt?

How to Add QListView/QListWidget to QGraphicsScene and add Widgets to ListView
When i Try to add QLisView to QGraphicsScene mouse scroll affects goes from Scene.
I want to add QPushButtons as ListView Items in QgraphicsScene with mouse scroll affect.
Thanks.
What about QGraphicsProxyWidget?
QListView *listView = new QListView;
QGraphicsProxyWidget *proxy = scene.addWidget(listView);
Then (or before that) you can populate the list with anything you want. QPushButton can be added to the list using setIndexWidget(). Also you might rethink the whole idea of having a QListView, and give it a try with QScrollArea and a linear layout containing buttons. That would require a bit more logic to organize items within the scroll area, but it should be more lightweight that QListView with custom widgets.
I second the answer above: ProxyWidget is the answer.
Here is my working code,
Header:
class CenterScreen{
private:
QListWidget* nameListWidget;
QGraphicsProxyWidget* nameProxyWidget;
...
C++ source:
void CenterScreen::addListView()
{
QGraphicsScene* scene = ui.centerGraphicsView->scene();
nameListWidget = new QListWidget();
nameProxyWidget = scene->addWidget(nameListWidget);
...
nameProxyWidget->hide(); // you can control your widget as you like

Resources