2

Since Qt doesnt allow templates in their slots, I tried to do the following solution without success.

First a would like to create a list like this:

list commands = 
0, "MyDashboard", DashBoard0
1, "MomsDashboard", Dashboard1

Dashboard 0 and 1 are both derived from widget

Lets say you have a QListWidget where we add the strings in the list and then do the connection:

connect(listWidget, SIGNAL(itemClicked(QListWidgetItem*)), 
       this, SLOT(addDashboard(QListWidgetItem*)));

void addDashboard(QListWidgetItem* item) {
    int index = listWidget->row(item);

    QWidget* widget = new typeof(command.atIndex(index).getType());
    widget->show();

}

How would I create that list and store types just like you do in C# Type?

4

1 に答える 1

3

C ++では、タイプが実行時にのみ認識されるオブジェクトを(new演算子を使用して)作成することはできません。ただし、回避策として、ファクトリメソッドパターンの簡略化された形式を使用できます。

次に例を示します。

// Type IDs that are associated with a widget type
enum WidgetTypeId {
    dashboard1WidgetTypeId,
    dashboard2WidgetTypeId
};

// Factory method
QWidget* createWidget(WidgetTypeId type) {
    switch (type)
    {
        case dashboard1WidgetTypeId:
            return new DashBoard0;

        case dashboard2WidgetTypeId:
            return new DashBoard1;
    }
}

void addDashboard(QListWidgetItem* item) {
    int index = listWidget->row(item);

    QWidget* widget = createWidget(command.atIndex(index).getWidgetTypeId());
    widget->show();

}

あまりきれいではありません、私は知っています。ウィジェットがクローン可能である場合std::mapは、醜いswitchステートメントの代わりに使用できます。この代替アプローチは、プロトタイプパターンの例です。このアプローチを示すサンプルコードを次に示します。

class WidgetFactory
{
public:
    QWidget* create(const std::string& name) {
        return prototypes_[name]->clone();
    }

    void addPrototype(const std::string& name, QWidget* prototype) {
        prototypes_[name] = prototype;
    }

private:
    std::map<std::string, QWidget*> prototypes_;
}


WidgetFactory factory;
factory.addPrototype("DashBoard0", new DashBoard0);
factory.addPrototype("DashBoard1", new DashBoard1);


void addDashboard(QListWidgetItem* item) {
    int index = listWidget->row(item);

    QWidget* widget = factory.create(command.atIndex(index).getWidgetTypeName());
    widget->show();

}

C++はあまり動的な言語ではありません。RTTI機能が制限されており、C#のリフレクション機能はほとんどありません。そのため、ファクトリメソッドやアブストラクトファクトリなどのパターンに頼る必要があります。


補遺

QtがC++で通常利用できるものを超えるランタイムクラス情報を提供する可能性があることに気づきませんでした(私は単純なユーティリティアプリにのみQtを使用したので、そのフレームワークで利用できるすべてのベルとホイッスルを知りません)。そのことを念頭に置いて、クラス名でQtオブジェクトをインスタンス化する方法に関するこのメーリングリストのディスカッションを検索して見つけました。ただし、そのソリューションがプラグインオブジェクトで機能するかどうかはわかりません。

于 2012-02-09T06:08:35.193 に答える