This paper mainly expounds the creation and calling methods and precautions of custom control plug-in.
catalogue
1, Create a custom control plug-in
1. Qt Designer special interface
2. Custom control class interface of plug-in
2, Calling a custom control plug-in
1, Create a custom control plug-in
1. Qt Designer special interface
1.1. Control collector interface
Base class: QDesignerCustomWidgetCollectionInterface
Purpose: load all custom control classes into a QList
#pragma once #include <QtDesigner> #include <qplugin.h> class WidgetCollectionInterface : public QObject, public QDesignerCustomWidgetCollectionInterface { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetCollectionInterface) #if QT_VERSION >= 0x050000 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetCollectionInterface") #endif // QT_VERSION >= 0x050000 public: WidgetCollectionInterface(QObject* parent = 0); QList<QDesignerCustomWidgetInterface*> customWidgets() const override; private: QList<QDesignerCustomWidgetInterface*> widgets; };
Key points:
Two macros that declare a unique interface
Q_INTERFACES(QDesignerCustomWidgetCollectionInterface) Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetCollectionInterface")
Constructor to load all custom control classes
WidgetCollectionInterface::WidgetCollectionInterface(QObject* parent) : QObject(parent) { widgets.append(new MyProgressBar1Interface(this)); //widgets.append(new CustomWidgetTwoInterface(this)); //widgets.append(new CustomWidgetThreeInterface(this)); }
1.2. Single custom control interface
Base class: QDesignerCustomWidgetInterface
Purpose: to define the information of a single custom control by rewriting the virtual function, so that Qt Designer can load the information of the custom control through dll Dynamic call,
Its information includes control icon, control name, control header file, control group name, control class name, default name of object instance automatically generated by Qt Designer drag, etc
#pragma once #include <QtUiPlugin/QDesignerCustomWidgetInterface> #include <QtDesigner/QtDesigner> class MyProgressBar1Interface : public QObject, public QDesignerCustomWidgetInterface { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: MyProgressBar1Interface(QObject *parent = Q_NULLPTR); bool isContainer() const; bool isInitialized() const; QIcon icon() const; QString domXml() const; QString group() const; QString includeFile() const; QString name() const; QString toolTip() const; QString whatsThis() const; QWidget *createWidget(QWidget *parent); void initialize(QDesignerFormEditorInterface *core); private: bool initialized; };
Key points:
Virtual function override of base class QDesignerCustomWidgetInterface
#include <QtUiPlugin/QDesignerCustomWidgetInterface> #include <QtDesigner/QtDesigner> class MyProgressBar1Interface : public QObject, public QDesignerCustomWidgetInterface { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) ... ... ... }
2. Custom control class interface of plug-in
2.1. Implementation of custom controls
Control inherits the base class, control properties, control drawing, signal / slot, event and other conventional custom control implementations. Refer to the use of QPainter for details
#pragma once #include <QProgressBar> #include <QFont> #include <QColor> #include <QBrush> #include <QPen> #include <QtDesigner/QtDesigner> class QDESIGNER_WIDGET_EXPORT MyProgressBar1 : public QProgressBar { Q_OBJECT Q_PROPERTY(QFont textFont READ getTextFont WRITE setTextFont) Q_PROPERTY(QColor textColor READ getTextColor WRITE setTextColor) Q_PROPERTY(QPen circleLinePen READ getCircleLinePen WRITE setCircleLinePen) Q_PROPERTY(QBrush barBackgroundBrush READ getBarBackgroundBrush WRITE setBarBackgroundBrush) Q_PROPERTY(QBrush barForegroundBrush READ getBarForegroundBrush WRITE setBarForegroundBrush) public: explicit MyProgressBar1(QWidget* parent = nullptr); virtual ~MyProgressBar1(); protected: virtual void paintEvent(QPaintEvent* event); public: QFont getTextFont() const; void setTextFont(const QFont& font); QColor getTextColor() const; void setTextColor(const QColor& color); QPen getCircleLinePen() const; void setCircleLinePen(const QPen& pen); QBrush getBarBackgroundBrush() const; void setBarBackgroundBrush(const QBrush& brush); QBrush getBarForegroundBrush() const; void setBarForegroundBrush(const QBrush& brush); private: QFont textFont; //Font format QColor textColor; //Font color QPen circleLinePen; //Circle outline brush QBrush barBackgroundBrush; //Progress bar background brush QBrush barForegroundBrush; //Progress bar brush private: void InitUi(); void TestPainter(); };
2.2 class interface export
- Using QDESIGNER_WIDGET_EXPORT declaration class. The header file of this macro is #include < qtdesigner / qtdesigner >
#include <QtDesigner/QtDesigner> class QDESIGNER_WIDGET_EXPORT MyProgressBar1 : public QProgressBar
-
Predefined macro QDESIGNER_EXPORT_WIDGETS
This macro is defined as follows, so be sure to predefine the macro QDESIGNER_EXPORT_WIDGETS to enable it to export interfaces, otherwise But dll is compiled.
#if defined(QDESIGNER_EXPORT_WIDGETS) # define QDESIGNER_WIDGET_EXPORT __declspec(dllexport) #else # define QDESIGNER_WIDGET_EXPORT __declspec(dllimport) #endif
2, Calling a custom control plug-in
1. Dynamic call plug-in
Implementation principle: mainly through dll project to implement WidgetCollectionInterface, MyProgressBar1Interface and other classes. First load all custom control classes into WidgetCollection, then export the custom class through name() when calling, and then createWidget().
Purpose: to enable Qt Designer to load all the controls in the custom control plug-in at one time, so that users can directly use the controls by dragging and dropping
Special note: this calling method cannot directly new the custom control class. You can only call the member function of the custom control class through the following methods (LoadInterface, CreateCustomWidget)
bool CustomWidgetTestDemo::LoadInterface(QString pluginName) { QFileInfo pluginFile( QString("%1/%2").arg(QCoreApplication::applicationDirPath()).arg(pluginName)); QString pluginFilePath = pluginFile.absoluteFilePath(); QPluginLoader load(pluginFilePath); QObject* obj = load.instance(); //Load dll if (obj != nullptr) { m_interface = qobject_cast<CustomWidgetCollectionInterface*>(obj); //Load interface if (m_interface != nullptr) { return true; } else { QMessageBox::critical(this, "ERROR", QString::fromStdWString(L"CustomWidgetCollectionInterface Loading failed!")); } } else { QMessageBox::critical(this, "ERROR", QString::fromStdWString(L"<%1>Loading failed!").arg(pluginFilePath)); } return false; } template<class T> T* CustomWidgetTestDemo::CreateCustomWidget(QString name, QWidget* parent) { QList<QDesignerCustomWidgetInterface*> widgets = m_interface->customWidgets(); for each (QDesignerCustomWidgetInterface * var in widgets) { if (var->name() == name) { T* widget; widget = static_cast<T*>(var->createWidget(parent)); if (widget != nullptr) { return widget; } break; } } QMessageBox::critical(this, "ERROR", QString::fromStdWString(L"Custom control<%1>Loading failed!").arg(name)); return nullptr; } LoadInterface("QtCustomYihPlugin.dll"); MyProgressBar1* myProgressBar1 = CreateCustomWidget<MyProgressBar1>("MyProgressBar1", this); myProgressBar1->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2. Static call plug-in
Implementation principle: mainly through Add qdesigner before the custom control class in dll project_ WIDGET_ Export. Actually, it's for you dll definition class interface
Purpose: to instantiate the custom control class, that is, the new custom control object The source code generated by the ui file is also used to instantiate the custom control through new, which is similar to the following code.
Special note: with static calls dll method, which needs to be set lib dependency and its path
MyProgressBar1* myProgressBar1_666; myProgressBar1_666 = new MyProgressBar1(this); myProgressBar1_666->setObjectName(QString::fromUtf8("myProgressBar1_1")); myProgressBar1_666->setGeometry(QRect(320, 60, 271, 191)); myProgressBar1_666->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); m_Layout->addWidget(myProgressBar1_666);
3, Conclusion
For information about the production of custom controls and the complete steps of calling control plug-ins, you can refer to the following materials:
Internet blog: < QT writing custom control plug-ins, passing pits and precautions >
Internet blog: < QT for Qt Designer >
Books: < QT creator quick start_ Third edition >
Demo source code (JaneYih PC):
Solution name: CustomWidgetProject
Create plug-in project name: QtCustomYihPlugin
Call plug-in project name: CustomWidgetTestDemo
Reprint please indicate the source!!
If there is any mistake, please give advice~