Я пытаюсь создать пользовательский интерфейс, используя PyQt5 и Python. Я построил базу, используя main.qml и несколько стилизованных файлов qml в том же каталоге, и она импортировалась нормально, но я решил разбить все по папкам, чтобы было более организовано, но теперь ни один из моих импортов не работает, что бы я ни делал.
Новая файловая структура:
Interface/
│ ├── main.py
│ ├── resources.qrc
│ ├── resources_rc.py
│ │
│ ├── src/
│ │ ├── main.qml
│ │ │
│ │ ├── Components/ # Directory for custom QML components
│ │ │ ├── Sections/ # Directory for "Sections" module
│ │ │ │ ├── Status.qml
├── Title.qml
│ │ │ │ └── qmldir # qmldir file for "Sections" module
│ │ │ │
│ │ │ └── StyledElements/ # Directory for "StyledElements" module
│ │ │ ├── StyledButton.qml
│ │ │ └── qmldir
StyledElements и разделы содержат файл qmldir, который выглядит следующим образом:
module Sections
Status 1.0 Status.qml
Title 1.0 Title.qml
Мой main.py вызывает это так:
import os
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtQml import QQmlApplicationEngine
def handle_warnings(warnings):
for warning in warnings:
print(f"QML Warning: {warning.toString()}")
app = QApplication([])
engine = QQmlApplicationEngine()
engine.warnings.connect(handle_warnings)
# Load QML file
qml_file_path = os.path.abspath('src/main.qml')
print(f"Loading QML file: {qml_file_path}")
engine.load(qml_file_path)
if not engine.rootObjects():
print("Failed to load QML file.")
sys.exit(-1)
else:
print("QML file loaded successfully.")
app.exec_()
sys.exit(app.exec_())
И мой main.qml выглядит так:
import QtQuick 2.15
import QtQuick.Controls 2.15
import StyledElements 1.0
import Sections 1.0
ApplicationWindow {
title: 'Interceptor'
visible: true
width: 700
height: 600
Rectangle {
id: rectangle
width: 700
height: 725
color: 'white'
Section_Title{}
StyledButton{}
}
}
Всегда выдает мне эти ошибки:
QML Warning: module "Sections" is not installed
QML Warning: module "StyledElements" is not installed
QML Warning: module "Sections" is not installed
QML Warning: module "StyledElements" is not installed
Вещи, которые я пробовал:
Я попытался разместить цитату вокруг моего импорта в моем main.qml, например:
import "StyledElements" 1.0
import "Sections" 1.0
Я пробовал настроить пути импорта следующим образом:
# Set the path to the QML files
engine.addImportPath(os.path.abspath("src/Components/Sections"))
engine.addImportPath(os.path.abspath("src/Components/StyledElements"))
# Load QML file
qml_file_path = os.path.abspath('src/main.qml')
engine.load(qml_file_path)
Также попробовал:
engine.addImportPath(os.path.abspath("qrc:/"))
or
engine.addImportPath(os.path.abspath("qrc:/src/main.qml"))
Насколько я могу судить, проблема не связана с загрузкой main.qml, потому что, когда я меняю путь, мне выдается ошибка о том, что он не найден, и, похоже, ошибка возникает из-за импорта в main.qml.
Я попробовал использовать файл ресурсов, который выглядит так:
<RCC>
<qresource prefix = "/">
<file>src/main.qml</file>
<file>src/Components/Sections/NvStatus.qml</file>
<file>src/Components/Sections/qmldir</file>
<file>src/Components/StyledElements/StyledButton.qml</file>
<file>src/Components/StyledElements/qmldir</file>
</qresource>
</RCC>
Я скомпилировал файл ресурсов в Python с помощью
pyrcc5 resources.qrc -o resources_rc.py
и импортировал новый файл py, используя main.py.
import resources_rc
На этом этапе я провел несколько часов в Chat GPT и Google, пытаясь найти ответ. Я пробовал несколько вещей, которые «работают» в том смысле, что они в конце загружают qml, но не могут загрузить пользовательский модуль. Я не знаю, как действовать. Все, что я пробовал, привело меня к одной и той же проблеме: main.qml не смог загрузить модуль с ошибками, показанными выше.
Привет, спасибо за предложение. Я только что попробовал это без /
перед компонентами/разделами, но результат все равно тот же.
Как уже было сказано, вы должны убедиться, что абсолютный путь правильно построен относительно рабочего каталога. Удалить только / явно будет недостаточно, поскольку: 1. он не содержит правильный путь (отсутствует src
); 2. Это может быть неточно в зависимости от cwd. Если вы не знаете, как рабочий каталог влияет на относительные пути, проведите соответствующее исследование, поскольку это весьма важные и обязательные знания в программировании.
Вы правы, там должен быть src
. Я перевернул эту штуку несколько раз, пытаясь найти различные способы устранения неполадок, и, должно быть, я скопировал ее до того, как у меня появилась папка src. Прошу прощения за путаницу и обновил. Я обязательно распечатал cwd, чтобы убедиться, что мои пути верны. Одна вещь, которая выделяется, — это любые изменения, внесенные в addImportPath: engine.addImportPath(os.path.abspath("src/Components/Sections"))
Не вызывают каких-либо видимых изменений с моей стороны. Никаких новых ошибок или чего-то еще, что бы я с этим ни делал.
сначала проверьте текущий рабочий каталог — print( os.getcwd() )
— потому что Python может запустить его в другой папке, а затем относительный путь будет искать файлы в другой папке. Вам нужно использовать __file__
, чтобы получить папку с вашим кодом - например. BASE = os.path.dirname(os.path.abppath(__file__))
, а затем создайте полный путь os.path.join(BASE, 'Components/Sections')
Бившись головой о стену еще несколько часов, я понял:
Большая проблема заключалась в том, как я импортировал свои модули в main.qml. Он хочет, чтобы вы добавили папки/подпапки при импорте следующим образом:
Ранее:
import StyledElements 1.0
import Sections 1.0
Зафиксированный:
import src.Components.StyledElements 1.0
import src.Components.Sections 1.0
После этого было так же просто, как повторно запустить преобразование qrc в скрипт Python с помощью:
pyrcc5 resources.qrc -o resources_rc.py
Информацию нашел здесь: https://doc.qt.io/qt-6/qtqml-modules-identifiedmodules.html
os.path.abspath("/Components/Sections")
кажется совершенно неправильным, поскольку предшествующий/
уже считается абсолютным путем. Путь должен быть реконструирован на основе относительного пути скрипта, используя__file__
в качестве ссылки.