优先采纳真人回答!
这是一个Qt Quick(安卓)应用程序,使用QML和C++开发,部署到真机后出现了多个显示问题及报错,希望大家可以帮我解决!
理想效果:
(1) 侧边栏打开前

(2) 侧边栏打开后

代码:
main.qml
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Window {
function pt(_pt) {
var ppi = Qt.application.primaryScreen.pixelDensity * 25.4;
const scaleFactor = 2;
return _pt * (ppi / 72) * scaleFactor;
}
visible: true
visibility: Window.FullScreen
Rectangle {
id: drawer
width: parent.width * 0.7
height: parent.height
z: 2
property bool isOpened: !touchArea.isMoving && x === 0
Component.onCompleted: {
x = -width
}
gradient: Gradient {
GradientStop { position: 0.0; color: "#CCFFE6" }
GradientStop { position: 1.0; color: "#FFCCCC" }
}
NumberAnimation {
id: drawerOpen
target: drawer
property: "x"
to: 0
duration: Math.abs(drawer.x / parent.width * 0.2)
// 根据初始位置计算动画时长
}
NumberAnimation {
id: drawerClose
target: drawer
property: "x"
to: -width
duration: Math.abs(drawer.x / parent.width * 0.2)
}
}
MultiPointTouchArea {
id: touchArea
anchors.fill: parent
maximumTouchPoints: 1 // 限制为单点触控
property real startX: 0 // 记录手势开始的X坐标
property real lastX: 0 // 记录手势结束的X坐标
property bool isMoving: false
onIsMovingChanged: {
drawerOpen.stop()
drawerClose.stop()
}
// 捕捉手势开始
onPressed: {
startX = touchPoints[0].x
lastX = drawer.x
isMoving = true
}
// 捕捉手势移动
onUpdated: {
if (touchPoints.length > 0) {
var delta = touchPoints[0].x - startX // 手指移动的距离
var newPosition = lastX + delta // 根据手指滑动更新Drawer位置
// 确保Drawer的位置在合理的范围内
drawer.x = Math.max(-drawer.width, Math.min(newPosition, 0));
}
}
// 捕捉手指松开,决定是否展开或隐藏
onReleased: {
if (drawer.x > -drawer.width / 2) {
drawerOpen.start(); // 如果超过一半,则展开Drawer
} else {
drawerClose.start(); // 如果不到一半,则隐藏Drawer
}
isMoving = false
}
}
Rectangle {
id: mainPage
anchors.fill: parent
x: drawer.x + drawer.width
Button {
z: 1
anchors.fill: parent
opacity: 0.4 * (-drawer.x / drawer.width)
visible: drawer.isOpened || touchArea.isMoving
onClicked: {
if (!touchArea.isMoving)
drawerClose.start()
}
}
z: 0
Rectangle {
id: header
anchors.top: parent.top
width: parent.width
height: pt(120)
color: "#3399FF"
Component.onCompleted: {
statusBarHandler.setStatusBarColor("#3399FF")
}
Button {
id: opendrawer
anchors.left: parent.left
anchors.margins: pt(40)
height: pt(120)
width: pt(120)
background: Rectangle {
anchors.fill: parent
color: "#3399FF"
radius: pt(60)
}
onClicked: {
if (!touchArea.isMoving)
drawerOpen.start()
}
}
TextField {
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
placeholderText: "搜索组织"
placeholderTextColor: "lightgray"
font.pixelSize: pt(20)
anchors.centerIn: parent
background: Rectangle {
id: searchingBox
color: "white"
anchors.centerIn: parent
border.color: "transparent"
width: pt(520)
height: pt(100)
radius: pt(50)
border.width: 0
}
}
Rectangle {
id: gradientColorBox
anchors.top: header.bottom
anchors.horizontalCenter: header.horizontalCenter
width: header.width
height: header.height
gradient: Gradient {
GradientStop {
position: 0.0
color: "#3399FF"
}
GradientStop {
position: 1.0
color: "#00000000"
}
}
}
Rectangle {
color: "#D4D4D4"
anchors.horizontalCenter: header.horizontalCenter
anchors.top: gradientColorBox.bottom
GridLayout {
id: gridLayout
anchors.fill: parent
columns: Math.floor(Screen.width - pt(120)) / pt(580)
anchors.leftMargin: pt(80)
anchors.rightMargin: pt(80)
rowSpacing: pt(40) // 行间距
columnSpacing: pt(40) // 列间距
Component {
id:infocard
Rectangle {
color: "white"
width: pt(540)
height: pt(520)
radius: pt(40)
}
}
function addItem() {
var newItem = infocard.createObject(gridLayout); // 创建新对象
if (newItem) {
gridLayout.addItem(newItem); // 添加到 GridLayout 中
}
}
Component.onCompleted: {
for (var i = 0; i < 5; i++)
addItem()
}
}
}
}
}
}
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "app_environment.h"
#include "import_qml_components_plugins.h"
#include "import_qml_plugins.h"
#include <QJniObject>
#include <QCoreApplication>
class StatusBarHandler : public QObject {
Q_OBJECT
public:
explicit StatusBarHandler(QObject *parent = nullptr) : QObject(parent) {}
Q_INVOKABLE void setStatusBarColor(const QString &colorHex) {
#ifdef Q_OS_ANDROID
// 通过 QJniObject 获取当前 Android 的 Activity
QJniObject activity = QJniObject::callStaticObjectMethod(
"org/qtproject/qt5/android/QtNative", // Qt 在 Android 上提供的类
"activity",
"()Landroid/app/Activity;"); // 返回类型是 Activity
if (activity.isValid()) {
QJniObject window = activity.callObjectMethod("getWindow", "()Landroid/view/Window;");
if (window.isValid()) {
// 解析颜色
jint colorInt = QJniObject::callStaticMethod<jint>(
"android/graphics/Color",
"parseColor",
"(Ljava/lang/String;)I",
QJniObject::fromString(colorHex).object<jstring>()
);
// 设置状态栏颜色
window.callMethod<void>("setStatusBarColor", "(I)V", colorInt);
}
}
#endif
}
};
int main(int argc, char *argv[])
{
set_qt_environment();
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(u"qrc:/qt/qml/Main/main.qml"_qs);
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreated,
&app,
[url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
},
Qt::QueuedConnection);
// 将 StatusBarHandler 类注册为 QML 中的对象
StatusBarHandler statusBarHandler;
engine.rootContext()->setContextProperty("statusBarHandler", &statusBarHandler);
engine.addImportPath(QCoreApplication::applicationDirPath() + "/qml");
engine.addImportPath(":/");
engine.load(url);
if (engine.rootObjects().isEmpty()) {
return -1;
}
return app.exec();
}
#include "main.moc"
而实际效果是:
(开发环境:Windows11 x64、Qt6.6.2开源版、Qt Creator 12.0.2)
(构建套件:Android Qt 6.6.2 Clang arm64-v8a JDK17 NDK25 SDK16 android-35 Android12.0+13.0)
(运行环境:华为Mate 20 HMA-AL00 Harmony4.0.0(Qt识别为:Android 10.0) 屏幕2244*1080)
1、setStatusBarColor(color) 调用后,设备上的状态栏仍是黑色的
2、除了侧边栏 drawer 在程序开始运行时可以显示0.5秒左右,其他的组件均不显示,屏幕一片空白
3、在主页面 mainPage 用手指向右滑动,侧边栏 drawer 不显示
报错信息:
1、W libAppApp_arm64-v8a.so: qrc:/qt/qml/Main/main.qml:117:13: TypeError: Cannot read property 'pixelDensity' of undefined
2、W libAppApp_arm64-v8a.so: qrc:/qt/qml/Main/main.qml:129:17: TypeError: Cannot read property 'pixelDensity' of undefined
3、W libAppApp_arm64-v8a.so: qrc:/qt/qml/Main/main.qml:128:17: TypeError: Cannot read property 'pixelDensity' of undefined
4、W libAppApp_arm64-v8a.so: qrc:/qt/qml/Main/main.qml:157:21: TypeError: Cannot read property 'pixelDensity' of undefined
5、W libAppApp_arm64-v8a.so: qrc:/qt/qml/Main/main.qml:156:21: TypeError: Cannot read property 'pixelDensity' of undefined
6、W libAppApp_arm64-v8a.so: qrc:/qt/qml/Main/main.qml:200:29: TypeError: Cannot read property 'pixelDensity' of undefined
7、W libAppApp_arm64-v8a.so: qrc:/qt/qml/Main/main.qml:201:29: TypeError: Cannot read property 'pixelDensity' of undefined
8、W libAppApp_arm64-v8a.so: qrc:/qt/qml/Main/main.qml:200:29: RangeError: Maximum call stack size exceeded.
9、W libAppApp_arm64-v8a.so: qrc:/qt/qml/Main/main.qml:201:29: RangeError: Maximum call stack size exceeded.
注:第117 128 129 156 157 200 201行:



_10、W libAppApp_arm64-v8a.so: qrc:/qt/qml/Main/main.qml:39: ReferenceError: parent is not defined
11、W libAppApp_arm64-v8a.so: qrc:/qt/qml/Main/main.qml:48: ReferenceError: parent is not defined
_
注:第39、48行:

12、W libAppApp_arm64-v8a.so: qrc:/qt/qml/Main/main.qml:68: TypeError: Cannot read property 'x' of undefined
注:第68行:

希望大家可以帮我解决以上报错和显示问题,谢谢!
最好可以使程序达到开头的理想效果