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
相关产品推荐
相关产品推荐

