I. Cahier des charges▲
Ce lecteur possédera trois menus :
- Fichier :
- Nouveau,
- Ouvrir,
- Enregistrer,
- Enregistrer sous,
- Quitter ;
- Édition :
- Couper,
- Copier,
- Coller ;
- Aide :
- À propos de JEditor,
- À propos de Qt Jambi.
On pourra donc créer, ouvrir, enregistrer et enregistrer sous un fichier texte. En plus d'avoir ces menus dans la barre de menu, on ajoutera une barre d'outils contenant les plus utiles.
II. La solution▲
Pour avoir une barre de menu, il nous faudra hériter de la classe QMainWindow de Qt. En effet, avec Qt, lorsque l'on veut créer un widget, on hérite de la classe Qt et ensuite on ajoute des méthodes d'actions spécifiques. Par exemple, les méthodes new(), open(), save(), saveas(), quit(). N'oubliez pas la documentation de Qt Jambi. C'est votre source de renseignements par excellence. Dedans, il y a absolument tout. Vous pouvez aussi la trouver dans votre installation de Qt Jambi en local. Vous le savez peut-être, Qt Jambi propose un outil très intéressant que l'on appelle QtDesigner. Malgré les apparences, cet outil est difficile à prendre en main. En le lançant, on s'aperçoit très vite que l'on peut faire des choses très jolies, mais c'est un faux semblant : vous n'arriverez pas à l'exploiter correctement dans vos programmes. Pour bien comprendre la manière dont les choses se présentent, on ne va pas utiliser QtDesigner dans un premier temps. Vous pouvez télécharger le pack d'image, ainsi que les sources.
/*
* JEditor.java
* Version : 2
*
* Créé le 2 novembre 2007
* Modifié le 13 novembre 2007
*/
/* Import des classes espace de nommage nécessaires */
import
com.trolltech.qt.QVariant;
/* Importation des éléments du GUI */
import
com.trolltech.qt.gui.QApplication;
import
com.trolltech.qt.gui.QMainWindow;
import
com.trolltech.qt.gui.QTextEdit;
import
com.trolltech.qt.gui.QMenu;
import
com.trolltech.qt.gui.QToolBar;
import
com.trolltech.qt.gui.QAction;
import
com.trolltech.qt.gui.QMenuBar;
import
com.trolltech.qt.gui.QFileDialog;
import
com.trolltech.qt.gui.QCloseEvent;
import
com.trolltech.qt.gui.QMessageBox;
import
com.trolltech.qt.gui.QIcon;
import
com.trolltech.qt.gui.QKeySequence;
import
com.trolltech.qt.gui.QCursor;
/* Importation des éléments de gestion */
import
com.trolltech.qt.core.QFile;
import
com.trolltech.qt.core.QTextStream;
import
com.trolltech.qt.core.Qt;
/* Définition de l'application et de ses attributs */
public
class
JEditor extends
QMainWindow {
private
String curFile; // Fichier actuellement ouvert
private
QTextEdit textEdit; // Widget permettant l'affichage et la modification du texte
private
QMenu fileMenu; // Menu Fichier
private
QMenu editMenu; // Menu Edition
private
QMenu helpMenu; // Menu Aide
private
QToolBar fileToolBar; // Barre d'outil Fichier
private
QToolBar editToolBar; // Barre d'outil Edition
private
QAction newAct; // Action Nouveau
private
QAction openAct; // Action Ouvrir
private
QAction saveAct; // Action Enregistrer
private
QAction saveAsAct; // Action Enregistrer Sous
private
QAction exitAct; // Action Quitter
private
QAction cutAct; // Action Couper
private
QAction copyAct; // Action Copier
private
QAction pasteAct; // Action Coller
private
QAction aboutAct; // Action A Propos de JEditor
private
QAction aboutQtAct; // Action A propos de Qt Jambi
private
String rsrcPath =
"classpath:images"
; // Répertoire des images
/* Définition du constructeur */
public
JEditor
(
)
{
QMenuBar menuBar =
new
QMenuBar
(
); // On crée la barre de menu
textEdit =
new
QTextEdit
(
this
);
setMenuBar
(
menuBar); // On ajoute la barre de menu à notre Application
setCentralWidget
(
textEdit); // On ajoute la zone de Texte
/* On lance les méthodes de création des différents attributs de notre fenêtre */
try
{
createActions
(
);
}
catch
(
Exception e) {
e.printStackTrace
(
);
}
createMenus
(
);
createToolBars
(
);
createStatusBar
(
);
/* On lance la méthode documentWasModified lorsque le contenu du texte est modifié */
textEdit.document
(
).contentsChanged.connect
(
this
, "documentWasModified()"
);
/* Le fichier de départ est un fichier vide */
setCurrentFile
(
""
);
}
/* On redéfinit la méthode lorsque l'on clique sur le bouton fermer de la fenêtre pour demander à l'utilisateur
s'il veut enregistrer avant de quitter */
public
void
closeEvent
(
QCloseEvent event)
{
if
(
maybeSave
(
)) {
event.accept
(
);
}
else
{
event.ignore
(
);
}
}
/* Lors de l'ouverture d'un nouveau fichier, on doit fermer le précédent, on avertit donc l'utilisateur.
On efface le contenu du widget textEdit et on met à 0 la valeur du nom de fichier */
public
void
newFile
(
)
{
if
(
maybeSave
(
)) {
textEdit.clear
(
);
setCurrentFile
(
""
);
}
}
/* Méthode d'ouverture du fichier */
public
void
open
(
)
{
if
(
maybeSave
(
)) {
String fileName =
QFileDialog.getOpenFileName
(
this
);
if
(
fileName.length
(
) !=
0
)
loadFile
(
fileName);
}
}
/* On enregistre les modifications effectuées dans le fichier */
public
boolean
save
(
)
{
if
(
curFile.length
(
) ==
0
) {
return
saveAs
(
);
}
else
{
return
saveFile
(
curFile);
}
}
/* On enregistre les modifications dans un nouveau fichier */
public
boolean
saveAs
(
)
{
String fileName =
QFileDialog.getSaveFileName
(
this
);
if
(
fileName.length
(
) ==
0
)
return
false
;
return
saveFile
(
fileName);
}
/* Fonction A propos de JEditor */
public
void
about
(
)
{
QMessageBox.about
(
this
,
tr
(
"A Propos de JEditor"
),
tr
(
"<b>JEditor<b> est une application d'exemple"
+
"pour faire une démonstration de l'utilisation de Qt Jambi"
));
}
/* Méthode qui définit que le document a été modifié pour savoir si on a besoin de le sauvegarder ou pas */
public
void
documentWasModified
(
)
{
setWindowModified
(
textEdit.document
(
).isModified
(
));
}
/* Création des actions des menus et des toolbars */
private
void
createActions
(
)
{
/* Actions du menu Fichier */
newAct =
new
QAction
(
new
QIcon
(
rsrcPath +
"/new.png"
), tr
(
"&Nouveau"
), this
);
newAct.setShortcut
(
new
QKeySequence
(
tr
(
"Ctrl+N"
)));
newAct.setStatusTip
(
tr
(
"Nouveau fichier"
));
newAct.triggered.connect
(
this
, "newFile()"
);
openAct =
new
QAction
(
new
QIcon
(
rsrcPath +
"/open.png"
), tr
(
"&Ouvrir..."
), this
);
openAct.setShortcut
(
tr
(
"Ctrl+O"
));
openAct.setStatusTip
(
tr
(
"Ouvrir un fichier"
));
openAct.triggered.connect
(
this
, "open()"
);
saveAct =
new
QAction
(
new
QIcon
(
rsrcPath +
"/save.png"
), tr
(
"&Enregistrer..."
), this
);
saveAct.setShortcut
(
tr
(
"Ctrl+S"
));
saveAct.setStatusTip
(
tr
(
"Enregistrer le fichier"
));
saveAct.triggered.connect
(
this
, "save()"
);
saveAsAct =
new
QAction
(
new
QIcon
(
rsrcPath +
"/save_as.png"
), tr
(
"Enregistrer Sous..."
), this
);
saveAsAct.setStatusTip
(
tr
(
"Enregistrer le fichier sous..."
));
saveAsAct.triggered.connect
(
this
, "saveAs()"
);
exitAct =
new
QAction
(
tr
(
"Quitter"
), this
);
exitAct.setStatusTip
(
tr
(
"Quitter l'application"
));
exitAct.triggered.connect
(
QApplication.instance
(
), "quit()"
);
/* Actions du Menu Edition */
cutAct =
new
QAction
(
new
QIcon
(
rsrcPath +
"/cut.png"
), tr
(
"Cou&per"
), this
);
cutAct.setShortcut
(
new
QKeySequence
(
tr
(
"Ctrl+X"
)));
cutAct.setStatusTip
(
tr
(
"Couper la séléction"
));
cutAct.triggered.connect
(
textEdit, "cut()"
);
copyAct =
new
QAction
(
new
QIcon
(
rsrcPath +
"/copy.png"
), tr
(
"&Copier..."
), this
);
copyAct.setShortcut
(
tr
(
"Ctrl+C"
));
copyAct.setStatusTip
(
tr
(
"Copier la séléction"
));
copyAct.triggered.connect
(
textEdit, "copy()"
);
pasteAct =
new
QAction
(
new
QIcon
(
rsrcPath +
"/paste.png"
), tr
(
"Co&ller..."
), this
);
pasteAct.setShortcut
(
tr
(
"Ctrl+V"
));
pasteAct.setStatusTip
(
tr
(
"Coller le texte précédement coupé ou copié"
));
pasteAct.triggered.connect
(
textEdit, "paste()"
);
/* Action du menu Aide */
aboutAct =
new
QAction
(
new
QIcon
(
rsrcPath +
"/about.png"
), tr
(
"A Propos de &JEditor"
), this
);
aboutAct.setStatusTip
(
tr
(
"A Propos de JEditor"
));
aboutAct.triggered.connect
(
this
, "about()"
);
aboutQtAct =
new
QAction
(
new
QIcon
(
rsrcPath +
"/qt.png"
), tr
(
"A Propos de &Qt"
), this
);
aboutQtAct.setStatusTip
(
tr
(
"Show the Qt library's About box"
));
aboutQtAct.triggered.connect
(
QApplication.instance
(
), "aboutQt()"
);
cutAct.setEnabled
(
false
);
copyAct.setEnabled
(
false
);
textEdit.copyAvailable.connect
(
cutAct, "setEnabled(boolean)"
);
textEdit.copyAvailable.connect
(
copyAct, "setEnabled(boolean)"
);
}
/* Création des Menus */
private
void
createMenus
(
)
{
/* Menu fichier */
fileMenu =
menuBar
(
).addMenu
(
tr
(
"&Fichier"
));
fileMenu.addAction
(
newAct);
fileMenu.addAction
(
openAct);
fileMenu.addAction
(
saveAct);
fileMenu.addAction
(
saveAsAct);
fileMenu.addSeparator
(
);
fileMenu.addAction
(
exitAct);
/* Menu Edition */
editMenu =
menuBar
(
).addMenu
(
tr
(
"&Edition"
));
editMenu.addAction
(
cutAct);
editMenu.addAction
(
copyAct);
editMenu.addAction
(
pasteAct);
menuBar
(
).addSeparator
(
);
/* Menu Aide */
helpMenu =
menuBar
(
).addMenu
(
tr
(
"&Aide"
));
helpMenu.addAction
(
aboutAct);
helpMenu.addAction
(
aboutQtAct);
}
/* Création de la barre de menu */
private
void
createToolBars
(
)
{
fileToolBar =
addToolBar
(
tr
(
"Fichier"
));
fileToolBar.addAction
(
newAct);
fileToolBar.addAction
(
openAct);
fileToolBar.addAction
(
saveAct);
editToolBar =
addToolBar
(
tr
(
"Edition"
));
editToolBar.addAction
(
cutAct);
editToolBar.addAction
(
copyAct);
editToolBar.addAction
(
pasteAct);
}
/* Création de la Barre de Status */
private
void
createStatusBar
(
)
{
statusBar
(
).showMessage
(
tr
(
"Prêt"
));
}
/* Teste si le fichier doit être sauvegardé ou non */
private
boolean
maybeSave
(
)
{
if
(
textEdit.document
(
).isModified
(
)) {
QMessageBox.StandardButton ret =
QMessageBox.warning
(
this
, tr
(
"JEditor"
),
tr
(
"Le document a été modifié.
\n
"
+
"Voulez-vous sauvegarder les modifications ?"
),
new
QMessageBox.StandardButtons
(
QMessageBox.StandardButton.Ok,
QMessageBox.StandardButton.Discard,
QMessageBox.StandardButton.Cancel));
if
(
ret ==
QMessageBox.StandardButton.Ok) {
return
save
(
);
}
else
if
(
ret ==
QMessageBox.StandardButton.Cancel) {
return
false
;
}
}
return
true
;
}
/* Charger un fichier */
public
void
loadFile
(
String fileName)
{
QFile file =
new
QFile
(
fileName);
if
(!
file.open
(
new
QFile.OpenMode
(
QFile.OpenModeFlag.ReadOnly, QFile.OpenModeFlag.Text))) {
QMessageBox.warning
(
this
, tr
(
"JEditor"
), String.format
(
tr
(
"Impossible de lire le fichier %1$s:
\n
%2$s."
), fileName, file.errorString
(
)));
return
;
}
QTextStream in =
new
QTextStream
(
file);
QApplication.setOverrideCursor
(
new
QCursor
(
Qt.CursorShape.WaitCursor));
textEdit.setPlainText
(
in.readAll
(
));
QApplication.restoreOverrideCursor
(
);
setCurrentFile
(
fileName);
statusBar
(
).showMessage
(
tr
(
"Fichier Chargé"
), 2000
);
}
/* Sauvegarde du fichier */
public
boolean
saveFile
(
String fileName)
{
QFile file =
new
QFile
(
fileName);
if
(!
file.open
(
new
QFile.OpenMode
(
QFile.OpenModeFlag.WriteOnly, QFile.OpenModeFlag.Text))) {
QMessageBox.warning
(
this
, tr
(
"JEditor"
), String.format
(
tr
(
"Impossible d'écrire dans le fichier %1$s:
\n
%2$s."
), fileName, file.errorString
(
)));
return
false
;
}
QTextStream out =
new
QTextStream
(
file);
QApplication.setOverrideCursor
(
new
QCursor
(
Qt.CursorShape.WaitCursor));
out.writeString
(
textEdit.toPlainText
(
));
QApplication.restoreOverrideCursor
(
);
setCurrentFile
(
fileName);
statusBar
(
).showMessage
(
tr
(
"Fichier sauvegardé"
), 2000
);
file.close
(
);
return
true
;
}
/* On enregistre le nom du fichier ouvert comme nom du fichier courant */
public
void
setCurrentFile
(
String fileName)
{
curFile =
fileName;
textEdit.document
(
).setModified
(
false
);
setWindowModified
(
false
);
String shownName;
if
(
curFile.length
(
) ==
0
)
shownName =
tr
(
"sans_titre.txt"
);
else
shownName =
curFile;
setWindowTitle
(
String.format
(
tr
(
"%1$s[*] - %2$s"
), shownName, tr
(
"JEditor"
)));
}
/* Lancement de l'application */
public
static
void
main
(
String[] args) {
QApplication.initialize
(
args);
JEditor application =
new
JEditor
(
);
application.show
(
);
QApplication.exec
(
);
}
}
III. Remerciements▲
Merci à Thibaut Cuvelier pour la mise en page et à Jacques Thery pour la relecture !