Question: i am trying to test some code using PyQt6. When I try to display en MenuBar in my main.qml, i have this error : 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.  (Sorry i'm french so my errors too, but "Le module spÚcifiÚ est introuvable." means "The specified module could not be found") I could not find any solved issue similar to my problem so i try my luck here. I am on Windows 11, and I am using Python3.13.3 (not the native Windows installation) Here is my code : 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}"])  models/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 } } } } 

Answer: The last version of QtQuick.Controls which supports a natively rendered Windows MenuBar was version 1.4. Unfortunately, for your current code, QtQuick.Controls available with PyQt6 is version 2. In order to use QtQuick.Controls 1.4, you have to use PyQt5. Use PyQt5 instead of PyQt6 in main.py, backend.py, and CommitList.py. Then, in your main.qml file, specify the QtQuick and QtQuick.Controls versions as show in the code below. In the second menu item, I changed "Action" to "MenuItem", because I'm guessing that is what you really intended. The menu bar should be specified as: menuBar: MenuBar {  Also, "padding: 4" is not supported with the above changes. I've marked all of the lines that I changed in main.qml with "// CHANGED". import QtQuick 2.5 // CHANGED import QtQuick.Controls 1.4 // CHANGED ApplicationWindow { visible: true width: 640 height: 480 title: qsTr("GUIt") menuBar: MenuBar { // CHANGED 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" MenuItem { // CHANGED text: "Option 1" onTriggered: { /* action ici */ } } MenuItem { // CHANGED 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 // CHANGED } } } }