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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Использование QFuture и QtConcurrent внутри класса с вызовом метода этого класса  (Прочитано 27357 раз)
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« : Сентябрь 04, 2012, 17:18 »

Здравствуйте!
Есть у меня 2 таблицы QTableWidget
Есть две функции заполняющие эти таблицы и выделяющие память под пользовательские виджеты
таблицы хранят информацию по пользовательским виджетам (наследование QWidget)

и если данных много, интерфейс начинает виснуть, что не хорошо
сначало решил воспользоваться QThread и передавать ему указатель на функцию, которую он будет в run() запускать, потом нашел информацию о QFuture и QtConcurrent

Теперь о главном, как запустить в двух потоках отдельные функции-члены, запуск нужно сделать в конструкторе класса, кроме того эти функции-члены принадлежат этому же классу

долго мучился, искал, потом тыкал пальцем в небо, и сгенерировал такой пример (который конечно не пашет, иначе не создавал здесь тему):
Код:
MyClass::MyClass(QWidget *parent):QWidget(parent)
{
 QFuture <void> threadLoadInTable1;
 QFuture <void> threadLoadInTable2;

 threadLoadInTable1 = QtConcurrent::run(&MyClass::loadInTable1);
 threadLoadInTable2 = QtConcurrent::run(&MyClass::loadInTable2);
}

Ошибка: no matching function for call to 'run(void (MyClass::*)())'

пытался так:
Код:
threadLoadInTable1 = QtConcurrent::run(loadInTable1);
Ошибка такая: no matching function for call to 'run(<unresolved overloaded function type>)'

прототипы для этих функций такого вида:
Код:
void function(void)
т.е. ничего не возвращают и параметры не принимают

Слышал, что gui нельзя создавать вне главного потока, и похоже все равно не получится запустить эти функции в отдельном потоке

Помогите пожалуйста!
Записан

mutineer
Гость
« Ответ #1 : Сентябрь 04, 2012, 17:31 »

Вместо тыканья пальцем куда ни попадя, лучше бы доку почитал...
http://doc.crossplatform.ru/qt/4.7.x/qtconcurrentrun.html#using-member-functions
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #2 : Сентябрь 04, 2012, 17:34 »

См:

QtConcurrent Image Scaling Example
QtConcurrent Progress Dialog Example
QtConcurrent Run Function Example
Записан

ArchLinux x86_64 / Win10 64 bit
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #3 : Сентябрь 04, 2012, 17:39 »

Читал уважаемый mutineer, и использовал для проверки такой код:
Код:
#include <QtGui/QApplication>
#include <QDebug>
#include <QtConcurrentRun>
#include <QFuture>

void func()
{
        for(int i = 0; i < 10; i++)
            qDebug() << i;
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QFuture <void> future = QtConcurrent::run(func);

    return a.exec();
}
Записан

mutineer
Гость
« Ответ #4 : Сентябрь 04, 2012, 17:41 »

Читал уважаемый mutineer, и использовал для проверки такой код:

И секцию под названием Using Member Functions, на которую я линку дал, читал? Твой проверочный код к ней отношения не имеет
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #5 : Сентябрь 04, 2012, 17:47 »

У меня пример компилится и работает!
Записан

ArchLinux x86_64 / Win10 64 bit
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #6 : Сентябрь 04, 2012, 17:52 »

Читал уважаемый mutineer, и использовал для проверки такой код:

И секцию под названием Using Member Functions, на которую я линку дал, читал? Твой проверочный код к ней отношения не имеет
Я знаю, потому что тоже читал это Улыбающийся

Уважаемый kuzulis, предоставленные вами названия примеров, кроме QtConcurrent Image Scaling Example, не имеют отношения к моему вопросу. Да и в QtConcurrent Image Scaling Example показывают только QFutureWatcher, который вряд ли поможет в решении проблемы
Записан

gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #7 : Сентябрь 04, 2012, 17:53 »

У меня пример компилится и работает!
У меня ос windows xp, qt 4.8.0, minGW
Записан

mutineer
Гость
« Ответ #8 : Сентябрь 04, 2012, 17:53 »

Читал уважаемый mutineer, и использовал для проверки такой код:

И секцию под названием Using Member Functions, на которую я линку дал, читал? Твой проверочный код к ней отношения не имеет
Я знаю, потому что тоже читал это Улыбающийся

Тогда почему в коде, приведенном в первом посте, ты первым аргументом в run не передаешь указатель или ссылку на объект?
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #9 : Сентябрь 04, 2012, 17:55 »

разве не ссылка указана?
Код:
threadLoadInTable1 = QtConcurrent::run(&MyClass::loadInTable1);
Записан

mutineer
Гость
« Ответ #10 : Сентябрь 04, 2012, 17:58 »

разве не ссылка указана?
Код:
threadLoadInTable1 = QtConcurrent::run(&MyClass::loadInTable1);

Указан адрес функции, который должен быть вторым параметром, а первым должен быть указатель или константная ссылка на объект

Цитировать
The first argument must be either a const reference or a pointer to an instance of the class
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #11 : Сентябрь 04, 2012, 18:03 »

Все разобрался, код такой:
Код:
QFuture <void> threadLoadInTable1 = QtConcurrent::run(this, &MyClass::loadInTable1);
Не знаю почему, писал сначала так:
Код:
QFuture <void> threadLoadInTable1 = QtConcurrent::run(MyClass, &MyClass::loadInTable1);

И потвердил свои сомнения, в консоль выдается такое:
QPixmap: It is not safe to use pixmaps outside the GUI thread
QObject::setParent: Cannot set parent, new parent is in a different thread
Записан

mutineer
Гость
« Ответ #12 : Сентябрь 04, 2012, 18:08 »

Для ускорения заполнения таблицы попробуй перейти на model/view
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #13 : Сентябрь 04, 2012, 18:15 »

Да не из-за таблицы, я думаю виснет интерфейс, а из-за выделения памяти и создания виджетов, в таблицах ведь каждая строка - один виджет, каждый виджет тратит на себя где-то 0.3мб, а ведь ему еще нужно загрузить еще свои данные, вот и виснет Улыбающийся

Есть вариант создавать эти виджеты в качестве отдельного процесса, но это будет не красиво (да и сработает ли вообще??), представьте если будет этих виджетов 50 или более..

Для ускорения заполнения таблицы попробуй перейти на model/view
Интерфейс виснет уже когда более 20 записей (20 виджетов) в таблице, от перехода ситуацию не изменится Улыбающийся

Можно, конечно, сделать отправление сигналов из потоков в главный поток типа: "Создай такой то виджет", но опять будет виснуть интерфейс...

Отдельные потоки нужны только при загрузке в таблицы, а дальше они не понадобятся, значит надо думать как "облегчить" инициализацию и отрисовку этих виджетов, может какие нибудь действия, не связанные с gui вынести в потоки...
Буду думать...
« Последнее редактирование: Сентябрь 04, 2012, 18:43 от gil9red » Записан

UNION labs
Гость
« Ответ #14 : Сентябрь 06, 2012, 12:56 »

И все-таки вам нужно смотреть в сторону model/view, а именно на делегаты, и при их помощи все что нужно отрисовывать.
И можете картинку прикрепить, показать что у вас является одной строкой?
« Последнее редактирование: Сентябрь 06, 2012, 13:06 от dimkanovikov » Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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