Seite 1 von 1

width() ermitteln beim Erstellen

Verfasst: 10. Juni 2009 01:17
von nico
Hallo,

ich weiß, dass ich dazu schoneinmal etwas gelesen hatte, aber ich kann es einfach nicht mehr finden.

Ich habe mir einen Multi-Slider programmiert. Auf diesem ist eine Skala, die Uhrzeiten darstellt und die beiden Slider können nur bestimmte Werte annehmen (5.00, 5.30, 6.00...).

Um nun die Slider auf gespeicherte Werte setzen zu können, benötige ich die tatsächliche Breite: width().

Aber wenn ich diese irgendwo in der Klasse abfrage, wird mir ja nur der Wert von minimumSizeHint() gegeben. Wie komme ich an den tatsächlichen Wert ran?

Ich muss doch die Abfrage width() dann erst erstellen, wenn mein Widget in einem Layout verarbeitet ist, richtig? Wie mache ich das?

Ich habe es schon hier versucht:

Code: Alles auswählen

bool QMultiSlider::event ( QEvent * e )
, aber leider keinen Erfolg gehabt.

Schoneinmal vielen Dank für eure Mühe!

Verfasst: 10. Juni 2009 08:26
von franzf
Ich versteh dein Problem nicht so richtig...
Ein Slider hat doch immer einen Range (minimum<->maximum), du hast dann halt 2. Aus dem Akuellen Wert lässt sich doch anhand von width() die Position des Sliders in Pixeln wunderbar berechnen. Und wann brauchst du die Position in Pixeln? Genau, im paintEvent(). Und da ist width() immer width() und nicht minimumSizeHint().width() oder so...

Wenn dein Slider nicht in nem Layout liegt, stimmt das, und wenn er in ein Layout gepackt wird und dabei die Größe ändert gibts ein resizeEvent() (hoffentlich ;)). Wenn du gaaaanz spezielle Sachen beim resize machen willst, kannst du das da machen. Aber die Position zu berechnen sollte eigentlich eine günstige Operation sein, das kannst du schon im paintEvent machen. (Wenn du das im resizeEvent machen willst, musst du für alle currentPos deiner Slider ne eigene Membervariable dauerhaft im Speicher halten, Also Tradeoff zwischen Speichernutzung und Prozessorarbeit.)

Wenn ich voll daneben liege, bitte sagen...

Grüße
Franz

Verfasst: 10. Juni 2009 10:27
von nico
Hey franzf,

mein Problem ist, dass ich die Punkte schon vor dem PaintEvent haben wollte.

Vielleicht mal etwas Code zum Verständnis...

Ich möchte folgende Liste mit den Punkten füllen:

Code: Alles auswählen

QList<zeitPunkt *> liste;
und zwar so:

Code: Alles auswählen

liste = zeitPunkt::berechnePunkte(width());
zeitPunkt.h sieht so aus:

Code: Alles auswählen

class zeitPunkt
{
public:
    zeitPunkt(QString zeit, int x);
    static QList<zeitPunkt *> berechnePunkte(int width);
    QString zeit;
    int x;
};
und die Methode:

Code: Alles auswählen

QList<zeitPunkt *> zeitPunkt::berechnePunkte(int width)
{
    QList<zeitPunkt *> liste;
    int ppHH = (int)(width-20)/30;
    for(int i=0; i<=30; ++i)
    {
        zeitPunkt *akt = new zeitPunkt("", 0);
        switch(i)
        {
                case 0: akt->zeit="05:00";
                    break;
                case 1: akt->zeit="05:30";
                    break;
                ...
        }
        akt->x=i*ppHH+10;
        liste.append(akt);
    }    
    return liste;
}
Nun habe ich meinem Slider die Methode

Code: Alles auswählen

void QMultiSlider::setCursor1(QString zeit)
{
    if(zeit=="Fehler")
        cursor1x = 0;
    for(int i = 0; i < liste.length(); ++i)
    {
        if(zeit == liste[i]->zeit)
            cursor1x = liste[i]->x;
    }
}
gegeben.

Wenn ich das Programm starte, lädt eine Methode Daten aus einer xml-Datei und nach diesen sollen die Slider-Positionen gesetzt werden.
Das heißt, dass PaintEvent noch nicht aufgerufen wurde - und damit width() den falschen Wert hat.

Mir ist eingefallen, dass ich die Suche nach dem Punkt ins PaintEvent verschieben kann und einfach nur den SuchString in setCursor1() schreiben, aber gibt es da noch eine andere Möglichkeit?!

Ich hoffe, das war einigermaßen verständlich...^^

Verfasst: 10. Juni 2009 10:32
von franzf
Gehts denn nicht auch im resizeEvent()? Wie ich oben eigentlich auch schon geschrieben hab?

Code: Alles auswählen

SliderWidget::resizeEvent( QResizeEvent *e )
{
    int w = e->size().width();
    calculateTimeWarpAgain(w);
}

Verfasst: 10. Juni 2009 13:28
von nico
Achso. Dann hatte ich das falsch verstanden. Hatte im ResizeEvent nur

Code: Alles auswählen

int breite = width();
probiert.

Vielen Dank für deine Hilfe!!