Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt Ввод/Вывод, Сеть. Межпроцессное взаимодействие _ Глупый вопрос по QConcurentRun

Автор: silver47 26.4.2011, 8:39

Доброго времени суток. Попытался применить простой пример у себя в приложении:
Пример:

int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    QFuture<void> f1 = run(hello, QString("Alice"));
    QFuture<void> f2 = run(hello, QString("Bob"));
    f1.waitForFinished();
    f2.waitForFinished();
}


Я делаю так:
void SomeClass::go(){
    QFuture<void> f1 = run(createCache());        
    f1.waitForFinished();
}


На выходе: error: invalid use of void expression

Автор: igor_bogomolov 26.4.2011, 9:04

Цитата(silver47 @ 26.4.2011, 9:39) *
QFuture<void> f1 = run(createCache());
Зачем ты createCache() вызываешь? Там функцию передать надо. Скобки круглые в общем убери
QFuture<void> f1 = run(createCache);

Автор: silver47 26.4.2011, 9:21

Гм... а теперь:
error: no matching function for call to 'run(<unresolved overloaded function type>)'

Вызываю так:

QFuture<void> f1 = run(createCache);
f1.waitForFinished();


createCache - приватная функция класса. Ничего не делает... пустая.

Автор: igor_bogomolov 26.4.2011, 10:07

Цитата(silver47 @ 26.4.2011, 10:21) *
createCache - приватная функция класса. Ничего не делает... пустая.

createCache - должна быть глобальной функцией или статической функцией класса.
Или используй bind для связи, если уж так с методом класса связать надо. http://www.forum.crossplatform.ru/index.php?s=&showtopic=981&view=findpost&p=34900 (в низу сообщения) есть пример

Автор: silver47 26.4.2011, 10:35

В примере не применяется bind(по ссылке я его тоже не нашел):

#include <QDebug>
#include <QThread>
#include <QString>
#include <qtconcurrentrun.h>
#include <QApplication>

using namespace QtConcurrent;
void hello(QString name)
{
    qDebug() << "Hello" << name << "from" << QThread::currentThread();
}

int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    QFuture<void> f1 = run(hello, QString("Alice"));
    QFuture<void> f2 = run(hello, QString("Bob"));
    f1.waitForFinished();
    f2.waitForFinished();
}


Поставим вопрос по-другому:
Возможен ли вызов метода класса таким образом? Если нет, то что можно вызвать?

Автор: wiz29 26.4.2011, 10:39

что конкретно ты пытаешься сделать?

сам по себе метод класса без объекта класса вызвать нельзя.

если этот метод не статический

Автор: silver47 26.4.2011, 10:41

Есть некий класс, один из методов которого нужно выполнить, как бы, в отдельном потоке. Этот метод получает данные по медленному соединению, данных немного.

Советовали воспользоваться QConcurentRun, т.к. он проще потока. Мне кажется, что уже сложнее :)

Автор: wiz29 26.4.2011, 10:50

class A
{
    public:

    void someFunc()
    {
        qDebug()<<"bla"<< a;
    }
    int a;
};
........................
  
    A a;
    a.a = 10;
    QtConcurrent::run(&a, &A::someFunc);
    A b;
    b.a = 20;
    QtConcurrent::run(&b, &A::someFunc);
....................


так подойдет?:)

Автор: silver47 26.4.2011, 11:03

Нет. не могу вызвать это непосредственно из класса.
Спасибо. Пойду в поток заворачивать.

Автор: wiz29 26.4.2011, 11:06

Цитата(silver47 @ 26.4.2011, 12:03) *
Нет. не могу вызвать это непосредственно из класса.
Спасибо. Пойду в поток заворачивать.

покажи кусок кода в котором нужно вызвать.

Автор: silver47 26.4.2011, 11:08

void MainWindow::updateUI(){
    if(socket){
        if (socket->isOpen() && socket->isEncrypted() && mainDB.isOpen()){ // Соединение с сервером установлено            
            // отсюда нужно вызвать this->createCache();
        }
    }
}

void MainWindow::createCache(){
    // some work
}

Автор: wiz29 26.4.2011, 11:09

писать наследника от потока, обычно приходится лишь в крайних случаях, когда нужно специальная функциональность с отдельной петлей обработки событий.

void MainWindow::createCache(){
// some work
}

это нужно вызвать?

Автор: silver47 26.4.2011, 11:10

Да

Автор: wiz29 26.4.2011, 11:25

void MainWindow::updateUI(){
    if(socket){
        if (socket->isOpen() && socket->isEncrypted() && mainDB.isOpen()){ // Соединение с сервером установлено            
            // отсюда нужно вызвать this->createCache();
                       QtConcurrent::run(this, &MainWindow::createCache);

        }
    }
}

void MainWindow::createCache(){
    // some work
}


Автор: Litkevich Yuriy 27.4.2011, 18:24

Цитата(silver47 @ 26.4.2011, 13:35) *
Возможен ли вызов метода класса таким образом? Если нет, то что можно вызвать?
нет, нельзя. просто функцию.
Опиши её в cpp-файле и пометь её как static.

Цитата(wiz29 @ 26.4.2011, 14:25) *
QtConcurrent::run(this, &MainWindow::createCache);
это работает?

Автор: silver47 27.4.2011, 18:28

Цитата(Litkevich Yuriy @ 27.4.2011, 20:24) *
это работает?

Ну по крайней мере выполняется. Пока операция занимает порядка 100 миллисекунд, поэтому сказать точно, выполняется ли это отдельно от потока я не знаю... по отладочным сообщениям вроде как другой поток. Но все равно в планах кеширование вынести в отдельный класс, унаследованный от QThread

Автор: wiz29 28.4.2011, 8:54

Цитата(Litkevich Yuriy @ 27.4.2011, 19:24) *
это работает?

а с какой радости, извините, это не должно работать?

Цитата(silver47 @ 27.4.2011, 19:28) *
Ну по крайней мере выполняется. Пока операция занимает порядка 100 миллисекунд....


Проверить можно элементарно, поставив sleep на несколько секунд.

http://doc.trolltech.com/latest/qtconcurrentrun.html читаем раздел Using Member Functions

Автор: silver47 28.4.2011, 9:04

Цитата(wiz29 @ 28.4.2011, 10:50) *
поставив sleep на несколько секунд.


как sleep ставиться не знаю сделал так:
qDebug() << "Started: " << QTime::currentTime().toString("mm:ss:zzz");
QTime timer;
timer.start();
for(; timer.elapsed() < 10000;){
    //
}


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

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)