Позвольте мне сначала представить проблему. Я представлю упрощение моего приложения проекта QT6 (в C ++), чтобы не затруднять чтение, так как у исходного кода есть много ненужных вещей, в частности, для этой проблемы, так что, возможно, что-то не хватает, но я пытался разместить все необходимое здесь.
У меня есть абстрактный класс, давайте называть это событием
Каждое событие < /code> может иметь 0 или любое количество детей любого типа, связанного с ним, и я хочу отобразить детские виджеты «Inside». Событие родительского (например, Teal Sructure)
< /li>
< /ul>
< /li>
Каждый полученный класс event_x < /code> должен иметь другой виджет (
Мой подход состоит в том, чтобы иметь абстрактный виджет class «эквивалент» для события один и подкласс для каждого ECVENT_X , который будет widget_x
widget_x
.
class WidgetViewer; // Stores and draws a vector of widgets, used for children.
class Widget : public QWidget
{
Q_OBJECT;
public:
Widget(QWidget* parent);
public slots:
virtual void setEvent(Event*) = 0;
// More things...
protected:
WidgetViewer * addChildren(EventList* list);
virtual uint16_t code() const = 0; // Similar to the prev. one
};
class Widget_1 : public Widget
{
Widget_1(QWidget* parent); // Constructor that will call Widget::Widget(parent)
void setEvent(Event* ev) override
{
Event_1* event = dynamic_cast(ev);
// Do things
}
// More things...
};
< /code>
Конструкторы этих классов обычно инициализации одного или нескольких меньших виджетов, например, эти метки, это пример одного из них: < /p>
Widget_1::Widget_1(QWidget *parent)
: WidgetViewer(parent),
label(new QLabel(this))
{
// Custom functions to customize a header widget every Widget_X shares.
setHeaderText("Show Text");
setHeaderColor("#b6d7a8");
setBackgroundColor("#d9ead3");
setBorderColor("#a2be96");
label->setWordWrap(true);
contents->layout()->addWidget(label);
}
Тогда у меня есть заводский метод для создания правильного экземпляра одного из widget_x из Code класса на основе кода ,
Widget* WidgetViewer::createWidget(Event* event)
{
QElapsedTimer timer;
timer.start();
Widget* widget = WidgetFactory::createWidget(this, event);
qDebug()
Это мой подход для этого. Проблема [b] [/b] заключается в том, что эти списки могут быть очень длинными, а создание нового класса виджета
каждый раз занимает столько времени , чем ожидалось (иногда до 2-3 секунды, в котором мое приложение останавливается). Я попробовал некоторые вещи, чтобы ускорить его, но я хотел бы знать, есть ли лучший способ, поскольку результат не очень удовлетворительным. /> Моя вторая попытка была (и является моей текущей лучшей) создать widgetpool , чтобы существовать widget_x любого типа x , уже хранящийся в памяти, поэтому их не нужно создавать через конструктор, что требует много времени (до 10 мс для некоторых из них). Я сделал это, создав новый класс, < /p>
class WidgetPool
{
public:
static WidgetPool& instance()
{
static WidgetPool instance;
return instance;
}
Widget* getWidget(WidgetViewer* parent, Event* event); // Gets a widget from the pool, if there is no one, uses the WidgetFactory to create one.
void returnWidget(Widget* widget); // Releases a widget to the pool again
private:
WidgetPool();
~WidgetPool();
WidgetPool(const WidgetPool&) = delete;
WidgetPool& operator=(const WidgetPool&) = delete;
QMap widget_pool;
};
и изменение WidgetViewer :: createWidget следующим образом:
Позвольте мне сначала представить проблему. Я представлю упрощение моего приложения проекта QT6 (в C ++), чтобы не затруднять чтение, так как у исходного кода есть много ненужных вещей, в частности, для этой проблемы, так что, возможно, что-то не хватает, но я пытался разместить все необходимое здесь. У меня есть абстрактный класс, давайте называть это событием [list] [*] Каждое событие < /code> может иметь 0 или любое количество детей любого типа, связанного с ним, и я хочу отобразить детские виджеты «Inside». Событие родительского (например, Teal Sructure)
< /li> < /ul> < /li> [*] Каждый полученный класс event_x < /code> должен иметь другой виджет ([code]Widget_X[/code])
Мой подход состоит в том, чтобы иметь абстрактный виджет class «эквивалент» для события один и подкласс для каждого ECVENT_X , который будет widget_x widget_x .[code]class WidgetViewer; // Stores and draws a vector of widgets, used for children. class Widget : public QWidget { Q_OBJECT; public: Widget(QWidget* parent); public slots: virtual void setEvent(Event*) = 0; // More things... protected: WidgetViewer * addChildren(EventList* list); virtual uint16_t code() const = 0; // Similar to the prev. one };
class Widget_1 : public Widget { Widget_1(QWidget* parent); // Constructor that will call Widget::Widget(parent) void setEvent(Event* ev) override { Event_1* event = dynamic_cast(ev); // Do things } // More things... }; < /code> Конструкторы этих классов обычно инициализации одного или нескольких меньших виджетов, например, эти метки, это пример одного из них: < /p> Widget_1::Widget_1(QWidget *parent) : WidgetViewer(parent), label(new QLabel(this)) { // Custom functions to customize a header widget every Widget_X shares. setHeaderText("Show Text"); setHeaderColor("#b6d7a8"); setBackgroundColor("#d9ead3"); setBorderColor("#a2be96");
[/code] Тогда у меня есть заводский метод для создания правильного экземпляра одного из widget_x из Code класса на основе кода , [code]class WidgetFactory { public: static Widget* createWidget(WidgetViewer* parent, Event* event); // More things... }; [/code] Class WidgetViewer отвечает на создание самих виджетов, используя эту функцию: [code]Widget* WidgetViewer::createWidget(Event* event) { QElapsedTimer timer; timer.start(); Widget* widget = WidgetFactory::createWidget(this, event); qDebug() Это мой подход для этого. Проблема [b] [/b] заключается в том, что эти списки могут быть очень длинными, а создание нового класса виджета [/code] каждый раз [b] занимает столько времени [/b], чем ожидалось (иногда до 2-3 секунды, в котором мое приложение останавливается). Я попробовал некоторые вещи, чтобы ускорить его, но я хотел бы знать, есть ли лучший способ, поскольку результат не очень удовлетворительным. /> Моя вторая попытка была (и является моей текущей лучшей) создать widgetpool , чтобы существовать widget_x любого типа x , уже хранящийся в памяти, поэтому их не нужно создавать через конструктор, что требует много времени (до 10 мс для некоторых из них). Я сделал это, создав новый класс, < /p> [code]class WidgetPool { public: static WidgetPool& instance() { static WidgetPool instance; return instance; }
Widget* getWidget(WidgetViewer* parent, Event* event); // Gets a widget from the pool, if there is no one, uses the WidgetFactory to create one. void returnWidget(Widget* widget); // Releases a widget to the pool again