QDialog

Alles rund um die Programmierung mit Qt
Antworten
Nvidia
Beiträge: 238
Registriert: 22. Februar 2010 21:23

QDialog

Beitrag 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);
    }
}
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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...
Nvidia
Beiträge: 238
Registriert: 22. Februar 2010 21:23

Beitrag 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.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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 :D

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).
Nvidia
Beiträge: 238
Registriert: 22. Februar 2010 21:23

Beitrag 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?
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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.
Nvidia
Beiträge: 238
Registriert: 22. Februar 2010 21:23

Beitrag 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?
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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.
Nvidia
Beiträge: 238
Registriert: 22. Februar 2010 21:23

Beitrag von Nvidia »

wie kann ich den vom Dialog aus funktionen aus der Hauptfenster aufrufen?
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

:roll:

Code: Alles auswählen

class Dialog : public QDialog {
  MyMainWindow* mainWin;
public:
  Dialog(MyMainWin* parent)
   : QDialog(parent), mainWin(parent)
  {
    mainWin->spezielleFunktion();
  }
};
Antworten