Как динамически загружать типы данных во время выполнения через механизм плагинов - PullRequest
2 голосов
/ 09 февраля 2012

Поскольку Qt не разрешает шаблоны в их слотах, я попытался сделать следующее решение безуспешно.

Сначала a хотел бы создать список, подобный этому:

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

Панель 0 и 1 являются производными от виджета

Допустим, у вас есть QListWidget, где мы добавляем строки в список, а затем выполняем соединение:

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();

}

Как бы я создал этот список и сохранял типы так же, как вы делаете это в C # Type?

1 Ответ

3 голосов
/ 09 февраля 2012

C ++ не позволяет создавать объект (используя оператор new), тип которого известен только во время выполнения. Однако вы можете использовать упрощенную форму шаблона Factory Method в качестве обходного пути.

Вот пример:

// 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. Этот альтернативный подход может быть примером Prototype Pattern . Вот пример кода, демонстрирующий этот подход:

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 #. Вот почему вам приходится прибегать к таким шаблонам, как Factory Method и Abstract Factory.


ДОПОЛНЕНИЕ

До меня не дошло, что Qt может предоставить информацию о классе времени выполнения сверх той, которая обычно доступна в C ++ (я использовал Qt только для простых служебных приложений, поэтому я не знаю всех наворотов, доступных в этой среде) , Имея это в виду, я искал и нашел этот список рассылки обсуждение о том, как создавать экземпляры объектов Qt по имени класса. Я не знаю, работает ли это решение для объектов плагинов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...