Construire des interfaces modernes et professionnelles avec PyQt
Les interfaces PyQt utilisent des layouts pour organiser automatiquement les widgets dans la fenĂȘtre. En complĂ©ment, les feuilles de style (setStyleSheet) sont essentielles pour amĂ©liorer lâapparence visuelle et rendre lâinterface plus moderne, professionnelle et adaptĂ©e aux applications de type dashboard.
Organisation horizontale des widgets.
# Importer les widgets nécessaires
from PyQt5.QtWidgets import (
QWidget,
QPushButton,
QHBoxLayout
)
# CrĂ©er une fenĂȘtre
window = QWidget()
# Créer un layout horizontal
layout = QHBoxLayout()
# Créer un bouton Start
buttonStart = QPushButton("Start")
# Créer un bouton Stop
buttonStop = QPushButton("Stop")
# Ajouter le bouton Start dans le layout
layout.addWidget(buttonStart)
# Ajouter le bouton Stop dans le layout
layout.addWidget(buttonStop)
# Appliquer le layout Ă la fenĂȘtre
window.setLayout(layout)
Empilement vertical des widgets.
# Importer les widgets nécessaires
from PyQt5.QtWidgets import (
QWidget,
QLabel,
QVBoxLayout
)
# Importer le widget graphique
from pyqtgraph import PlotWidget
# CrĂ©er une fenĂȘtre
window = QWidget()
# Créer un layout vertical
layout = QVBoxLayout()
# Créer un titre
title = QLabel("Capteurs")
# Créer un graphique
graph = PlotWidget()
# Ajouter le titre
layout.addWidget(title)
# Ajouter le graphique
layout.addWidget(graph)
# DĂ©finir le layout dans la fenĂȘtre
window.setLayout(layout)
Placement des widgets sous forme de grille.
from PyQt5.QtWidgets import (
QWidget,
QLabel,
QLineEdit,
QGridLayout
)
# CrĂ©er une fenĂȘtre principale
window = QWidget()
# Créer un layout en grille
grid = QGridLayout()
# ----------------------------
# Ligne 0 : Nom
# ----------------------------
# Créer le label "Nom"
nameLabel = QLabel("Nom")
# Créer le champ de saisie
nameEdit = QLineEdit()
# Ajouter le label Ă la ligne 0, colonne 0
grid.addWidget(nameLabel, 0, 0)
# Ajouter le champ de saisie Ă la ligne 0, colonne 1
# Il s'étend sur 2 colonnes
grid.addWidget(nameEdit, 0, 1, 1, 2)
# ----------------------------
# Ligne 1 : Age
# ----------------------------
# Créer le label "Age"
ageLabel = QLabel("Age")
# Créer le champ de saisie pour l'ùge
ageEdit = QLineEdit()
# Ajouter le label Ă la ligne 1, colonne 0
grid.addWidget(ageLabel, 1, 0)
# Ajouter le champ de saisie Ă la ligne 1, colonne 1
grid.addWidget(ageEdit, 1, 1)
# ----------------------------
# Ligne 2 : Commentaire (exemple spanning)
# ----------------------------
# Créer le label "Commentaire"
commentLabel = QLabel("Commentaire")
# Créer un champ de saisie pour le commentaire
commentEdit = QLineEdit()
# Ajouter le label Ă la ligne 2, colonne 0
grid.addWidget(commentLabel, 2, 0)
# Ajouter le champ de saisie sur 2 colonnes
grid.addWidget(commentEdit, 2, 1, 1, 2)
# Appliquer le layout Ă la fenĂȘtre
window.setLayout(grid)
Ajouter un espace flexible dans un layout.
# Importer les widgets nécessaires
from PyQt5.QtWidgets import (
QWidget,
QPushButton,
QHBoxLayout
)
# CrĂ©er une fenĂȘtre
window = QWidget()
# Créer un layout horizontal
layout = QHBoxLayout()
# Créer le bouton gauche
button1 = QPushButton("Gauche")
# Créer le bouton droite
button2 = QPushButton("Droite")
# Ajouter le premier bouton
layout.addWidget(button1)
# Ajouter un espace extensible
layout.addStretch()
# Ajouter le deuxiĂšme bouton
layout.addWidget(button2)
# Appliquer le layout Ă la fenĂȘtre
window.setLayout(layout)
ContrĂŽle la taille relative des widgets.
# Importer les widgets nécessaires
from PyQt5.QtWidgets import (
QWidget,
QHBoxLayout
)
# CrĂ©er une fenĂȘtre
window = QWidget()
# Créer un layout horizontal
layout = QHBoxLayout()
# Créer un panneau gauche
leftPanel = QWidget()
# Créer un panneau graphique
graphPanel = QWidget()
# Ajouter le panneau gauche
# avec un facteur de taille 1
layout.addWidget(leftPanel, 1)
# Ajouter le panneau graphique
# avec un facteur de taille 3
layout.addWidget(graphPanel, 3)
# Le panneau graphique prendra
# plus de place dans la fenĂȘtre
# Appliquer le layout Ă la fenĂȘtre
window.setLayout(layout)
Boutons dâaction utilisateur.
# Importer les widgets nécessaires
from PyQt5.QtWidgets import (
QWidget,
QPushButton,
QHBoxLayout
)
# CrĂ©er une fenĂȘtre
window = QWidget()
# Créer un layout horizontal
layout = QHBoxLayout()
# Créer le bouton Start
startButton = QPushButton("Start")
# Créer le bouton Stop
stopButton = QPushButton("Stop")
# Ajouter les boutons dans le layout
layout.addWidget(startButton)
layout.addWidget(stopButton)
# Listener : action lors du clic sur Start
def startAcquisition():
print("Acquisition démarrée")
# Listener : action lors du clic sur Stop
def stopAcquisition():
print("Acquisition arrĂȘtĂ©e")
# Connexion des signaux (listeners)
startButton.clicked.connect(startAcquisition)
stopButton.clicked.connect(stopAcquisition)
# Appliquer le layout Ă la fenĂȘtre
window.setLayout(layout)
Affichage des informations texte.
# Importer les widgets nécessaires
from PyQt5.QtWidgets import (
QWidget,
QLabel,
QVBoxLayout
)
# Importer le timer Qt
from PyQt5.QtCore import QTimer
# CrĂ©er une fenĂȘtre
window = QWidget()
# Créer un layout vertical
layout = QVBoxLayout()
# Créer un label titre
title = QLabel("Température")
# Créer un label valeur
value = QLabel("25 °C")
# Ajouter les labels dans le layout
layout.addWidget(title)
layout.addWidget(value)
# Listener simulé (mise à jour dynamique)
def updateValue():
value.setText("26 °C")
# Exemple : appel périodique (listener externe type timer)
# QTimer.singleShot(1000, updateValue)
# Appliquer le layout Ă la fenĂȘtre
window.setLayout(layout)
Liste déroulante de sélection.
# Importer les widgets nécessaires
from PyQt5.QtWidgets import (
QWidget,
QComboBox,
QHBoxLayout
)
# CrĂ©er une fenĂȘtre
window = QWidget()
# Créer un layout horizontal
layout = QHBoxLayout()
# Créer une liste déroulante
combo = QComboBox()
# Ajouter des éléments
combo.addItems([
"Capteur 1",
"Capteur 2",
"Capteur 3"
])
# Ajouter la liste dans le layout
layout.addWidget(combo)
# Listener : changement de sélection
def onSensorChanged(index):
print("Capteur sélectionné :", combo.currentText())
# Connexion du signal
combo.currentIndexChanged.connect(onSensorChanged)
# Appliquer le layout Ă la fenĂȘtre
window.setLayout(layout)
Affichage dâune progression.
# Importer les widgets nécessaires
from PyQt5.QtWidgets import (
QWidget,
QVBoxLayout,
QProgressBar
)
# Importer le timer Qt
from PyQt5.QtCore import QTimer
# CrĂ©er une fenĂȘtre
window = QWidget()
# Créer un layout vertical
layout = QVBoxLayout()
# Créer une barre de progression
progress = QProgressBar()
# Définir la valeur initiale
progress.setValue(70)
# Ajouter la barre dans le layout
layout.addWidget(progress)
# Listener simulé (mise à jour)
def updateProgress():
progress.setValue(90)
# Exemple de déclenchement (timer ou event)
# QTimer.singleShot(2000, updateProgress)
# Appliquer le layout Ă la fenĂȘtre
window.setLayout(layout)
Gestion de plusieurs pages.
# Importer les widgets nécessaires
from PyQt5.QtWidgets import (
QWidget,
QTabWidget
)
# CrĂ©er une fenĂȘtre
window = QWidget()
# Créer un systÚme d'onglets
tabs = QTabWidget()
# Créer les pages
graphPage = QWidget()
configPage = QWidget()
logPage = QWidget()
# Ajouter les pages
tabs.addTab(graphPage, "Graphiques")
tabs.addTab(configPage, "Configuration")
tabs.addTab(logPage, "Logs")
# Listener : changement dâonglet
def onTabChanged(index):
print("Onglet changé :", index)
# Connexion du signal
tabs.currentChanged.connect(onTabChanged)
# Appliquer le widget principal Ă la fenĂȘtre
window.setLayout(tabs.layout() if tabs.layout() else None)
Regroupement logique des widgets.
# Importer les widgets nécessaires
from PyQt5.QtWidgets import (
QWidget,
QGroupBox,
QVBoxLayout
)
# CrĂ©er une fenĂȘtre
window = QWidget()
# Créer un groupe de widgets
group = QGroupBox("Capteurs")
# Créer un layout vertical
layout = QVBoxLayout()
# Exemple de widgets capteurs (doivent exister)
sensor1 = QPushButton("Capteur 1")
sensor2 = QPushButton("Capteur 2")
# Ajouter des widgets
layout.addWidget(sensor1)
layout.addWidget(sensor2)
# Appliquer le layout au groupe
group.setLayout(layout)
# Listener sur capteur (exemple bouton interne)
def onSensorAction():
print("Action sur capteur")
sensor1.clicked.connect(onSensorAction)
Permet de sélectionner une valeur en glissant un curseur.
# Importer les widgets nécessaires
from PyQt5.QtWidgets import (
QWidget,
QVBoxLayout,
QSlider
)
# Importer les constantes Qt
from PyQt5.QtCore import Qt
# CrĂ©er une fenĂȘtre
window = QWidget()
# Créer un layout vertical
layout = QVBoxLayout()
# Créer un slider horizontal
slider = QSlider(Qt.Horizontal)
# Définir la valeur minimale du slider
slider.setMinimum(0)
# Définir la valeur maximale du slider
slider.setMaximum(100)
# Ajouter le slider dans le layout
layout.addWidget(slider)
# Listener : déclenché quand la valeur change
def onSliderChanged(value):
# Afficher la valeur sélectionnée
print("Valeur du slider :", value)
# Connexion du signal (listener)
slider.valueChanged.connect(onSliderChanged)
# Appliquer le layout Ă la fenĂȘtre
window.setLayout(layout)
Champ de saisie texte avec interaction utilisateur.
# Importer les widgets nécessaires
from PyQt5.QtWidgets import (
QWidget,
QVBoxLayout,
QLineEdit
)
# CrĂ©er une fenĂȘtre
window = QWidget()
# Créer un layout vertical
layout = QVBoxLayout()
# Créer un champ de texte
edit = QLineEdit()
# Ajouter un placeholder
edit.setPlaceholderText("Entrer une valeur")
# Ajouter le champ texte dans le layout
layout.addWidget(edit)
# Listener : déclenché quand le texte change
def onTextChanged(text):
# Afficher la valeur saisie
print("Texte saisi :", text)
# Connexion du signal (listener)
edit.textChanged.connect(onTextChanged)
# Appliquer le layout Ă la fenĂȘtre
window.setLayout(layout)
Bouton compact avec icĂŽne.
# Importer les widgets nécessaires
from PyQt5.QtWidgets import (
QWidget,
QHBoxLayout,
QToolButton
)
# Importer les classes GUI
from PyQt5.QtGui import QIcon
# Importer les constantes Qt
from PyQt5.QtCore import QSize
# CrĂ©er une fenĂȘtre
window = QWidget()
# Créer un layout horizontal
layout = QHBoxLayout()
# Créer un bouton outil
toolButton = QToolButton()
# Définir une icÎne pour le bouton
toolButton.setIcon(QIcon("icon_play.png"))
# Définir la taille de l'icÎne
toolButton.setIconSize(QSize(32, 32))
# Ajouter le bouton dans le layout
layout.addWidget(toolButton)
# Listener : action lors du clic
def onToolButtonClicked():
# Action exécutée lors du clic
print("ToolButton cliqué")
# Connexion du signal (listener)
toolButton.clicked.connect(onToolButtonClicked)
# Appliquer le layout Ă la fenĂȘtre
window.setLayout(layout)
PyQt permet de personnaliser complĂštement lâapparence des widgets grĂące au systĂšme de feuilles de style appelĂ© Qt StyleSheet.
Personnalisation complĂšte dâun bouton.
# Importer les widgets nécessaires
from PyQt5.QtWidgets import QPushButton
# Créer un bouton
button = QPushButton("Start")
# Ajouter un style CSS
button.setStyleSheet("""
QPushButton{
background-color:#22c55e;
color:white;
border:none;
padding:10px;
border-radius:8px;
font-size:14px;
}
QPushButton:hover{
background-color:#16a34a;
}
""")
Style transparent pour boutons icĂŽne (effet dashboard moderne).
# Importer les widgets nécessaires
from PyQt5.QtWidgets import QToolButton
# Importer les classes GUI
from PyQt5.QtGui import QIcon
# Importer les constantes Qt
from PyQt5.QtCore import QSize
# CrĂ©er une fenĂȘtre
window = QWidget()
# Créer un bouton outil
toolButton = QToolButton()
# Définir une icÎne
toolButton.setIcon(QIcon("icon_play.png"))
# DĂ©finir la taille de lâicĂŽne
toolButton.setIconSize(QSize(32, 32))
# Ajouter un style transparent moderne
toolButton.setStyleSheet("""
QToolButton{
background-color:transparent;
border:none;
padding:8px;
}
QToolButton:hover{
background-color:rgba(56,189,248,0.15);
border-radius:8px;
}
QToolButton:pressed{
background-color:rgba(56,189,248,0.25);
}
""")
Style moderne pour panneaux professionnels.
# Importer les widgets nécessaires
from PyQt5.QtWidgets import QGroupBox
# CrĂ©er une fenĂȘtre
window = QWidget()
# Créer un groupe
group = QGroupBox("Capteurs")
# Appliquer un thĂšme sombre
group.setStyleSheet("""
QGroupBox{
background-color:#111a33;
border:1px solid #334155;
border-radius:12px;
margin-top:10px;
padding:15px;
color:white;
font-weight:bold;
}
QGroupBox::title{
subcontrol-origin:margin;
left:15px;
padding:0 5px;
}
""")
Champ texte avec style sombre moderne.
# Importer les widgets nécessaires
from PyQt5.QtWidgets import QLineEdit
# CrĂ©er une fenĂȘtre
window = QWidget()
# Créer un champ texte
edit = QLineEdit()
# Ajouter un placeholder
edit.setPlaceholderText("Entrer une valeur")
# Appliquer le style
edit.setStyleSheet("""
QLineEdit{
background-color:#0f172a;
border:1px solid #334155;
border-radius:8px;
padding:8px;
color:white;
}
QLineEdit:focus{
border:1px solid #38bdf8;
}
""")
Style moderne pour liste déroulante.
# Importer les widgets nécessaires
from PyQt5.QtWidgets import QComboBox
# CrĂ©er une fenĂȘtre
window = QWidget()
# Créer une liste déroulante
combo = QComboBox()
# Ajouter des éléments
combo.addItems([
"Capteur 1",
"Capteur 2"
])
# Ajouter le style
combo.setStyleSheet("""
QComboBox{
background-color:#111827;
border:1px solid #334155;
border-radius:8px;
padding:8px;
color:white;
}
QComboBox::drop-down{
border:none;
}
""")
Style appliquĂ© Ă toute lâapplication.
# Importer QApplication nécessaire pour le thÚme global
from PyQt5.QtWidgets import QApplication
# Importer sys pour lancer l'application
import sys
# Créer l'application Qt
app = QApplication(sys.argv)
# Appliquer un thĂšme global
app.setStyleSheet("""
QWidget{
background-color:#0f172a;
color:white;
font-size:13px;
}
QPushButton{
background-color:#2563eb;
border:none;
padding:8px;
border-radius:8px;
}
QPushButton:hover{
background-color:#1d4ed8;
}
""")
Exemple complet dâinterface dashboard moderne.
# Importer les widgets nécessaires
from PyQt5.QtWidgets import QWidget
# CrĂ©er une fenĂȘtre
window = QWidget()
# Créer un panneau principal
panel = QWidget()
# Ajouter un thĂšme dashboard
panel.setStyleSheet("""
QWidget{
background-color:#111827;
}
QLabel{
color:#e2e8f0;
font-size:14px;
}
QPushButton{
background-color:#22c55e;
color:black;
border:none;
padding:10px;
border-radius:10px;
font-weight:bold;
}
QPushButton:hover{
background-color:#16a34a;
}
QGroupBox{
border:1px solid #334155;
border-radius:12px;
margin-top:10px;
padding:15px;
}
""")