Commencer à programmer avec QtBienvenue dans le monde de Qt - l'outil de développement multiplateforme. Dans ce guide d'introduction, nous apprendrons les bases de Qt en créant un simple bloc-notes. Après avoir lu ce guide, vous devriez être prêts à plonger dans nos présentations et dans la documentation de l'API afin de trouver les informations nécessaires à l'application que vous développez. Bonjour bloc-notesDans ce premier exemple, nous créons et affichons simplement un champ d'édition de texte dans une fenêtre sur le bureau. Il s'agit du programme Qt le plus simple ayant une interface graphique. Voici le code : 1 #include <QApplication> 2 #include <QTextEdit> 3 4 int main(int argv, char **args) 5 { 6 QApplication app(argv, args); 7 8 QTextEdit textEdit; 9 textEdit.show(); 10 11 return app.exec(); 12 } Analysons le code ligne par ligne. Dans les deux premières lignes, nous incluons les fichiers en-têtes QApplication et QTextEdit, qui sont les classes dont nous avons besoin dans cet exemple. Toutes les classes de Qt ont des fichiers en-têtes nommés comme celles-ci. À la ligne 6, nous créons un objet QApplication, qui gère les ressources de l'application et est requis pour n'importe quel programme Qt qui a une interface graphique. Il prend les paramètres argv et args, car Qt accepte les paramètres en ligne de commande. La ligne 8 crée un objet QTextEdit. Un champ d'édition de texte est un élément graphique dans une interface graphique. Dans Qt, nous les appelons des widgets. Des exemples de widgets sont les barres de défilement, les étiquettes ou les cases à cocher. Un widget peut aussi contenir d'autres widgets ; une fenêtre, par exemple, est un widget qui en contient d'autres. À la ligne 9, nous affichons le champ d'édition de texte à l'écran dans sa propre fenêtre. Puisque les widgets sont aussi des conteneurs (par exemple, un objet QMainWindow qui a des barres d'outils, des menus, une barre d'état et d'autres widgets), il est possible de les afficher dans leur propre fenêtre. Les widgets ne sont pas visibles par défaut ; la fonction show() rend un widget visible. La ligne 11 fait entrer le QApplication dans un boucle d'événements. Quand une application Qt est lancée, des événements sont générés et envoyés aux widgets de l'application. Des exemples d'événements sont les clics de souris ou les appuis sur des touches du clavier. Quand vous écrivez dans le champ d'édition, il reçoit des événements de touches de clavier appuyées et réagit en écrivant le texte tapé. Pour lancer l'application, lancez une console, allez dans le répertoire où est situé le .cpp du programme. Les commandes suivantes compilent le programme : qmake -project
qmake
make Cela créera un exécutable dans le dossier part1 (notez que, sous Windows, il faudra peut-être utiliser nmake au lieu de make ; l'exécutable créé sera placé dans part1/debug ou part1/release). qmake est l'outil de Qt qui, à partir d'un fichier de configuration .pro, créé avec le paramètre -project, génère un Makefile qui compilera le programme pour vous. Nous étudierons la création de nos propres .pro plus tard. Plus d'informations
Ajouter un bouton QuitterDans une application normale, vous aurez normalement plus d'un widget. Nous ajouterons un objet QPushButton en dessous du champ de texte. Ce bouton fermera le bloc-notes lorsqu'il sera cliqué. Regardons le code. 1 #include <QtGui> 2 3 int main(int argv, char **args) 4 { 5 QApplication app(argv, args); 6 7 QTextEdit textEdit; 8 QPushButton quitButton("Quit"); 9 10 QObject::connect(&quitButton, SIGNAL(clicked()), qApp, SLOT(quit())); 11 12 QVBoxLayout layout; 13 layout.addWidget(&textEdit); 14 layout.addWidget(&quitButton); 15 16 QWidget window; 17 window.setLayout(&layout); 18 19 window.show(); 20 21 return app.exec(); 22 } À la ligne 1, nous incluons QtGui, qui contient toutes les classes graphiques de Qt. À la ligne 10, nous utilisons le système de signaux et de slots de Qt pour quitter l'application quand le bouton Quit est cliqué. Un slot est une fonction qui peut être appelée à l'exécution en utilisant son nom (représenté par une chaîne littérale). Un signal est une fonction qui, lorsqu'elle est appelée, appelle les slots qui lui sont connectés. On dit qu'on connecte un slot à un signal et qu'on émet un signal. quit() est un slot de QApplication. clicked() est un signal qu'un QPushButton émet lorsqu'il est cliqué. La fonction statique QObject::connect() permet de connecter le slot au signal. SIGNAL() et SLOT() sont deux macros qui prennent la signature du signal et du slot à connecter. Il faut aussi donner des pointeurs vers les objets qui envoient et reçoivent le signal. La ligne 12 crée un objet QVBoxLayout. Nous avons dit que les widgets peuvent en contenir d'autres. Il est possible de stipuler les frontières de chaque widget (position et taille) mais il est souvent plus simple d'utiliser un layout. Un layout gère les frontières des enfants d'un widget. QVBoxLayout, par exemple, met les enfants en rang vertical. Les lignes 13 et 14 ajoutent le champ d'édition et le bouton au layout. À la ligne 17, nous appliquons le layout au widget fenêtre. Plus d'informations
Hériter de QWidgetQuand l'utilisateur quitte une application, on peut vouloir ajouter une boîte de dialogue pour demander de confirmer avant de quitter. Dans cet exemple, nous créons une classe qui hérite de QWidget et nous ajoutons un slot à connecter au bouton pour quitter. Regardons le code : 5 class Notepad : public QWidget 6 { 7 Q_OBJECT 8 9 public: 10 Notepad(); 11 12 private slots: 13 void quit(); 14 15 private: 16 QTextEdit *textEdit; 17 QPushButton *quitButton; 18 }; La macro Q_OBJECT doit être située en premier dans la classe et déclare notre classe comme un QObject (bien sûr, elle doit aussi hériter de QObject). Un objet QObject ajoute quelques possibilités supplémentaires par rapport à une classe normale en C++. Par exemple, le nom de la classe et de ses slots peut être récupéré à l'exécution, ainsi que les paramètres d'un slot. La ligne 13 déclare le slot quit(), avec la macro slots. Le slot quit() peut maintenant être connecté à n'importe quel signal avec la même signature, c'est-à-dire aucun paramètre. Au lieu de créer l'interface et de connecter le slot dans la fonction main(), nous le faisons dans le constructeur de la classe Notepad. Notepad::Notepad() { textEdit = new QTextEdit; quitButton = new QPushButton(tr("Quit")); connect(quitButton, SIGNAL(clicked()), this, SLOT(quit())); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(textEdit); layout->addWidget(quitButton); setLayout(layout); setWindowTitle(tr("Notepad")); } Comme vu dans la déclaration de la classe, nous utilisons des pointeurs vers nos QObject (textEdit et quitButton). En règle générale, vous devriez toujours allouer des QObject dynamiquement et ne jamais les copier. Nous utilisons maintenant la fonction tr() pour nos variables texte. Cette fonction est nécessaire pour fournir une traduction à votre application. Nous n'entrerons pas dans les détails mais vous pouvez vous renseigner avec le lien Qt Linguist dans Plus d'informations. Plus d'informations
Créer un fichier .proPour cet exemple, nous créons notre propre fichier .pro au lieu d'utiliser l'option -project de qmake. HEADERS = notepad.h SOURCES = notepad.cpp \ main.cpp Les commandes suivantes compilent l'exemple. qmake make Utiliser QMainWindowBeaucoup d'applications profiteront de l'utilisation de QMainWindow, qui a son propre layout auquel vous pouvez ajouter une barre de menus, des barres d'outils, des docks et une barre de statut. QMainWindow a une partie centrale qui peut être occupée par n'importe quel widget. Pour notre bloc-notes, nous placerons notre champ de texte ici. Regardons la nouvelle déclaration de Notepad. #include <QtGui> class Notepad : public QMainWindow { Q_OBJECT public: Notepad(); private slots: void open(); void save(); void quit(); private: QTextEdit *textEdit; QAction *openAction; QAction *saveAction; QAction *exitAction; QMenu *fileMenu; }; Nous ajoutons deux slots supplémentaires pour sauvegarder et ouvrir un document. Nous les implémenterons dans la section suivante. Souvent, dans une fenêtre, le même slot peut être appelé par plusieurs widgets. Par exemple, les menus et boutons d'une barre d'outils. Pour rendre ceci plus facile, Qt propose la classe QAction, qui peut être donnée à plusieurs widgets et être connectée à un slot. Par exemple, QMenu et QToolBar permettent de créer des menus et des boutons à partir d'une même QAction. Nous verrons comment cela fonctionne. Comme précédemment, nous utilisons le constructeur pour mettre en place l'interface graphique. Notepad::Notepad() { saveAction = new QAction(tr("&Open"), this); saveAction = new QAction(tr("&Save"), this); exitAction = new QAction(tr("E&xit"), this); connect(openAction, SIGNAL(triggered()), this, SLOT(open())); connect(saveAction, SIGNAL(triggered()), this, SLOT(save())); connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit())); fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(openAction); fileMenu->addAction(saveAction); fileMenu->addSeparator(); fileMenu->addAction(exitAction); textEdit = new QTextEdit; setCentralWidget(textEdit); setWindowTitle(tr("Notepad")); } Les QAction sont créées à partir du texte à afficher sur les widgets auxquels nous les ajoutons (ici, des éléments de menu). Si nous voulions les ajouter à une barre d'outils, nous aurions aussi pu définir des icônes. Lorsqu'un élément du menu est cliqué, il déclenchera l'action et le slot connecté sera appelé. Plus d'informations
Sauvegarder et chargerDans cet exemple, nous implémenterons les fonctionnalités des slots open() et save() que nous avions ajoutés précédemment. Commençons avec le slot open(). QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "", tr("Text Files (*.txt);;C++ Files (*.cpp *.h)")); if (fileName != "") { QFile file(fileName); if (!file.open(QIODevice::ReadOnly)) { QMessageBox::critical(this, tr("Error"), tr("Could not open file")); return; } QString contents = file.readAll().constData(); textEdit->setPlainText(contents); file.close(); } La première étape est de demander à l'utilisateur le nom du fichier à ouvrir. Qt propose QFileDialog, qui est une boîte de dialogue permettant de sélectionner un fichier (ici sous Kubuntu). La fonction statique getOpenFileName() permet d'en afficher une et ne se termine pas tant qu'un fichier n'a pas été sélectionné. Elle retourne le chemin vers le fichier sélectionné ou une chaîne vide si l'utilisateur annule l'action. Si nous obtenons un nom de fichier, nous essayons de l'ouvrir avec open(), qui retourne true si le fichier a pu être ouvert. Nous ne traiterons pas de la gestion d'erreurs ici mais des liens sont disponibles dans la section Plus d'informations. Si le fichier ne peut pas être ouvert, nous utilisons un QMessageBox pour afficher une boîte de dialogue avec l'erreur (voir la documentation de QMessageBox). Lire les données est simple avec la fonction readAll(), qui retourne toutes les données dans un QByteArray. La fonction constData() retourne ces données dans une chaîne en tant que const char*, pour lequel QString possède un constructeur. Le contenu est ensuite affiché dans le champ d'édition. Enfin, nous fermons le fichier avec la fonction close(). Maintenant, occupons-nous du slot save(). QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "", tr("Text Files (*.txt);;C++ Files (*.cpp *.h)")); if (fileName != "") { QFile file(fileName); if (!file.open(QIODevice::WriteOnly)) { // error message } else { QTextStream stream(&file); stream << textEdit->toPlainText(); stream.flush(); file.close(); } } Lorsque nous écrivons le contenu du champ d'édition dans le fichier, nous utilisons un objet QTextStream, qui englobe l'objet QFile. Le QTextStream peut écrire des QString directement dans le fichier, alors que QFile n'accepte que les données sous forme de char* avec la méthode write() de QIODevice. Plus d'informations
RemerciementsMerci à <!buffer!> pour la traduction ainsi qu'à <!idiallo!>, <!dourouc!> et <!jacques_jean!> pour leur relecture ! |
Cette page est une traduction d'une page de la documentation de Qt, écrite par Nokia Corporation and/or its subsidiary(-ies). Les éventuels problèmes résultant d'une mauvaise traduction ne sont pas imputables à Nokia. | Qt 4.7 | |
Copyright © 2024 Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon, vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD. | ||
Vous avez déniché une erreur ? Un bug ? Une redirection cassée ? Ou tout autre problème, quel qu'il soit ? Ou bien vous désirez participer à ce projet de traduction ? N'hésitez pas à nous contacter ou par MP ! |