Android-приложение Qt6 аварийно завершает работу на Redmi Note 8 Pro, когда принимается QDialogAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Android-приложение Qt6 аварийно завершает работу на Redmi Note 8 Pro, когда принимается QDialog

Сообщение Anonymous »

У меня есть приложение Qt 6 для Android, которое отлично работает на большинстве устройств (Samsung S22, Redmi Note 8, Emulator), но вылетает на Redmi Note 8 Pro, когда я открываю QDialog (например, NewDevice) и нажимаю кнопку «Сохранить».
Вот упрощенный обзор моей настройки:
main.cpp

Код: Выделить всё

#include "anapencere.h"
#include 
#include 
#include 
#include "veri/veritabani.h"
#include 
void applySystemTheme() { Qt::ColorScheme scheme = qApp->styleHints()->colorScheme();
QString themeFile;

if (scheme == Qt::ColorScheme::Dark)
themeFile = ":/themes/dark.qss";
else
themeFile = ":/themes/light.qss";

QFile file(themeFile);
if (file.open(QFile::ReadOnly | QFile::Text))
qApp->setStyleSheet(file.readAll());
}
int main(int argc, char *argv[]) {
QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL); QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
QApplication a(argc, argv);
applySystemTheme();
QObject::connect(qApp->styleHints(), &QStyleHints::colorSchemeChanged, qApp, {
applySystemTheme(); });
veritabani::vt().load();
anapencere w;
w.show();

auto sonuc = a.exec();

veritabani::vt().save();
return sonuc;
}
anapencere.cpp (главное окно)

Код: Выделить всё

anapencere::anapencere(QWidget *parent) :
QMainWindow(parent) ,
ui(new Ui::anapencere) {
ui->setupUi(this);
this->showMaximized();
this->setFocusPolicy(Qt::StrongFocus);
this->setFocus();
qApp->installEventFilter(this);
//Devices ui->leDevicesSearch->installEventFilter(this);
ui->tblwgDevices->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
ui->tblwgDevices->horizontalHeader()->setStretchLastSection(true);
ui->tblwgDevices->verticalHeader()->setVisible(false);
ui->tblwgDevices->setEditTriggers(QAbstractItemView::NoEditTriggers);
ui->tblwgDevices->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->btnNewComp->setObjectName("primaryButton");
ui->btnNewDevice->setObjectName("primaryButton");

connect(ui->tblwgDevices,&QTableWidget::itemSelectionChanged,this,&anapencere::devtblwSecim);

searchTimer1 = new QTimer(this);
searchTimer1->setSingleShot(true);
connect(ui->leDevicesSearch, &QLineEdit::textChanged, this, [this](){
searchTimer1->start(500);
});
connect(searchTimer1, &QTimer::timeout, this, &anapencere::devsearch);

//Components
ui->leCompSearch->installEventFilter(this);

ui->tblwgComp->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
ui->tblwgComp->horizontalHeader()->setStretchLastSection(true);
ui->tblwgComp->verticalHeader()->setVisible(false);
ui->tblwgComp->setEditTriggers(QAbstractItemView::NoEditTriggers);
ui->tblwgComp->setSelectionBehavior(QAbstractItemView::SelectRows);

connect(ui->tblwgComp,&QTableWidget::itemSelectionChanged,this,&anapencere::comptblwSecim);

searchTimer2 = new QTimer(this);
searchTimer2->setSingleShot(true);
connect(ui->leCompSearch, &QLineEdit::textChanged, this, [this](){
searchTimer2->start(500);
});
connect(searchTimer2, &QTimer::timeout, this, &anapencere::compsearch);
}
void anapencere::showMessage(QMessageBox::Icon icon, const QString &title, const QString &text) { if (QWidget *focused = qApp->focusWidget()) {
focused->clearFocus();
}
QTimer::singleShot(150, this, = {
QMessageBox *msg = new QMessageBox(icon, title, text, QMessageBox::Ok, this);
msg->setAttribute(Qt::WA_DeleteOnClose);
msg->open(); });
}
bool anapencere::eventFilter(QObject *obj, QEvent event) {
if (qApp->activeModalWidget() != nullptr || qApp->activeWindow() != this) {
return QObject::eventFilter(obj, event);
}
if (qobject_cast(obj)) {
return QObject::eventFilter(obj, event);
}
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast(event);
if (keyEvent->key() == Qt::Key_Backspace) {
return QObject::eventFilter(obj, event);
}

if (keyEvent->key() == Qt::Key_Back || keyEvent->key() == Qt::Key_Escape) {
if (ui->stackedWidget->currentIndex() != 0) {
back();
return true;
}
else {
QMessageBox *msg = new QMessageBox(QMessageBox::Question,
"Çıkış",
"Uygulamadan çıkmak istiyor musunuz?",
QMessageBox::NoButton,
this);

QPushButton *evetButonu = msg->addButton("Evet", QMessageBox::YesRole);
msg->addButton("Hayır", QMessageBox::NoRole);

connect(msg, &QMessageBox::buttonClicked, this,
[=](QAbstractButton *btn){
if (btn == evetButonu)
QCoreApplication::quit();
});

msg->setAttribute(Qt::WA_DeleteOnClose);
msg->open();

return true;
}
}
}
return QObject::eventFilter(obj, event);
} //...  other code
void anapencere::on_btnNewDevice_clicked() {
NewDevice *frm = new NewDevice(this);
frm->setAttribute(Qt::WA_DeleteOnClose);
auto device = veritabani::vt().devices()._new();
frm->setData(device);
connect(frm, &QDialog::accepted, this, [=]() {
*device = *frm->getData();

auto existing = veritabani::vt().devices().search([device](DeviceTable::VeriPointer d){
return d->getSerialnumber().toLower() == device->getSerialnumber().toLower();
});

if (!existing.isEmpty()) {
showMessage(QMessageBox::Critical,
"Error",
QString("%1 serial number already exists!").arg(device->getSerialnumber()));
return;
}

veritabani::vt().devices().add(device);
veritabani::vt().save();
showMessage(QMessageBox::Information,
"Info",
QString("%1 device added.").arg(device->getSerialnumber()));
devsearch();
});

frm->open();  // Using open() instead of exec()
}
anapencere.h (MainWindow)

Код: Выделить всё

#pragma once
#include "veri/veritabani.h"
#include 
#include 
#include "ui/editcomponent.h"
#include "ui/editdevice.h"
#include "ui/newcomponent.h"
#include "ui/newdevice.h"
#include "ui/repairtasks.h"
#include 
#include 
QT_BEGIN_NAMESPACE namespace Ui {
class anapencere;
} QT_END_NAMESPACE

class anapencere : public QMainWindow { Q_OBJECT
public:
anapencere(QWidget *parent = nullptr);
~anapencere();

void devicesload();
void devsearch();
void devtblwSecim();

void compload();
void compsearch();
void comptblwSecim();

void showMessage(QMessageBox::Icon icon,
const QString &title,
const QString &text);
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
void back();
private slots:
void on_btnDevices_clicked();
void on_btnComp_clicked();

void on_btnRepairTask_clicked();

void on_btnNewDevice_clicked();

void on_btnDevicesEdit_clicked();

void on_btnDevicesDel_clicked();

void on_btnCompEdit_clicked();

void on_btnCompDel_clicked();

void on_btnNewComp_clicked();

void on_btnBack_clicked();

void on_btnBack2_clicked();
private:
Ui::anapencere *ui;
QTimer *searchTimer1;
QTimer *searchTimer2;
DeviceTable::VeriListesi deviceslist;
ComponentTable::VeriListesi complist;
};
NewDevice.cpp QDialog

Код: Выделить всё

#include "newdevice.h"
#include "ui/ui_newdevice.h"
NewDevice::NewDevice(QWidget *parent) :
QDialog(parent) ,
ui(new Ui::NewDevice)
{
ui->setupUi(this);
ui->dteEntryDate->setDateTime(QDateTime::currentDateTime());
ui->btnSave->setObjectName("primaryButton");
}
NewDevice::~NewDevice()
{
delete ui;
}
DeviceTable::VeriPointer NewDevice::getData() const {
data->setSerialnumber(ui->leSerial->text());
data->setModelName(ui->leModel->text());
data->setCustomerName(ui->leCustomer->text());
data->setEntryDate(ui->dteEntryDate->dateTime());
auto n=ui->cbStatus->currentText();
statusenum status;
if(n=="Tamirde"){
status = statusenum::Tamirde;
}else if(n=="Tamamlandi"){
status = statusenum::Tamamlandi;
}else if(n=="Iade"){
status = statusenum::Iade;
}else if(n=="Testte"){
status = statusenum::Testte;
}else{
status = statusenum::Beklemede;
}
data->setStatus(status);
data->setFaultDescription(ui->teFaultDesc->toPlainText());
return data;
}
void NewDevice::setData(DeviceTable::VeriPointer newData) {
data = newData;
ui->leSerial->setText(data->getSerialnumber());
ui->leModel->setText(data->getModelName());
ui->leCustomer->setText(data->getCustomerName());
ui->dteEntryDate->setDateTime(data->getEntryDate());
statusenum status=data->getStatus();
switch (status) {
case statusenum::Beklemede:
ui->cbStatus->setCurrentText("Beklemede");
break;
case statusenum::Iade:
ui->cbStatus->setCurrentText("İade");
break;
case statusenum::Tamamlandi:
ui->cbStatus->setCurrentText("Tamamlandı");
break;
case statusenum::Tamirde:
ui->cbStatus->setCurrentText("Tamirde");
break;
case statusenum::Testte:
ui->cbStatus->setCurrentText("Testte");
break;
default:
ui->cbStatus->setCurrentText("Beklemede");
break;
}
ui->teFaultDesc->setPlainText(data->getFaultDescription());
}
void NewDevice::on_btnSave_clicked() {
if (ui->leModel->text().trimmed().isEmpty())
{
QMessageBox::warning(this, "Eksik Bilgi", "Lütfen Model Kısmını Boş Geçmeyiniz!");
return;
}
if (ui->leSerial->text().trimmed().isEmpty()) {
QMessageBox::warning(this, "Eksik Bilgi", "Lütfen Seri No Kısmını Boş Geçmeyiniz!");
return;
}
if (ui->teFaultDesc->toPlainText().trimmed().isEmpty()) {
QMessageBox::warning(this, "Eksik Bilgi", "Lütfen Arıza Açıklaması Kısmını Boş Geçmeyiniz!"); return;
}
QDialog::accept();
}
NewDevice.h QDialog

Код: Выделить всё

#pragma once
#include 
#include 
#include "../veri/veritabani.h"
namespace Ui {
class NewDevice;
}
class NewDevice : public QDialog {
Q_OBJECT
public:
explicit NewDevice(QWidget *parent = nullptr);
~NewDevice();
DeviceTable::VeriPointer getData() const;
void setData(DeviceTable::VeriPointer newData);
private slots:
void on_btnSave_clicked();
private:
Ui::NewDevice *ui;
DeviceTable::VeriPointer data;
};
Проблема
Приложение вылетает только на Redmi Note 8 Pro при принятии диалогового окна.
Отлично работает на Redmi Note 8, Samsung S22 и эмуляторе.
Я подозреваю, что это может быть связано со временем жизни указателя, QDialog::open() против exec() или проблемами с памятью конкретного устройства, но я не могу понять, почему это происходит только в этом случае устройство.
DeviceTable::VeriPointer сохраняется в главном окне после закрытия диалогового окна.
Вопрос
Был ли у кого-нибудь сбой QDialog на определенных устройствах Android после нажатия кнопки «Принять»?
Может ли это быть связано с различиями в куче, времени жизни указателя или архитектуре процессора?
Как я могу безопасно отладить или предотвратить этот сбой на Redmi Note 8 Pro?
Конфигурация Qt и Android:
  • Версия Qt: 6.10.2
  • Комплект сборки: Android Arm64-v8a
  • Версия инструментов сборки Android: 36.1.0
  • SDK платформы Android: android-36
  • Настройка Android: Нет.
Тестирование устройства:
  • Samsung S22: работает правильно.
  • Samsung S9 Fe: работает правильно.
  • Устройство Android Studio Android 16.0 x86_64: работает правильно.
  • Redmi Note 8: работает. правильно.
  • Redmi Note 8 Pro: сбои


Подробнее здесь: https://stackoverflow.com/questions/798 ... s-accepted
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»