Улучшение реализации «структуры дерева виджетов» в QT6C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Улучшение реализации «структуры дерева виджетов» в QT6

Сообщение Anonymous »

Позвольте мне сначала представить проблему. Я представлю упрощение моего приложения проекта QT6 (в C ++), чтобы не затруднять чтение, так как у исходного кода есть много ненужных вещей, в частности, для этой проблемы, так что, возможно, что-то не хватает, но я пытался разместить все необходимое здесь.
У меня есть абстрактный класс, давайте называть это событием
  • Каждое событие < /code> может иметь 0 или любое количество детей любого типа, связанного с ним, и я хочу отобразить детские виджеты «Inside». Событие родительского (например, Teal Sructure)


    < /li>
    < /ul>
    < /li>
  • Каждый полученный класс event_x < /code> должен иметь другой виджет (

    Код: Выделить всё

    Widget_X
    )

    Мой подход состоит в том, чтобы иметь абстрактный виджет 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 из Codation класса на основе кода ,

    Код: Выделить всё

    class WidgetFactory
    {
    public:
    static Widget* createWidget(WidgetViewer* parent, Event* event);
    // More things...
    };
    
    Class WidgetViewer отвечает на создание самих виджетов, используя эту функцию:

    Код: Выделить всё

    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 следующим образом:

    Код: Выделить всё

    Widget* WidgetViewer::createWidget(Event* event)
    {
    QElapsedTimer timer;
    timer.start();
    Widget* widget = WidgetPool::instance().getWidget(this, event);
    qDebug() 
    
    Подробнее здесь: [url]https://stackoverflow.com/questions/79736543/improve-implementation-of-a-widget-tree-structure-in-qt6[/url]
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»