#include "MainWindow.h" #include "bank/AccountWindow.h" #include #include #include #include #include #include #include "TutorialWindow.h" #include "bank/BankListWindow.h" #include "event/EventWindow.h" #include "log/LogWindow.h" #include "log/FileLogWindow.h" #include "db/DeviceInfo.h" #include "device/DeviceWidget.h" #include "dao/DeviceDAO.h" #include "dao/SettingsDAO.h" #include #include #include "widget/common/FlowLayout.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setWindowTitle("ARC"); // Инициализируем таймер обновления timer = new QTimer(this); connect(timer, &QTimer::timeout, this, &MainWindow::loadDevices); stackedWidget = new QStackedWidget(this); setCentralWidget(stackedWidget); createDevicePage(); stackedWidget->addWidget(m_devicesWindow); stackedWidget->setCurrentWidget(m_devicesWindow); // FIXME переделать на ленивое создание // m_accountsWindow = new AccountWindow(this); // stackedWidget->addWidget(m_accountsWindow); // stackedWidget->setCurrentWidget(accountPage); resize(800, 600); // Работа с меню QMenu *menu = menuBar()->addMenu("Меню"); auto *devicesPageAction = new QAction("Активные устройства", this); // auto *accountPageAction = new QAction("Аккаунты", this); auto *bankListAction = new QAction("Банки", this); auto *tutorialPageAction = new QAction("Инструкция", this); auto *eventAction = new QAction("События", this); auto *errorLogAction = new QAction("Ошибки", this); auto *fileLogAction = new QAction("Логи", this); menu->addAction(devicesPageAction); // menu->addAction(accountPageAction); menu->addAction(bankListAction); menu->addAction(eventAction); menu->addAction(tutorialPageAction); menu->addAction(errorLogAction); menu->addAction(fileLogAction); connect(devicesPageAction, &QAction::triggered, this, [=]() { if (!m_devicesWindow) { createDevicePage(); } stackedWidget->setCurrentWidget(m_devicesWindow); }); // connect(accountPageAction, &QAction::triggered, this, [=]() { // stackedWidget->setCurrentWidget(m_accountsWindow); // deleteDevicePage(); // освобождаем ресурсы // }); connect(bankListAction, &QAction::triggered, this, [=]() { if (!m_bankListWindow) { m_bankListWindow = new BankListWindow(this); } m_bankListWindow->show(); m_bankListWindow->raise(); m_bankListWindow->activateWindow(); }); connect(tutorialPageAction, &QAction::triggered, this, [=]() { if (!m_tutorialWindow) { m_tutorialWindow = new TutorialWindow(this); } m_tutorialWindow->show(); m_tutorialWindow->raise(); m_tutorialWindow->activateWindow(); }); connect(eventAction, &QAction::triggered, this, [=]() { if (!m_eventWindow) { m_eventWindow = new EventWindow(this); } m_eventWindow->show(); m_eventWindow->raise(); m_eventWindow->activateWindow(); }); connect(errorLogAction, &QAction::triggered, this, [=]() { if (!m_logWindow) { m_logWindow = new LogWindow(this); } m_logWindow->show(); m_logWindow->raise(); m_logWindow->activateWindow(); }); connect(fileLogAction, &QAction::triggered, this, [=]() { if (!m_fileLogWindow) { m_fileLogWindow = new FileLogWindow(this); } m_fileLogWindow->show(); m_fileLogWindow->raise(); m_fileLogWindow->activateWindow(); }); if (SettingsDAO::get("tutorial_shown").isEmpty()) { QTimer::singleShot(0, this, [this]() { m_tutorialWindow = new TutorialWindow(this); m_tutorialWindow->show(); m_tutorialWindow->raise(); m_tutorialWindow->activateWindow(); SettingsDAO::set("tutorial_shown", "1"); }); } } void MainWindow::createDevicePage() { if (m_devicesWindow) { return; } auto *container = new QWidget(this); auto *containerLayout = new QVBoxLayout(container); containerLayout->setContentsMargins(0, 0, 0, 0); m_noDevicesLabel = new QLabel(container); m_noDevicesPixmap = QPixmap(QCoreApplication::applicationDirPath() + "/no_devices.png"); m_noDevicesLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); m_noDevicesLabel->setAlignment(Qt::AlignCenter); containerLayout->addWidget(m_noDevicesLabel); m_scrollArea = new QScrollArea(container); auto *contentWidget = new QWidget; flowLayout = new FlowLayout(contentWidget, 0, 0, 0); QVector devices = DeviceDAO::getAllDevices(false); for (const auto &device: devices) { flowLayout->addWidget(new DeviceWidget(device)); } contentWidget->setLayout(flowLayout); static_cast(m_scrollArea)->setWidget(contentWidget); static_cast(m_scrollArea)->setWidgetResizable(true); containerLayout->addWidget(m_scrollArea); m_noDevicesLabel->setVisible(devices.isEmpty()); m_scrollArea->setVisible(!devices.isEmpty()); m_devicesWindow = container; stackedWidget->addWidget(m_devicesWindow); timer->start(1000); if (devices.isEmpty()) { QTimer::singleShot(0, this, [this]() { if (m_noDevicesLabel && !m_noDevicesPixmap.isNull()) { m_noDevicesLabel->setPixmap(m_noDevicesPixmap.scaled( m_noDevicesLabel->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); } }); } } void MainWindow::deleteDevicePage() { if (!m_devicesWindow) { return; } timer->stop(); stackedWidget->removeWidget(m_devicesWindow); m_devicesWindow->deleteLater(); m_devicesWindow = nullptr; flowLayout = nullptr; } /** * Однако, в нем вы вызываете delete для элементов, что изменяет память. * Для того, чтобы не нарушать константность, этот метод должен быть неконстантным (без const в сигнатуре). */ void MainWindow::loadDevices() { const auto devices = DeviceDAO::getAllDevices(false); // Очистить старые виджеты QLayoutItem *item; while ((item = flowLayout->takeAt(0)) != nullptr) { if (item->widget()) { item->widget()->deleteLater(); } delete item; } // Добавляем новые виджеты для каждого устройства for (const auto &device: devices) { flowLayout->addWidget(new DeviceWidget(device)); } m_noDevicesLabel->setVisible(devices.isEmpty()); m_scrollArea->setVisible(!devices.isEmpty()); } void MainWindow::resizeEvent(QResizeEvent *event) { QMainWindow::resizeEvent(event); if (m_noDevicesLabel && m_noDevicesLabel->isVisible() && !m_noDevicesPixmap.isNull()) { m_noDevicesLabel->setPixmap(m_noDevicesPixmap.scaled( m_noDevicesLabel->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); } }