[英]How to communicate between plugin and main application in Qt?
我需要讓我的繪圖板應用程序及其幾何圖形插件(繪制矩形,圓形等)相互通信:加載.so文件時,主應用程序將獲得一個具體的工廠來實例化一個圖形類和一個按鈕。 (將在主應用程序中加載以表示該圖)。 單擊按鈕時,應用程序可以繪制該圖。
我愚蠢地實現了這一點:
主應用程序具有一個QString
來標識客戶端選擇的圖形對象。 我在工廠中存儲了一個QString *point
該QString *point
,並編寫如下代碼:
QPushButton *CircleFactory::MyButton()
{
QPushButton *drawCircleBut = new QPushButton;
drawCircleBut->setIcon(QIcon(":/shape/circle"));
connect(drawCircleBut, SIGNAL(clicked()), this, SLOT(changeShape()));
return drawCircleBut;
}
void CircleFactory::changeShape()
{
*point = ID_LABEL;
}
我相信必須有更好的方法來解決此問題...請給我一些建議。
最簡單的解決方案是利用QObject的屬性系統:
QPushButton * CircleFactory::MyButton()
{
QScopedPointer<QPushButton> button(new QPushButton);
button->setIcon(QIcon(":/shape/circle"));
button->setProperty("identity", ID_LABEL);
return button->take();
}
然后,在連接到這些按鈕的任何插槽中,您都可以輕松檢查它們的身份;
void Foo::buttonClicked() {
qDebug() << "clicked on:" << sender()->property("identity");
}
這樣,您就不需要全局變量。
我質疑按鈕是否需要以這種方式標識自己。 我擔心的是您正在使用按鈕的標識,然后以某種方式返回到圓形對象或正確的插件。
相反,圈子工廠應該提供一個已經連接到正確插槽的按鈕。 如果不可能,那么您將不得不進一步解釋“繪圖板應用程序”的設計和預期功能。 您可能會想像到,這樣的應用程序應該如何工作還很遙遠-對您而言顯而易見的對其他人而言並不明顯。
另一個解決方案是擴展幾何圖形插件界面,以便只有插件知道如何調用其形狀以及如果將其表示為QIcon
則看起來如何。 該應用程序本身對圓形或矩形一無所知。
#include <QString>
class GeometricPluginInterface
{
public:
GeometricPluginInterface() {}
virtual ~GeometricPluginInterface() {}
virtual QString name() const = 0;
virtual QIcon icon() const = 0;
};
在啟動應用程序時,您可以將所有已加載的插件存儲在QList
(例如QList<GeometricPluginInterface*> m_plugins;
)。 如果用按鈕填充UI,則可以遍歷列表,並使用從插件本身獲取的圖標為每個插件創建QPushButton
。 您可以像代碼中那樣通過lambda(自C ++ 11起)將按鈕的clicked
信號連接到插槽。
foreach (GeometricPluginInterface *plugin, m_plugins) {
QPushButton *button = new QPushButton;
button->setIcon(plugin->icon());
connect(button, &QPushButton::clicked,
[this, plugin] {
geometryButtonClicked(plugin->name());
});
ui->buttonLayout->addWidget(button);
}
void GeometricPluginInterface::geometryButtonClicked(const QString &geometryName)
{
qDebug() << "Geometry clicked: " << geometryName;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.