Fenster zentrieren nach resizeEvent unter Windows
Fenster zentrieren nach resizeEvent unter Windows
Hallo Miteinander,
Unter Windows funktioniert mein resizeEvent nicht richtig. Beim vergrößern des Fensters bleibt die alte größe erhalten.
Ich möchte, dass das Fenster bei einem resize wieder zentriert wird. Dies mache ich am Ende mit move(), was jedoch das Verändern der Fenstergröße verhindert, aber warum, und was kann ich dagegen tun?
Gruß, Hakaishi
Unter Windows funktioniert mein resizeEvent nicht richtig. Beim vergrößern des Fensters bleibt die alte größe erhalten.
Ich möchte, dass das Fenster bei einem resize wieder zentriert wird. Dies mache ich am Ende mit move(), was jedoch das Verändern der Fenstergröße verhindert, aber warum, und was kann ich dagegen tun?
Gruß, Hakaishi
Zuletzt geändert von hakaishi am 10. Dezember 2009 13:45, insgesamt 1-mal geändert.
hakaishi hat geschrieben:Hi! Das mit den Speicherlecks habe ich noch nicht ganz begriffen...
Kannst du mir eine Stelle in meinem Programm zeigen und mir sagen, wie ich das behebe?
Code: Alles auswählen
pos = new QPoint((desktop->width() - frameGeometry().width()) / 2,
(desktop->height() - frameGeometry().height()) / 2);pos ist zwar ein Member deiner Klasse. Nach obiger Zeile ist aber das alte Objekt nicht mehr erreichbar und somit nicht mehr löschbar, es dümpelt irgendwo im Speicher rum bis nach Programmende das OS den Speicher säubert.
Da ein resizeEvent() ziemlich oft aufgerufen wird, fällt das besonders ins Gewicht. In dem Fall ist es vor allem unnötig, pos als Member zu deklarieren, und dann auch noch als Pointer! pos ist eine Variable die nur in resizeEvent() für das move() gebraucht wird, so was hat nichts bei den Membervariablen zu suchen!
Insvesondere ist das Konstruieren eine QPoint-Objekts an der STelle unnötig, da es noch eine zweite für dich geeignetere Variante von move() gibt!
Und jetzt schau dir das closeEvent() an, da solltest du zwei potentielle Lecks entdecken. Es ist zwar das Letzte, was dein Programm macht, aber trotzdem.
Allerdings ist das vom Programmiertechnischen doof, das ins closeEvent() zu legen. Das ist typische Destruktorarbeit!
Wobei du auch beachten solltest, dass dein Settings-Objekt nie zerstört wird, und damit auch nie Settings geschrieben werden (hast du dich da noch gar nicht gewundert?) Du brauchst settings nicht als Member, und auch nicht als Pointer!
Das "saubere Beenden" durch den Destruktor kannst du dir auch irgendwo schenkden... Der shutdown schickt allen Programmen das SIGTERM, wenn sie nicht schließen wollen ein SIGKILL (für SIGTERM musst du einen Signal-Handler installieren, SIGKILL kannst du nicht abfangen), da gibt es eh keinen ordnungsgemäßen Destruktor mehr. Wenn du die Settings speichern willst, mach das in einer Methode saveSettings(), die du direkt aufrufst. Es ist dir bei einem shutdown nämlich nicht garantiert, dass dein Programm noch in die nächste Runde der EventLoop kommt, wo dann im closeEvent() die Settings "gespeichert" werden (werden sie ja eh bei dir nicht
Du solltest vertieft die Programme aus den Examples anschauen. Bei dir herrscht bei der Programmkonzeption noch ziemliches Chaos
Sorry, sieht ganz so aus, als hätte ich den ganzen Mist gestern da reingebaut...
Ich habe hier eine verbesserte Version. Wenn es sonst noch was ist,.. *please tell me*
Gruß, Hakaishi
Ich habe hier eine verbesserte Version. Wenn es sonst noch was ist,.. *please tell me*
Gruß, Hakaishi
- Dateianhänge
-
- qt-shutdown-p-1.5-all.zip
- Für jene die Windows benutzen...
- (18.63 KiB) 135-mal heruntergeladen
-
- qt-shutdown-p-1.5-all.tar.gz
- (11.07 KiB) 152-mal heruntergeladen
Hey, ich habe eine Lösung, aber wie ich finde, keine sehr gute:
Nachteil: das Fenster wird erst 1 Sekunde nach dem resizeEvent zentriert und zusätzlich noch erst nach dem betätigen des OK-Buttons...
Hat jemand eine bessere Idee?
Code: Alles auswählen
gui.h
...
bool hasBeenResized;
Code: Alles auswählen
gui.cpp
void Gui::update(){
if(hasBeenResized){
QDesktopWidget *desktop = qApp->desktop();
QPoint pos((desktop->width() - frameGeometry().width()) / 2,
(desktop->height() - frameGeometry().height()) / 2);
move(pos);
}
...
}
...
void Gui::resizeEvent(QResizeEvent* window_resize){
hasBeenResized = true;
QWidget::resizeEvent(window_resize);
}
Hat jemand eine bessere Idee?
Sorry, stimmt. Die Funktion void Gui::update() wird durch einen timeout()-SLOT eines QTimers jede Sekunde aufgerufen. Allerdings beginnt dieser Timer erst nach dem drücken des OK-Buttons.upsala hat geschrieben:Warum willst du das Fenster mit aller Gewalt zentrieren?
Wo soll denn die 1 Sekunde herkommen, das ist aus dem Code nicht ersichtlich.
Ich finde, dass es besser ist, wenn das Fenster immer zentriert ist...
Eigentlich benutze ich ja eh Linux und es kann mir egal sein, was unter Windows passiert... Vorübergehend habe ich es einfach so gemacht:
Code: Alles auswählen
void Gui::resizeEvent(QResizeEvent* window_resize){
#ifndef Q_OS_WIN32
QDesktopWidget *desktop = qApp->desktop();
QPoint pos((desktop->width() - frameGeometry().width()) / 2,
(desktop->height() - frameGeometry().height()) / 2);
move(pos);
#endif
QWidget::resizeEvent(window_resize);
}Gruß, Hakaishi
Also... Ich bin da auf etwas gestoßen: Wenn man unter Linux einen resize macht und das resizeEvent so aussieht:
dann wird beim Programmstart einmal und nach jedem weiteren resize ein weiteres "hallo" ausgegeben. Unter Windows dagegen wird beim Programmstart zwar auch einmal "hallo" ausgegeben, aber beim größer Ziehen des Fensters nicht nur einmal (danach), sondern solange bis die man den Mauszeiger wieder los lässt.
Ich habe nun versucht, eine bool-Variable beim resizeEvent true zu setzten, und dann ein SIGNAL emit isResized(); auszugeben, welches dann in der Klasse Gui mit connect(this, SIGNAL(isResized()), this, SLOT(center())); das Fenter wieder zentrieren soll. Hierzu habe ich noch die Funktion center() angelegt:
aber auch dieser Umweg hat nichts genützt.
Hat jemand nicht doch noch eine Idee (oder weiß wie es geht)?
Gruß, Hakaishi
Code: Alles auswählen
gui.cpp
void Gui::resizeEvent(QResizeEvent* window_resize){
qDebug()<<"hallo";
QWidget::resizeEvent(window_resize);
}
Ich habe nun versucht, eine bool-Variable beim resizeEvent true zu setzten, und dann ein SIGNAL emit isResized(); auszugeben, welches dann in der Klasse Gui mit connect(this, SIGNAL(isResized()), this, SLOT(center())); das Fenter wieder zentrieren soll. Hierzu habe ich noch die Funktion center() angelegt:
Code: Alles auswählen
gui.cpp
void Gui::center(){
QDesktopWidget *desktop = qApp->desktop();
QPoint pos((desktop->width() - frameGeometry().width()) / 2,
(desktop->height() - frameGeometry().height()) / 2);
move(pos);
hasBeenResized = false;
}
Hat jemand nicht doch noch eine Idee (oder weiß wie es geht)?
Gruß, Hakaishi
aha... und was soll ich dann unter Windows anders machen? (unter Win XP habe ich nur einen Bildschirm bzw. eine Arbeitsfläche, im Gegensatz zu Linux....)upsala hat geschrieben:Note that the desktop may be composed of multiple screens, so it would be incorrect, for example, to attempt to center some widget in the desktop's geometry.
PS: Wo hast du das Zitat her?