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

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

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: suggestion  (Прочитано 41159 раз)
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.084 секунд. Запросов: 23.