uic: Generate string-based connections for custom slots

Qt Designer let's you add custom slots and signals to the main
form; they should use string-based connection syntax since the
class is not known in setupUI(). Amends
da3cb1deb6c752f8e4c05434e3451432e5d787ba.

Task-number: QTBUG-76375
Change-Id: I5a3a5630f77c812d48db1cdb7a8658a4d2718228
Reviewed-by: Liang Qi <liang.qi@qt.io>
This commit is contained in:
Friedemann Kleint 2020-05-05 07:56:29 +02:00
parent ca33e7a740
commit ae7e701074
4 changed files with 438 additions and 12 deletions

View File

@ -470,6 +470,11 @@ void WriteInitialization::acceptUI(DomUI *node)
if (node->hasAttributeConnectslotsbyname())
m_connectSlotsByName = node->attributeConnectslotsbyname();
if (auto customSlots = node->elementSlots()) {
m_customSlots = customSlots->elementSlot();
m_customSignals = customSlots->elementSignal();
}
acceptLayoutDefault(node->elementLayoutDefault());
acceptLayoutFunction(node->elementLayoutFunction());
@ -2573,9 +2578,8 @@ bool WriteInitialization::isCustomWidget(const QString &className) const
return m_uic->customWidgetsInfo()->customWidget(className) != nullptr;
}
ConnectionSyntax WriteInitialization::connectionSyntax(const QString &senderSignature,
const QString &senderClassName,
const QString &receiverClassName) const
ConnectionSyntax WriteInitialization::connectionSyntax(const language::SignalSlot &sender,
const language::SignalSlot &receiver) const
{
if (m_option.forceMemberFnPtrConnectionSyntax)
return ConnectionSyntax::MemberFunctionPtr;
@ -2584,12 +2588,18 @@ ConnectionSyntax WriteInitialization::connectionSyntax(const QString &senderSign
// Auto mode: Use Qt 5 connection syntax for Qt classes and parameterless
// connections. QAxWidget is special though since it has a fake Meta object.
static const QStringList requiresStringSyntax{QStringLiteral("QAxWidget")};
if (requiresStringSyntax.contains(senderClassName)
|| requiresStringSyntax.contains(receiverClassName)) {
if (requiresStringSyntax.contains(sender.className)
|| requiresStringSyntax.contains(receiver.className)) {
return ConnectionSyntax::StringBased;
}
return senderSignature.endsWith(QLatin1String("()"))
|| (!isCustomWidget(senderClassName) && !isCustomWidget(receiverClassName))
if ((sender.name == m_mainFormVarName && m_customSignals.contains(sender.signature))
|| (receiver.name == m_mainFormVarName && m_customSlots.contains(receiver.signature))) {
return ConnectionSyntax::StringBased;
}
return sender.signature.endsWith(QLatin1String("()"))
|| (!isCustomWidget(sender.className) && !isCustomWidget(receiver.className))
? ConnectionSyntax::MemberFunctionPtr : ConnectionSyntax::StringBased;
}
@ -2617,8 +2627,7 @@ void WriteInitialization::acceptConnection(DomConnection *connection)
m_output << m_indent;
language::formatConnection(m_output, theSignal, theSlot,
connectionSyntax(senderSignature, senderDecl.className,
receiverDecl.className));
connectionSyntax(theSignal, theSlot));
m_output << language::eol;
}

View File

@ -38,6 +38,7 @@
#include <qtextstream.h>
enum class ConnectionSyntax;
namespace language { struct SignalSlot; }
QT_BEGIN_NAMESPACE
@ -241,9 +242,8 @@ private:
void addButtonGroup(const DomWidget *node, const QString &varName);
void addWizardPage(const QString &pageVarName, const DomWidget *page, const QString &parentWidget);
bool isCustomWidget(const QString &className) const;
ConnectionSyntax connectionSyntax(const QString &senderSignature,
const QString &senderClassName,
const QString &receiverClassName) const;
ConnectionSyntax connectionSyntax(const language::SignalSlot &sender,
const language::SignalSlot &receiver) const;
const Uic *m_uic;
Driver *m_driver;
@ -305,6 +305,8 @@ private:
QString m_generatedClass;
QString m_mainFormVarName;
QStringList m_customSlots;
QStringList m_customSignals;
bool m_mainFormUsedInRetranslateUi = false;
QString m_delayedInitialization;

View File

@ -0,0 +1,250 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Tests that custom slots on the form use string-based connections. Source: svggenerator -->
<ui version="4.0">
<class>Window</class>
<widget class="QWidget" name="Window">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>339</width>
<height>353</height>
</rect>
</property>
<property name="windowTitle">
<string>SVG Generator</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<item row="0" column="0">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="DisplayWidget" name="displayWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>200</horstretch>
<verstretch>200</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>200</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>200</height>
</size>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" colspan="3">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>&amp;Shape:</string>
</property>
<property name="buddy">
<cstring>shapeComboBox</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="shapeComboBox">
<item>
<property name="text">
<string>House</string>
</property>
</item>
<item>
<property name="text">
<string>Car</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>&amp;Color:</string>
</property>
<property name="buddy">
<cstring>colorButton</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QToolButton" name="colorButton">
<property name="text">
<string>Choose Color...</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>&amp;Background:</string>
</property>
<property name="buddy">
<cstring>shapeComboBox_2</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="shapeComboBox_2">
<item>
<property name="text">
<string>Sky</string>
</property>
</item>
<item>
<property name="text">
<string>Trees</string>
</property>
</item>
<item>
<property name="text">
<string>Road</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item row="2" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="toolButton_2">
<property name="text">
<string>Save &amp;As...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>DisplayWidget</class>
<extends>QWidget</extends>
<header>displaywidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>shapeComboBox</sender>
<signal>currentIndexChanged(int)</signal>
<receiver>Window</receiver>
<slot>updateShape(int)</slot>
<hints>
<hint type="sourcelabel">
<x>288</x>
<y>232</y>
</hint>
<hint type="destinationlabel">
<x>336</x>
<y>234</y>
</hint>
</hints>
</connection>
<connection>
<sender>colorButton</sender>
<signal>clicked()</signal>
<receiver>Window</receiver>
<slot>updateColor()</slot>
<hints>
<hint type="sourcelabel">
<x>301</x>
<y>262</y>
</hint>
<hint type="destinationlabel">
<x>337</x>
<y>267</y>
</hint>
</hints>
</connection>
<connection>
<sender>shapeComboBox_2</sender>
<signal>currentIndexChanged(int)</signal>
<receiver>Window</receiver>
<slot>updateBackground(int)</slot>
<hints>
<hint type="sourcelabel">
<x>306</x>
<y>299</y>
</hint>
<hint type="destinationlabel">
<x>337</x>
<y>311</y>
</hint>
</hints>
</connection>
<connection>
<sender>toolButton_2</sender>
<signal>clicked()</signal>
<receiver>Window</receiver>
<slot>saveSvg()</slot>
<hints>
<hint type="sourcelabel">
<x>298</x>
<y>336</y>
</hint>
<hint type="destinationlabel">
<x>307</x>
<y>348</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>updateBackground(int)</slot>
<slot>updateColor()</slot>
<slot>updateShape(int)</slot>
<slot>saveSvg()</slot>
</slots>
</ui>

View File

@ -0,0 +1,165 @@
/********************************************************************************
** Form generated from reading UI file 'window.ui'
**
** Created by: Qt User Interface Compiler version 6.0.0
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef WINDOW_H
#define WINDOW_H
#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QSpacerItem>
#include <QtWidgets/QToolButton>
#include <QtWidgets/QWidget>
#include "displaywidget.h"
QT_BEGIN_NAMESPACE
class Ui_Window
{
public:
QGridLayout *gridLayout_2;
QSpacerItem *horizontalSpacer_2;
DisplayWidget *displayWidget;
QSpacerItem *horizontalSpacer_3;
QGridLayout *gridLayout;
QLabel *label;
QComboBox *shapeComboBox;
QLabel *label_2;
QToolButton *colorButton;
QLabel *label_3;
QComboBox *shapeComboBox_2;
QHBoxLayout *horizontalLayout;
QSpacerItem *horizontalSpacer;
QToolButton *toolButton_2;
void setupUi(QWidget *Window)
{
if (Window->objectName().isEmpty())
Window->setObjectName(QString::fromUtf8("Window"));
Window->resize(339, 353);
gridLayout_2 = new QGridLayout(Window);
gridLayout_2->setObjectName(QString::fromUtf8("gridLayout_2"));
gridLayout_2->setSizeConstraint(QLayout::SetFixedSize);
horizontalSpacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
gridLayout_2->addItem(horizontalSpacer_2, 0, 0, 1, 1);
displayWidget = new DisplayWidget(Window);
displayWidget->setObjectName(QString::fromUtf8("displayWidget"));
QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
sizePolicy.setHorizontalStretch(200);
sizePolicy.setVerticalStretch(200);
sizePolicy.setHeightForWidth(displayWidget->sizePolicy().hasHeightForWidth());
displayWidget->setSizePolicy(sizePolicy);
displayWidget->setMinimumSize(QSize(200, 200));
displayWidget->setMaximumSize(QSize(200, 200));
gridLayout_2->addWidget(displayWidget, 0, 1, 1, 1);
horizontalSpacer_3 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
gridLayout_2->addItem(horizontalSpacer_3, 0, 2, 1, 1);
gridLayout = new QGridLayout();
gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
label = new QLabel(Window);
label->setObjectName(QString::fromUtf8("label"));
gridLayout->addWidget(label, 0, 0, 1, 1);
shapeComboBox = new QComboBox(Window);
shapeComboBox->addItem(QString());
shapeComboBox->addItem(QString());
shapeComboBox->setObjectName(QString::fromUtf8("shapeComboBox"));
gridLayout->addWidget(shapeComboBox, 0, 1, 1, 1);
label_2 = new QLabel(Window);
label_2->setObjectName(QString::fromUtf8("label_2"));
gridLayout->addWidget(label_2, 1, 0, 1, 1);
colorButton = new QToolButton(Window);
colorButton->setObjectName(QString::fromUtf8("colorButton"));
gridLayout->addWidget(colorButton, 1, 1, 1, 1);
label_3 = new QLabel(Window);
label_3->setObjectName(QString::fromUtf8("label_3"));
gridLayout->addWidget(label_3, 2, 0, 1, 1);
shapeComboBox_2 = new QComboBox(Window);
shapeComboBox_2->addItem(QString());
shapeComboBox_2->addItem(QString());
shapeComboBox_2->addItem(QString());
shapeComboBox_2->setObjectName(QString::fromUtf8("shapeComboBox_2"));
gridLayout->addWidget(shapeComboBox_2, 2, 1, 1, 1);
gridLayout_2->addLayout(gridLayout, 1, 0, 1, 3);
horizontalLayout = new QHBoxLayout();
horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout->addItem(horizontalSpacer);
toolButton_2 = new QToolButton(Window);
toolButton_2->setObjectName(QString::fromUtf8("toolButton_2"));
horizontalLayout->addWidget(toolButton_2);
gridLayout_2->addLayout(horizontalLayout, 2, 0, 1, 3);
#if QT_CONFIG(shortcut)
label->setBuddy(shapeComboBox);
label_2->setBuddy(colorButton);
label_3->setBuddy(shapeComboBox_2);
#endif // QT_CONFIG(shortcut)
retranslateUi(Window);
QObject::connect(shapeComboBox, SIGNAL(currentIndexChanged(int)), Window, SLOT(updateShape(int)));
QObject::connect(colorButton, SIGNAL(clicked()), Window, SLOT(updateColor()));
QObject::connect(shapeComboBox_2, SIGNAL(currentIndexChanged(int)), Window, SLOT(updateBackground(int)));
QObject::connect(toolButton_2, SIGNAL(clicked()), Window, SLOT(saveSvg()));
QMetaObject::connectSlotsByName(Window);
} // setupUi
void retranslateUi(QWidget *Window)
{
Window->setWindowTitle(QCoreApplication::translate("Window", "SVG Generator", nullptr));
label->setText(QCoreApplication::translate("Window", "&Shape:", nullptr));
shapeComboBox->setItemText(0, QCoreApplication::translate("Window", "House", nullptr));
shapeComboBox->setItemText(1, QCoreApplication::translate("Window", "Car", nullptr));
label_2->setText(QCoreApplication::translate("Window", "&Color:", nullptr));
colorButton->setText(QCoreApplication::translate("Window", "Choose Color...", nullptr));
label_3->setText(QCoreApplication::translate("Window", "&Background:", nullptr));
shapeComboBox_2->setItemText(0, QCoreApplication::translate("Window", "Sky", nullptr));
shapeComboBox_2->setItemText(1, QCoreApplication::translate("Window", "Trees", nullptr));
shapeComboBox_2->setItemText(2, QCoreApplication::translate("Window", "Road", nullptr));
toolButton_2->setText(QCoreApplication::translate("Window", "Save &As...", nullptr));
} // retranslateUi
};
namespace Ui {
class Window: public Ui_Window {};
} // namespace Ui
QT_END_NAMESPACE
#endif // WINDOW_H