Вот упрощенный обзор моей настройки:
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::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()
}
Код: Выделить всё
#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;
};
Код: Выделить всё
#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();
}
Код: Выделить всё
#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
Мобильная версия