QWidget als Platzhalter verwenden

Alles rund um die Programmierung mit Qt
Antworten
harbok
Beiträge: 6
Registriert: 12. Juni 2010 21:12

QWidget als Platzhalter verwenden

Beitrag von harbok »

Hallo,

ich bin noch recht neu in der Welt von QT und bin jetzt an ein Problem gestossen, zu dem ich leider bisher keine Lösung finden konnte:

Ich arbeite mit dem QT Designer und wollte die Forms modular aufbauen, d.h. ich füge QWidgets als reine Platzhalter an den Stellen in die Dialoge ein, die dann später mit echtem Inhalt gefüllt werden sollen.

Die "Als Platzhalter definieren .." Funktion des Designers kann ich dafür leider nicht verwenden, da die Klasse, die später tatsächlich den Inhalt füllt, erst zur Laufzeit feststeht bzw. mehrfach wechseln soll.


Mein Ansatz war es, einfach den Pointer auf mein Platzhalter-QWidget mit einem Pointer auf ein Inhalts-Widget zu ersetzen und update(), repaint() aufzurufen, aber leider hatte ich damit kein Glück.

Beispiel:

Ich habe eine Klasse MainWidget, in der zwei QWidgets (widgetLeft, widgetRight) per Designer definiert sind. Ich möchte jetzt zur Laufzeit das widgetRight mit einem ganz anderen Widget ersetzen. Mein Code dazu sah etwa wie folgt aus:

Code: Alles auswählen

pContentWidgetRight = new IrgendeinWidget();
pContentWidgetLeft = new IrgendeinAnderesWidget();
this->ui.widgetRight = pContentWidget;
this->ui.widgetRight->update();
this->ui.widgetRight->repaint();
und scheiterte :)

Wenn ich testweise die Widgets im Konstruktor als Kinder des MainWidgets definiere (mit: new IrgendeinWidget(this) ), dann werden sie übereinander mitten in die Geometrie des MainWidgets gezeichnet.


WidgetContainer wie das StackedWidget etc würde ich gern vermeiden, da ich meine, so einen Lösungsansatz schon einmal lauffähig implementiert zu haben - nur leider nicht mehr weiss, wie :)


Ich hoffe, jemand kann etwas Licht ins Dunkel bringen.


Gruß,
harbok
sanni
Beiträge: 39
Registriert: 27. Mai 2010 11:53

Beitrag von sanni »

Mit dem Designer kenne ich mich nicht so gut aus,
aber wenn das Widget in der Mitte des Parent-Widgets gezeichnet wird, hast du es nicht dem Layout hinzugefügt.
harbok
Beiträge: 6
Registriert: 12. Juni 2010 21:12

Beitrag von harbok »

Es ist auch keinem Layout hinzugefügt, weil es ja eigentlich das Widget ersetzen soll, welches dem Layout hinzugefügt wurde und an dessen Stelle dann positioniert sein soll.


Ich möchte einfach ein QWidget gegen ein anderes austauschen. Zur Laufzeit.
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Die QStackedWidget-Methode wäre aber die einfachste Möglichkeit...
harbok
Beiträge: 6
Registriert: 12. Juni 2010 21:12

Beitrag von harbok »

Ist das nicht umständlicher? Ich muss dann ja immer das alte Widget löschen, das neue hinzufügen und dann raise() oder setCurrentWidget() aufrufen. Eigentlich habe ich ja gar keine stackedwidgets, sondern immer nur ein Widget, welches ich anzeigen möchte und benötige da gar keine Containerklasse.

So wird es sicherlich gehen, ich schrecke aber noch etwas davor zurück, weil es ja doch irgendwie einen Overkill darstellt, überall Container zu nehmen, die immer nur genau 1 Widget beinhalten.
Chris81T
Beiträge: 82
Registriert: 4. Mai 2008 00:06
Wohnort: Urbar

Beitrag von Chris81T »

Ich persönlich würde mir so ein Platzhalter- Widget sparen.

Zu 99,9% kann man woll von ausgehen, dass du ein Layout benötigst. Dieses kannst du ja mittels Designer "platzieren" und zur Laufzeit dann dein spezifisches Widget in dem Layout hinzufügen. Da brauchst du auch kein update oder sonstiges, da dies dann durch das Layout bewerkstelligt wird.
So hättest du das instanziieren eines leeren Widgets gespart (auch wenn es an dieser Stelle keinen großen Overhead darstellt).
harbok
Beiträge: 6
Registriert: 12. Juni 2010 21:12

Beitrag von harbok »

Der Designer erlaubt es mir leider nicht, ein Layout zu setzen, ohne dass ich da einen Inhalt habe.

Ich wollte mir die Form-Klassen als lightweight Designer-Klassen ohne grosse Implementierung umsetzen, aber das scheint so ja leider nicht ganz zu laufen. Ich werde mal den Ansatz mit einem QStackedWidget verfolgen - vielleicht kann ich da ja doch ein paar Widgets wiederverwenden und im Container liegenlassen.
Chris81T
Beiträge: 82
Registriert: 4. Mai 2008 00:06
Wohnort: Urbar

Beitrag von Chris81T »

harbok hat geschrieben:Der Designer erlaubt es mir leider nicht, ein Layout zu setzen, ohne dass ich da einen Inhalt habe.
:shock: Also das bezweifle ich sehr, da ich es selber so mach! Ich hoffe mal, wir reden auch vom Gleichen 8)

Also ich mach das grad mal selber (okay, ich glaub ich seh das Problem):
- Designer starten
- Leeres Widget erstellen lassen
- Über Kontextmenü kann man aktuell kein Layout setzen
- Also setz ich irgendein Widget rein
- Setze nun mein Layout
- Lösche das Widget
- Dann hab ich in dem Ui ein Layout gesetzt (Wobei das Ui an der Stelle auch überhaupt keinen Sinn mehr macht, da ich dies auch direkt im Code machen kann!)

Das wird von Qt erzeugt:

Code: Alles auswählen

/********************************************************************************
** Form generated from reading UI file 'designerer9965.ui'
**
** Created: Sun Jun 13 15:34:40 2010
**      by: Qt User Interface Compiler version 4.6.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef DESIGNERER9965_H
#define DESIGNERER9965_H

#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QGridLayout>
#include <QtGui/QHeaderView>
#include <QtGui/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Form
{
public:
    QGridLayout *gridLayout;

    void setupUi(QWidget *Form)
    {
        if (Form->objectName().isEmpty())
            Form->setObjectName(QString::fromUtf8("Form"));
        Form->resize(426, 354);
        gridLayout = new QGridLayout(Form);
        gridLayout->setObjectName(QString::fromUtf8("gridLayout"));

        retranslateUi(Form);

        QMetaObject::connectSlotsByName(Form);
    } // setupUi

    void retranslateUi(QWidget *Form)
    {
        Form->setWindowTitle(QApplication::translate("Form", "Form", 0, QApplication::UnicodeUTF8));
    } // retranslateUi

};

namespace Ui {
    class Form: public Ui_Form {};
} // namespace Ui

QT_END_NAMESPACE

#endif // DESIGNERER9965_H
Und mit layout() (oder wie die Zugriffsfunktion nun heißt) kommst du an das in diesem Fall erzeugte GridLayout.

Alternativ kann man auch einfach Layout aus der Liste einfügen, dem Kind einen Namen geben und dieses dann verwenden.
harbok
Beiträge: 6
Registriert: 12. Juni 2010 21:12

Beitrag von harbok »

Ok, wenn man erst ein Widget einfügt, kann man natürlich auch ein Layout erstellen :)
Antworten