You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt 6.7 Android端QList功能异常及SDK版本警告问题求助

Qt 6.7 Android部署QList相关功能异常排查

问题描述

基于Qt 6.7开发的蓝牙设备搜索+传感器数据显示应用,在Windows 11(MSVC2019编译)环境运行完全正常,但部署到Android设备(Clang arm64-v8a编译)后出现以下核心异常:

  • 点击按钮无响应,无法完成列表清空+添加新项操作
  • 无法选中列表中的任何项
  • 打开部件后布局整体向左偏移

伴随警告信息

(:-1: warning: Warning: SDK processing. This version only understands SDK XML versions up to 3 but an SDK XML file of version 4 was encountered. This can happen if you use versions of Android Studio and the command-line tools that were released at different times.)

已尝试无效操作

  • 手动重绘部件
  • 强制处理事件循环
  • 调用部件更新/更新几何状态方法

相关代码

scanwindow.h

#ifndef SCANWINDOW_H
#define SCANWINDOW_H

#include <QMainWindow>
#include <QBluetoothDeviceDiscoveryAgent>
#include <QBluetoothDeviceInfo>
#include <QLowEnergyController>
#include <QListWidgetItem>

namespace Ui {
class ScanWindow;
}

class ScanWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit ScanWindow(QWidget *parent = nullptr);
    ~ScanWindow();

private slots:
    void on_startScanButton_clicked();
    void deviceDiscovered(const QBluetoothDeviceInfo &device);
    void on_deviceList_itemClicked(QListWidgetItem *item);
    void on_connectButton_clicked();

    void on_clearButton_clicked();

signals:
    void characteristicValueChanged(const QString &value);
    void deviceSelected(const QBluetoothDeviceInfo &device);

private:
    Ui::ScanWindow *ui;
    QBluetoothDeviceDiscoveryAgent *discoveryAgent;
    QBluetoothDeviceInfo selectedDevice;
    QList<QLowEnergyService*> services;
};

#endif

scanwindow.cpp

#include "scanwindow.h"
#include "ui_scanwindow.h"
#include <QMessageBox>
#include <QPermissions>
#include <QCoreApplication>

ScanWindow::ScanWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::ScanWindow)
    , discoveryAgent(new QBluetoothDeviceDiscoveryAgent(this))
{
    ui->setupUi(this);

    ui->connectButton->setDisabled(true);

    connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &ScanWindow::deviceDiscovered);
}

ScanWindow::~ScanWindow()
{

    qDeleteAll(services);
    services.clear();

    delete ui;

}

void ScanWindow::on_startScanButton_clicked()
{
    ui->deviceList->clear();

#if QT_CONFIG(permissions)
    QBluetoothPermission permission;
    permission.setCommunicationModes(QBluetoothPermission::Access);

    switch (qApp->checkPermission((permission))) {
    case Qt::PermissionStatus::Undetermined:
        qDebug() << "Undetermined";
        qApp->requestPermission(permission, this,  &ScanWindow::on_startScanButton_clicked);
    break;
    case Qt::PermissionStatus::Denied:
        qDebug() << "Denied";
    break;
    case Qt::PermissionStatus::Granted:
        qDebug() << "Granted";
    break;

    }
#endif

    discoveryAgent->setLowEnergyDiscoveryTimeout(15000);
    discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
}

void ScanWindow::deviceDiscovered(const QBluetoothDeviceInfo &device){

    if (device.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) {
        qDebug() << "Added";
        QString label = device.name();
        QListWidgetItem *item = new QListWidgetItem(label, ui->deviceList);
        item->setData(Qt::UserRole,QVariant::fromValue(device));
    }

}

void ScanWindow::on_deviceList_itemClicked(QListWidgetItem *item) {
    QBluetoothDeviceInfo device = item->data(Qt::UserRole).value<QBluetoothDeviceInfo>();

    selectedDevice = device;

    ui->connectButton->setEnabled(true);

    qDebug() << "Selected device:" << device.name() << device.address().toString();
}

void ScanWindow::on_connectButton_clicked()
{
    if(!selectedDevice.isValid()){
        qDebug() << "No device selected or device info is invalid";
        return;
    }

    emit deviceSelected(selectedDevice);
}

void ScanWindow::on_clearButton_clicked()
{
    ui->deviceList2->clear();
    new QListWidgetItem(tr("Oak2"), ui->deviceList2);
    ui->deviceList2->repaint();
    ui->deviceList2->updateGeometry();
    ui->deviceList2->update();
    QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}

解决建议

1. 先修复SDK版本不匹配警告

该警告是Qt构建工具与Android SDK工具版本不一致导致的,直接影响Android打包稳定性:

  • 同步Android Studio和命令行SDK工具版本,确保两者发布时间接近
  • 在Qt Creator中检查工具>选项>设备>Android,确认SDK Build Tools版本≥34.0.0、NDK版本为25.x(Qt 6.7官方推荐配置)
  • 若仍有问题,可临时降级SDK XML版本到3,或调整构建工具版本至Qt兼容的范围

2. QListWidget操作适配Android环境

(1)列表清空/添加无响应

Android要求所有UI操作必须在主线程执行,蓝牙设备发现回调可能在子线程触发,需强制切换到主线程更新UI:
修改deviceDiscovered函数:

void ScanWindow::deviceDiscovered(const QBluetoothDeviceInfo &device){
    if (device.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) {
        qDebug() << "Added";
        QString label = device.name();
        // 切换到主线程执行UI更新
        QMetaObject::invokeMethod(this, [=](){
            QListWidgetItem *item = new QListWidgetItem(label, ui->deviceList);
            item->setData(Qt::UserRole, QVariant::fromValue(device));
        }, Qt::QueuedConnection);
    }
}

简化on_clearButton_clicked,去掉多余的UI强制刷新调用:

void ScanWindow::on_clearButton_clicked()
{
    ui->deviceList2->clear();
    new QListWidgetItem(tr("Oak2"), ui->deviceList2);
}

(2)列表项无法选中

  • 在UI设计器中确认QListWidget的selectionMode设置为SingleSelection或其他允许选中的模式
  • 添加列表项时显式设置可选中标记:
item->setFlags(item->flags() | Qt::ItemIsSelectable | Qt::ItemIsEnabled);
  • 给QListWidget设置强焦点策略:ui->deviceList->setFocusPolicy(Qt::StrongFocus),避免焦点被其他控件抢占

(3)布局向左偏移

  • 检查UI设计器中的布局配置,确保使用自适应布局(如QVBoxLayout/QHBoxLayout),而非固定位置的控件
  • 调整控件的sizePolicy为Expanding或Preferred,让布局自动适配不同屏幕尺寸
  • 移除代码中手动设置窗口/控件位置、大小的逻辑,完全依赖布局管理器

3. 完善Android蓝牙权限配置

Qt 6权限系统在Android上需要额外的Manifest配置:
在AndroidManifest.xml中添加以下权限:

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />

同时修改权限申请代码,明确指定所需权限类型:

QBluetoothPermission permission;
permission.setCommunicationModes(QBluetoothPermission::Scan | QBluetoothPermission::Connect);

内容的提问来源于stack exchange,提问作者Adrian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 07:35:04