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

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

Страниц: 1 2 3 [4] 5   Вниз
  Печать  
Автор Тема: MoveToThread (все-таки хочется понять ..)  (Прочитано 47963 раз)
BRE
Гость
« Ответ #45 : Март 20, 2012, 17:48 »

просто потому, что такое решение создает проблемы на пустом месте и менее универсально. возникает два противоречивых требования: с одной стороны, объект QThread, живущий в потоке, хорошо бы уничтожить до завершения потока, но с другой стороны, прежде чем уничтожить QThread мы должны завершить работу потока, прервав цикл обработки событий через QThread::exit().
Ну на самом деле противоречий никаких нет. Понятие "объект QThread живет в потоке" это очень абстрактное понятие, которое было введено в Qt для организации передачи сигналов между потоками. На самом деле все объекты живут в одном адресном пространстве и прямая операция delete корректно этот объект разрушит.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #46 : Март 21, 2012, 14:29 »

Однако же.. как быстро завершились наши архитектурные дебаты  Улыбающийся
Хорошо, попробуем подвести итоги, предлагаю такую формулировку

Наследование от QThread (с эвентуальным moveToThread(this)) не является ошибкой - ни технической, ни архитектурной. Просто такое наследование совсем необязательно, более того, часто агрегация лучше/гибче, т.к. она более логична/идейна

Спасибо за внимание
Записан
Bepec
Гость
« Ответ #47 : Март 21, 2012, 15:20 »

И тебе спасибо за раскрытие данного дела Подмигивающий
Записан
andrew.k
Гость
« Ответ #48 : Май 18, 2012, 18:37 »

У меня есть класс (class Scanner), который дергает блокирующие функции. Поэтому хочу, чтобы они отрабатывали в отдельном потоке, чтоб не вис гуй.
Допустим я захотел сделать его реализацию "архитектурно красиво" (без наследования). Но что-то у меня пока не получается красивости.

Хочу чтобы в итоге выглядело так:
Код
C++ (Qt)
Scanner scanner(this);
scanner.scan() // получаем не блокирующий вызов, который выполняется в отдельном потоке и не тормозит основной.

Сделать в одном классе не получается. Получается нужно делать два класса. Собственно Scanner и ScannerWorker (в котором будет реализация). А если делать это в одном классе, то нельзя будет создавать Scanner имеющим родителя.
А с двумя классами получается нужно будет воркер выносить в ашник, чего бы не хотелось. Зачем он там нужен? Не это ли недостаток такой концепции?

Или я что-то не так делаю?
Записан
V1KT0P
Гость
« Ответ #49 : Май 18, 2012, 18:49 »

Или я что-то не так делаю?
Тут проблема в том что нельзя просто вызвать слот не соединяя его с сигналом. Меня это например бесит. В итоге класс напоминает примерно следующее:
Код
C++ (Qt)
class SomeClass : public QObject
{
   Q_OBJECT
public:
   explicit SomeClass(QObject *parent = 0);
 
signals:
   void workSignal();
 
public slots:
   void work();
   void nonBlockWork();
 
};
Код
C++ (Qt)
SomeClass::SomeClass(QObject *parent) :
   QObject(parent)
{
   connect(this, SIGNAL(workSignal()), this, SLOT(work()));
}
 
void SomeClass::work()
{
}
 
void SomeClass::nonBlockWork()
{
   emit workSignal();
}
Записан
Странник
Гость
« Ответ #50 : Май 18, 2012, 19:58 »

Тут проблема в том что нельзя просто вызвать слот не соединяя его с сигналом. Меня это например бесит.
серьезно?
Код:
QMetaObject::invokeMethod(someClass, "work", Qt::QueuedConnection);
Записан
V1KT0P
Гость
« Ответ #51 : Май 18, 2012, 20:10 »

Тут проблема в том что нельзя просто вызвать слот не соединяя его с сигналом. Меня это например бесит.
серьезно?
Код:
QMetaObject::invokeMethod(someClass, "work", Qt::QueuedConnection);
Вот это да, а я этого не знал. Большое спасибо.
Записан
DmitryM
Гость
« Ответ #52 : Май 23, 2012, 10:19 »

Не очень понял весь сыр бор из-за MoveToThread, когда у connect есть пятый параметр.
Код:
bool QObject::connect ( const QObject * sender, const char * signal, const QObject * receiver, const char * method, Qt::ConnectionType type = Qt::AutoConnection ) [static]
Записан
Bepec
Гость
« Ответ #53 : Май 23, 2012, 10:23 »

DmitryM - если не поняли, лучше спросить, а не тыкать строку из ассистента Подмигивающий

Обсуждение было закончено.

PS а тема собственно - полезно, вредно или безразлично использование moveToThread.
Записан
DmitryM
Гость
« Ответ #54 : Май 23, 2012, 10:34 »

DmitryM - если не поняли, лучше спросить, а не тыкать строку из ассистента Подмигивающий

Обсуждение было закончено.

PS а тема собственно - полезно, вредно или безразлично использование moveToThread.
Кок раз из-за этого пятого параметра можно не думать где находиться принимающий объект.
Записан
mutineer
Гость
« Ответ #55 : Май 23, 2012, 10:36 »

Кок раз из-за этого пятого параметра можно не думать где находиться принимающий объект.

Вопрос не в том, где находится принимающий объект, а в том, корректно ли перемещать экземпляр QThread в поток, которым он управляет (this->moveToThread(this))
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #56 : Май 23, 2012, 10:51 »

Кок раз из-за этого пятого параметра можно не думать где находиться принимающий объект.
Думать всегда полезно.
В каком потоке выполняется код - важная вещь, которая определяет нужна ли защита потоконебезопасных данных, где могут возникать дэдлоки, в конце концов какой из потоков будет фризиться на время выполнения слота (например надолго фризящийся гуёвый поток у пользователя вызывает негативные эмоции).

Ну и опять же про пятый парметр, как показывает практика большинство новичков считает что:
Код
C++ (Qt)
myThread = new MyThread( this );
connect ( ui->pushButton, SIGNAL( clicked() ), muThread, SLOT( doWork() ), Qt::QueuedConnection );
myThread->start();
обеспечит выполнение doWork() в созданном потоке.
Записан
DmitryM
Гость
« Ответ #57 : Май 24, 2012, 09:49 »

Ну и опять же про пятый парметр, как показывает практика большинство новичков считает что:
Код
C++ (Qt)
myThread = new MyThread( this );
connect ( ui->pushButton, SIGNAL( clicked() ), muThread, SLOT( doWork() ), Qt::QueuedConnection );
myThread->start();
обеспечит выполнение doWork() в созданном потоке.
Кто, где и чем делают таких новичков?

У меня есть класс (class Scanner), который дергает блокирующие функции. Поэтому хочу, чтобы они отрабатывали в отдельном потоке, чтоб не вис гуй.
Допустим я захотел сделать его реализацию "архитектурно красиво" (без наследования). Но что-то у меня пока не получается красивости.

Хочу чтобы в итоге выглядело так:
Код
C++ (Qt)
Scanner scanner(this);
scanner.scan() // получаем не блокирующий вызов, который выполняется в отдельном потоке и не тормозит основной.

Сделать в одном классе не получается. Получается нужно делать два класса. Собственно Scanner и ScannerWorker (в котором будет реализация). А если делать это в одном классе, то нельзя будет создавать Scanner имеющим родителя.
А с двумя классами получается нужно будет воркер выносить в ашник, чего бы не хотелось. Зачем он там нужен? Не это ли недостаток такой концепции?

Или я что-то не так делаю?
Код
C++ (Qt)
class CScaner: public QThread
{
public:
 
CScaner( QObject * parent = 0):QThread(parent)
{
}
 
void scan()
{
start(QThread::NormalPriority);
};
 
//...
 
protected:
virtual void run()
{
reallyLongMethod();
emit image(/*...*/);
}
private:
 
void reallyLongMethod()
{
// ....
}
};
 
CMyWidget::foo()
{
CScaner* scaner = new CScaner(this);
scaner->deleteLater();
connect(scaner, SIGNAL(image(/*...*/)), this, SLOT(setImageScan(/*....*/)));
connect(scaner, SIGNAL(finished()), scaner, SLOT(deleteLater());
}
 
ЧЯДНТ?
Записан
Bepec
Гость
« Ответ #58 : Май 24, 2012, 10:07 »

Дмитрий, вы "со свинным рылом в оружейный ряд" суётесь.

Тут была битва по другой теме, другому поводу и охватывающая более сложные конструкции, нежели ваш пример Подмигивающий

Ключевое слово БЫЛА Улыбающийся
Записан
andrew.k
Гость
« Ответ #59 : Май 25, 2012, 23:15 »

ЧЯДНТ?
Быдлосленг еще не умер?

Как бы спасибо, конечно, но зачем ты это выложил?
Прочитал бы тему с начала. Я спрашивал, как сделать в одном классе не переопределяя run!
Записан
Страниц: 1 2 3 [4] 5   Вверх
  Печать  
 
Перейти в:  


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