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

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

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: suggestion  (Прочитано 40297 раз)
vunder
Гость
« Ответ #15 : Март 14, 2011, 09:05 »

Замена
Код
C++ (Qt)
fSocket = new QTcpSocket(this);
на
Код
C++ (Qt)
fSocket = new QTcpSocket();
fSocket->moveToThread(this);
На на что не влияет. Результат одинаковый. Помогает только thread->moveToThread(thread)
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #16 : Март 14, 2011, 09:24 »

этого кода мало. если вы сокет используете из методов треда, то естесственно тред надо перемещать.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #17 : Март 14, 2011, 21:22 »

неправда! Если так:
Код
C++ (Qt)
Thread::run()
{
...
fSocket = new QTcpSocket();
...
}
 
то QTcpSocket будет в контексте потока создан, и ничо мувить не нужно
а если так:
Код
C++ (Qt)
Thread::run()
{
...
fSocket = new QTcpSocket(this);
...
}
 
то в главном потоке. И так вообще-то буит матюгатся.
Записан

ArchLinux x86_64 / Win10 64 bit
vunder
Гость
« Ответ #18 : Март 14, 2011, 21:42 »

А как на счет
Цитировать
QObject::connect: Cannot queue arguments of type 'QAbstractSocket::SocketError'
(Make sure 'QAbstractSocket::SocketError' is registered using qRegisterMetaType().)
ЧЗХ?
Записан
BRE
Гость
« Ответ #19 : Март 14, 2011, 21:47 »

ЧЗХ?
На форуме есть поиск!!!
http://www.prog.org.ru/topic_11103_0.html
Записан
CL0NE
Гость
« Ответ #20 : Апрель 06, 2011, 03:19 »

К четвертому сообщению могу добавить пару линков
http://blog.exys.org/entries/2010/QThread_affinity.html
http://blog.exys.org/entries/2010/thread_abuse.html

А для себя хотел бы прояснить несколько моментов.
Имеем, к примеру, следующий код:
Код
C++ (Qt)
class HeavyJob : public QObject
{
   Q_OBJECT
public:
   explicit HeavyJob(QObject *parent = 0);
 
   bool isRunning();
 
public slots:
   void start();
   void stop();
 
private:
   bool running;
};
Код
C++ (Qt)
HeavyJob::HeavyJob(QObject *parent) :
   QObject(parent),
   running(false)
{
}
 
bool HeavyJob::isRunning()
{
   return running;
}
 
void HeavyJob::start()
{
   if (running)
       return;
 
   running = true;
   qDebug() << "started";
   while(running)
   {
       for(int i = 0; i < 1000; ++i);
   }
   qDebug() << "stopped";
}
 
void HeavyJob::stop()
{
   qDebug() << "stop()";
   running = false;
}
 
Где-то в GUI:
Код
C++ (Qt)
HeavyJob *job = new HeavyJob();
   QThread *worker = new QThread(this);
   job->moveToThread(worker);
   worker->start();
Код
C++ (Qt)
if (!job->isRunning())
   {
//     job->start(); // 1
       QTimer::singleShot(10, job, SLOT(start())); // 2
   }
   else
   {
       job->stop(); // 3
//        QTimer::singleShot(10, job, SLOT(stop())); // 4
   }
1) Вызываем в контексте текущего потока, не Ъ!
2) Слот отработает в отдельном потоке. Гут.
Вроде бы ясно, а вот дальше
3) Отрабатывает как надо, останавливая поток.
4) Не отправляется, и, соответственно, цикл не останавливается.
Ведь event loop в потоке свой есть, но, я так понимаю, что после получения сигнала, event loop потока ожидает исполнения тела слота, которому назначалось данное событие, чтобы продолжить обработку следующих событий. И следует добавить processEvents() в тело слота. Вот кто бы подтвердил или опровергнул данные утверждения..
« Последнее редактирование: Апрель 10, 2011, 04:12 от CL0NE » Записан
vunder
Гость
« Ответ #21 : Апрель 08, 2011, 19:18 »

Вопрос к гуру.
Топик убедил меня в отсутствие необходимости наследоваться от QThread. Я попытался перевести свой проект на эту технологию, но пока не очень выходит.
Вообще задача такая. Клиент пытается подключиться к серверу. Если не получается подключиться, то запускается таймер ожидания, по истечении которого производится новая попытка подключиться. Данные - xml-документы. Поток данных может быть очень большой, поэтому чтение и обработка обязательно должны быть в отдельном потоке.
Я сделал следующее: объявил класс-наследник от QObject, в классе объявлены члены QTcpSocket socket и Qthread thread. В конструкторе класса делаю
Код
C++ (Qt)
this->moveToThread(&thread);
thread.start();
Если сокет не переносить в поток socket.moveToThread(&thread), то не читаются данные, не скаратывает слот сигнала readyRead, в отладке пишет что-то про QSocketNotifier. Кроме того, приходиться использовать сигнал-слот, чтобы подключаться к серверу, т.к. сокет и мой объект находятся в разных потоках.
Если сокет перенести также в поток, то данные нормально читаются и нет необходимости подключаться через вызов сигнала, можно напрямую socket.connectToHost(), но возникают другие проблемы. При выходе их программы получаю ASSERT, что нельзя вызвать сигнал для объектов из разных потоков.
Весь код привести не могу по 2-м причинам: во-первых, его "нет под рукой", а, во-вторых, часть его утеряна, т.к. для решения других задач пришлось следать откат, но желание разобраться в проблема осталось.
Записан
CL0NE
Гость
« Ответ #22 : Апрель 10, 2011, 04:06 »

Самое интересное, что касательно использования агрегации QThread вместо наследования, то в самом фреймворке и в ассистенте наблюдается противоречие, например, QFileInfoGatherer является наследником QThread. Этот подход и Шлее в своей книге толкает.
Записан
like-nix
Гость
« Ответ #23 : Апрель 10, 2011, 14:17 »

У меня складывается впечатление что заметка в блоге должна называться "we doing it wrong".=) Сори за оффтоп.
Записан
SASA
Гость
« Ответ #24 : Апрель 10, 2011, 15:04 »

Про агрегацию и наследование.
Например, поток делает периодически какие-то действия. Делает, ждёт, делает ...
Так вот, ждать лучше всего sleep'ом. А он защищенный у потока. Так что приходиться наследоваться.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #25 : Апрель 10, 2011, 15:58 »

таймер спасет отца русской демократии
Записан
SASA
Гость
« Ответ #26 : Апрель 10, 2011, 16:26 »

таймер спасет отца русской демократии
Как?
Записан
like-nix
Гость
« Ответ #27 : Апрель 10, 2011, 17:17 »

Я так делал.

Код:
int m_timeInterval = 100;
QTime m_elapsedTime;
m_elapsedTime.start();

if(m_elapsedTime.elapsed() > m_timeInterval)
{
m_elapsedTime.start();
m_elapsedTime.addMSecs(m_timeInterval);
//do smthn
}
« Последнее редактирование: Апрель 10, 2011, 17:28 от like-nix » Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #28 : Апрель 10, 2011, 17:34 »

периодически дергать слот не?
Записан
like-nix
Гость
« Ответ #29 : Апрель 10, 2011, 18:07 »

нужно запускать евент луп =)
Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


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