Seite 1 von 1
QDialog
Verfasst: 13. Mai 2010 16:41
von Nvidia
Hallo mein Dialogsystem funktioniert nicht.
Ich hab in meinem MainWindow folgendes stehen:
hab Dialog von QDialog abgeleitet.
Code: Alles auswählen
void MainWindow::Dialog()
{
Dialog *dialog = new Dialog();
connect(dialog ,SIGNAL(accepted()),this,SLOT(dialogAccepted()));
}
void MainWindow::dialogAccepted()
{
if(!dialog->getLine().isEmpty())
{
QString k = dlg->getLine();
createTab(k);
}
}
Code: Alles auswählen
Dialog::Dialog()
{
line = new QLineEdit();
create->setText(tr("Ok >"));
close->setText(tr("Quit"));
create->setDefault(true);
connect(create,SIGNAL(clicked()),this,SLOT(validInput()));
connect(close, SIGNAL(clicked()),this,SLOT(reject()));
exec();
}
QString Dialog::getLine()
{
return line->text();
}
void Dialog::validInput()
{
if(!line->text().isEmpty())
{
setResult(1);
}
}
Verfasst: 13. Mai 2010 17:17
von franzf
Was spricht gegen den Einzeiler
Code: Alles auswählen
void MainWindow::Dialog()
{
QString text = QIputDialog::getText(this, "Text eingeben", "Bitte hier tippseln");
createTabe(text);
}
Weil mehr willst du glaub ich nicht...
Ansonsten:
*) QDialog startet man eigentlich immer mit exec().
*) exec wiederum returniert einen DialogCode, mit dem du direkt weitermachen kannst. Du musst in einer eigenen QDialog-Klasse nur das SIGNAL(clicked()) des jeweilgen OK/CANCEL-Buttons auf den SLOT accept oder reject connecten.
Demnach wäre es korrekt, wenn du das machst:
Code: Alles auswählen
void MainWindow::Dialog()
{
Dialog dlg;
if( dlg.exec() == QDialog::Accepted ) {
createTab( dlg.getLine() );
}
}
Nebenbei eliminiert das dein MemoryLeak, das du vorher hier eingebaut hast

Stichwort RAII -> google!
Und zum Schluss: Warum hat deine Version nicht funktioniert?
1) MainWindow::Dialog() erstellt ein neues Dialog-Objekt, das ist nicht das selbe wie das welches du als Member deklariert hast!
2) machst du nirgendwo eine dialog->exec(), welches den Dialog anzeigen würde...
Verfasst: 13. Mai 2010 17:35
von Nvidia
srry das .exec hatte ich, habs nur vergessen zu kopieren.
Da stehen noch mehr Dinge, die ich auslesen will, aber ich wollt erstmal das LineEdit hinkriegen.
Aber wenn ich nun den Button mit accepted verbinde, dann heißt das der Dialog wird geschlossen.
Wenn aber das Feld leer ist, will ich ihn nicht schließen.
und deine zweite Codezeile will er nicht kompilieren.
außerdem versteh ich die nicht ganz.
Er baut den Dialog:
Aber eigentlich müsste er mit Dialog *dlg = new Dialog gebaut werden.
Weil er sonst gleich am Ende der Methode ist udn dann zerstört er den Dialog wieder.
Er baut den Dialog. Schaut ob er Accepted ist, was er natürlich nicht ist, weil er sofort nachdem er ihn gebaut hat prüft und dann ist er am Ende der Methode angekommen und zerstört den Dialog wieder.
Das versteh ich nicht so ganz.
Verfasst: 13. Mai 2010 17:51
von franzf
Nvidia hat geschrieben:Aber wenn ich nun den Button mit accepted verbinde, dann heißt das der Dialog wird geschlossen.
Wenn aber das Feld leer ist, will ich ihn nicht schließen.
Dann verbinde ihn einfach nicht direkt mit accept() sondern mit einem eigenen SLOT, in dem du prüfst ob lineEdit leer ist. Falls nein -> rufe accept() auf. Falls ja - mach einfach nix
Code: Alles auswählen
Dialog::Dialog() {
// sonstwas
connect(okBtn, SIGNAL(clicked()), SLOT(on_okBtn_clicked()));
}
void Dialog::on_okBtn_clicked() {
if( !lineEdit->text().isEmpty() ) {
accept();
}
}
und deine zweite Codezeile will er nicht kompilieren.
Tjo, ohne Fehlermeldung kann dir dann keiner helfen. Und evtl. gleich den angemeckerten Code mitposten...
Aber eigentlich müsste er mit Dialog *dlg = new Dialog gebaut werden.
Weil er sonst gleich am Ende der Methode ist udn dann zerstört er den Dialog wieder.
Nein, eben nicht. exec() blockiert die aufrufende Funktion, in diesem Fall MainWindow::Dialog(), bis du accept(), reject() oder done() aufrufst.
Er baut den Dialog. Schaut ob er Accepted ist, was er natürlich nicht ist, weil er sofort nachdem er ihn gebaut hat prüft und dann ist er am Ende der Methode angekommen und zerstört den Dialog wieder.
Das versteh ich nicht so ganz.
Was heißt bei dir "Hat den Dialog gebaut"?
Und btw hab ich dein exec() gefunden. Das steht schon im Konstruktor von Dialog, was nicht so doll ist, weil du 1) von außen den return-Code nicht kriegen kannst, und 2) exec() im Konstruktor blockiert. Damit gilt dein Dialog-Objekt erst als vollständig erzeugt, wenn es schon wieder geschlossen wurde. Ich kenn den Standard aber zu wenig, um sagen zu können ob das irgendwo in undefiniertes Verhalten läuft oder nicht (denke eher nein, würde es aber trotzdem nicht machen).
Verfasst: 13. Mai 2010 18:12
von Nvidia
Ok danke franz es klappt super. danke
Aber nur ein Problem, wenn ich das erste mal auf Ok klicke,
verschwindet das Fenster und taucht sofort wieder auf(mit meinem Text)
Wenn ich nochmal Ok drücke, führt er es aus?
Kann das das "Undefinierte Verhalten sein"? XD
//ok Edit 2
ich hab ja mein .exec im Konstruktor gehabt.
ich hab das jetzt mal in // gesetzt.
Mein Dialog wird trotzdem ausgeführt und diesmal richtig.
Das erklärt auch den fehler. Aber dann brauchte ich ja gar kein .exec mehr ?!
//ok Edit 3
Ich habs nun gefunden, was das fenster aufruft:
franz dein code ruft, das auf.
Code: Alles auswählen
if( dlg.exec() == QDialog::Accepted )
{
createTab( dlg.getLine() );
}
Soll er das?
Verfasst: 13. Mai 2010 18:53
von franzf
Nvidia hat geschrieben:Ich habs nun gefunden, was das fenster aufruft:
franz dein code ruft, das auf.
Code: Alles auswählen
if( dlg.exec() == QDialog::Accepted )
{
createTab( dlg.getLine() );
}
Soll er das?
Soll er was? Ruft was auf?
Das ist eigentlich das normale, wie man den Dialog öffnet. Das exec() sorgt auch dafür dass er angezeigt wird - vllt. ist es ja das was du meinst.
Verfasst: 13. Mai 2010 19:06
von Nvidia
ja ok also es klappt jetzt alles supper. danke
Ich hätte doch noch ein paar Fragen
a) Warum hat der Dialog sein eigenes Fenster unten in der Taskleiste?
(Wie kann man das beheben)
b)
Wenn man das Projekt ausführt und in den Taskmanger schaut, sieht man den Arbeitsspeicherverbrauch:
Der ist selbst bei Programmen, die nur Hello World anzeigen bei 15k.
Verbraucht der auch so viel, wenn er außerhalb vom QT Creater läuft oder braucht er nur jetzt so viel, weil das ist schon einer der größeren Programme.
Mein Musikspieler braucht knapp die Hälfte und besitzt so viele Widget(wenn er die benutzt), dass ich zu faul bin sie zu zählen.
Wie kommt das?
c) Was passiert, wenn sich ein Programm aufhängt?
Also was ist der Grund dafür?
Verfasst: 14. Mai 2010 09:07
von franzf
a)
http://doc.qt.nokia.com/4.6/qdialog.html#QDialog
Also: Gib deinem dialog ein parent mit.
b) k.A. aber ich finde 15K in Zeiten von RAM im GB-Bereich vollkommen in Ordnung. Es kommt mir ehrlich gesagt auch zu wenig vor. K.A. Was Windows da misst wie es das misst. Gibt sicher bessere Tools. Ich würd mich daran aber jetzt nicht aufhängen.
c) -> Debuggen! Endlosschleife, Blockierende IO-Operation, Mieser Scheduler des Betriebssystems, usw.
Verfasst: 19. Mai 2010 12:28
von Nvidia
wie kann ich den vom Dialog aus funktionen aus der Hauptfenster aufrufen?
Verfasst: 19. Mai 2010 12:34
von franzf
Code: Alles auswählen
class Dialog : public QDialog {
MyMainWindow* mainWin;
public:
Dialog(MyMainWin* parent)
: QDialog(parent), mainWin(parent)
{
mainWin->spezielleFunktion();
}
};