Страницы

Поиск по вопросам

воскресенье, 29 марта 2020 г.

QT C++ работа с базой данных в разных потоках

#cpp #qt


Как можно модифицировать ПО для мультипоточной работы. 

Хотелось бы увидеть минимальный базовый пример, дабы разобраться и пока не лезть в дебри.

Есть большая таблица(100 тыс наименований) при их запросе виснет GUI.
Хотелось бы это устранить.

Логика была такая.


Человек открывает программу.
Конструктор формы отправил запрос потоку в БД.
Строится каркас приложения.
Берём данные из потока в основной.
Заполняем полученными данными таблицу.


p.s
Пробовал сделать подобное на сигналах и слотах с применением QThread. Отправлял запрос
в другой поток, но он начинал работать только когда закроется основное приложение...



mainwindow.СPP

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    //QSqlDatabase objDatabase;
    objDatabase = QSqlDatabase::addDatabase("QMYSQL");
    objDatabase.setDatabaseName("librarydb");
    objDatabase.setHostName("127.0.0.1");
    objDatabase.setPort(3306);
    objDatabase.setUserName("hays0503");
    objDatabase.setPassword("hays0503");
    objDatabase.open();

    //QSqlTableModel *objTableModel;
    objTableModel = new QSqlTableModel();
    objTableModel->setTable("author");
    if (!objTableModel->select())
    {
        qDebug()<<"Error";
    }else {
       ui->tableView->setModel(objTableModel);
    }
}


mainwindow.H

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include 

#include 
#include 
#include 
#include 

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
    QSqlDatabase objDatabase;
    QSqlTableModel *objTableModel;
};

#endif // MAINWINDOW_H

    


Ответы

Ответ 1



void MainWindow::on_pushButton_clicked() { QFuture future = QtConcurrent::run( [this]() { // Исполняем этот код в другом потоке //QSqlDatabase objDatabase; objDatabase = QSqlDatabase::addDatabase("QMYSQL"); objDatabase.setDatabaseName("librarydb"); objDatabase.setHostName("127.0.0.1"); objDatabase.setPort(3306); objDatabase.setUserName("hays0503"); objDatabase.setPassword("hays0503"); objDatabase.open(); //QSqlTableModel *objTableModel; objTableModel = new QSqlTableModel(this); objTableModel->setTable("author"); if (!objTableModel->select()) { delete objTableModel; objTableModel = nullptr; qDebug()<<"Error"; } return objTableModel; }); QFutureWatcher *watcher = new QFutureWatcher(this); connect(watcher, SIGNAL(finished()), watcher, [this, watcher]() { // Запускаем этот код в UI потоке, когда объект future завершит свою работу в рабочем потоке ui->tableView->setModel(watcher->result()); watcher->deleteLater(); // Удалим ненужный watcher }, Qt::QueuedConnection); ); watcher->setFuture(future); // Связываем watcher с feature. Это быстрая операция и не тормозит поток UI } Если много раз кликать на кнопку, то будет запущено сразу много одинаковых задач. Надо не забывать, что работать с объектами objDatabase и objTableModel можно только из одного потока одновременно.

Комментариев нет:

Отправить комментарий