Solved QWidget::windowRole() use as storage for small textual data
-
@SGaist I'm trying to use
bool QObject::setProperty(const char *name, const QVariant &value)
In myMainWindow
I callMyClass
where I create some objects and set for each of them property:MyClass::BlaBla(){ ads::CDockWidget* dockWidget = new ads::CDockWidget("2D Window"); dockWidget->setWidget(qvtkOpenGLStereoWidget); dockWidget->setProperty("IsVisualization", true); dockManager->addDockWidget(ads::RightDockWidgetArea, dockWidget); }
If I write
QVariant variant = dockWidget->property("IsVisualization");
then thevariant
contains correct data everything if ok at this step.
But if I do the same in theMainWindow
insideonFocusChanged
method I get invalid QVariant:void MainWindow::onFocusChanged(QWidget* old, QWidget* now){ if (old != nullptr){ QVariant variantOLD = old->property("IsVisualization"); } if (now != nullptr){ QVariant variantNOW = now->property("IsVisualization"); } }
What is wrong?
P.S.
dockManager
anddockWidget
are from advanced_docking_system library -
@Please_Help_me_D
Since being insideonFocusChanged()
makes no difference to whether you can read a property or not, I can only conclude that neitherold
nornow
are thedockWidget
on which you previously set the property, or you have reset it since then.Did you even try
object_cast<>
ingold
/now
to verify they areads::CDockWidget*
? -
@JonB after you wrote I tried it... Yes you are right, they are not a
ads::CDockWidget*
I guess I should be able to getads::CDockWidget*
fromold/now
viaold->children
? -
@Please_Help_me_D
I was doing this just today. The focus can be hitting some sub widget on a container. In my case widgets on aQMdiSubWindow
. To find that I go up viaparentWidget()
till I find one or hit the topmost. If you are same thing you will want to go up parents fromold
/now
, not chidren? -
@JonB nice to hear that
As I understood I should go up fromold/now
until I meetads::CDockWidget* dockWidget != nullptr
condition, correct? Like:{ ads::CDockWidget* dockWidget = qobject_cast<ads::CDockWidget*>(old->parent()); if (CDockWidget != nullptr){} }
but in some while or for loop...
-
ads::CDockWidget* dockWidget = nullptr; while (old != nullptr && (dockWidget = qobject_cast<ads::CDockWidget*>(old)) == nullptr) old = old->parentWidget(); qDebug() << dockWidget;
-
@JonB thank you
But the loop ended and dockWidget is always nullptr. It takes about 7 cycles and there is noads::CDockWidget*
-
@Please_Help_me_D
So in that case theold
ornow
(you have written this loop on both, haven't you?!) in the focus change is not a descendent of yourads::CDockWidget* dockWidget
. I never said it was, you did! Or you check children if whatever it is works that way. -
@JonB yes I have written both
old
andnow
Yes I'm trying to find this widget viaold->children();
. I need few minuts -
@JonB this code can't find
ads::CDockWidget*
neither:void MainWindow::onFocusChanged(QWidget* old, QWidget* now){ if (old != nullptr){ ads::CDockWidget* dockWidget = nullptr; QObjectList objList = old->children(); int i = 0; while (i < objList.count() && dockWidget == nullptr){ dockWidget = qobject_cast<ads::CDockWidget*>(objList.at(i)); i++; } } if (now != nullptr){ ads::CDockWidget* dockWidget = nullptr; QObjectList objList = now->children(); int i = 0; while (i < objList.count() && dockWidget == nullptr){ dockWidget = qobject_cast<ads::CDockWidget*>(objList.at(i)); i++; } } }
-
@Please_Help_me_D
So read up on what aads::CDockWidget
is/how it works. Your assumption in thatQWidget::focusChanged(old, now)
must lead to widgets either ancestors or descendants of this dock widget. I have no idea whether that is the case. Also your code may need to recurse down through children, no? At least start by finding out whatold
&now
actually are in your focus change. -
@JonB yes possibly I should have done the recursion down to the other children but it alredy becomes too complicated solution for such kind of a task.
Now I'm trying to set property not on CDockWidget but to some parent. I'm trying... -
Hi
It wont be the DockWidget that has the focus. it will be its widget/children.I would call dumpObjectTree()
on old and now to see how they are made up. -
@mrjj thank you for advice. Here is the output:
setFocus(Qt::OtherFocusReason); setFocus(Qt::OtherFocusReason); ads::CDockWidget::2D Window QBoxLayout:: QAction:: QScrollArea::dockWidgetScrollArea QWidget::qt_scrollarea_viewport QVTKOpenGLStereoWidget:: QVBoxLayout:: QWindowContainer:: QWidget::qt_scrollarea_hcontainer QScrollBar:: QBoxLayout:: QWidget::qt_scrollarea_vcontainer QScrollBar:: QBoxLayout:: setFocus(Qt::OtherFocusReason); setFocus(Qt::OtherFocusReason); setFocus(Qt::OtherFocusReason);
So the focus should be on one of those?
By the way this tree is fromads::CDockWidget
Just a moment and I find tree forold
/
and here is tree fornow
object:ads::CDockWidgetTab:: QBoxLayout:: ads::CElidingLabel::dockWidgetTabLabel QPushButton::tabCloseButton
-
hi
yes it should but we don't have to guess.
you can do
QWidget * fw = qApp->focusWidget();
and check out in the debugger (or qDebug its object name) to see what it is.It should be possible to get hold of the Dock again to get your data back.
-
@mrjj QWidget * fw and now widget is the same. See the picture please
-
@mrjj now I'm trying to set property to the tabWidgets to wich CDockWidget belongs to:
QVTKOpenGLStereoWidget* MainWindowObjectCreator::createVTK2DWindow(){ QVTKOpenGLStereoWidget* qvtkOpenGLStereoWidget = new QVTKOpenGLStereoWidget; ads::CDockWidget* dockWidget = new ads::CDockWidget("2D Window"); dockWidget->setWidget(qvtkOpenGLStereoWidget); dockManager->addDockWidget(ads::RightDockWidgetArea, dockWidget); dockWidget->tabWidget()->setProperty("IsVisualization", 4443); //dockWidget->dumpObjectTree(); return qvtkOpenGLStereoWidget; }
but each time I manually change the focus the
MainWindow::onFocusChanged(QWidget* old, QWidget* now)
works twice:
first time now is the old window
second time is the new window
and when the second time this method works then I get the correct value of property:void MainWindow::onFocusChanged(QWidget* old, QWidget* now){ QWidget * fw = qApp->focusWidget(); fw->dumpObjectTree(); if (now != nullptr){ now->dumpObjectTree(); QVariant varia = now->property("IsVisualization"); } }
By the way this works only if the focused window is tabbed. Otherwise the focused widget is not a
tabWidget()
. So idea to set property to thetabWidget()
doesn't seem to work -
Ah silly me. of cause now will be the same as qApp->focusWidget(); :)
and it does seem to be the actual DockWidget ! which i didn't expect.Is it possible you have 2 connects to the onFocusChanged signal ?
Not really sure why it should run twice. I don't recall it normally does that.Its normally not an issue to loop up the chain to find the top parent.
So not sure why it dont seem to work for you here. -
@mrjj yes, now I also find this looking for parent not working for me strange :)
Just a moment I guess that I'm missing something important... -
@Please_Help_me_D
Yeah as the dumptree clearly shows its the top as we expect
ads::CDockWidget::2D Window
QBoxLayout::
QAction::
QScrollArea::dockWidgetScrollArea
QWidget::qt_scrollarea_viewport
QVTKOpenGLStereoWidget::
QVBoxLayout::
....But the test with qApp->focusWidget(); showd now is the Dock so
looking at this code.f (now != nullptr){
ads::CDockWidget* dockWidget = nullptr;
QObjectList objList = now->children();Do you only check its children ?
and in that case, the line
dockWidget = qobject_castads::CDockWidget*(objList.at(i));will always return null as you skip the now ? and only cast children ?