Database Connection Dialog: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
 
(6 intermediate revisions by 3 users not shown)
Line 1: Line 1:
[[Category:HowTo]]<br />[[Category:snippets]]
{{LangSwitch}}
 
[[Category:HowTo]]
'''English''' | [[DatabaseConnectionDialog_German|Deutsch]]
[[Category:snippets]]
 
= General Database Connection Dialog =
 
This code snippet shows how to implement a general database dialog that will prompt the user for general database connection properties (username, password, hostname, ecc.) as well as a combo with all available database drivers. The dialog provides also a signal that will pass the database connection (if established) so that third party components can use such connection.
This code snippet shows how to implement a general database dialog that will prompt the user for general database connection properties (username, password, hostname, ecc.) as well as a combo with all available database drivers. The dialog provides also a signal that will pass the database connection (if established) so that third party components can use such connection.


Line 13: Line 10:
<code>DatabaseConnectionDialog* dialog = new DatabaseConnectionDialog(this);
<code>DatabaseConnectionDialog* dialog = new DatabaseConnectionDialog(this);


// optional: set the data that will be presented to the user as auto-filled form<br /> dialog-&gt;setDatabaseName( &quot;mydb&amp;quot; );<br /> dialog-&gt;setDatabasePortNumber( 1234 );<br /> dialog-&gt;setDatabaseHostName( &quot;localhost&amp;quot; );<br /> dialog-&gt;setDatabaseUsername( &quot;luca&amp;quot; );<br /> dialog-&gt;setDatabaseDriverName( &quot;QPSQL&amp;quot; );<br /> dialog-&gt;setDatabasePassword( &quot;pwd&amp;quot; );
// optional: set the data that will be presented to the user as auto-filled form
dialog->setDatabaseName( "mydb" );
dialog->setDatabasePortNumber( 1234 );
dialog->setDatabaseHostName( "localhost" );
dialog->setDatabaseUsername( "luca" );
dialog->setDatabaseDriverName( "QPSQL" );
dialog->setDatabasePassword( "pwd" );


// enable the connect button if all the data is correct<br /> dialog-&gt;checkFormData();<br /> // connect the dialog signal to a slot where I will use the connection<br /> connect( dialog,<br /> SIGNAL (databaseConnect(QSqlDatabase&amp;amp;)),<br /> this,<br /> SLOT (slotHandleNewDatabaseConnection(QSqlDatabase&amp;amp;)));
// enable the connect button if all the data is correct
dialog->checkFormData();
// connect the dialog signal to a slot where I will use the connection
connect( dialog,
SIGNAL (databaseConnect(QSqlDatabase&)),
this,
SLOT (slotHandleNewDatabaseConnection(QSqlDatabase&)));


// show the dialog (without auto-connection)<br /> dialog-&gt;run( false );</code>
// show the dialog (without auto-connection)
dialog->run( false );</code>


The dialog allows for pre-initialization of form fields, as well as an auto-connect mode that make the connection to happen automatically if all the data is in place.<br />Please note that this dialog can be improved in several ways, and represents therefore a starting point for a more specific database connection dialog.
The dialog allows for pre-initialization of form fields, as well as an auto-connect mode that make the connection to happen automatically if all the data is in place.
Please note that this dialog can be improved in several ways, and represents therefore a starting point for a more specific database connection dialog.


=== Auto-Connect mode ===
=== Auto-Connect mode ===
Line 29: Line 40:
The following is the header file:
The following is the header file:


<code>/*!<br /> * databasedialog.h<br /> '''/<br />#ifndef DATABASEDIALOG_H<br />#define DATABASEDIALOG_H
<code>
<br />#include &lt;QDialog&amp;gt;<br />#include &lt;QLabel&amp;gt;<br />#include &lt;QLineEdit&amp;gt;<br />#include &lt;QComboBox&amp;gt;<br />#include &lt;QSpinBox&amp;gt;<br />#include &lt;QDialogButtonBox&amp;gt;<br />#include &lt;QHBoxLayout&amp;gt;<br />#include &lt;QVBoxLayout&amp;gt;<br />#include &lt;QGridLayout&amp;gt;<br />#include &lt;QSqlDatabase&amp;gt;<br />#include &lt;QString&amp;gt;<br />#include &lt;QMessageBox&amp;gt;<br />#include &lt;QDebug&amp;gt;<br />#include &lt;QSqlError&amp;gt;<br />#include &lt;QPushButton&amp;gt;<br />#include &lt;QGroupBox&amp;gt;
/*!
<br />class DatabaseConnectionDialog : public QDialog<br />{<br /> Q_OBJECT
* databasedialog.h
<br />private:
*/
<br /> /'''!<br /> * The display label for the database driver name.<br /> '''/<br /> QLabel''' labelDatabaseDriverName;
#ifndef DATABASEDIALOG_H
#define DATABASEDIALOG_H
 
#include <QDialog>
#include <QLabel>
#include <QLineEdit>
#include <QComboBox>
#include <QSpinBox>
#include <QDialogButtonBox>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QSqlDatabase>
#include <QString>
#include <QMessageBox>
#include <QDebug>
#include <QSqlError>
#include <QPushButton>
#include <QGroupBox>
 
class DatabaseConnectionDialog : public QDialog
{
Q_OBJECT
 
private:
 
/*!
* The display label for the database driver name.
*/
QLabel* labelDatabaseDriverName;
 
/*!
* The display label for the TCP/IP port the database
* is listening for connections.
*/
QLabel* labelDatabasePort;
 
/*!
* The label for the database name.
*/
QLabel* labelDatabaseName;
 
/*!
* The label for the database host name.
*/
QLabel* labelDatabaseHostName;
 
/*!
* The label for the database username.
*/
QLabel* labelDatabaseUsername;
 
/*!
* The label for the database password.
*/
QLabel* labelDatabasePassword;
 
/*!
* A label to display the summary database URL
* connection string.
*/
QLabel* labelDatabaseURL;
 
/*!
* The editable name of the database to which the user
* wants to connect to.
*/
QLineEdit* editDatabaseName;
 
/*!
* The editable name of the database name to which connect.
*/
QLineEdit* editDatabaseHostName;
 
/*!
* The database listening port.
*/
QSpinBox* spinBoxDatabasePort;
 
/*!
* The editable username to use for the connection.
*/
QLineEdit* editDatabaseUsername;
 
/*!
* The editable password to use for the connection.
*/
QLineEdit* editDatabasePassword;
 
/*!
* The combo from which the user can select the database
* driver name and type
*/
QComboBox* comboDatabaseDriverName;
 
/*!
* A Dialog button box for displaying the
* connect/cancel buttons.
*/
QDialogButtonBox* buttons;
 
/*!
* A method to create all the components of this dialog window
* and lay out them correctly.
*/
void setUpGUI();


/*!<br /> * The display label for the TCP/IP port the database<br /> * is listening for connections.<br /> '''/<br /> QLabel''' labelDatabasePort;
/*!
* Searches for and populates the combo box with the
* available database drivers.
*/
void findAvailableDrivers();


/*!<br /> * The label for the database name.<br /> '''/<br /> QLabel''' labelDatabaseName;


/*!<br /> * The label for the database host name.<br /> '''/<br /> QLabel''' labelDatabaseHostName;
/*!
* Performs the connection to the database
* and emits the signal to pass the connection.
*/
void doDatabaseConnection();


/*!<br /> * The label for the database username.<br /> '''/<br /> QLabel''' labelDatabaseUsername;
public:
explicit DatabaseConnectionDialog(QWidget* parent=0);


/*!<br /> * The label for the database password.<br /> '''/<br /> QLabel''' labelDatabasePassword;
/*!
* Sets the database name in the dialog.
* dbName the name of the database
*/
void setDatabaseName( const QString& dbName );


/*!<br /> * A label to display the summary database URL<br /> * connection string.<br /> '''/<br /> QLabel''' labelDatabaseURL;
/*!
* Sets the port number for the database connection.
* portNumber the port number the database is listening for
* connections
*/
void setDatabasePortNumber( int& portNumber );


/*!<br /> * The editable name of the database to which the user<br /> * wants to connect to.<br /> '''/<br /> QLineEdit''' editDatabaseName;
/*!
* Sets the remote host name mnemonic name.
* hostname the name of the host the database is running on
*/
void setDatabaseHostName( const QString& hostname );


/*!<br /> * The editable name of the database name to which connect.<br /> '''/<br /> QLineEdit''' editDatabaseHostName;
/*!
* Sets the username to use for the connection.
* username the username to use for the connection
*/
void setDatabaseUsername( const QString& username );


/*!<br /> * The database listening port.<br /> '''/<br /> QSpinBox''' spinBoxDatabasePort;
/*!
* Selects the driver name.
* the driver name (therefore the database type) to
* select in the combo box.
*/
void setDatabaseDriverName( const QString& drvName );


/*!<br /> * The editable username to use for the connection.<br /> '''/<br /> QLineEdit''' editDatabaseUsername;
/*!
* Sets the user password.
* the password to use for the connection
*/
void setDatabasePassword( const QString& pwd );


/*!<br /> * The editable password to use for the connection.<br /> '''/<br /> QLineEdit''' editDatabasePassword;


/*!<br /> * The combo from which the user can select the database<br /> * driver name and type<br /> '''/<br /> QComboBox''' comboDatabaseDriverName;
/*!
* Performs a check against the user data and enables/disables
* the connect button depending on the form fill status.
* true if the data allows a database connection
*/
bool checkFormData();


/*!<br /> * A Dialog button box for displaying the<br /> * connect/cancel buttons.<br /> '''/<br /> QDialogButtonBox''' buttons;
/*!
* Performs the database connection or prompt the user
* showing this dialog in the case data is not completed
* or should not perform the autoconnection.
* autoConnect if set to true tries to perform an automatic
* connection to the database, if the data is complete, or prompt the user
* for missing data. If set to false, simply shows the dialog and waits.
*/
void run( bool autoConnect );


/*!<br /> * A method to create all the components of this dialog window<br /> * and lay out them correctly.<br /> '''/<br /> void setUpGUI();
<br /> /'''!<br /> * Searches for and populates the combo box with the<br /> * available database drivers.<br /> '''/<br /> void findAvailableDrivers();


<br /> /'''!<br /> * Performs the connection to the database<br /> * and emits the signal to pass the connection.<br /> */<br /> void doDatabaseConnection();
signals:


public:<br /> explicit DatabaseConnectionDialog(QWidget '''parent = 0);
/*!
<br /> /'''!<br /> * Sets the database name in the dialog.<br /> * dbName the name of the database<br /> '''/<br /> void setDatabaseName( const QString&amp;amp; dbName );
* Passes the database connection in the case the connection
<br /> /'''!<br /> * Sets the port number for the database connection.<br /> * portNumber the port number the database is listening for<br /> * connections<br /> '''/<br /> void setDatabasePortNumber( int&amp;amp; portNumber );
* is succesful.
<br /> /'''!<br /> * Sets the remote host name mnemonic name.<br /> * hostname the name of the host the database is running on<br /> '''/<br /> void setDatabaseHostName( const QString&amp;amp; hostname );
* databaseConnection the connection object
<br /> /'''!<br /> * Sets the username to use for the connection.<br /> * username the username to use for the connection<br /> '''/<br /> void setDatabaseUsername( const QString&amp;amp; username );
*/
<br /> /'''!<br /> * Selects the driver name.<br /> * the driver name (therefore the database type) to<br /> * select in the combo box.<br /> '''/<br /> void setDatabaseDriverName( const QString&amp;amp; drvName );
void databaseConnect( QSqlDatabase& databaseConnection );
<br /> /'''!<br /> * Sets the user password.<br /> * the password to use for the connection<br /> '''/<br /> void setDatabasePassword( const QString&amp;amp; pwd );


<br /> /'''!<br /> * Performs a check against the user data and enables/disables<br /> * the connect button depending on the form fill status.<br /> '''true if the data allows a database connection<br />'''/<br /> bool checkFormData();
public slots:


/*!<br /> * Performs the database connection or prompt the user<br /> * showing this dialog in the case data is not completed<br /> * or should not perform the autoconnection.<br /> * autoConnect if set to true tries to perform an automatic<br /> * connection to the database, if the data is complete, or prompt the user<br /> * for missing data. If set to false, simply shows the dialog and waits.<br /> '''/<br /> void run( bool autoConnect );
/*!
* Checks if the user has entered enough data to
* try a database connection.
*/
bool slotCheckFormData();


<br />signals:
<br /> /'''!<br /> * Passes the database connection in the case the connection<br /> * is succesful.<br /> * databaseConnection the connection object<br /> '''/<br /> void databaseConnect( QSqlDatabase&amp;amp; databaseConnection );
<br />public slots:
<br /> /'''!<br /> * Checks if the user has entered enough data to<br /> * try a database connection.<br /> '''/<br /> bool slotCheckFormData();


<br /> /'''!<br /> * Performs the database connection.<br /> */<br /> void slotPerformConnection();
/*!
* Performs the database connection.
*/
void slotPerformConnection();


};
};


#endif // DATABASEDIALOG_H<br /></code>
#endif // DATABASEDIALOG_H
</code>


And the following is the class implementation:
And the following is the class implementation:


<code>#include &quot;databasedialog.h&amp;quot;
<code>#include "databasedialog.h"
 
DatabaseConnectionDialog::DatabaseConnectionDialog(QWidget* parent) :
QDialog(parent)
{
// this dialog is modal
setModal( true );
// the title of this dialog
setWindowTitle( tr("Database connection") );
// place each GUI component
setUpGUI();
// load available drivers
findAvailableDrivers();
}


DatabaseConnectionDialog::DatabaseConnectionDialog(QWidget '''parent) :<br /> QDialog(parent)<br />{<br /> // this dialog is modal<br /> setModal( true );<br /> // the title of this dialog<br /> setWindowTitle( tr(&quot;Database connection&amp;quot;) );<br /> // place each GUI component<br /> setUpGUI();<br /> // load available drivers<br /> findAvailableDrivers();<br />}
void DatabaseConnectionDialog::setUpGUI()
<br />void DatabaseConnectionDialog::setUpGUI()<br />{
{


<br /> // create all gui components<br /> labelDatabaseDriverName = new QLabel( tr(&quot;Database Type (driver name)&quot;), this );<br /> labelDatabasePort = new QLabel( tr(&quot;TCP/IP Port Number&amp;quot;), this );<br /> labelDatabaseName = new QLabel( tr(&quot;Database Name&amp;quot;), this );<br /> labelDatabaseHostName = new QLabel( tr(&quot;Host Name&amp;quot;), this );<br /> labelDatabaseUsername = new QLabel( tr(&quot;Username&amp;quot;), this );<br /> labelDatabasePassword = new QLabel( tr(&quot;Password&amp;quot;), this );<br /> labelDatabaseURL = new QLabel( this );<br /> labelDatabaseURL-&gt;setAlignment( Qt::AlignCenter );
<br /> spinBoxDatabasePort = new QSpinBox( this );<br /> spinBoxDatabasePort-&gt;setMaximum( 9999 );<br /> spinBoxDatabasePort-&gt;setMinimum( 100 );<br /> spinBoxDatabasePort-&gt;setSingleStep( 1 );
<br /> comboDatabaseDriverName = new QComboBox( this );<br /> comboDatabaseDriverName-&gt;setEditable( false );


<br /> editDatabaseName = new QLineEdit( this );<br /> editDatabaseHostName = new QLineEdit( this );<br /> editDatabaseUsername = new QLineEdit( this );<br /> editDatabasePassword = new QLineEdit( this );<br /> editDatabasePassword-&gt;setEchoMode( QLineEdit::Password );<br /> connect( editDatabaseName,<br /> SIGNAL (editingFinished()),<br /> this,<br /> SLOT (slotCheckFormData()) );<br /> connect( editDatabaseHostName,<br /> SIGNAL (editingFinished()),<br /> this,<br /> SLOT (slotCheckFormData()) );<br /> connect( editDatabaseUsername,<br /> SIGNAL (editingFinished()),<br /> this,<br /> SLOT (slotCheckFormData()) );<br /> connect( editDatabasePassword,<br /> SIGNAL (editingFinished()),<br /> this,<br /> SLOT (slotCheckFormData()) );<br /> connect( editDatabasePassword,<br /> SIGNAL (returnPressed()),<br /> this,<br /> SLOT (slotCheckFormData()) );
// create all gui components
labelDatabaseDriverName = new QLabel( tr("Database Type (driver name)"), this );
labelDatabasePort = new QLabel( tr("TCP/IP Port Number"), this );
labelDatabaseName = new QLabel( tr("Database Name"), this );
labelDatabaseHostName = new QLabel( tr("Host Name"), this );
labelDatabaseUsername = new QLabel( tr("Username"), this );
labelDatabasePassword = new QLabel( tr("Password"), this );
labelDatabaseURL = new QLabel( this );
labelDatabaseURL->setAlignment( Qt::AlignCenter );


<br /> // create the button box<br /> buttons = new QDialogButtonBox( this );<br /> buttons-&gt;addButton( QDialogButtonBox::Ok );<br /> buttons-&gt;addButton( QDialogButtonBox::Cancel );<br /> QPushButton''' okButton = buttons-&gt;button( QDialogButtonBox::Ok );<br /> okButton-&gt;setText( tr( &quot;Connect!&quot; ) );<br /> okButton-&gt;setEnabled( false );<br /> connect( buttons,<br /> SIGNAL (accepted()),<br /> this,<br /> SLOT (slotPerformConnection()));<br /> connect( buttons,<br /> SIGNAL (rejected()),<br /> this,<br /> SLOT (close()));
spinBoxDatabasePort = new QSpinBox( this );
spinBoxDatabasePort->setMaximum( 9999 );
spinBoxDatabasePort->setMinimum( 100 );
spinBoxDatabasePort->setSingleStep( 1 );


// create a vertical layout to display components<br /> QVBoxLayout* verticalLayout = new QVBoxLayout( this );
comboDatabaseDriverName = new QComboBox( this );
comboDatabaseDriverName->setEditable( false );


// create a grid layout to add all the components<br /> QGridLayout* formGridLayout = new QGridLayout( this );<br /> QGroupBox* gridGroupBox = new QGroupBox( this );<br /> gridGroupBox-&gt;setTitle( tr(&quot;Database connection properties&amp;quot; ) );<br /> formGridLayout-&gt;addWidget( labelDatabaseDriverName, 0, 0 );<br /> formGridLayout-&gt;addWidget( comboDatabaseDriverName, 0, 1 );<br /> labelDatabaseDriverName-&gt;setBuddy( comboDatabaseDriverName );<br /> formGridLayout-&gt;addWidget( labelDatabaseHostName, 1, 0 );<br /> formGridLayout-&gt;addWidget( editDatabaseHostName, 1, 1);<br /> labelDatabaseHostName-&gt;setBuddy( editDatabaseHostName );<br /> formGridLayout-&gt;addWidget( labelDatabasePort, 2, 0 );<br /> formGridLayout-&gt;addWidget( spinBoxDatabasePort, 2, 1 );<br /> labelDatabasePort-&gt;setBuddy( spinBoxDatabasePort );<br /> formGridLayout-&gt;addWidget( labelDatabaseName, 3, 0 );<br /> formGridLayout-&gt;addWidget( editDatabaseName , 3, 1 );<br /> labelDatabaseName-&gt;setBuddy( editDatabaseName );<br /> formGridLayout-&gt;addWidget( labelDatabaseUsername, 4, 0 );<br /> formGridLayout-&gt;addWidget( editDatabaseUsername, 4, 1 );<br /> labelDatabaseUsername-&gt;setBuddy( editDatabaseUsername );<br /> formGridLayout-&gt;addWidget( labelDatabasePassword, 5, 0 );<br /> formGridLayout-&gt;addWidget( editDatabasePassword, 5, 1 );<br /> labelDatabasePassword-&gt;setBuddy( editDatabasePassword );<br /> // add all the elements to groupbox<br /> gridGroupBox-&gt;setLayout( formGridLayout );


// place a new groupbox to contain the database connection URL<br /> QGroupBox* urlGroupBox = new QGroupBox( this );<br /> urlGroupBox-&gt;setTitle( tr( &quot;Database URL&amp;quot; ) );<br /> QHBoxLayout* urlLayout = new QHBoxLayout( this );<br /> urlLayout-&gt;addWidget( labelDatabaseURL );<br /> urlGroupBox-&gt;setLayout( urlLayout );
editDatabaseName = new QLineEdit( this );
editDatabaseHostName = new QLineEdit( this );
editDatabaseUsername = new QLineEdit( this );
editDatabasePassword = new QLineEdit( this );
editDatabasePassword->setEchoMode( QLineEdit::Password );
connect( editDatabaseName,
SIGNAL (editingFinished()),
this,
SLOT (slotCheckFormData()) );
connect( editDatabaseHostName,
SIGNAL (editingFinished()),
this,
SLOT (slotCheckFormData()) );
connect( editDatabaseUsername,
SIGNAL (editingFinished()),
this,
SLOT (slotCheckFormData()) );
connect( editDatabasePassword,
SIGNAL (editingFinished()),
this,
SLOT (slotCheckFormData()) );
connect( editDatabasePassword,
SIGNAL (returnPressed()),
this,
SLOT (slotCheckFormData()) );


// nest all layouts together<br /> verticalLayout-&gt;addWidget( gridGroupBox );<br /> verticalLayout-&gt;addStretch();<br /> verticalLayout-&gt;addWidget( urlGroupBox );<br /> verticalLayout-&gt;addWidget( buttons );


comboDatabaseDriverName-&gt;setFocus();<br />}
// create the button box
buttons = new QDialogButtonBox( this );
buttons->addButton( QDialogButtonBox::Ok );
buttons->addButton( QDialogButtonBox::Cancel );
QPushButton* okButton = buttons->button( QDialogButtonBox::Ok );
okButton->setText( tr( "Connect!" ) );
okButton->setEnabled( false );
connect( buttons,
SIGNAL (accepted()),
this,
SLOT (slotPerformConnection()));
connect( buttons,
SIGNAL (rejected()),
this,
SLOT (close()));


void DatabaseConnectionDialog::findAvailableDrivers()<br />{<br /> // remove all items<br /> comboDatabaseDriverName-&gt;clear();
// create a vertical layout to display components
QVBoxLayout* verticalLayout = new QVBoxLayout( this );


// populate the combo box with all available drivers<br /> foreach( QString driverName, QSqlDatabase::drivers() )<br /> comboDatabaseDriverName-&gt;addItem( driverName );<br />}
// create a grid layout to add all the components
QGridLayout* formGridLayout = new QGridLayout( this );
QGroupBox* gridGroupBox = new QGroupBox( this );
gridGroupBox->setTitle( tr("Database connection properties" ) );
formGridLayout->addWidget( labelDatabaseDriverName, 0, 0 );
formGridLayout->addWidget( comboDatabaseDriverName, 0, 1 );
labelDatabaseDriverName->setBuddy( comboDatabaseDriverName );
formGridLayout->addWidget( labelDatabaseHostName, 1, 0 );
formGridLayout->addWidget( editDatabaseHostName, 1, 1);
labelDatabaseHostName->setBuddy( editDatabaseHostName );
formGridLayout->addWidget( labelDatabasePort, 2, 0 );
formGridLayout->addWidget( spinBoxDatabasePort, 2, 1 );
labelDatabasePort->setBuddy( spinBoxDatabasePort );
formGridLayout->addWidget( labelDatabaseName, 3, 0 );
formGridLayout->addWidget( editDatabaseName , 3, 1 );
labelDatabaseName->setBuddy( editDatabaseName );
formGridLayout->addWidget( labelDatabaseUsername, 4, 0 );
formGridLayout->addWidget( editDatabaseUsername, 4, 1 );
labelDatabaseUsername->setBuddy( editDatabaseUsername );
formGridLayout->addWidget( labelDatabasePassword, 5, 0 );
formGridLayout->addWidget( editDatabasePassword, 5, 1 );
labelDatabasePassword->setBuddy( editDatabasePassword );
// add all the elements to groupbox
gridGroupBox->setLayout( formGridLayout );


bool DatabaseConnectionDialog::slotCheckFormData()<br />{<br /> return checkFormData();<br />}
// place a new groupbox to contain the database connection URL
QGroupBox* urlGroupBox = new QGroupBox( this );
urlGroupBox->setTitle( tr( "Database URL" ) );
QHBoxLayout* urlLayout = new QHBoxLayout( this );
urlLayout->addWidget( labelDatabaseURL );
urlGroupBox->setLayout( urlLayout );


bool DatabaseConnectionDialog::checkFormData(){<br /> if( editDatabaseName-&gt;text().isEmpty()<br /> || editDatabaseHostName-&gt;text().isEmpty()<br /> || editDatabaseUsername-&gt;text().isEmpty()<br /> || editDatabasePassword-&gt;text().isEmpty() )<br /> buttons-&gt;button( QDialogButtonBox::Ok )<s>&gt;setEnabled( false );<br /> else{<br /> // enable the connect button and give focus<br /> buttons</s>&gt;button( QDialogButtonBox::Ok )<s>&gt;setEnabled( true );<br /> buttons</s>&gt;button( QDialogButtonBox::Ok )<s>&gt;setFocus();<br /> }
// nest all layouts together
verticalLayout->addWidget( gridGroupBox );
verticalLayout->addStretch();
verticalLayout->addWidget( urlGroupBox );
verticalLayout->addWidget( buttons );


<br /> // if the connection can be established (or at least tried)<br /> // display the URL<br /> if( buttons</s>&gt;button( QDialogButtonBox::Ok )<s>&gt;isEnabled() )<br /> labelDatabaseURL</s>&gt;setText( comboDatabaseDriverName-&gt;currentText()<br /> + &quot;://&amp;quot;<br /> + editDatabaseUsername-&gt;text()<br /> + &quot;</code>&quot;<br /> + editDatabaseHostName-&gt;text()<br /> + &quot;/&amp;quot;<br /> + editDatabaseName-&gt;text() );<br /> else<br /> labelDatabaseURL-&gt;setText( &quot;&quot; );
comboDatabaseDriverName->setFocus();
}


return buttons-&gt;button( QDialogButtonBox::Ok )<s>&gt;isEnabled();<br />}
void DatabaseConnectionDialog::findAvailableDrivers()
<br />void DatabaseConnectionDialog::doDatabaseConnection()<br />{<br /> // check the database driver is really available<br /> // (should never happen)<br /> if( ! QSqlDatabase::isDriverAvailable( comboDatabaseDriverName</s>&gt;currentText() ) ){<br /> QMessageBox::critical( this,<br /> tr(&quot;Database Connection Error&amp;quot;),<br /> tr(&quot;Database driver not available!&quot;)<br /> );
{
// remove all items
comboDatabaseDriverName->clear();


return;<br /> }
// populate the combo box with all available drivers
foreach( QString driverName, QSqlDatabase::drivers() )
comboDatabaseDriverName->addItem( driverName );
}


qDebug() &lt;&lt; &quot;Performing the database driver setup..&quot;;
bool DatabaseConnectionDialog::slotCheckFormData()
{
return checkFormData();
}


// set database driver properties<br /> QSqlDatabase databaseConnection = QSqlDatabase::addDatabase( comboDatabaseDriverName-&gt;currentText() );<br /> databaseConnection.setDatabaseName( editDatabaseName-&gt;text() );<br /> databaseConnection.setUserName( editDatabaseUsername-&gt;text() );<br /> databaseConnection.setHostName( editDatabaseHostName-&gt;text() );<br /> databaseConnection.setPassword( editDatabasePassword-&gt;text() );<br /> databaseConnection.setPort( spinBoxDatabasePort-&gt;text().toInt() );
bool DatabaseConnectionDialog::checkFormData(){
if( editDatabaseName->text().isEmpty()
|| editDatabaseHostName->text().isEmpty()
|| editDatabaseUsername->text().isEmpty()
|| editDatabasePassword->text().isEmpty() )
buttons->button( QDialogButtonBox::Ok )->setEnabled( false );
else{
// enable the connect button and give focus
buttons->button( QDialogButtonBox::Ok )->setEnabled( true );
buttons->button( QDialogButtonBox::Ok )->setFocus();
}


if( ! databaseConnection.open() ){<br /> QMessageBox::critical( this,<br /> tr(&quot;Database Connection Error&amp;quot;),<br /> databaseConnection.lastError().text()<br /> );


// disable the connect button and set the focus again<br /> // on the first field<br /> buttons-&gt;button( QDialogButtonBox::Ok )<s>&gt;setEnabled( false );<br /> editDatabaseHostName</s>&gt;setFocus();<br /> }<br /> else{<br /> // hide the dialog<br /> this-&gt;hide();
// if the connection can be established (or at least tried)
// display the URL
if( buttons->button( QDialogButtonBox::Ok )->isEnabled() )
labelDatabaseURL->setText( comboDatabaseDriverName->currentText()
+ "://"
+ editDatabaseUsername->text()
+ "@"
+ editDatabaseHostName->text()
+ "/"
+ editDatabaseName->text() );
else
labelDatabaseURL->setText( "" );


// emit the signal<br /> qDebug() &lt;&lt; &quot;Emitting signal since the database is connected!&quot;;<br /> emit databaseConnect( databaseConnection );<br /> }<br />}
return buttons->button( QDialogButtonBox::Ok )->isEnabled();
}


void DatabaseConnectionDialog::slotPerformConnection()<br />{<br /> // perform another check against the user data<br /> if( slotCheckFormData() )<br /> doDatabaseConnection();
void DatabaseConnectionDialog::doDatabaseConnection()
{
// check the database driver is really available
// (should never happen)
if( ! QSqlDatabase::isDriverAvailable( comboDatabaseDriverName->currentText() ) ){
QMessageBox::critical( this,
tr("Database Connection Error"),
tr("Database driver not available!")
);


return;
}
qDebug() << "Performing the database driver setup..";
// set database driver properties
QSqlDatabase databaseConnection = QSqlDatabase::addDatabase( comboDatabaseDriverName->currentText() );
databaseConnection.setDatabaseName( editDatabaseName->text() );
databaseConnection.setUserName( editDatabaseUsername->text() );
databaseConnection.setHostName( editDatabaseHostName->text() );
databaseConnection.setPassword( editDatabasePassword->text() );
databaseConnection.setPort( spinBoxDatabasePort->text().toInt() );
if( ! databaseConnection.open() ){
QMessageBox::critical( this,
tr("Database Connection Error"),
databaseConnection.lastError().text()
);
// disable the connect button and set the focus again
// on the first field
buttons->button( QDialogButtonBox::Ok )->setEnabled( false );
editDatabaseHostName->setFocus();
}
else{
// hide the dialog
this->hide();
// emit the signal
qDebug() << "Emitting signal since the database is connected!";
emit databaseConnect( databaseConnection );
}
}
}


void DatabaseConnectionDialog::setDatabaseName(const QString &amp;dbName)<br />{<br /> editDatabaseName-&gt;setText( dbName );<br />}
void DatabaseConnectionDialog::slotPerformConnection()
{
// perform another check against the user data
if( slotCheckFormData() )
doDatabaseConnection();


void DatabaseConnectionDialog::setDatabasePortNumber(int &amp;portNumber)<br />{<br /> spinBoxDatabasePort-&gt;setValue( portNumber );<br />}
}
 
void DatabaseConnectionDialog::setDatabaseName(const QString &dbName)
{
editDatabaseName->setText( dbName );
}
 
void DatabaseConnectionDialog::setDatabasePortNumber(int &portNumber)
{
spinBoxDatabasePort->setValue( portNumber );
}


void DatabaseConnectionDialog::setDatabaseHostName(const QString &amp;hostname)<br />{<br /> editDatabaseHostName-&gt;setText( hostname );<br />}
void DatabaseConnectionDialog::setDatabaseHostName(const QString &hostname)
{
editDatabaseHostName->setText( hostname );
}


void DatabaseConnectionDialog::setDatabaseUsername(const QString &amp;username)<br />{<br /> editDatabaseUsername-&gt;setText( username );<br />}
void DatabaseConnectionDialog::setDatabaseUsername(const QString &username)
{
editDatabaseUsername->setText( username );
}


void DatabaseConnectionDialog::setDatabaseDriverName(const QString &amp;drvName)<br />{<br /> int index = comboDatabaseDriverName-&gt;findText( drvName );<br /> if( index &gt;= 0 )<br /> comboDatabaseDriverName-&gt;setCurrentIndex( index );<br />}
void DatabaseConnectionDialog::setDatabaseDriverName(const QString &drvName)
{
int index = comboDatabaseDriverName->findText( drvName );
if( index >= 0 )
comboDatabaseDriverName->setCurrentIndex( index );
}


void DatabaseConnectionDialog::setDatabasePassword(const QString &amp;pwd)<br />{<br /> editDatabasePassword-&gt;setText( pwd );<br />}
void DatabaseConnectionDialog::setDatabasePassword(const QString &pwd)
{
editDatabasePassword->setText( pwd );
}


void DatabaseConnectionDialog::run(bool autoConnect)<br />{<br /> bool statusOk = checkFormData();<br /> if( ! autoConnect || ! statusOk )<br /> exec&amp;amp;#40;&amp;#41;;<br /> else<br /> doDatabaseConnection();<br />}
void DatabaseConnectionDialog::run(bool autoConnect)
{
bool statusOk = checkFormData();
if( ! autoConnect || ! statusOk )
exec();
else
doDatabaseConnection();
}

Latest revision as of 13:35, 28 June 2015

En Ar Bg De El Es Fa Fi Fr Hi Hu It Ja Kn Ko Ms Nl Pl Pt Ru Sq Th Tr Uk Zh

This code snippet shows how to implement a general database dialog that will prompt the user for general database connection properties (username, password, hostname, ecc.) as well as a combo with all available database drivers. The dialog provides also a signal that will pass the database connection (if established) so that third party components can use such connection.

Usage

Usage of the presented dialog is like the following:

DatabaseConnectionDialog* dialog = new DatabaseConnectionDialog(this);

// optional: set the data that will be presented to the user as auto-filled form
 dialog->setDatabaseName( "mydb" );
 dialog->setDatabasePortNumber( 1234 );
 dialog->setDatabaseHostName( "localhost" );
 dialog->setDatabaseUsername( "luca" );
 dialog->setDatabaseDriverName( "QPSQL" );
 dialog->setDatabasePassword( "pwd" );

// enable the connect button if all the data is correct
 dialog->checkFormData();
 // connect the dialog signal to a slot where I will use the connection
 connect( dialog,
 SIGNAL (databaseConnect(QSqlDatabase&)),
 this,
 SLOT (slotHandleNewDatabaseConnection(QSqlDatabase&)));

// show the dialog (without auto-connection)
 dialog->run( false );

The dialog allows for pre-initialization of form fields, as well as an auto-connect mode that make the connection to happen automatically if all the data is in place. Please note that this dialog can be improved in several ways, and represents therefore a starting point for a more specific database connection dialog.

Auto-Connect mode

When the run() method is invoked an autoconnect mode can be specified as boolean value true. In such mode, if all the form data is filled, the dialog immediately attempts to connect to the database, and in the case it succeed the dialog is not shown to the user and the signal is emitted. In the case the form data is not complete or the connection cannot be established, the dialog is shown to the user. If the autoconnect mode is off (parameter = false) the dialog is always shown.

Source code

The following is the header file:

/*!
 * databasedialog.h
 */
#ifndef DATABASEDIALOG_H
#define DATABASEDIALOG_H

#include <QDialog>
#include <QLabel>
#include <QLineEdit>
#include <QComboBox>
#include <QSpinBox>
#include <QDialogButtonBox>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QSqlDatabase>
#include <QString>
#include <QMessageBox>
#include <QDebug>
#include <QSqlError>
#include <QPushButton>
#include <QGroupBox>

class DatabaseConnectionDialog : public QDialog
{
 Q_OBJECT

private:

 /*!
 * The display label for the database driver name.
 */
 QLabel* labelDatabaseDriverName;

/*!
 * The display label for the TCP/IP port the database
 * is listening for connections.
 */
 QLabel* labelDatabasePort;

/*!
 * The label for the database name.
 */
 QLabel* labelDatabaseName;

/*!
 * The label for the database host name.
 */
 QLabel* labelDatabaseHostName;

/*!
 * The label for the database username.
 */
 QLabel* labelDatabaseUsername;

/*!
 * The label for the database password.
 */
 QLabel* labelDatabasePassword;

/*!
 * A label to display the summary database URL
 * connection string.
 */
 QLabel* labelDatabaseURL;

/*!
 * The editable name of the database to which the user
 * wants to connect to.
 */
 QLineEdit* editDatabaseName;

/*!
 * The editable name of the database name to which connect.
 */
 QLineEdit* editDatabaseHostName;

/*!
 * The database listening port.
 */
 QSpinBox* spinBoxDatabasePort;

/*!
 * The editable username to use for the connection.
 */
 QLineEdit* editDatabaseUsername;

/*!
 * The editable password to use for the connection.
 */
 QLineEdit* editDatabasePassword;

/*!
 * The combo from which the user can select the database
 * driver name and type
 */
 QComboBox* comboDatabaseDriverName;

/*!
 * A Dialog button box for displaying the
 * connect/cancel buttons.
 */
 QDialogButtonBox* buttons;

/*!
 * A method to create all the components of this dialog window
 * and lay out them correctly.
 */
 void setUpGUI();

 /*!
 * Searches for and populates the combo box with the
 * available database drivers.
 */
 void findAvailableDrivers();


 /*!
 * Performs the connection to the database
 * and emits the signal to pass the connection.
 */
 void doDatabaseConnection();

public:
 explicit DatabaseConnectionDialog(QWidget* parent=0);

 /*!
 * Sets the database name in the dialog.
 * dbName the name of the database
 */
 void setDatabaseName( const QString& dbName );

 /*!
 * Sets the port number for the database connection.
 * portNumber the port number the database is listening for
 * connections
 */
 void setDatabasePortNumber( int& portNumber );

 /*!
 * Sets the remote host name mnemonic name.
 * hostname the name of the host the database is running on
 */
 void setDatabaseHostName( const QString& hostname );

 /*!
 * Sets the username to use for the connection.
 * username the username to use for the connection
 */
 void setDatabaseUsername( const QString& username );

 /*!
 * Selects the driver name.
 * the driver name (therefore the database type) to
 * select in the combo box.
 */
 void setDatabaseDriverName( const QString& drvName );

 /*!
 * Sets the user password.
 * the password to use for the connection
 */
 void setDatabasePassword( const QString& pwd );


 /*!
 * Performs a check against the user data and enables/disables
 * the connect button depending on the form fill status.
 * true if the data allows a database connection
*/
 bool checkFormData();

/*!
 * Performs the database connection or prompt the user
 * showing this dialog in the case data is not completed
 * or should not perform the autoconnection.
 * autoConnect if set to true tries to perform an automatic
 * connection to the database, if the data is complete, or prompt the user
 * for missing data. If set to false, simply shows the dialog and waits.
 */
 void run( bool autoConnect );


signals:

 /*!
 * Passes the database connection in the case the connection
 * is succesful.
 * databaseConnection the connection object
 */
 void databaseConnect( QSqlDatabase& databaseConnection );

public slots:

 /*!
 * Checks if the user has entered enough data to
 * try a database connection.
 */
 bool slotCheckFormData();


 /*!
 * Performs the database connection.
 */
 void slotPerformConnection();

};

#endif // DATABASEDIALOG_H

And the following is the class implementation:

#include "databasedialog.h"

DatabaseConnectionDialog::DatabaseConnectionDialog(QWidget* parent) :

QDialog(parent)

{

// this dialog is modal
setModal( true );
// the title of this dialog
setWindowTitle( tr("Database connection") );
// place each GUI component
setUpGUI();
// load available drivers
findAvailableDrivers();

}

void DatabaseConnectionDialog::setUpGUI() {


// create all gui components
labelDatabaseDriverName = new QLabel( tr("Database Type (driver name)"), this );
labelDatabasePort = new QLabel( tr("TCP/IP Port Number"), this );
labelDatabaseName = new QLabel( tr("Database Name"), this );
labelDatabaseHostName = new QLabel( tr("Host Name"), this );
labelDatabaseUsername = new QLabel( tr("Username"), this );
labelDatabasePassword = new QLabel( tr("Password"), this );
labelDatabaseURL = new QLabel( this );
labelDatabaseURL->setAlignment( Qt::AlignCenter );
spinBoxDatabasePort = new QSpinBox( this );
spinBoxDatabasePort->setMaximum( 9999 );
spinBoxDatabasePort->setMinimum( 100 );
spinBoxDatabasePort->setSingleStep( 1 );
comboDatabaseDriverName = new QComboBox( this );
comboDatabaseDriverName->setEditable( false );


editDatabaseName = new QLineEdit( this );
editDatabaseHostName = new QLineEdit( this );
editDatabaseUsername = new QLineEdit( this );
editDatabasePassword = new QLineEdit( this );
editDatabasePassword->setEchoMode( QLineEdit::Password );
connect( editDatabaseName,
SIGNAL (editingFinished()),
this,
SLOT (slotCheckFormData()) );
connect( editDatabaseHostName,
SIGNAL (editingFinished()),
this,
SLOT (slotCheckFormData()) );
connect( editDatabaseUsername,
SIGNAL (editingFinished()),
this,
SLOT (slotCheckFormData()) );
connect( editDatabasePassword,
SIGNAL (editingFinished()),
this,
SLOT (slotCheckFormData()) );
connect( editDatabasePassword,
SIGNAL (returnPressed()),
this,
SLOT (slotCheckFormData()) );


// create the button box
buttons = new QDialogButtonBox( this );
buttons->addButton( QDialogButtonBox::Ok );
buttons->addButton( QDialogButtonBox::Cancel );
QPushButton* okButton = buttons->button( QDialogButtonBox::Ok );
okButton->setText( tr( "Connect!" ) );
okButton->setEnabled( false );
connect( buttons,
SIGNAL (accepted()),
this,
SLOT (slotPerformConnection()));
connect( buttons,
SIGNAL (rejected()),
this,
SLOT (close()));

// create a vertical layout to display components

QVBoxLayout* verticalLayout = new QVBoxLayout( this );

// create a grid layout to add all the components

QGridLayout* formGridLayout = new QGridLayout( this );
QGroupBox* gridGroupBox = new QGroupBox( this );
gridGroupBox->setTitle( tr("Database connection properties" ) );
formGridLayout->addWidget( labelDatabaseDriverName, 0, 0 );
formGridLayout->addWidget( comboDatabaseDriverName, 0, 1 );
labelDatabaseDriverName->setBuddy( comboDatabaseDriverName );
formGridLayout->addWidget( labelDatabaseHostName, 1, 0 );
formGridLayout->addWidget( editDatabaseHostName, 1, 1);
labelDatabaseHostName->setBuddy( editDatabaseHostName );
formGridLayout->addWidget( labelDatabasePort, 2, 0 );
formGridLayout->addWidget( spinBoxDatabasePort, 2, 1 );
labelDatabasePort->setBuddy( spinBoxDatabasePort );
formGridLayout->addWidget( labelDatabaseName, 3, 0 );
formGridLayout->addWidget( editDatabaseName , 3, 1 );
labelDatabaseName->setBuddy( editDatabaseName );
formGridLayout->addWidget( labelDatabaseUsername, 4, 0 );
formGridLayout->addWidget( editDatabaseUsername, 4, 1 );
labelDatabaseUsername->setBuddy( editDatabaseUsername );
formGridLayout->addWidget( labelDatabasePassword, 5, 0 );
formGridLayout->addWidget( editDatabasePassword, 5, 1 );
labelDatabasePassword->setBuddy( editDatabasePassword );
// add all the elements to groupbox
gridGroupBox->setLayout( formGridLayout );

// place a new groupbox to contain the database connection URL

QGroupBox* urlGroupBox = new QGroupBox( this );
urlGroupBox->setTitle( tr( "Database URL" ) );
QHBoxLayout* urlLayout = new QHBoxLayout( this );
urlLayout->addWidget( labelDatabaseURL );
urlGroupBox->setLayout( urlLayout );

// nest all layouts together

verticalLayout->addWidget( gridGroupBox );
verticalLayout->addStretch();
verticalLayout->addWidget( urlGroupBox );
verticalLayout->addWidget( buttons );

comboDatabaseDriverName->setFocus(); }

void DatabaseConnectionDialog::findAvailableDrivers() {

// remove all items
comboDatabaseDriverName->clear();

// populate the combo box with all available drivers

foreach( QString driverName, QSqlDatabase::drivers() )
comboDatabaseDriverName->addItem( driverName );

}

bool DatabaseConnectionDialog::slotCheckFormData() {

return checkFormData();

}

bool DatabaseConnectionDialog::checkFormData(){

if( editDatabaseName->text().isEmpty()
|| editDatabaseHostName->text().isEmpty()
|| editDatabaseUsername->text().isEmpty()
|| editDatabasePassword->text().isEmpty() )
buttons->button( QDialogButtonBox::Ok )->setEnabled( false );
else{
// enable the connect button and give focus
buttons->button( QDialogButtonBox::Ok )->setEnabled( true );
buttons->button( QDialogButtonBox::Ok )->setFocus();
}


// if the connection can be established (or at least tried)
// display the URL
if( buttons->button( QDialogButtonBox::Ok )->isEnabled() )
labelDatabaseURL->setText( comboDatabaseDriverName->currentText()
+ "://"
+ editDatabaseUsername->text()
+ "@"
+ editDatabaseHostName->text()
+ "/"
+ editDatabaseName->text() );
else
labelDatabaseURL->setText( "" );

return buttons->button( QDialogButtonBox::Ok )->isEnabled(); }

void DatabaseConnectionDialog::doDatabaseConnection() {

// check the database driver is really available
// (should never happen)
if( ! QSqlDatabase::isDriverAvailable( comboDatabaseDriverName->currentText() ) ){
QMessageBox::critical( this,
tr("Database Connection Error"),
tr("Database driver not available!")
);

return;

}

qDebug() << "Performing the database driver setup..";

// set database driver properties

QSqlDatabase databaseConnection = QSqlDatabase::addDatabase( comboDatabaseDriverName->currentText() );
databaseConnection.setDatabaseName( editDatabaseName->text() );
databaseConnection.setUserName( editDatabaseUsername->text() );
databaseConnection.setHostName( editDatabaseHostName->text() );
databaseConnection.setPassword( editDatabasePassword->text() );
databaseConnection.setPort( spinBoxDatabasePort->text().toInt() );

if( ! databaseConnection.open() ){

QMessageBox::critical( this,
tr("Database Connection Error"),
databaseConnection.lastError().text()
);

// disable the connect button and set the focus again

// on the first field
buttons->button( QDialogButtonBox::Ok )->setEnabled( false );
editDatabaseHostName->setFocus();
}
else{
// hide the dialog
this->hide();

// emit the signal

qDebug() << "Emitting signal since the database is connected!";
emit databaseConnect( databaseConnection );
}

}

void DatabaseConnectionDialog::slotPerformConnection() {

// perform another check against the user data
if( slotCheckFormData() )
doDatabaseConnection();

}

void DatabaseConnectionDialog::setDatabaseName(const QString &dbName) {

editDatabaseName->setText( dbName );

}

void DatabaseConnectionDialog::setDatabasePortNumber(int &portNumber) {

spinBoxDatabasePort->setValue( portNumber );

}

void DatabaseConnectionDialog::setDatabaseHostName(const QString &hostname) {

editDatabaseHostName->setText( hostname );

}

void DatabaseConnectionDialog::setDatabaseUsername(const QString &username) {

editDatabaseUsername->setText( username );

}

void DatabaseConnectionDialog::setDatabaseDriverName(const QString &drvName) {

int index = comboDatabaseDriverName->findText( drvName );
if( index >= 0 )
comboDatabaseDriverName->setCurrentIndex( index );

}

void DatabaseConnectionDialog::setDatabasePassword(const QString &pwd) {

editDatabasePassword->setText( pwd );

}

void DatabaseConnectionDialog::run(bool autoConnect) {

bool statusOk = checkFormData();
if( ! autoConnect || ! statusOk )
exec();
else
doDatabaseConnection();

}