Russian Qt Forum
Ноябрь 23, 2024, 08:38 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Выборка данных для моделей в отдельном потоке [РЕШЕНО]  (Прочитано 10517 раз)
vovan1982
Гость
« : Июль 24, 2012, 09:00 »

Привет всем.

У меня есть своя модель унаследованная от QAbstractItemModel, в ней есть метод select() который отвечает за выборку данных из БД и заполнение модели.
Хочу вынести метод select() в отдельный поток, подскажите пожалуйста как правильно это сделать?

Хочу сделать это для того чтоб пока идёт загрузка данных показывать гифку загрузки.
« Последнее редактирование: Июль 27, 2012, 15:36 от vovan1982 » Записан
vovan1982
Гость
« Ответ #1 : Июль 24, 2012, 13:49 »

Сделал по аналогии с этим постом http://www.prog.org.ru/topic_16736_0.html попытался вынести всю модель в отдельный поток

.h файл
Код:
#ifndef POPULATEDEVICETHREAD_H
#define POPULATEDEVICETHREAD_H

#include <QThread>

class DeviceModel;

class PopulateDeviceThread : public QThread
{
    Q_OBJECT
public:
    PopulateDeviceThread(QObject *parent = 0);
    ~PopulateDeviceThread();
    DeviceModel *model();
    void selectData(const QString &filter = "");
protected:
    void run();
signals:
    void done(bool);
private:
    DeviceModel *devModel;
};

#endif // POPULATEDEVICETHREAD_H


.cpp файл
Код:
#include <QSqlDatabase>
#include "headers/populatedevicethread.h"
#include "headers/devicemodel.h"

PopulateDeviceThread::PopulateDeviceThread(QObject *parent)
    : QThread(parent)
{
    devModel = new DeviceModel();
    devModel->moveToThread(this);
}

PopulateDeviceThread::~PopulateDeviceThread(){}

void PopulateDeviceThread::run()
{
    QSqlDatabase db = QSqlDatabase::database();
    if(!db.isOpen()){
        qDebug()<<"DB not open!!!";
        emit done(false);
    }else{
        devModel->select();
        emit done(true);
    }
}

DeviceModel *PopulateDeviceThread::model()
{
    return devModel;
}

void PopulateDeviceThread::selectData(const QString &filter)
{
    devModel->setFilter(filter);
    this->start();
}


при первом запуске всё работает, но если попытаться обновить модель ещё раз запустив selectData() то программа вылетает, прошёлся по отладчику вылет идёт именно при выборке из модели devModel->select().
Ещё ещё появился глюк в самой программе, у меня MDI интерфейс, всё работает пока не откроешь окно в котором запускается поток, после этого при открытии любого другого окна программа вылетает.

Не пойму что я делаю не так.
Записан
vovan1982
Гость
« Ответ #2 : Июль 26, 2012, 13:18 »

Вообщем засунуть модель в отдельный поток мне так и не удалось, точнее удалось но вот нормально с ней работать не получилось, появилось куча глюков и вылетов программы, поэтому решил закопаться ещё глубже, в саму модель и уже непосредственно в ней запускать поток и выборку данных делать в нём.

При таком подходе всё получилось, на данный момент всё работает нормально, но появился следующий вопрос, корректно ли так делать, ведь при каждом создании модели будет создаваться отдельный поток для этой модели, у меня в программе данная модель может быть одновременно создана в трёх окнах, соответственно будут созданы три потока для каждой из моделей, не многовато ли потоков?
А если я захочу ещё в одной модели выборку вынести в отдельный поток, это же сколько их может создаться.

Я подумал на счёт отдельного потока который создаётся при запуске программы и все длительные вычисления и выборки перенести в него, но вот только ни как не соображу как с таким потоком работать, к примеру:
При открытии главного окна QMainWindow создаётся дополнительный поток, как работать с этим потоком к примеру из модели которая находится в виджете который в свою очередь является дочерним окном QMdiArea?

Если кто то подобное делал поделитесь опытом.
Записан
vovan1982
Гость
« Ответ #3 : Июль 26, 2012, 14:34 »

Появилась ещё одна проблема, у меня на машине программа работает нормально и релиз и дебаг сборка, но при запуске программы на другой машине данные из второго потока не приходят, хотя сигнал о том что данные выбраны приходит, об этом говорит закрытие окна загрузки, не пойму чего не хватает программе, кто нибудь с таким сталкивался?
Записан
vovan1982
Гость
« Ответ #4 : Июль 26, 2012, 16:55 »

На счёт количества потоков разобрался, если правильно понял потоков может быть максимум 1000 и не имеет значения сколько их в программе 10 или 100, важно то что они делаю, исходя из этого надобность в отдельном глобальном потоке отпадает.

Но вот со второй проблемой на счёт запуска приложения на другой машине так и не разобрался.

Решил поставить на вторую машину такой же SDK который стоит у меня, не помогло, для теста собрал на своей машине маленький пример работы с потоками из книги Земскова "Qt4 на примерах".

Сделал конечный вариант приложения скопировав в одну папку экзешник и все необходимые библиотеки.
Запускаю на своей машине, всё работает, запускаю на второй машине, не работает.
Решил собрать данный пример на второй машине, собрал, сделал паку с программой, запускаю работает  Шокированный
Копирую программу собранную на второй машине себе, запускаю не работает  Непонимающий
Подменил библиотеки программы собранной на второй машине со своей, запускаю работает  Непонимающий

В чём прикол, я не пойму, SDK одна и таже.

Кто нибудь запускал многопоточные программы на других машинах, не там где прога собиралась?

P.S.: использую SDK 1.2.1  qt версии 4.8.1, пробовал собирать с qt 4.7.4 результат тот же.
« Последнее редактирование: Июль 26, 2012, 17:18 от vovan1982 » Записан
Bepec
Гость
« Ответ #5 : Июль 26, 2012, 20:15 »

Я советую прекратить искать телепатов, а выложить пробный проект, который у вас где то да, а где то нет, а где то вообще не запускается.

PS почти все мои проекты многопоточные, летают почти на любых машинах.
Записан
vovan1982
Гость
« Ответ #6 : Июль 26, 2012, 21:03 »

Тестовый проект в приложении
Записан
vovan1982
Гость
« Ответ #7 : Июль 27, 2012, 09:02 »

А вот уже собранный тестовый проект, он нормально работает на моей машине и не работает на любой другой.

http://code.google.com/p/workerplace/downloads/detail?name=test%20thread.zip&can=2&q=

Результатом нажатия кнопки "Старт" должен быть "Получен результат. Кол-во записей: 1000000", у меня на машине так и есть, а на остальных машинах Кол-во записей: 0
Записан
Bepec
Гость
« Ответ #8 : Июль 27, 2012, 09:31 »

Нууу...

Что сказать - у вас где то в вашем проекте косяк. И он не в этой части кода. Потому что она работоспособная на 100% Улыбающийся

« Последнее редактирование: Июль 27, 2012, 09:36 от Bepec » Записан
vovan1982
Гость
« Ответ #9 : Июль 27, 2012, 09:32 »

Всё правильно, ты собрал и у тебя на машине работает, скачай вариант собраный у меня на машине, и попробуй запустить релизную твою сбору на другой машине
Записан
vovan1982
Гость
« Ответ #10 : Июль 27, 2012, 09:39 »

Что сказать - у вас где то в вашем проекте косяк. И он не в этой части кода. Потому что она работоспособная на 100% Улыбающийся

Собственно это и есть весь проект. Это не кусок кода моего проекта. Это пример из книги, который работает также как мой проект.

Не направите в нужное русло, где искать косяк?

Я просто у же не знаю что не так и какую сторону копать.
Записан
Bepec
Гость
« Ответ #11 : Июль 27, 2012, 09:40 »

Запустил на ноутбуке - результат 1000000 Веселый

Помоему проблема в одной простой загогулинке...

PS разрешаю спросить в какой Веселый
Записан
vovan1982
Гость
« Ответ #12 : Июль 27, 2012, 09:42 »

В какой НепонимающийНепонимающийНепонимающийНепонимающий??
Записан
Bepec
Гость
« Ответ #13 : Июль 27, 2012, 09:44 »

Плагины для Qt должны находиться в той же папке, что и программа.

К плагинам Qt относятся и драйверы баз данных и форматы иконок и многое прочее.

Скопируйте вместе с вашим проектом папочку sqldrivers, которая находится в Qt 4.8.1/plugins/.

В принципе хватит и одного файлика - qsqlite4.dll. Но он обязан находиться в каталоге sqldrivers в директории программы.

PS поясняю - у вас программа не могла подцепить драйвер за его отсутствием. Советую в таких вот проектах вести лог файл - будет в сотни раз понятнее, что и почему не работает Веселый
Записан
vovan1982
Гость
« Ответ #14 : Июль 27, 2012, 09:56 »

Спасибо большое, ошибка действительно глупая, тем более что я знал про эту особенность и в моём  проекте эта папочка с драйвером присутствует.

Пошёл разбираться что не так в моём проекте.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.051 секунд. Запросов: 21.