我尝试为Qt Designer创建一个简单的小部件。当我设置一个房产时,在我尝试阅读我的房产之后或很久之后,她总是空着。
setProperty("iconConnection", QIcon("toto.png"));
qDebug() << property("iconConnection");
我尝试不同的测试,一切都没有做。也许我不理解Q_PROPERTY的概念
完整代码:
QKSwitchButton.h
#pragma once
// Qt
#include <QStateMachine>
#include <QPushButton>
#include <QState>
#include <QVariant>
#include <QDebug>
#include <QtUiPlugin/QDesignerExportWidget>
class QDESIGNER_WIDGET_EXPORT QKSwitchButton: public QPushButton
{
Q_OBJECT
Q_PROPERTY(QIcon iconDisconnected READ iconDisconnected WRITE setIconDisconnected NOTIFY iconDisconnectedChanged)
Q_PROPERTY(QIcon iconConnection READ iconConnection WRITE setIconConnection NOTIFY iconConnectionChanged)
Q_PROPERTY(QIcon iconConnected READ iconConnected WRITE setIconConnected NOTIFY iconConnectedChanged)
Q_PROPERTY(QIcon iconDisconnection READ iconDisconnection WRITE setIconDisconnection NOTIFY iconDisconnectionChanged)
public:
QKSwitchButton(QWidget * parent = 0);
~QKSwitchButton();
QIcon iconDisconnected();
QIcon iconConnection();
QIcon iconConnected();
QIcon iconDisconnection();
public slots:
void setIconDisconnected(QIcon icon);
void setIconConnection(QIcon icon);
void setIconConnected(QIcon icon);
void setIconDisconnection(QIcon icon);
signals:
void iconDisconnectedChanged(QIcon icon);
void iconConnectionChanged(QIcon icon);
void iconConnectedChanged(QIcon icon);
void iconDisconnectionChanged(QIcon icon);
private:
QStateMachine* m_machine;
QState *m_stateOFF;
QState *m_stateConnection;
QState *m_stateON;
QState *m_stateDisconnection;
QIcon m_iconDisconnected;
QIcon m_iconConnection;
QIcon m_iconConnected;
QIcon m_iconDisconnection;
};
QKSwitchButton.cpp
#include "QKSwitchButton.h"
// Qt
#include <QState>
#include <QStateMachine>
#include <QEventTransition>
#include <QEvent>
#include <QDebug>
//
#include "QKEvent.h"
#include <QMetaProperty>
#include <vector>
#include <utility>
#include <algorithm>
static void dump_props(QObject *o)
{
auto mo = o->metaObject();
qDebug() << "## Properties of" << o << "##";
do {
qDebug() << "### Class" << mo->className() << "###";
std::vector<std::pair<QString, QVariant> > v;
v.reserve(mo->propertyCount() - mo->propertyOffset());
for (int i = mo->propertyOffset(); i < mo->propertyCount();
++i)
v.emplace_back(mo->property(i).name(),
mo->property(i).read(o));
std::sort(v.begin(), v.end());
for (auto &i : v)
qDebug() << i.first << "=>" << i.second;
} while ((mo = mo->superClass()));
}
QKSwitchButton::QKSwitchButton(QWidget * parent)
: QPushButton(parent)
{
m_machine = new QStateMachine(this);
this->setText("");
// States
m_stateOFF = new QState();
m_stateConnection = new QState();
m_stateON = new QState();
m_stateDisconnection = new QState();
// Changes of states
QEventTransition *connectionTransition = new QEventTransition(this, QEvent::MouseButtonPress);
connectionTransition->setTargetState(m_stateConnection );
m_stateOFF->addTransition(connectionTransition);
QKTransition *connectedTransition = new QKTransition(QKEvent::DeviceConnected );
connectedTransition->setTargetState(m_stateON );
m_stateConnection->addTransition( connectedTransition );
QKTransition *connectionFailedTransition = new QKTransition(QKEvent::DeviceConnectionFailed);
connectionFailedTransition->setTargetState(m_stateOFF);
m_stateConnection->addTransition(connectionFailedTransition);
QEventTransition *disconnectionTransition = new QEventTransition(this, QEvent::MouseButtonPress);
disconnectionTransition->setTargetState(m_stateDisconnection);
m_stateON->addTransition(disconnectionTransition);
QKTransition *disconnectedTransition = new QKTransition(QKEvent::DeviceDisconnected );
disconnectedTransition->setTargetState(m_stateOFF);
m_stateDisconnection->addTransition(disconnectedTransition);
m_machine->addState(m_stateON);
m_machine->addState(m_stateOFF);
m_machine->addState(m_stateConnection);
m_machine->addState(m_stateDisconnection);
//this->setIcon(QIcon(":/icons/ribbon/ON-OFF-off.png"));
m_machine->setInitialState(m_stateOFF);
m_machine->start();
}
QKSwitchButton::~QKSwitchButton()
{
}
QIcon QKSwitchButton::iconDisconnected()
{
return m_iconDisconnected;
}
QIcon QKSwitchButton::iconConnection()
{
return m_iconConnection;
}
QIcon QKSwitchButton::iconConnected()
{
return m_iconConnected;
}
QIcon QKSwitchButton::iconDisconnection()
{
return m_iconDisconnection;
}
void QKSwitchButton::setIconDisconnected(QIcon icon)
{
dump_props(this);
m_stateOFF->assignProperty(this, "icon", icon);
const QMetaObject *mo = metaObject();
QMetaProperty prop = mo->property(mo->indexOfProperty("iconConnection"));
qDebug() << property(prop.name());
qDebug() << "============================";
setProperty("iconConnection", QIcon("toto.png"));
qDebug() << property("iconConnection");
emit iconDisconnectedChanged(icon);
}
void QKSwitchButton::setIconConnection(QIcon icon)
{
m_stateConnection->assignProperty(this, "icon", icon);
emit iconConnectionChanged(icon);
}
void QKSwitchButton::setIconConnected(QIcon icon)
{
m_stateON->assignProperty(this, "icon", icon);
emit iconConnectedChanged(icon);
}
void QKSwitchButton::setIconDisconnection(QIcon icon)
{
m_stateDisconnection->assignProperty(this, "icon", icon);
emit iconDisconnectionChanged(icon);
}
QKSwitchButtonPlugin.h:
#pragma once
#include <QtUiPlugin/QDesignerCustomWidgetInterface>
class QIcon;
class QWidget;
class QKSwitchButtonPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
//Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidget")
Q_PLUGIN_METADATA(IID "com.toto.plugin.Qt.SwitchButton" FILE "QKSwitchButtonMetadata.json") // It's important to change the version name after every modification.
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
explicit QKSwitchButtonPlugin(QObject *parent = 0);
bool isContainer() const override;
bool isInitialized() const override;
QIcon icon() const override;
QString domXml() const override;
QString group() const override;
QString includeFile() const override;
QString name() const override;
QString toolTip() const override;
QString whatsThis() const override;
QWidget *createWidget(QWidget *parent) override;
void initialize(QDesignerFormEditorInterface *formEditor) override;
private slots:
void iconDisconnectedChanged(QIcon icon);
/*void iconConnectionChanged(QIcon icon);
void iconConnectedChanged(QIcon icon);
void iconDisconnectionChanged(QIcon icon);*/
private:
bool initialized;
};
QKSwitchButtonPlugin.cpp:
#include <QtDesigner/QExtensionFactory>
#include <QtDesigner/QExtensionManager>
#include <QtDesigner/QDesignerFormEditorInterface>
#include <QtDesigner/QDesignerFormWindowInterface>
#include <QtDesigner/QDesignerContainerExtension>
#include <QtDesigner/QDesignerPropertySheetExtension>
#include <QIcon>
#include <QtPlugin>
#include "QKSwitchButton.h"
#include "QKSwitchButtonPlugin.h"
QKSwitchButtonPlugin::QKSwitchButtonPlugin(QObject *parent)
: QObject(parent)
, initialized(false)
{
}
QString QKSwitchButtonPlugin::name() const
{
return QLatin1String("QKSwitchButton");
}
QString QKSwitchButtonPlugin::group() const
{
return QLatin1String("toto");
}
QString QKSwitchButtonPlugin::toolTip() const
{
return QString();
}
QString QKSwitchButtonPlugin::whatsThis() const
{
return QString();
}
QString QKSwitchButtonPlugin::includeFile() const
{
return QLatin1String("QKSwitchButton.h");
}
QIcon QKSwitchButtonPlugin::icon() const
{
return QIcon();
}
bool QKSwitchButtonPlugin::isContainer() const
{
return false;
}
QWidget *QKSwitchButtonPlugin::createWidget(QWidget *parent)
{
QKSwitchButton *widget = new QKSwitchButton(parent);
connect(widget, &QKSwitchButton::iconDisconnectedChanged, this, &QKSwitchButtonPlugin::iconDisconnectedChanged);
return widget;
}
bool QKSwitchButtonPlugin::isInitialized() const
{
return initialized;
}
void QKSwitchButtonPlugin::initialize(QDesignerFormEditorInterface *formEditor )
{
Q_UNUSED(formEditor)
if (initialized)
return;
initialized = true;
}
QString QKSwitchButtonPlugin::domXml() const
{
return QLatin1String("\
<ui language=\"c++\">\
<widget class=\"QKSwitchButton\" name=\"qkswitchbutton\">\
<property name=\"geometry\">\
<rect>\
<x>0</x>\
<y>0</y>\
<width>63</width>\
<height>30</height>\
</rect>\
</property>\
</widget>\
<customwidgets>\
<customwidget>\
<class>QKSwitchButton</class>\
<extends>QPushButton</extends>\
</customwidget>\
</customwidgets>\
</ui>");
}
void QKSwitchButtonPlugin::iconDisconnectedChanged(QIcon icon)
{
setProperty("iconDisconnected", icon);
}