Details
-
Bug
-
Resolution: Done
-
P5: Not important
-
4.7.1
-
None
-
6f2720d4
Description
If you add a property "buttonGroupId" to any widget in QtDesigner then:
- it will be added to xxx.ui file
- but it will not be created in resulting ui_xxx.h file generated by uic.
There are also other special property names which may lead to problems.
In the attached example 1, I assign to a button two properties: "testProperty" and "buttonGroupId". This leads to correct test.ui file:
<property name="buttonGroupId" stdset="0"> <number>1</number> </property> <property name="testProperty" stdset="0"> <string>value</string> </property>
but in ui_test.h generated by uic during compilation there is only:
pushButton->setProperty("testProperty", QVariant(QApplication::translate("Dialog", "value", 0, QApplication::UnicodeUTF8)));
but no trace of "buttonGroupId".
FYI: it's very confusing: we used to have running code where in constructor of a dialog we did something based on a custom property "btnGrpId" assigned in designer. Then we cleaned-up the code, among other changes we expanded our weird abbreviation to more readable "buttonGroupId". And suddenly our application stopped working! It took us a while to figure out that the problem was that the property assigned in QtDesigner was not in fact assigned (and not visible from c++ code). Just because of change of the name of our property....
It seems that the problem is in qt-git/src/tools/uic/cpp/cppwriteinitialization.cpp:
DomWidget *buttonGroupWidget = findWidget(QLatin1String("Q3ButtonGroup"));
} else if (propertyName == QLatin1String("buttonGroupId")) { // Q3ButtonGroup support if (buttonGroupWidget) m_output << m_indent << m_driver->findOrInsertWidget(buttonGroupWidget) << "->insert(" << varName << ", " << p->elementNumber() << ");\n"; continue; } else if (propertyName == QLatin1String("currentRow") // QListWidget::currentRow
=> if custom property name is "buttonGroupId" and Q3ButtonGroup is not found, then nothing is written.
(Note: that my example does not use any Qt3 support widgets! Above code is a quote from uic code!)
1. I think, if Q3ButtonGroup is not found, we should proceed (and not skip the rest of the for loop by "continue;") i.e. treat buttonGroupId just as any other regular custom property. Thus I would suggest changing the above code to:
} else if (propertyName == QLatin1String("buttonGroupId")) { // Q3ButtonGroup support if (buttonGroupWidget) { m_output << m_indent << m_driver->findOrInsertWidget(buttonGroupWidget) << "->insert(" << varName << ", " << p->elementNumber() << ");\n"; continue; } } else if (propertyName == QLatin1String("currentRow") // QListWidget::currentRow
(i.e. "continue" only if buttonGroupWidget was found) => I did check that this leads to proper
pushButton->setProperty("buttonGroupId", QVariant(1));
in ui_test.h resulting from uic. Alternatively, condition on button group could be moved to the previous line:
} else if (propertyName == QLatin1String("buttonGroupId" && buttonGroupWidget )) { // Q3ButtonGroup support m_output << m_indent << m_driver->findOrInsertWidget(buttonGroupWidget) << "->insert(" << varName << ", " << p->elementNumber() << ");\n"; continue; } else if (propertyName == QLatin1String("currentRow") // QListWidget::currentRow
which puts it more in line with other sections in this stream of "else-ifs".
2. But, I think, additionally this whole part of uic code has to be reviewed.
Most cases in this series of ifs in the uic source are quite safe: they are restricted to specific widgets (e.g. tabSpacing only for QToolBox) which is fine. But there are a few which are not limited in this way. For example, when I add to a pushbutton a benign QStringList property "database", I get during compilation errors (see attached example 2):
main.o: In function `~Ui_Dialog': uic-properties-example2/ui_test.h:28: undefined reference to `QSqlDatabase::~QSqlDatabase()' test.o: In function `Ui_Dialog': uic-properties-example2/ui_test.h:28: undefined reference to `QSqlDatabase::QSqlDatabase()' test.o: In function `Ui_Dialog::setupUi(QDialog*)': uic-properties-example2/ui_test.h:35: undefined reference to `QSqlDatabase::database(QString const&, bool)' uic-properties-example2/ui_test.h:35: undefined reference to `QSqlDatabase::operator=(QSqlDatabase const&)' uic-properties-example2/ui_test.h:35: undefined reference to `QSqlDatabase::~QSqlDatabase()' uic-properties-example2/ui_test.h:35: undefined reference to `QSqlDatabase::~QSqlDatabase()' collect2: ld returned 1 exit status make: *** [test] Error 1
(I admit that adding QStringList property "database" for some custom purposes is not that likely, but, you know - one day someone will run into this; after all we ourselves did run by accident into the above problem with buttonGroupId in a real-life project!)