QGraphicsScene : get the QGraphicsItemGroup under the cursor - qt

I'm having trouble getting a pointer of a QGraphicsItemGroup bellow my cursor. QGraphicsScene::ItemAt return one of the objects of the group but the not ItemGroup it self.
Any clue how to do it ?
Thx

You can call QGraphicsItem::group() on the QGraphicsItem returned by QGraphicsScene::itemAt().

Related

Retrieve QSlider child from a QGridLayout

I want to acces the value of the QSliders that are in my QGridLayout, but I don't find the right command.
An example of what I try:
QSlider* slider=ui->gridLayout->takeAt(1)->widget();
The error message I get is:
cannot convert 'QLayoutItem*' to 'QSlider*' in initialization
Is there a command to ask the QSlider right away and not the widget?
Is it possible to cast? I tried it, but this also didn't work.
How can I solve this?
You can use QGridLayout::findChild<T> method:
QSlider *slider = ui->gridLayout->findChild<QSlider *>("widget_name"); // Name is optional
Or alternatively
QList<QSlider*> sliders = ui->gridLayout->findChildren<QSlider *>();
As pointed by G.M, QLayout::takeAt is used to safely remove and return a Widget from a QLayout, so not what you are trying to do.

How to avoid segfault after calling deleteLater on pointer?

I have a GraphicsScene:public QGraphicsScene inherited class with a single QGraphicsView looking at it and QTimer, ticking to call function
void GraphicsScene::adv()
{
if (actor)
views().at(0)->ensureVisible(actor,200,100);
advance();
}
advance() is an overriden method which is send to all QGraphicsItem objects on scene. The point of this function - I want to make sure actor is always visible.
actor is a unit:public QGraphicsPixmapItem object on GraphicsScene.
At some point in actor method I call deleteLater().
The next timer tick I receive SEGFAULT at views().at(0)->ensureVisible(actor,200,100); line
I wonder, why if (actor) passes as true after deleteLater() and what is the correct condition should I use?
I have an object being asynchronically deleted by deleteLater()
and wonder if there is a way to prevent accessing it from other
objects?
Yes, there is a way to tell programmatically whether or not the object was already deleted by using QPointer<MyQObject> as described. But that way is somewhat slow and your application code should rather have better logic to avoid that. Like, before calling deleteLater your code removes the reference for that object from, say, views() and your code should check for the view still there.
If you call deleteLater() from inside your actor, the container GraphicsScene still has its pointer on it - the object itself doesn't reset all external pointers to it.
You have to reset this pointer - the member actor of your GraphicsScene to get your if-statement in adv() working.

Cannot save the contents of a QGraphicsScene in QGraphicsView

I want my application to save the contents of my scene which contains graphics items in it and later be able to retrieve all those items(not as a QPixmap, but as actual individual items).
I have tried using Qsettings but get a QVariant error.
My code is:
QSettings settings("AdvProgLab","ERapp");
settings.beginGroup("MainWindow");
settings.setValue("saved_scene",scene); //Here, scene is a QGraphicsScene
settings.endGroup();
And the error which I am getting is:
qvariant.h:471: error: ‘QVariant::QVariant(void*)’ is private
inline QVariant(void *) Q_DECL_EQ_DELETE;
^
error: use of deleted function ‘QVariant::QVariant(void*)’
Can anybody please explain me where I am going wrong ?
Or is there any other way by which I can achieve this .
Thank You.

Single function that handle multiple QObjects

Hi I have a problem, in my program I have several QLabel and QTextbrowser, at times, I want each of them to display something, but I want to do this through another function called NewMessage. So NewMessage will receive message from QLabel or QTextbrowser, and process them, then display it. But the problem is I don't want to have overloading function for QLabel and QTextBrowser, I want only 1 NewMessage function that can handle message pass in by either QLabel or QTextBrowser(the objects have to pass themselves in as well), how should I do that? Does it has to do with something called casting? Thank you !
I'm not sure I fully understand what you want to achieve. May be you could start by reading Qt documentation about QObject and qobject_cast :
http://doc.qt.io/qt-5/qobject.html#qobject_cast

QPlainTextEdit segmentation fault

I have some Qt application with QPlainTextEdit in Tab widget. When try to make a pointer on it
QPlainTextEdit *w = (QPlainTextEdit*)ui->tabWidget->widget(0)
and call a document() method
w->document()
I get a segfault.
But if i call document directly, e.g. ui->mainEdit->document(), then everything works fine.
Can anybody explain me why it happens?
You want to do:
QPlainTextEdit *w = ui->mainEdit;
Then w->document() will return what you want. You are getting the segmentation fault because when you cast ui->tabWidget->widget(0); gives a pointer to a tab page object. When you cast this to QPlainTextEdit* are telling your program to treat a part of memory that does not represent a QPlainTextEdit as a QPlainTextEdit. This causes trouble at the time that you call w->document() because that is in the memory location that it tries to access is not what it would expect from memory which belongs to QPlainTextEdit.
i'm almost sure, that ui->tabWidget->widget(0) return container widget inside of tabWidget. Try qDebug() << ui->tabWidget->widget(0)->metaObject()->className() and see what is printed. It's probably just "QWidget" not "QPlainTextEdit". Your edit is inside of layout of this widget
You can use qobject_cast to make sure that it returns the right type.
QPlainTextEdit *w = qobject_cast<QPlainTextEdit*>(ui->tabWidget->widget(0));
if (w)
{
...
}
It'll return 0 if the type is not of QPlainTextEdit*.
As stated, widget(0) is probably not returning what you wanted - and probably contains a container or some other item, and is probably not the way you want to be accessing your widgets unless there is no other way.

Resources