Estou tentando testar um código usando PyQt6. Quando tento exibir uma barra de menu no meu main.qml, recebo este erro:
QQmlApplicationEngine failed to load component
file:///C:/Users/[blablabla]/GUIt/main.qml:11:9: Type Menu unavailable
qrc:/qt-project.org/imports/QtQuick/Controls/Windows/Menu.qml:32:15: Type MenuItem unavailable
qrc:/qt-project.org/imports/QtQuick/Controls/Windows/MenuItem.qml:7:1: Impossible de charger la bibliothÞque C:\Users\[blablabla]\Python\Python313\Lib\site-packages\PyQt6\Qt6\qml\QtQuick\Controls\Windows\impl\qtquickcontrols2windowsstyleimplplugin.dllá: Le module spÚcifiÚ est introuvable.
(Desculpe, sou francês, então meus erros também, mas "Le module spÚcifiÚ est introuvable." significa "O módulo especificado não pôde ser encontrado")
Não consegui encontrar nenhum problema resolvido semelhante ao meu, então tentei a sorte aqui.
Estou no Windows 11 e estou usando Python3.13.3 (não a instalação nativa do Windows)
Aqui está meu código: main.py:
from PyQt6.QtWidgets import QApplication
from PyQt6.QtQml import QQmlApplicationEngine
from backend import Backend
app = QApplication([])
engine = QQmlApplicationEngine()
backend = Backend()
engine.rootContext().setContextProperty("pybackend", backend)
engine.load("main.qml")
if not engine.rootObjects():
import sys
sys.exit(-1)
app.exec()
backend.py:
from PyQt6.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal
from PyQt6.QtWidgets import QFileDialog
from git import Repo
from models.CommitList import CommitListModel
class Backend(QObject):
repoPathChanged = pyqtSignal()
repoNameChanged = pyqtSignal()
commitListChanged = pyqtSignal()
def __init__(self):
super().__init__()
self._commit_list = CommitListModel()
self._repo_path = ""
self.repo = None
self._repo_name = ""
@pyqtProperty(str, notify=repoPathChanged)
def repoPath(self):
return self._repo_path
@pyqtProperty(str, notify=repoNameChanged)
def repoName(self):
return self._repo_name
@pyqtProperty(QObject, notify=commitListChanged)
def commitList(self):
return self._commit_list
@pyqtSlot()
def chooseAndLoadRepo(self):
dialog = QFileDialog()
dialog.setFileMode(QFileDialog.FileMode.Directory)
dialog.setOption(QFileDialog.Option.ShowDirsOnly, True)
if dialog.exec():
selected_dirs = dialog.selectedFiles()
if selected_dirs:
self.loadRepo(selected_dirs[0]) # charge le dossier sélectionné
@pyqtSlot()
def loadRepo(self, path = "C:/Users/lucie/Hesias/B2/MajorProject/major-project-b2"):
try:
self.repo = Repo(path)
self._repo_path = path
self._repo_name = path.split("/")[-1]
self.repoPathChanged.emit()
self.repoNameChanged.emit()
except Exception as e:
print(f"Erreur : {e}")
@pyqtSlot()
def loadCommits(self):
try:
commits = [f"{c.hexsha[:7]}: {c.summary}" for c in self.repo.iter_commits()]
print(commits)
self._commit_list.setCommits(commits)
self.commitListChanged.emit()
except Exception as e:
self._commit_list.setCommits([f"Erreur : {e}"])
modelos/CommitList.py:
from PyQt6.QtCore import QAbstractListModel, Qt, QModelIndex
class CommitListModel(QAbstractListModel):
def __init__(self, commits=None):
super().__init__()
self._commits = commits or []
def data(self, index, role):
if role == Qt.ItemDataRole.DisplayRole and index.isValid():
return self._commits[index.row()]
return None
def rowCount(self, index):
return len(self._commits)
def setCommits(self, commits):
self.beginResetModel()
self._commits = commits
self.endResetModel()
main.qml:
import QtQuick
import QtQuick.Controls
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("GUIt")
MenuBar {
Menu {
title: "Fichier"
Action {
text: "Charger un dépôt"
onTriggered: pybackend.chooseAndLoadRepo()
}
// Tu peux ajouter plus d'actions ici
// Action {
// text: "Autre option"
// onTriggered: { /* action ici */ }
// }
}
// Ajoute un menu "Édition"
Menu {
title: "Édition"
Action {
text: "Option 1"
onTriggered: { /* action ici */ }
}
Action {
text: "Option 2"
onTriggered: { /* action ici */ }
}
}
}
Column {
anchors.centerIn: parent
spacing: 10
Text {
text: pybackend.repoPath !== "" ? "Repo actuel : " + pybackend.repoName : "Aucun dépôt chargé"
font.pixelSize: 20
}
Button {
text: "Charger le dépôt"
// onClicked: pybackend.loadRepo()
onClicked: pybackend.chooseAndLoadRepo()
}
Button {
text: "Charger les commits"
onClicked: pybackend.loadCommits()
enabled: pybackend.repoPath !== ""
}
ListView {
width: parent.width
height: 300
model: pybackend.commitList
delegate: Text {
text: model.display // ou juste `modelData` si le rôle par défaut est utilisé
font.pixelSize: 14
padding: 4
}
}
}
}