Seite 1 von 1

Widget updaten

Verfasst: 25. November 2005 22:44
von nalpak01
Hey Leute,

Ich hab ein QWidget, in dem per Layoutmanager mehrere Widgets zusammengefasst werden. Nun werden diese Widgets geändert, und der Layoutmanager wird nochmal zugewiesen, damit sich das ganze updatet, soweit so gut. Das funktioniert auch. Nur wird das geänderte Layout einfach über das alte rübergeklatscht, sodass die alten Elemente teilweise noch sichtbar sind.

Mir ist schon bekannt, dass es diverse update() Funktionen für QWidget und QLayout gibt, aber wo muss ich die wie anwenden??

Eins noch: Der Widget, der geupdatet werden soll, steckt nochmal in einem anderen Widget, das centralWidget eines QMainWindows ist.

thx,
nalpak01

Re: Widget updaten

Verfasst: 28. November 2005 07:23
von macman
nalpak01 hat geschrieben:Nun werden diese Widgets geändert, und der Layoutmanager wird nochmal zugewiesen,
Warum?
nalpak01 hat geschrieben:Nur wird das geänderte Layout einfach über das alte rübergeklatscht, sodass die alten Elemente teilweise noch sichtbar sind.
Kein Wunder. So wie sich das anhört, erstellst Du einiges doppelt und gibst einem Widget 2 Layouts, was eigentlich nicht geht. Hast Du das alte Layout vorher gelöscht?
nalpak01 hat geschrieben:Mir ist schon bekannt, dass es diverse update() Funktionen für QWidget und QLayout gibt, aber wo muss ich die wie anwenden??
Du kennst QLayout::removeWidget(...)? Wenn Du es dynamisch machen willst, schmeiß das alte Layout vorher weg, wenn der Weg über removeWidget() zu viel wird.
nalpak01 hat geschrieben:Der Widget, der geupdatet werden soll,
Oh mann, was das für deutsch? Es gibt aber noch eine Steigerung, upgedatet ;) Manchmal ist es wirklich besser, einfach 'aktualisiert' zu schreiben.

Verfasst: 7. Dezember 2005 17:48
von nalpak01
okay ... ich bin jetzt schon etwas weiter. Ich hab das Problem mal in ein eingenes Programm isoliert:

testprog.cpp:

Code: Alles auswählen

#include <QApplication>
#include <mainwindow.h>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MainWindow fenster;
    fenster.show();
    return app.exec();
}
mainwindow.h:

Code: Alles auswählen

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
class QPushButton;
class QWidget;
class QLabel;
class QVBoxLayout;

class MainWindow : public QMainWindow
{
    Q_OBJECT

    public:
        MainWindow();

    private slots:
        void Fbutton1();
        void Fbutton2();
       
    private:
        QPushButton *button1, *button2;
        QWidget *anzeige, *mainwg;
        QLabel *label;
        QVBoxLayout *anzeigelayout;
};

#endif
mainwindow.cpp:

Code: Alles auswählen

#include <QtGui>
#include "mainwindow.h"

MainWindow::MainWindow()
{
    button1 = new QPushButton("Aktion1");
    connect(button1,SIGNAL(clicked()),this,SLOT(Fbutton1()));
   
    button2 = new QPushButton("Aktion2");
    connect(button2,SIGNAL(clicked()),this,SLOT(Fbutton2()));
   
    anzeige = new QWidget();
    anzeigelayout = new QVBoxLayout;
    anzeige->setLayout(anzeigelayout);
   
    mainwg = new QWidget();
    QHBoxLayout *mainlayout = new QHBoxLayout();
    mainlayout->addWidget(button1);
    mainlayout->addWidget(button2);
    mainlayout->addWidget(anzeige);
    mainwg->setLayout(mainlayout);
    setCentralWidget(mainwg);
}

void MainWindow::Fbutton1()
{
    QLayoutItem *child;
    while((child = anzeigelayout->takeAt(0)) != 0)
    {
        delete child;
    }
   
    for(int i=0;i<2;i++)
    {
        label = new QLabel("Testtext");
        anzeigelayout->addWidget(label);
    }
}

void MainWindow::Fbutton2()
{
    QLayoutItem *child;
    while((child = anzeigelayout->takeAt(0)) != 0)
    {
        delete child;
    }
   
    for(int i=0;i<1;i++)
    {
        label = new QLabel("Testtext");
        anzeigelayout->addWidget(label);
    }
}
und hier wie es aussieht, wenn man auf den rechten Button drückt:
Bild
und hier beim linken:
Bild

Ich wäre euch für des Rätsels Lösung echt mega dankbar ... :D
Und dann hab ich wärend ich dieses kleine Programm geschrieben hab, mal probiert, einfach beim Klick auf den Button immer ein weiteres QLabel mit "Testtext" einfügen zu lassen. Merkwürdigerweise funktioniert dass ohne das Problem...

Re: Widget updaten

Verfasst: 7. Dezember 2005 17:56
von Goos
macman hat geschrieben: Oh mann, was das für deutsch? Es gibt aber noch eine Steigerung, upgedatet ;) Manchmal ist es wirklich besser, einfach 'aktualisiert' zu schreiben.
Kann man sehen wie man will, aber Duden sagt, dass upgedatet in Ordnung ist :)

Goos

Verfasst: 8. Dezember 2005 07:42
von macman
nalpak01 hat geschrieben:Ich wäre euch für des Rätsels Lösung echt mega dankbar
Sorry, wenn ich das Programm nicht getestet habe, aber solche Probleme fordern den Geist und die versuche ich dann durch Logik zu lösen :-) Die Bilder waren da sehr hilfreich.

Du zeichnest beim Klick auf den Button ein Label mit einem vertikal zentrierten Text. Beim nächsten Klick löscht Du es, aber dadurch wird es nicht vom Dialog entfernt, sprich der Bereich wird nicht neu gemalt, der Text bleibt also stehen. Beim Klick auf den linken Button erstellst Du 2 neue Label, die sich die Höhe des Dialogs teilen, aber einen gewissen Abstand zueinander haben, 6 Pixel Spacing beim Layout. Dadurch gibt es wohl einen Bereich zwischen den Labels, der von den beiden nicht übermalt wird und deshalb bleibt der ursprüngliche Text, von dem dein Programm ja gar nichts mehr weiß, stehen. Setz das Layoutspacing auf 0 und das Problem sollte weg sein.
nalpak01 hat geschrieben:Merkwürdigerweise funktioniert dass ohne das Problem...
Naja, ab 3 Label liegt eins über deinem Text und er wird korrekt übermalt.

Re: Widget updaten

Verfasst: 8. Dezember 2005 07:51
von macman
Goos hat geschrieben:Kann man sehen wie man will, aber Duden sagt, dass upgedatet in Ordnung ist :)
Bitte? Wo? In der Onlineausgabe bekommt man keine Treffer mit dem Begriff. Im Duden wurden aber schon öfter Begriffe aufgenommen die sich umgangssprachlich durch gesetzt haben, auch wenn sie noch so krank sind :-) Handy z.B. Was hat Handy mit einem Telefon zu tun? Gibt es auch nur in D-Land, aber wir sind hier offtopic, deshalb besser EOT.

Verfasst: 8. Dezember 2005 17:12
von nalpak01
mmh ... ne
anzeigelayout->setSpacing(0);
ändert leider nix ... aber ich hab noch ein bisschen mit dem Fenster rumprobiert, und ich hab das jetz so verstanden, dass ich grunde alles richtig mache, bloß dass eben beim entfernen der Elemente aus dem Layoutmanager anzeigelayout sie einfach auf dem Bildschirm 'vergessen' werden ... gibts denn nich irgendne Möglichkeit den Bereich kurz nach dem Löschen des Layouts einmal zu malern? Ich hab schon mit anzeige->repaint(); rumprobiert, aber das tuts einfach nicht ...
Mensch sowas kann doch nicht so schwer sein, das machen Programme doch öfter ;)

Verfasst: 9. Dezember 2005 08:18
von macman
Das Einzige was mir dazu einfällt wäre, das Label zu leeren und neu zu malen, bevor du es löscht.

Verfasst: 10. Dezember 2005 00:33
von ArneStocker
probier doch mal, dein Widget nicht nur zu deleten, sondern vorsorglich

Code: Alles auswählen

anzeigelayout->removeItem(child)
ausserdem werden die layoutinformationen wohl gecachet (wieder ein Dudenanwärter). Also vielleicht zum Schluss

Code: Alles auswählen

anzeigelayout->invalidate();
MainWindow->update()
aufrufen. nur so'ne Idee

OK, ich sehe, Du entwickelst wohl mit QT 4.0 (zumindest gibt es die Methode takeAt nicht in Qt 3.x) also meinen Kommentar einfach wieder vergessen

Gruss Arne

Verfasst: 26. Dezember 2005 13:20
von nalpak01
Was ich bräuchte wär im Prinzip nen QTabWidget ohne die Tableiste ... das kann doch nich so schwer sein, wenn ich ein paar QLabels hab, und ich auswählen will, welches 'oben' liegt!

Verfasst: 26. Dezember 2005 18:27
von nalpak01
so, ich hab mein Problem nochmal ausführlich formuliert ... ;)
also:::
Ich will einen Editor bauen. Und da gibts verschiedene Module. Die werden im Programm links in einem QListWidget alle angezeigt. Man kann natürlich Module hinzufügen etc.
Und rechts ist das eigentliche Editorbereich, hier wird dann der Inhalt des jeweils angezeigen Moduls angezeigt. Man kann also zwischen den Modulen hin- und herwechseln. Dazu muss sich der Bereich rechts natürlich verändern.

Im Moment hab ich das so gelöst, dass der Bereich rechts aus einem QTabWidget besteht. Da es aber zu viele Module sind und die Namen zu lang, würde die "Tableiste", die bei mir oben ist, weit über den Bildschirm hinaus reichen und man müsste sich ewig bis zum gewünschten Modul durchklicken. Also verwende ich das QListWidget links als eine Art 2. Navigation, beim Klicken auf ein Modul hier wird rechts automatisch die richtige Tabseite aufgerufen.

Das ganze System ist allerdings für den Benutzer ziemlich irreführend ... die (von mir schon deaktivierten) Elemente der Tableiste oben rechts müssten also irgendwie ganz weg ...

Ist das irgendwie mit vertretbaren Mitteln möglich? Oder müsste man dazu die QTabWidget-Klasse umschreiben? Die hat natürlich angenehme Vorteile eingebaut, wie das nach-unten-scrollen, wenn der Inhalt zu lang wird ...

Ich könnte mir vorstellen, dass man in einer Liste die Inhalte der rechten Seiten von den ganzen Modulen speichert und dann per Klick auf ein Element im QListWidget links das richtige Widget ins mainlayout einfügt, aber wie realisiere ich das "austauschen" der rechten Seite?

Verfasst: 27. Dezember 2005 12:30
von macman
nalpak01 hat geschrieben:Was ich bräuchte wär im Prinzip nen QTabWidget ohne die Tableiste ... das kann doch nich so schwer sein, wenn ich ein paar QLabels hab, und ich auswählen will, welches 'oben' liegt!
Das kann doch nicht so schwer sein, mal durch die Doku zu stöbern. Ich hab sie jetzt nicht zur Hand, aber gibt es da keinen Querverweis von QTabWidget nach QWidgetStack oder QStackWidget? Eins ist für Qt3, das andere für Qt4, weiß jetzt nicht genau welches wozu gehört.

Man merke, es kann nicht schaden sich die vorhandenen Klassen einfach mal so anzuschauen. Auch wenn man sie momentan nicht braucht, merkt man sich doch was möglich ist.