Qt Z-Order Assignment Is Not A Valid Widgets

My poor English...let me try...hope you can understand...

This bug was found in version 4.8.5 & 5.9.0 at working place,and 5.2.0 at home.Sometime you compile a ui file, it may waring "zorder assignment is not a valid widget", because some items which are not widgets in ui file have zorder info.

Scene restoration: Here is a effective way to restoration.First we create a new blank widget,then put two widgets on it.we name them "widget_A"and"widget_B",i.e we have a new widget with "widget_A" and "widget_B" on it, neither of them has layout. Now we put another one item, maybe a widget or spacer or something on "widget_A", so we just call it "C", and drag "C" to "widget_B". Then call undo("C" backs to "widget_A"), and drag "C" to "widget_B" again(or we can call redo).Just repeat the step any number of times.Finally, we save this file, if "C" is spacer, we should give a layout to content("widget_A" or "widget_B", based on where is "C" layed on) before saving.Now we will find some "zorder" if we open this file in text mode.Also if "C" isn't a widget, there wiil be some warings like "zorder assignment is not a valid widget".

Reason: The "C", we put into widget, can cause redo function when it was dragged to "widget_B" or we call action "Redo", can cause undo function when we call action "Undo".As we know, redo should turn to new state, and undo turns back.But, in this situation, something was wrong here.

Issue code: Here is a file named qdesigner_command.cpp in Src of Qt Designer.A Class named ReparentWidgetCommand, let's have a look at its function redo & undo:

From what I understand, this class is about the operation of changing parent. In redo function, target("m_widget") was removed from the old "_q_widgetOrder" and "_q_zOrder",  the other side, it was appended to the new "_q_widgetOrder" and "_q_zOrder". Then in undo function, target("m_widget") was appended to the old "_q_widgetOrder" and "_q_zOrder"(because it has two members to note them, so just set them back).Here comes the point! We can see it removes target from the new "_q_widgetOrder", but dose nothing with the new "_q_zOrder"!!!

Here it is what was done on "_q_zOrder" in redo function:

But in undo function:

See it?Should we insert "newZOrder.removeAll(m_widget);" between these two rows?

Originally, target always be removed from the old "_q_widgetOrder" and "_q_zOrder", and be appended to the new "_q_widgetOrder" and "_q_zOrder" in redo function. So both "_q_widgetOrder" and "_q_zOrder" have same list.When we save file, the code checks wether they are equal or not.if they are equal, Designer will not write any "zorder" in .ui file.As mentioned above, undo can make them not eaqual, So Designer writes "zorder" in .ui file.

So I think target should be removed from both the new "_q_widgetOrder" and "_q_zOrder" in undo function.

void ReparentWidgetCommand::redo() { m_widget->setParent(m_newParentWidget); m_widget->move(m_newPos); QWidgetList oldList = m_oldParentList; oldList.removeAll(m_widget); m_oldParentWidget->setProperty("_q_widgetOrder", QVariant::fromValue(oldList)); QWidgetList newList = qvariant_cast<QWidgetList>(m_newParentWidget->property("_q_widgetOrder")); newList.append(m_widget); m_newParentWidget->setProperty("_q_widgetOrder", QVariant::fromValue(newList)); QWidgetList oldZOrder = m_oldParentZOrder; oldZOrder.removeAll(m_widget); m_oldParentWidget->setProperty("_q_zOrder", QVariant::fromValue(oldZOrder)); QWidgetList newZOrder = qvariant_cast<QWidgetList>(m_newParentWidget->property("_q_zOrder")); newZOrder.append(m_widget); m_newParentWidget->setProperty("_q_zOrder", QVariant::fromValue(newZOrder)); m_widget->show(); core()->objectInspector()->setFormWindow(formWindow()); } void ReparentWidgetCommand::undo() { m_widget->setParent(m_oldParentWidget); m_widget->move(m_oldPos); m_oldParentWidget->setProperty("_q_widgetOrder", QVariant::fromValue(m_oldParentList)); QWidgetList newList = qvariant_cast<QWidgetList>(m_newParentWidget->property("_q_widgetOrder")); newList.removeAll(m_widget); m_newParentWidget->setProperty("_q_widgetOrder", QVariant::fromValue(newList)); m_oldParentWidget->setProperty("_q_zOrder", QVariant::fromValue(m_oldParentZOrder)); QWidgetList newZOrder = qvariant_cast<QWidgetList>(m_newParentWidget->property("_q_zOrder")); m_newParentWidget->setProperty("_q_zOrder", QVariant::fromValue(newZOrder)); m_widget->show(); core()->objectInspector()->setFormWindow(formWindow()); }
QWidgetList newZOrder = qvariant_cast<QWidgetList>(m_newParentWidget->property("_q_zOrder")); newZOrder.append(m_widget); m_newParentWidget->setProperty("_q_zOrder", QVariant::fromValue(newZOrder));
QWidgetList newZOrder = qvariant_cast<QWidgetList>(m_newParentWidget->property("_q_zOrder")); m_newParentWidget->setProperty("_q_zOrder", QVariant::fromValue(newZOrder));

- У вас в номере проститутка? - Он оглядел комнату. Роскошная обстановка, как в лучших отелях. Розы, шампанское, широченная кровать с балдахином.

0 thoughts on “Qt Z-Order Assignment Is Not A Valid Widgets”

    -->

Leave a Comment

Your email address will not be published. Required fields are marked *