Название: Работа с БД в отдельном потоке Отправлено: INZER от Май 30, 2022, 16:50 Решил вынести работу с базой данных в отдельный поток
Приложение строится на архитектуре Model-View-Presenter В модели БД воркер (SqlWorker ниже), агрегирующий класс-исполнитель запросов (SqlQueryExecutor) Код:
Проблема в том что ранее в однопоточном исполнении результат выполнения запроса попадал в модель A618SqlModel, котрая успешно скармливалась QtableView Однако сейчас я не могу передать результат выполения запроса, так как не могу использовать A618SqlModel для передачи в виде параметра сигнала (не могу зарегистрировать его как метатип, потому что конструктор копирования закрыт). Подскажите пожалуйста как правильно в Qt правильно передать результат выполния запроса к БД из другого потока. Код: QObject::connect(modelObject, SIGNAL(return618Data(A618SqlModel &)), this, SLOT(slotSet618Messages(A618SqlModel &))); Код: qRegisterMetaType<A618SqlModel>(); Заранее спасибо Название: Re: Работа с БД в отдельном потоке Отправлено: sergek от Май 30, 2022, 17:18 Может, сделать наоборот - в вокер передать ссылку на TableView? Проблем с совместным использованием, вроде, не наблюдается.
Название: Re: Работа с БД в отдельном потоке Отправлено: INZER от Май 30, 2022, 21:47 Спасибо, завтра обязательно попробую,
Была такая мысль, но сомневался в корректности доступа к табличке из другого потока. Единственное что смущает - не нашел что у QTableView реализован конструктор копирования, как я понимаю без него не получится зарегистрироовать мета тип и, соответственно, установить коннекты между методами объектов. Название: Re: Работа с БД в отдельном потоке Отправлено: sergek от Май 30, 2022, 22:00 Вы не поняли - я предлагаю использовать TableView из того потока, где вы работаете с базой. Т.е. в конструкторе вокера предусматриваете ссылку на вьюшник, ну и в конструкторе делаете tableView-> setModel(model618).
Название: Re: Работа с БД в отдельном потоке Отправлено: INZER от Май 31, 2022, 07:11 Дело в том что у меня ~20 вью в которые необходимо отдавать результаты запросов. Не хочется хранить ссылки на вью в модели. Согласно архитектуре Model View Presenter отображение и модель не должны быть связаны друг с другом никак. Потому хочется прокидывать результат. Ну либо ссылку на требуемую вью непосредственно при запросе.
Название: Re: Работа с БД в отдельном потоке Отправлено: sergek от Май 31, 2022, 09:09 Да хоть 40, какая разница? Массив указателей, в отдельном методе установка модели. Не понимаю проблемы. Но хозяин - барин...
Название: Re: Работа с БД в отдельном потоке Отправлено: INZER от Май 31, 2022, 09:16 Ни в коем случае не ругаюсь на ваше предложение, огромное спасибо за подсказку, не думал о таком решении, так как мыслил в связи с выбранной архитектурой. Реализую как временное решение.
Может кто то еще подскажет решения как из потока получить данные из БД. Название: Re: Работа с БД в отдельном потоке Отправлено: sergek от Май 31, 2022, 09:45 так как мыслил в связи с выбранной архитектурой. Архитектура тут не виновата ;)Может кто то еще подскажет решения как из потока получить данные из БД. Еще как подскажут, жалеть будете, что спросили :)Название: Re: Работа с БД в отдельном потоке Отправлено: INZER от Июнь 01, 2022, 16:02 Если кому то вдруг пригодится через СИГНАЛ-СЛОТ можно прокидвать указатели на любые типы данных :) Прокидываю указатель на QSqlQuery
Тему можно считать закрытой Название: Re: Работа с БД в отдельном потоке Отправлено: sergek от Июнь 01, 2022, 22:11 Не очень понятно, что вы сделали, но имейте в виду, что подключение к БД может быть использовано только в том потоке, в котором оно было создано.
Название: Re: Работа с БД в отдельном потоке Отправлено: INZER от Июнь 01, 2022, 23:20 Да, спасибо я знаю
Результат возвращаю во вью через указатель на QSqlQuery Код: void SqlQueryExecutor::slotGet618Data(uint turplesCount) Название: Re: Работа с БД в отдельном потоке Отправлено: sergek от Июнь 02, 2022, 08:31 Как я понял, модель у вас в гуёвом потоке? Так делать нельзя по той причине, о которой я вам напоминал.
Другой вопрос, можно ли перенести модель в поток БД и использовать ее для нескольких представлений, существующих в основном потоке? Не уверен, может, коллеги что подскажут? Upd. Да, собственно, и не нужны подсказки. Тут простая логика - модель должна быть одна, связана с источником данных (БД) и находиться в потоке БД. Представлений может быть много и находиться они в любом потоке. Так что см. мой первый совет. Название: Re: Работа с БД в отдельном потоке Отправлено: diten от Июнь 21, 2022, 08:20 Нужно в том потоке создавать динамически экземпляр модели.
В методе инициализации окна: connect(ссылка_на_объект_класса_потока_работающего_с_БД, SIGNAL(resultReady(QSqlQueryModel*)), this, SLOT(completeModel(QSqlQueryModel*))); В определение класса, который работает с БД: QSqlQueryModel *model; В методе run(): model = new QSqlQueryModel(); model->setQuery(qry, db); emit resultReady(this->model); Это решение вашей проблемы. Но, есть в этом подводный камень, иногда выносит ошибку во время присвоения модели в QTableView. Пока в поисках, как это сделать правильно |