Ein weitere, jedoch sehr umständliche Möglichkeit besteht darin ein Dialog-Objekt anzulegen und das Ergebnis in einem Slot zu behandeln. Dabei wird über die open()
-Methode das Signal xSelected()
(wobei „x“ von der Art des Dialogs abhängig ist) mit dem übergebenen Objekt und Slot verbunden.
Als Beispiel soll eine Art Todo-Liste erstellt werden, bei der über einen Dialog Einträge hinzugefügt und wieder gelöscht werden können.
// main.cpp #include <QApplication> #include "MessageListWidget.h" int main ( int argc, char *argv[] ) { QApplication app( argc, argv ); MessageListWidget w; w.show(); return app.exec(); }
// MessageListWidget.h #ifndef MESSAGELISTWIDGET_H #define MESSAGELISTWIDGET_H #include <QWidget> class QListWidget; class QPushButton; class QInputDialog; class MessageListWidget : public QWidget { Q_OBJECT public: MessageListWidget(); private: QListWidget *messageList; // Liste aus Texten QPushButton *addButton, *removeButton; // Buttons zum Hinzufügen und Löschen QInputDialog *dialog; // Dialog zur Eingabe von Text private slots: void showInputDialog(); void addMessage( const QString& text ); void removeSelectedMessage(); }; #endif // MESSAGELISTWIDGET_H
// MessageListWidget.cpp #include "MessageListWidget.h" #include <QPushButton> #include <QListWidget> #include <QHBoxLayout> #include <QVBoxLayout> #include <QInputDialog> #include <QList> MessageListWidget::MessageListWidget() : messageList( new QListWidget() ), addButton( new QPushButton ("+" ) ), removeButton( new QPushButton( "-" ) ), dialog( new QInputDialog() ) { QVBoxLayout *vLayout = new QVBoxLayout(); QHBoxLayout *hLayout = new QHBoxLayout(); // Es kann nur ein Element der Liste selektiert werden. messageList->setSelectionMode( QAbstractItemView::SingleSelection ); // Der Dialog bekommt text als Eingabe und ist modal dialog->setInputMode( QInputDialog::TextInput ); dialog->setModal( true ); dialog->setWindowTitle( "Neuer Eintrag" ); // Verbindungen aufbauen connect( addButton, SIGNAL( clicked() ), this, SLOT( showInputDialog() ) ); connect( removeButton, SIGNAL( clicked() ), this, SLOT( removeSelectedMessage() ) ); // Widgets in Layout einfügen hLayout->addStretch(); hLayout->addWidget( addButton ); hLayout->addWidget( removeButton ); vLayout->addWidget( messageList ); vLayout->addLayout( hLayout ); setWindowTitle( "Todo" ); setLayout( vLayout ); resize( 400, 400 ); } void MessageListWidget::showInputDialog() { // Dialog zurücksetzen, anzeigen und das Ergebnis mit dem Slot des Objekts verbinden dialog->setTextValue( "" ); dialog->open( this, SLOT( addMessage( const QString& ) ) ); } void MessageListWidget::addMessage( const QString& text ) { // Text in die Liste einfügen, wenn er nicht nur aus Whitespaces besteht if( text.trimmed().size() > 0 ) messageList->addItem( text ); } void MessageListWidget::removeSelectedMessage() { // Ausgewähltes Objekt aus der Liste löschen (es kann immer nur 1 Objekt gelöscht werden) QList<QListWidgetItem *> items = messageList->selectedItems(); if( items.size() > 0 ) { for( int i = 0; i < messageList->count(); i++ ) { if( messageList->item( i ) == items.first() ) { delete messageList->takeItem( i ); return; } } } }
Der wichtigste Teil des Codes ist folgender Slot:
void MessageListWidget::showInputDialog() { dialog->setTextValue( "" ); dialog->open( this, SLOT( addMessage( const QString& ) ) ); }
Dieser Slot wird aufgerufen, wenn der Button zum Hinzufügen betätigt wurde. Als Reaktion darauf wird das Eingabefeld des Dialogs geleert und der Dialog angezeigt. Wird der Dialog erfolgreich geschlossen, wird automatisch der Slot addMessage()
unserer Klasse aufgerufen. Dadurch erspart man sich die Abfrage eines Abbruchs durch den Benutzer.