Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. Qt6 Android app crashes on Redmi Note 8 Pro when QDialog is accepted

Qt6 Android app crashes on Redmi Note 8 Pro when QDialog is accepted

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
2 Posts 2 Posters 86 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Melih Ky.
    wrote last edited by Melih Ky.
    #1

    Hi everyone,

    I have a Qt 6 Android application that works fine on most devices (Samsung S22, Redmi Note 8, Emulator), but crashes on Redmi Note 8 Pro when I open a QDialog (like NewDevice) and press the Save button.

    Here’s a simplified overview of my setup:

    main.cpp

    #include "anapencere.h"
    
    #include <QApplication>
    #include <QLocale>
    #include <QTranslator>
    #include "veri/veritabani.h"
    #include <QStyleHints>
    
    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 (Main Window)

    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<QLineEdit*>(obj)) {
            return QObject::eventFilter(obj, event);
        }
    
        if (event->type() == QEvent::KeyPress) {
            QKeyEvent *keyEvent = static_cast<QKeyEvent *>(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 <QMainWindow>
    #include <QTimer>
    #include "ui/editcomponent.h"
    #include "ui/editdevice.h"
    #include "ui/newcomponent.h"
    #include "ui/newdevice.h"
    #include "ui/repairtasks.h"
    #include <qevent.h>
    #include <QMessageBox>
    
    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 <QDialog>
    #include <QMessageBox>
    #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;
    };
    

    Problem

    The app crashes only on Redmi Note 8 Pro when accepting the dialog.

    Works fine on Redmi Note 8, Samsung S22, and emulator.

    I suspect this could be related to pointer lifetimes, QDialog::open() vs exec(), or device-specific memory issues, but I can’t figure out why it happens only on this device.

    The DeviceTable::VeriPointer is stored in the main window after the dialog closes.

    Question

    Has anyone experienced QDialog crashes on specific Android devices after pressing accept?

    Could this be related to heap, pointer lifetime, or CPU architecture differences?

    How can I safely debug or prevent this crash on Redmi Note 8 Pro?
    Qt and Android Configuration:

    Qt Version: 6.10.2
    
    Build Kit: Android arm64-v8a
    
    Android Build-tools Version: 36.1.0
    
    Android Platform SDK: android-36
    
    Android Customization: None
    

    Device Testing:

    Samsung S22 : Works correctly.
    
    Samsung S9 Fe (tablet) : Works correctly.
    
    Android Studio Device Android 16.0 x86_64 : Works correctly.
    
    Redmi Note 8: Works correctly.
    
    Redmi Note 8 Pro: Crashes
    
    1 Reply Last reply
    0
    • Axel SpoerlA Online
      Axel SpoerlA Online
      Axel Spoerl
      Moderators
      wrote last edited by
      #2

      Hi,
      please provide a simple, compilable reproducer.
      Yours doesn't compile, because you are using a UI file which is not posted.
      It also would make the reproducer too large.

      My wild guess is that you have a use-after-free, which randomly works when the freed memory hasn't been re-used and crashes when it has been re-used.

      Either simplify this further, preferably into one single file.
      Or, at least, through debug statements in all your destructors and observe what happens.
      Please also provide a stack trace.

      Software Engineer
      The Qt Company, Oslo

      1 Reply Last reply
      1

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved