Verbessern Sie die Implementierung einer "Widget -Baumstruktur" in QT6C++

Programme in C++. Entwicklerforum
Anonymous
 Verbessern Sie die Implementierung einer "Widget -Baumstruktur" in QT6

Post by Anonymous »

Lassen Sie mich zunächst das Problem vorstellen. Ich werde eine Vereinfachung meiner QT6-Projekt-App (in C ++) vorstellen, um es nicht zu sehr zu lesen, da der ursprüngliche Code für dieses Problem viele unnötige Dinge aufweist. Vielleicht fehlt etwas, aber ich habe versucht, hier alles zu platzieren.

Code: Select all

class EventList; // "Shortcut" for std::vector
class Event
{
protected:
uint16_t _code;
std::shared_ptr _children_lists;
// More things...
public:
// More things...
static Event* create(VALUE obj);
inline virtual uint16_t code() const { return _code; }
};
, das ein Ereignis darstellt, das von sehr unterschiedlichen Typen abhängig von einem Parameter des Argumentwerts OBJ der Methode create sein kann, wobei jeder einer abgeleiteten Klasse eine abgeleitete Klasse ist, z. B.:
class Event_1 : public Event
{
public:
Event_1(...);
static Event_1* create(VALUE obj);
inline uint16_t code() const override { return 1; }
// More things...
}

Jetzt möchte ich ein QT6 -Widget erstellen, um jedes dieser Ereignisse Klassen in einer GUI darzustellen. Key things to have in mind:
  • Each Event may have 0 or any number of childs of any type associated to it, and I want to display the children widgets "inside" the parent widget (like a tree structure) as this example:

    Event #1 (Type 1)

    Child #1.1 of Event #1 (Typ 1)

    Kind #1.1.1 von Kind #1.1 (Typ 2) < /li>
    Kind #1.1.2 von Child #1.1 (Typ 3) < /li>
    < /ul>
    < /li>
    Kind #1.2 von Ereignis #1 (Typ 2) (Typ 2) (Typ 2) (Typ 2) (Typ 2) (Typ 2) (Typ 2) (Typ 2) (Typ 2) (Typ 2) (Typ 2) (Typ 2) (Typ 2) (Typ 2) (Typ 2) (Typ 2) #1 (Typ 2) (Typ 2) (Typ 2) #1 (Typ 2) (Typ 2) (Typ 2) #1 (Typ 2) (Typ 2) (Typ 2) #1 (Typ 2) (Typ 2) #1 (Typ 2) (Typ 2) #1 (Typ 2) (Typ 2) (Typ 2) #1 (Typ 2) (Typ 2) #1 (type #1 /> < /ul>
    < /li>
    < /ul>
    < /li>
    Jeweils abgeleitete Klasse Event_x < /code> sollte ein anderes Widget haben ((

    Code: Select all

    Widget_X
    )
Mein Ansatz ist es, ein abstraktes Widget Klasse "äquivalent" zu dem Ereignis zu haben und eine Unterklasse für jede ecvent_x , die 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>
Diese Klassenkonstruktoren initialisieren typischerweise ein oder mehrere kleinere Widgets.

Code: Select all

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

Dann habe ich eine Werksmethode, um die richtige Instanz eines der Widget_X aus der Ereignis-Klasse zu erstellen, basierend auf Code ,

Code: Select all

class WidgetFactory
{
public:
static Widget* createWidget(WidgetViewer* parent, Event* event);
// More things...
};
Die Klasse WidgetViewer reagiert für das Erstellen der Widgets selbst mit dieser Funktion:

Code: Select all

Widget* WidgetViewer::createWidget(Event* event)
{
QElapsedTimer timer;
timer.start();
Widget* widget = WidgetFactory::createWidget(this, event);
qDebug() 
Dies ist mein Ansatz, dies zu tun. Das [b] [url=viewtopic.php?t=26065]Problem[/url] [/b] ist, dass diese Listen sehr lang sein können und jedes Mal eine neue Widget 
-Klasse zu erstellen kann so viel Zeit als erwartet (manchmal bis zu 2-3 Sekunden, in denen meine App gestoppt wird). Ich habe einige Dinge ausprobiert, um es zu beschleunigen, aber ich würde gerne wissen, ob es einen besseren Weg gibt, da das Ergebnis nicht sehr zufriedenstellend ist. < /P>

Der erste Versuch, den ich versuchte, das Problem der Langsamkeit zu lösen, bestand darin, Multitreading zu verwenden, aber GUI -Operationen können auf anderen Threads, die auf andere Threads als das Hauptbrot sind. /> Mein zweiter Versuch war (und ist mein aktuelles Bestes), um einen WidgetPool zu erstellen, damit Widget_x von jedem X -Typ vorhanden ist, der bereits im Speicher gespeichert ist. Daher müssen sie nicht über Konstruktor erstellt werden. Ich habe dies getan, indem ich eine neue Klasse erstellt habe, < /p>

Code: Select all

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;
};
und Änderung von WidgetViewer :: createwidget wie folgt:

Code: Select all

Widget* WidgetViewer::createWidget(Event* event)
{
QElapsedTimer timer;
timer.start();
Widget* widget = WidgetPool::instance().getWidget(this, event);
qDebug()

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post