ihm avec qt cpp
REMARQUE PREALABLE :
Cette page constitue une série d’exemples utiles pour certains labos de l’ENIB.
Cela ne constitue en aucun cas un tutoriel suffisant pour appréhender toutes les subtilités de Qt.
Les exemples suivants ont été testés pour qt 5 sous ubuntu linux et centos 7.
Ouvrir un projet Qt
Tous les projets de ce chapitre sont disponibles ici :
!! Eviter les chemins trop longs
Pour ouvrir un projet :
- open file or project –> ouvrir le fichier *.pro
- Menu vertical (gauche) : Projects : Modifier si besoin les différents répertoires (compilation et travail)
SI LE PROJET NE S’OUVRE PAS CORRECTEMENT, SUIVRE LA PROCEDURE SUIVANTE :
Configuration kit de Developpement
Si, lors de l’ouverture du projet, il n’est pas possible d’aller plus loin que ‘Configure Project’,
cliquer sur Options ou Manage Kits
Sélectionner le kit Desktop :
Qt Version n’est pas définie.
Au passage, vérifier que les compilateurs C et C++ sont cohérents avec la machine utilisée.
Dans l’onglet Qt Versions, cliquer sur ajouter…
Et aller chercher le fichier /usr/bin/qmake-qt5 ( et non qmake-qt5.sh qui est le choix par défaut ).
Appuyer alors sur Appliquer
Revenir dans l’onglet Kits, Qt version doit être alors défini :
Appuyer sur Appliquer et OK
Il est alors possible de cocher la case Desktop, cliquer sur Configure Project.
Exemples de base
RAPPELS VOCABULAIRE C++
- Classe = Ensemble de Fonctions et de variables / Evolution de la notion de structure en langage C
- Objet = Instance d’une classe
- Méthode = Fonction d’une classe
- Attribut (privé) = Variable d’une classe
CLASSES Qt
widget = élément d’une fenêtre
ex: boutons, case, images, etc ..
une fenêtre est un widget (widget de base)
Un Widget peut en contenir un autre
QApplication : Classe de base, à inclure nécessairement (initialisation et lancement de l’application)
QObject <– | QWidget | <–QAbstractButton | <– QCheckBox |
<– QPushButton | |||
<– QRadioButton | |||
<– QProgressBar | |||
<– QFrame | <– QLabel | ||
<– QLCDNumber |
EX1 : BOUTON
-
Ouvrir QtCreator
-
new project : Other Project –> Empty qmake Project
Donner un nom + emplacement (!! Eviter chemins trop longs) -
new file : C++ –> C++ Source File
main.cpp -
ajouter dans le fichier *.pro :
QT += widgets
clic droit sur nom projet –> Execute qmake -
Compiler : Ctrl+B
-
Exécuter (Run) : Ctrl+R
-
Débugger : Debug –> Start Debugging : F5 (permet de placer des points d’arrêt et d’observer des variables)
REMARQUE: Les erreurs de compilation sont explicitées dans la fenêtre “compile output”
#include <QApplication> // Classes
#include <QPushButton>
int main(int argc, char *argv[])
{
QApplication app(argc, argv); // Création de l'objet app
/* Création de l'objet fenetre (appartient à classe Qwidget) */
QWidget myWindow;
myWindow.setFixedSize(700,150); // Personnalisation de la fenetre
/*Création et personnalisation de l'objet bouton */
QPushButton bouton("bouton", &myWindow); // Parent = fenetre
bouton.setText("texte bouton modifié"); // accesseur *set* de l'attribut texte du bouton
bouton.setFont(QFont("Courier",12));
bouton.setToolTip("un bouton"); // Info bulle
//bouton.move(50,50); // Repositionner le bouton ( Positionnement absolu)
bouton.setGeometry(50,50,500,50); // Abs / Ord / largeur / hauteur
myWindow.show(); // Méthode pour afficher la fenetre
return app.exec();
}
EX2 : AFFICHAGE D’UN MESSAGE (après appui sur un bouton)
Signal = Message envoyé par un widget lorsqu’un événement se produit
Ex : Clic sur un bouton (clicked())
Slot = Fonction appelée lorsqu’un événement s’est produit
Le Signal appelle le Slot
Slot == méthode d’une classe
Ex : Slot quit() (class QApplication) –> arrêt du programme
OBJET 1 | OBJET 2 | |
---|---|---|
Attributs | ||
Méthodes | ||
Signaux | ———> | Slots |
Slots |
#include "mywindow.h"
#include <QApplication>
int main(int argc, char *argv[]) // c'est ici que ça commence
{
QApplication a(argc, argv); // constructeur de l'application
MyWindow w; // Constructeur de la fenetre
w.show(); // Affichage de la fenetre
return a.exec(); // Exécution de l'application
}
#ifndef MYWINDOW_H
#define MYWINDOW_H
#include <QWidget>
#include <QPushButton>
#include <QMessageBox>
class MyWindow : public QWidget // On hérite de QWidget (IMPORTANT)
{
Q_OBJECT // Nécessaire pour créer un slot maison
public:
MyWindow(); // Constructeur (forcément pubic)
public slots: // Slots maison
void Dialogue();
private:
QPushButton *m_bouton; // Attribut (forcément privé)
// pointeur --> il faudra le construire dynamiquement (new)
};
#endif // MYWINDOW_H
#include "mywindow.h"
MyWindow::MyWindow() : QWidget() // spécification du constructeur
{
setFixedSize(300,400); // setFixedSize appartient à classe MaFenetre (héritage de QWidget
// Largeur / Hauteur
/* Construction du bouton */
m_bouton = new QPushButton("open", this); // this = pointeur vers le widget parent, pointeur vers 'moi'
m_bouton->move(100, 100); // RePositionnement Absolu
/* Connexions Signal - Slot */
QObject::connect(m_bouton, SIGNAL(clicked()), this, SLOT(Dialogue())); // this = SLOT de MyWindow (SLOT MAISON)
}
//==========================================================================================
void MyWindow::Dialogue()
{
QMessageBox::information(this, "Titre de la fenêtre", "Hello");
// REM : information / warning / critical / question
// int reponse = QMessageBox::question(this, "Titre de la fenêtre", "vraiment ?", QMessageBox::Yes | QMessageBox::No);
// (OU LOGIQUE)
}
//==========================================================================================
EX3 : RECOPIE D’UN MESSAGE
Application Simple : Fenêtre QWidget suffisant
Application complexe (Multifenêtres, menus, ..) : QMainWindow
Layout = Calque –> Positionnement Relatif des Widgets (à privilégier)
|
|
- new project : Application –> Qt Application with widgets
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QLineEdit>
#include <QPushButton>
#include <QVBoxLayout>
#include <QLineEdit>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void btnClick();
private:
Ui::MainWindow *ui;
QPushButton *m_bouton;
QVBoxLayout *m_layout;
QLineEdit *emetteur;
QLineEdit *recepteur;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)//,
//ui(new Ui::MainWindow)
{
QWidget *zoneCentrale = new QWidget;
setCentralWidget(zoneCentrale); // Définition d'une Fenêtre
// Nécessaire avec mainwindow
m_bouton = new QPushButton("recopie"); // NB : on ne précise pas le parent
emetteur = new QLineEdit();
recepteur = new QLineEdit();
m_layout = new QVBoxLayout(); // REM : existe aussi QHBoxLayout / QGridLayout / QFormLayout
m_layout->addWidget(emetteur);
m_layout->addWidget(m_bouton);
m_layout->addWidget(recepteur);
zoneCentrale->setLayout(m_layout);
connect( m_bouton, SIGNAL(clicked()), this, SLOT(btnClick()));
//*******************************************************
// AFFICHAGE BARRE DE MENUS
//*******************************************************
QMenu *menuFichier = menuBar()->addMenu("&Fichier");
QAction *actionQuitter = new QAction("&Quitter", this);
menuFichier->addAction(actionQuitter);
connect(actionQuitter, SIGNAL(triggered()), qApp, SLOT(quit()));
//ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::btnClick()
{
recepteur->setText(emetteur->text()); // Action de recopie
emetteur->clear();
}
EX3 bis : RECOPIE D’UN MESSAGE AVEC INTERFACE DESIGNER
- new project : Application –> Qt Application with widgets
ouvrir Formulaires -> mainwindow.ui
Placer successivement :
- 1 Vertical Layout
- 1 Line Edit renommé ’emetteur'
- 1 Push Button renommé ‘recopie’
- 1 Line Edit renommé ‘recepteur’
Passer en vue Signal/Slots (taper F4)
Tirer sur le Push Button ‘recopie’
- Sélectionner le signal Clicked()
- Mainwindow -> Editer
- Ajouter un Slot btnClick()
Apporter les modifications suivantes dans le code :
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
/**********A AJOUTER*****************/
public slots:
void btnClick();
/************************************/
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
/**********A AJOUTER*****************/
void MainWindow::btnClick()
{
ui->recepteur->setText(ui->emetteur->text());
ui->emetteur->clear();
}
/************************************/
EX4 : CHRONOMETRE ( Utilisation d’un Timer)
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
#include <QGridLayout>
#include <QLCDNumber>
#include <QTimer>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void resetCount();
void updateCount();
public slots:
void onTimer_Tick();
void onButton_Start();
void onButton_Reset();
private:
Ui::MainWindow *ui;
QPushButton *m_bout_start;
QPushButton *m_bout_stop;
QPushButton *m_bout_reset;
QGridLayout *m_layout;
QLCDNumber *m_lcd;
QTimer *timer_chrono;
int countTimer;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
QWidget *zoneCentrale = new QWidget;
setCentralWidget(zoneCentrale); // Définition d'une Fenêtre
//---------------------------------------------------------------------
m_bout_start = new QPushButton("start"); // Liste des Widgets
m_bout_reset = new QPushButton("reset");
m_bout_stop = new QPushButton("stop");
m_lcd = new QLCDNumber();
//---------------------------------------------------------------------
m_layout = new QGridLayout(); // Création du calque
m_layout->addWidget(m_bout_start,0,0);
m_layout->addWidget(m_bout_stop,1,0);
m_layout->addWidget(m_lcd,0,1);
m_layout->addWidget(m_bout_reset,1,1);
zoneCentrale->setLayout(m_layout);
//---------------------------------------------------------------------
timer_chrono = new QTimer(); // Création du Compteur
resetCount(); // MAZ variable de comptage
//---------------------------------------------------------------------
connect( m_bout_start, SIGNAL(clicked()), this, SLOT(onButton_Start()));
connect( timer_chrono, SIGNAL(timeout()), this, SLOT(onTimer_Tick()));
connect( m_bout_stop, SIGNAL(clicked()), timer_chrono, SLOT(stop()));
connect( m_bout_reset, SIGNAL(clicked()), this, SLOT(onButton_Reset()));
//---------------------------------------------------------------------
// AFFICHAGE BARRE DE MENUS
//---------------------------------------------------------------------
QMenu *menuFichier = menuBar()->addMenu("&Fichier");
QAction *actionQuitter = new QAction("&Quitter", this);
menuFichier->addAction(actionQuitter);
connect(actionQuitter, SIGNAL(triggered()), qApp, SLOT(quit()));
// ui->setupUi(this);
}
//=========================================================================
void MainWindow::resetCount()
{
countTimer=0;
}
//=========================================================================
void MainWindow::updateCount()
{
countTimer++;
}
//=========================================================================
void MainWindow::onButton_Start()
{
timer_chrono -> start(1000); // 1000 ms
}
//=========================================================================
void MainWindow::onButton_Reset()
{
resetCount();
m_lcd -> display(countTimer);
}
//=========================================================================
void MainWindow::onTimer_Tick()
{
updateCount();
m_lcd -> display(countTimer);
}
//=========================================================================
MainWindow::~MainWindow()
{
delete ui;
}
//=========================================================================
Qt et Liaison Série UART (RS232)
Sur vos PCs persos : Port série et utilisateur
par défaut il faut être en root pour utiliser le port série
Taper
sudo usermod -a -G dialout [MYUSERNAME]
puis redémarrer le PC
Pour vérifier le nom du port série
- Ouvrir gtkterm
- Configuration –> Port
!!! Un seul programme peut utiliser un port série
Exemple de Programme UART
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtSerialPort/QSerialPort>
#include <QString>
#include <QMessageBox>
#include <QDebug>
#include <QLineEdit>
#include <QPushButton>
#include <QVBoxLayout>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void openSerialPort();
void onButSendClicked();
void writeData(const QByteArray &);
void readData();
private:
QSerialPort *serial;
Ui::MainWindow *ui;
QVBoxLayout *m_layout;
QPushButton *but_send;
QLineEdit *mes_to_send;
QLineEdit *mes_received;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
QString nameport = "/dev/ttyACM0";
//=================================================================================
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
QWidget *zoneCentrale = new QWidget;
setCentralWidget(zoneCentrale); // Définition d'une Fenêtre
// Nécessaire avec mainwindow
QLabel *label_to_send = new QLabel;
label_to_send->setText("Message à Envoyer");
QLabel *label_received = new QLabel;
label_received->setText("Message reçu");
but_send = new QPushButton("Send Message"); // NB : on ne précise pas le parent
mes_to_send = new QLineEdit();
mes_received = new QLineEdit();
m_layout = new QVBoxLayout();
m_layout->addWidget(label_to_send);
m_layout->addWidget(mes_to_send);
m_layout->addWidget(but_send);
m_layout->addWidget(label_received);
m_layout->addWidget(mes_received);
zoneCentrale->setLayout(m_layout);
openSerialPort();
connect(serial,SIGNAL(readyRead()),this,SLOT(readData()));
connect(but_send,SIGNAL(clicked()),this,SLOT(onButSendClicked()));
// ui->setupUi(this);
}
//=================================================================================
MainWindow::~MainWindow()
{
delete ui;
}
//=================================================================================
void MainWindow::openSerialPort()
{
serial = new QSerialPort(this);
serial->setPortName(nameport);
serial->open(QIODevice::ReadWrite);
if( serial->isOpen()==false)
{
serial->clearError();
QMessageBox::critical(this, "Port error", "Port: "+nameport);
QMessageBox::information(this, "Port error", "Vérifier nom du port \n Fermer tout programme utilisant la lisaison RS232 "+nameport);
}
else
{
QMessageBox::information(this, "Port open", " "+nameport);
serial->setBaudRate(QSerialPort::Baud115200);
serial->setStopBits(QSerialPort::OneStop);
serial->setParity(QSerialPort::NoParity);
serial->setDataBits(QSerialPort::Data8);
serial->setFlowControl(QSerialPort::NoFlowControl);
}
}
//====================================================
void MainWindow::onButSendClicked()
{
QString message=mes_to_send->text();
writeData(message.toUtf8()); // QString --> QByteArray
}
//====================================================
void MainWindow::writeData(const QByteArray &data)
{
serial->write(data);
}
//====================================================
void MainWindow::readData()
{
QByteArray data = serial->readAll();
mes_received->setText(data);
}
//====================================================
Qt et BUS CAN (Sonde Peak PCAN-USB)
Programmes utilitaires pour la sonde Peak PCAN( dans un terminal )_
!! débit par défaut 500kb/s
Une fois la sonde pcan-usb branchée, taper dans un terminal :
$ ip_set_can
( REMARQUE : cela lance la commande $ sudo ip link set can0 up type can bitrate 500000 )
La sonde pcan-usb est alors vue comme une interface réseau avec le nom can0 .
$ifconfig
can0: flags=193<UP,RUNNING,NOARP> mtu 16
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 10 (UNSPEC)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Pour observer la réception des trames :
$ cansniffer can0
ou
$ candump can0
Pour envoyer une trame ( identifiant 0x005, donnée 0x1122334455667788 ) :
$ cansend can0 005#1122334455667788
Programme Qt et Bus CAN
Exemple de Programme QT BUS CAN
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtCore>
#include <QDebug>
#include <QString>
#include <QMessageBox>
#include <QDebug>
#include <QLineEdit>
#include <QPushButton>
#include <QGridLayout>
#include <QLabel>
#include <QTimer>
#include "socketcan_cpp.h"
#include <fcntl.h> // O_RDWR
#include <signal.h>
#include <unistd.h> // exit
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void openCANPort();
void sendCANMessage();
void receiveCANMessage();
public slots:
void onButSendClicked();
void onTimer_Tick();
private:
scpp::SocketCan socket_can;
Ui::MainWindow *ui;
QGridLayout *m_layout;
QPushButton *but_send;
QLineEdit *receive_box_0,*receive_box_1,*receive_box_2,*receive_box_3 ;
QLineEdit *receive_box_4,*receive_box_5,*receive_box_6,*receive_box_7 ;
QLineEdit *send_box_0, *send_box_1,*send_box_2,*send_box_3;
QLineEdit *send_box_4, *send_box_5,*send_box_6,*send_box_7;
QTimer *timer_tick;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
//===============================================================
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
QWidget *zoneCentrale = new QWidget;
setCentralWidget(zoneCentrale);
but_send = new QPushButton("Send Message");
m_layout = new QGridLayout();
QLabel *label_to_send = new QLabel;
label_to_send->setText("Message to Send");
QLabel *label_received = new QLabel;
label_received->setText("Message Received");
send_box_0 = new QLineEdit();
send_box_1 = new QLineEdit();
send_box_2 = new QLineEdit();
send_box_3 = new QLineEdit();
send_box_4 = new QLineEdit();
send_box_5 = new QLineEdit();
send_box_6 = new QLineEdit();
send_box_7 = new QLineEdit();
receive_box_0 = new QLineEdit();
receive_box_1 = new QLineEdit();
receive_box_2 = new QLineEdit();
receive_box_3 = new QLineEdit();
receive_box_4 = new QLineEdit();
receive_box_5 = new QLineEdit();
receive_box_6 = new QLineEdit();
receive_box_7 = new QLineEdit();
m_layout->addWidget(label_to_send,0,1);
m_layout->addWidget(but_send,1,0);
m_layout->addWidget(send_box_7,1,1);
m_layout->addWidget(send_box_6,1,2);
m_layout->addWidget(send_box_5,1,3);
m_layout->addWidget(send_box_4,1,4);
m_layout->addWidget(send_box_3,1,5);
m_layout->addWidget(send_box_2,1,6);
m_layout->addWidget(send_box_1,1,7);
m_layout->addWidget(send_box_0,1,8);
m_layout->addWidget(label_received,2,1);
m_layout->addWidget(receive_box_7,3,1);
m_layout->addWidget(receive_box_6,3,2);
m_layout->addWidget(receive_box_5,3,3);
m_layout->addWidget(receive_box_4,3,4);
m_layout->addWidget(receive_box_3,3,5);
m_layout->addWidget(receive_box_2,3,6);
m_layout->addWidget(receive_box_1,3,7);
m_layout->addWidget(receive_box_0,3,8);
zoneCentrale->setLayout(m_layout);
openCANPort();
timer_tick = new QTimer();
connect( timer_tick, SIGNAL(timeout()), this, SLOT(onTimer_Tick()));
connect(but_send,SIGNAL(clicked()),this,SLOT(onButSendClicked()));
timer_tick -> start(1); // in ms
}
//===============================================================
MainWindow::~MainWindow()
{
delete ui;
}
//===============================================================
void MainWindow::openCANPort()
{
if (socket_can.open("can0") == scpp::STATUS_OK)
{
printf("can socket opened");
}
else
{
printf("Cannot open can socket!");
}
}
//===============================================================
void MainWindow::onButSendClicked()
{
sendCANMessage();
}
//===============================================================
void MainWindow::sendCANMessage()
{
scpp::CanFrame frame_to_write;
frame_to_write.id = 0x4;
frame_to_write.len = 8;
frame_to_write.data[0] = send_box_0->text().toInt();
frame_to_write.data[1] = send_box_1->text().toInt();
frame_to_write.data[2] = send_box_2->text().toInt();
frame_to_write.data[3] = send_box_3->text().toInt();
frame_to_write.data[4] = send_box_4->text().toInt();
frame_to_write.data[5] = send_box_5->text().toInt();
frame_to_write.data[6] = send_box_6->text().toInt();
frame_to_write.data[7] = send_box_7->text().toInt();
socket_can.write(frame_to_write);
}
//===============================================================
void MainWindow::receiveCANMessage()
{
scpp::CanFrame fr;
if(socket_can.read(fr) == scpp::STATUS_OK)
{
receive_box_0->setText(QString::number((uint)fr.data[0]));
receive_box_1->setText(QString::number((uint)fr.data[1]));
receive_box_2->setText(QString::number((uint)fr.data[2]));
receive_box_3->setText(QString::number((uint)fr.data[3]));
receive_box_4->setText(QString::number((uint)fr.data[4]));
receive_box_5->setText(QString::number((uint)fr.data[5]));
receive_box_6->setText(QString::number((uint)fr.data[6]));
receive_box_7->setText(QString::number((uint)fr.data[7]));
}
}
//===============================================================
void MainWindow::onTimer_Tick()
{
receiveCANMessage();
}
Qt et OpenGL (dessin 3D)
Installation
Pour Ubuntu :
$ sudo apt-get install freeglut3 freeglut3-dev
Exemple de Programme QT OpenGL
#include <QtWidgets/QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w(0,800,600);
w.show();
return a.exec();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <iostream>
#include <QtWidgets/QMainWindow>
#include <qgridlayout.h>
#include <objectgl.h>
#include <QMenuBar>
#include <QMessageBox>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
// Constructor and destructor
MainWindow(QWidget *parent = 0, int w=600, int h=400);
~MainWindow();
bool connect();
protected slots:
// Redraw the scene
void onTimer_UpdateDisplay();
protected:
// Overload of the resize event
void resizeEvent(QResizeEvent *);
private:
// Layout of the window
QGridLayout *gridLayout;
QWidget *gridLayoutWidget;
// Central widget (where the openGL window is drawn)
QWidget *centralWidget;
// OpenGL object
ObjectOpenGL *Object_GL;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
//=============================================================================================
// Constructor of the main window
// Create window properties, menu etc ...
//=============================================================================================
MainWindow::MainWindow(QWidget *parent,int w, int h)
: QMainWindow(parent)
{
// Set the window size
this->resize(w,h);
this->setWindowTitle("Object viewer");
// Create a layout in the main window
centralWidget = new QWidget(this);
gridLayoutWidget = new QWidget(centralWidget);
gridLayoutWidget->setGeometry(QRect(0, 0, this->width(), this->height()));
gridLayout = new QGridLayout(gridLayoutWidget);
// Create the openGL display for the map
Object_GL = new ObjectOpenGL(gridLayoutWidget);
Object_GL->setObjectName(QString::fromUtf8("ObjectOpenGL"));
Object_GL->setGeometry(QRect(0, 0, this->width(), this->height()));
// Insert the Open Gl display into the layout
gridLayout->addWidget(Object_GL, 0, 0, 1, 1);
setCentralWidget(centralWidget);
// Create the menubar
QMenu *FileMenu = menuBar()->addMenu("&File");
FileMenu->addSeparator();
FileMenu->addAction("Quit", qApp, SLOT (quit()), QKeySequence(tr("Ctrl+Q")));
// Add menu items
QMenu *ViewMenu = menuBar()->addMenu("&View");
ViewMenu->addAction("Front view", Object_GL, SLOT (FrontView()), QKeySequence(tr("Ctrl+f")));
ViewMenu->addAction("Rear view", Object_GL, SLOT (RearView()), QKeySequence(tr("Ctrl+e")));
ViewMenu->addAction("Left view", Object_GL, SLOT (LeftView()), QKeySequence(tr("Ctrl+l")));
ViewMenu->addAction("Right view", Object_GL, SLOT (RightView()), QKeySequence(tr("Ctrl+r")));
ViewMenu->addAction("Top view", Object_GL, SLOT (TopView()), QKeySequence(tr("Ctrl+t")));
ViewMenu->addAction("Bottom view", Object_GL, SLOT (BottomView()), QKeySequence(tr("Ctrl+b")));
FileMenu->addSeparator();
ViewMenu->addAction("Isometric", Object_GL, SLOT (IsometricView()), QKeySequence(tr("Ctrl+i")));
// Timer (used for repainting the GL Window every 50 ms)
QTimer *timerDisplay = new QTimer();
timerDisplay->connect(timerDisplay, SIGNAL(timeout()),this, SLOT(onTimer_UpdateDisplay()));
timerDisplay->start(50);
}
//=============================================================================================
MainWindow::~MainWindow()
{}
//=============================================================================================
// On resize event, the items in the window are resized
//=============================================================================================
void MainWindow::resizeEvent(QResizeEvent *)
{
Object_GL->resize(centralWidget->width(),centralWidget->height());
gridLayoutWidget->setGeometry(QRect(0, 0, centralWidget->width(), centralWidget->height()));
}
//=============================================================================================
// Timer event : repain the Open Gl window
//=============================================================================================
void MainWindow::onTimer_UpdateDisplay()
{
Object_GL->updateGL();
}
//=============================================================================================
L’orientation de l’objet se fait avec les angles d’euler phi, theta, psi.
Exemple de mise à jour des angles d’Euler :
!!! phi, theta, psi en degrés, dans l’intervalle [0° 360°[
Object_GL->setAngles(phi , theta , psi );