На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела *nix / gcc / Eclipse / Qt / wxWidgets / GTK+
  • При создании темы ОБЯЗАТЕЛЬНО указывайте версию тулкита / библиотеки / компилятора.
  • Перед тем как задать вопрос, сформулируйте его правильно, чтобы вас могли понять.
  • Нарушение Правил может повлечь наказание со стороны модераторов.


Полезные ссылки:
user posted image Boost по-русски
user posted image Qt по-русски
Модераторы: archimed7592
  
> QDialog
    попытался создать диалог, который при создании создает таймер и обновляет иконку.
    Тоесть я хочу его запускать при длительных операциях для отображения окна действия пользователя.

    ExpandedWrap disabled
      QDialog dialog;
      dialog.show();
      ...
      // долгие расчеты, возможно в разных потоках и с синхронизацией
      Sleep (10000); // эмуляция
      ...
       
      dialog.hide();


    Но таймер не срабатывает. Было предположение, что таймер работает в контексте GUI-потока.
    Попытался вместо таймера использовать поток. Кричит, что нельзя изменять компанент созданный в GUI-потоке из другого потока.

    Создал этот диалог вообще в отдельном потоке - таже фигня.

    Как создать такой диалог ?

    Добавлено
    P.S. Вся проблемма в том, что нужен именно диалог в отдельном поке, а не обработка данных. Т.к. при обработке данных обновляются
    компаненты, созданные в GUI-потоке.
      Цитата zss @
      Создал этот диалог вообще в отдельном потоке - таже фигня.

      Ты в отдельном потоке метод exec, который проталкивает очередь сообщений, вызываешь?
        Цитата Flex Ferrum @
        Ты в отдельном потоке метод exec, который проталкивает очередь сообщений, вызываешь?

        так exec для диалога это синхронный вызов окна (на сколько я понял)
          Цитата zss @
          так exec для диалога это синхронный вызов окна (на сколько я понял)

          Да нет. У самого потока есть метод exec.
            Цитата Flex Ferrum @
            Да нет. У самого потока есть метод exec.

            я не использую Qt-потоки :) я использую boost...
              Цитата zss @
              я не использую Qt-потоки :) я использую boost...

              Хех. Ну тогда ищи класс QEventLoop, и дергай у его экземпляра, созданного в потоке, метод processEvents.
                Цитата Flex Ferrum @
                Хех. Ну тогда ищи класс QEventLoop, и дергай у его экземпляра, созданного в потоке, метод processEvents.

                а можно ли все-таки создать поток в самом диалоге, чтою не плодить потоки из первичного потока ?
                  Цитата zss @
                  а можно ли все-таки создать поток в самом диалоге, чтою не плодить потоки из первичного потока ?

                  Если только ты во время твоих длительных вычислений будешь руками толкать сообщения.
                    Цитата Flex Ferrum @
                    Если только ты во время твоих длительных вычислений будешь руками толкать сообщения.

                    не получится - дергаеются методы библиотек, которые не возвращают управления до завершения :(
                      Цитата zss @
                      не получится - дергаеются методы библиотек, которые не возвращают управления до завершения

                      Тогда, если эти библиотеки не просят callback'и, только в отдельном потоке. И, кстати, элементы основного потока у тебя (при таком раскладе) врядли будут перерисовываться.
                        Цитата Flex Ferrum @
                        И, кстати, элементы основного потока у тебя (при таком раскладе) врядли будут перерисовываться.

                        при каком ? Если создаю в отдельном потоке ?

                        З.Ы. Ну принципе элементы основного потока и не так выжны...
                          Цитата zss @
                          при каком ? Если создаю в отдельном потоке ?

                          При любом.
                            Цитата Flex Ferrum @
                            При любом.

                            ну так и при показе обычного диалога этого не происходит. Это же никому не мешает
                              zss
                              я так понял, что хочешь создать диалог в не gui-потоке?

                              или диалог создается в gui-потоке и отображается во время длительных операций в другом, не gui-потоке?
                              Т.е. пользователь может сделать что-то с программой, пока в параллельном потоке что-то выполняется?
                              для чего таймер?
                                Цитата gryz @
                                для чего таймер?

                                таймер у меня в диалоге для смены картинки. Но ни разу не срабатывает. Кроме того сам диалог не перетаскивается. Он не реагирует на действия пользователя вообще.

                                Цитата gryz @
                                я так понял, что хочешь создать диалог в не gui-потоке?

                                да нет. хочу как раз в GUI-потоке. но после того как
                                ExpandedWrap disabled
                                  dialog.show();
                                  Sleep (10000);


                                на Sleep замирает весь GUI и диалог не отрисовывается.

                                Flex Ferrum, я попробовал создать QThread и вызывать exec. Не дает он создавать Widget в не GUI-потоке.
                                Или я чего-то не понял ?
                                ExpandedWrap disabled
                                  void fmMain::start (void)
                                  {
                                      m_stopped = false;
                                      QThread::start ();
                                  }
                                  void fmMain::stop (void)
                                  {
                                      m_stopped = true;
                                      QThread::wait ();
                                  }
                                  void Console::run (void)
                                  {
                                      QWaitDialog dialog ("Running...");
                                      while (!m_stopped)
                                      {
                                          QThread::exec();
                                          QThread::msleep (100);
                                      }
                                  }
                                  void fmMain::func ()
                                  {
                                      start   ();
                                      Sleep   (5000);
                                      stop    ();
                                  }
                                  Цитата zss @
                                  Flex Ferrum, я попробовал создать QThread и вызывать exec. Не дает он создавать Widget в не GUI-потоке.

                                  Это как?
                                    Говорит что Widget можно создать только в перыичном потоке.
                                    Это отладочное сообщение Qt. Там еще приводятся ID потоков и показываются что они разные
                                      Вообщем, читай и думай:
                                      Цитата
                                      QObject Reentrancy
                                      QObject is reentrant. Most of its non-GUI subclasses, such as QTimer, QTcpSocket, QUdpSocket, QHttp, QFtp, and QProcess, are also reentrant, making it possible to use these classes from multiple threads simultaneously. Note that these classes are designed to be created and used from within a single thread; creating an object in one thread and calling its functions from another thread is not guaranteed to work. There are three constraints to be aware of:
                                      The child of a QObject must always be created in the thread where the parent was created. This implies, among other things, that you should never pass the QThread object (this) as the parent of an object created in the thread (since the QThread object itself was created in another thread).
                                      Event driven objects may only be used in a single thread. Specifically, this applies to the timer mechanism and the network module. For example, you cannot start a timer or connect a socket in a thread that is not the object's thread.
                                      You must ensure that all objects created in a thread are deleted before you delete the QThread. This can be done easily by creating the objects on the stack in your run() implementation.
                                      Although QObject is reentrant, the GUI classes, notably QWidget and all its subclasses, are not reentrant. They can only be used from the main thread. As noted earlier, QCoreApplication::exec() must also be called from that thread.
                                      In practice, the impossibility of using GUI classes in other threads than the main thread can easily be worked around by putting time-consuming operations in a separate worker thread and displaying the results on screen in the main thread when the worker thread is finished. This is the approach used for implementing the Mandelbrot and the Blocking Fortune Client example.


                                      Добавлено
                                      Т. е., по идее, ты можешь создать диалог в другом потоке, но у этого диалога должен отсутствовать родитель.
                                        Цитата Flex Ferrum @
                                        Вообщем, читай и думай:
                                        Цитата
                                        QObject Reentrancy
                                        QObject is reentrant. Most of its non-GUI subclasses, such as QTimer, QTcpSocket, QUdpSocket, QHttp, QFtp, and QProcess, are also reentrant, making it possible to use these classes from multiple threads simultaneously. Note that these classes are designed to be created and used from within a single thread; creating an object in one thread and calling its functions from another thread is not guaranteed to work. There are three constraints to be aware of:
                                        The child of a QObject must always be created in the thread where the parent was created. This implies, among other things, that you should never pass the QThread object (this) as the parent of an object created in the thread (since the QThread object itself was created in another thread).
                                        Event driven objects may only be used in a single thread. Specifically, this applies to the timer mechanism and the network module. For example, you cannot start a timer or connect a socket in a thread that is not the object's thread.
                                        You must ensure that all objects created in a thread are deleted before you delete the QThread. This can be done easily by creating the objects on the stack in your run() implementation.
                                        Although QObject is reentrant, the GUI classes, notably QWidget and all its subclasses, are not reentrant. They can only be used from the main thread. As noted earlier, QCoreApplication::exec() must also be called from that thread.
                                        In practice, the impossibility of using GUI classes in other threads than the main thread can easily be worked around by putting time-consuming operations in a separate worker thread and displaying the results on screen in the main thread when the worker thread is finished. This is the approach used for implementing the Mandelbrot and the Blocking Fortune Client example.


                                        Добавлено
                                        Т. е., по идее, ты можешь создать диалог в другом потоке, но у этого диалога должен отсутствовать родитель.

                                        Цитата Flex Ferrum @
                                        Вообщем, читай и думай:

                                        ну я не знаю что тут написано (с английским проблемма)

                                        но вот код потока, в котором диалог не имеет родителя
                                        ExpandedWrap disabled
                                          void fmMain::run (void)
                                          {
                                              QWaitDialog dialog;
                                              dialog.show();
                                           
                                              while (true);
                                           
                                              dialog.hide();
                                          }


                                        И вот сообщение QT

                                        Добавлено
                                        P.S. Кстати - почему эти диалоги показываются там где захотят. Как заставить их покацываться по центру MainWindow ?
                                        Прикреплённая картинка
                                        Прикреплённая картинка
                                          Вот, собственно, существенная часть:
                                          Цитата Flex Ferrum @
                                          In practice, the impossibility of using GUI classes in other threads than the main thread can easily be worked around by putting time-consuming operations in a separate worker thread and displaying the results on screen in the main thread when the worker thread is finished. This is the approach used for implementing the Mandelbrot and the Blocking Fortune Client example.

                                          "На практике, невозможность использования GUI-классов в других потоках, отличных от главного, может быть несложно обойдена путем расположения сложных и ресурсоемких операций в отдельных (рабочих) потоках, а отображать результаты их работы в основном потоке, когда рабочие потоки будут завершены. Такой подход использован в примерах "Mandelbrot" и "Blocking Fortune Client".
                                            Цитата Flex Ferrum @
                                            "На практике, невозможность использования GUI-классов в других потоках, отличных от главного, может быть несложно обойдена путем расположения сложных и ресурсоемких операций в отдельных (рабочих) потоках, а отображать результаты их работы в основном потоке, когда рабочие потоки будут завершены. Такой подход использован в примерах "Mandelbrot" и "Blocking Fortune Client".

                                            тоесть не диалон в потоке, обработка данных ?

                                            Но тогда возникает сложность. Пусть есть пара десятков методов, которые занимаются общетом данных.
                                            Тоесть каждый из них нужно запускать в отдельном потоке. Для этого нужно создать такое же количесто потокомых методов.
                                            В основнфх методах запускать диалог и из него дергать потоковый.

                                            Не слишком ли много кода ? Да и как создать такие потоки, если унаследовшись от QThread я имею только один поток (метод run).
                                              Цитата zss @
                                              тоесть не диалон в потоке, обработка данных ?

                                              Ну да. А как ты в основном потоке обработку данных делал? Последовательно, небось? Так же и тут. Числодробилку запускай в отдельном потоке, а в основном - отображай прогрессбар, гуевые элементы обновляй и все такое прочее. Я особых проблем не вижу.
                                                Flex Ferrum, так как в отдельном потоке при помощи QThread, если там один фиртуальный метод, а у меня их десяток
                                                  Цитата zss @
                                                  если там один фиртуальный метод, а у меня их десяток

                                                  Десяток чего? Потоков? Или методов?
                                                    zss
                                                    Значит, диалог немодальный? Ведь модальный должен отображаться при помощи метода exec().
                                                    Каким образом привязываешь таймер к диалогу?
                                                    Какого рода вычисления должны при этом выполняться?
                                                      Цитата Flex Ferrum @
                                                      Десяток чего? Потоков? Или методов?

                                                      методов, которые должны запускаться в отдельных потоках


                                                      Цитата gryz @
                                                      Значит, диалог немодальный? Ведь модальный должен отображаться при помощи метода exec().

                                                      наверное не модальный, т.к. exec не позволит запустить поток, пока не вернется управление из него


                                                      Цитата gryz @
                                                      Каким образом привязываешь таймер к диалогу?

                                                      создаю в конструкторе диалога таймер и запускаю его. В деструкторе убиваю


                                                      Цитата gryz @
                                                      Какого рода вычисления должны при этом выполняться?

                                                      вычисления - просто вызов методов, которые долго работают
                                                        Цитата zss @
                                                        методов, которые должны запускаться в отдельных потоках

                                                        Передавай методы по указателям. Или, действительно, используй бустовские потоки.
                                                          Цитата zss @
                                                          наверное не модальный, т.к. exec не позволит запустить поток, пока не вернется управление из него

                                                          Что за поток?
                                                          Для чего его запускать после показа диалога?

                                                          -Added
                                                          Цитата zss @
                                                          создаю в конструкторе диалога таймер и запускаю его. В деструкторе убиваю

                                                          и используешь для замера времени сигнал timeout()?
                                                          тогда должно все работать.
                                                            Цитата Flex Ferrum @
                                                            Передавай методы по указателям. Или, действительно, используй бустовские потоки.

                                                            Куда передавать ? Я так понят от Qt потоков можно только наследоваться.Просто я не работал с Qt-потоками. (может конечно и boost использовать, но хочется разобраться :))

                                                            Цитата gryz @
                                                            Для чего его запускать после показа диалога?

                                                            ну смотри
                                                            ExpandedWrap disabled
                                                              dialog.exec();
                                                              startLongTimeFunction();
                                                              dialog.hide();


                                                            как ты думаешь - вызовется ли эта функция, пока диалог, показанный exec не закроется ?

                                                            Цитата gryz @
                                                            и используешь для замера времени сигнал timeout()?

                                                            ну а как еще обработать таймер. Конечно использую сигнал и изменяю в обработчике картинку.

                                                            P.S. Или я что-то не понимаю. Можно тогда простой примерчик
                                                              Цитата zss @
                                                              Я так понят от Qt потоков можно только наследоваться.Просто я не работал с Qt-потоками. (может конечно и boost использовать, но хочется разобраться :))

                                                              Наследуешься, в конструкторе принимаешь указатель на функцию или функтор, в run его вызываешь. Какие проблемы?
                                                                Цитата Flex Ferrum @
                                                                Наследуешься, в конструкторе принимаешь указатель на функцию или функтор, в run его вызываешь. Какие проблемы?

                                                                Тоесть должен быть отдельный класс-поток ? Просто я думал QMainWindow от него унаследовать :)

                                                                Тут еще проблемма. Что если сигнатура методов различна. И как поведет себя приложение если в потоковом
                                                                методе произойдет исключение. Просто я его ловлю и вызываю соответствующие (разные) диалоговые сообщения.

                                                                Как мне тогда из потока сказать, что ничего не получилось.

                                                                Добавлено
                                                                P.S. Да кстати - и как тогда обмениваться данными с потоком ?
                                                                  Цитата zss @
                                                                  ExpandedWrap disabled
                                                                    dialog.exec();
                                                                    startLongTimeFunction();
                                                                    dialog.hide();

                                                                  функция gui-потоке выполняется?
                                                                    Цитата gryz @
                                                                    функция gui-потоке выполняется?

                                                                    она библиотечная. Выполняется в GUI, но может создавать внутри себя еще потоки
                                                                      Цитата zss @
                                                                      Просто я думал QMainWindow от него унаследовать

                                                                      Ни в коем случае.

                                                                      Цитата zss @
                                                                      Тоесть должен быть отдельный класс-поток ?

                                                                      Ну да. Только обобщенный.

                                                                      Цитата zss @
                                                                      Тут еще проблемма. Что если сигнатура методов различна.

                                                                      boost::function спасет отца русской демократии.

                                                                      Цитата zss @
                                                                      И как поведет себя приложение если в потоковом
                                                                      методе произойдет исключение. Просто я его ловлю и вызываю соответствующие (разные) диалоговые сообщения.

                                                                      Можешь точно также - через boost::function передать указатель на функцию-обработчик исключения.
                                                                        Цитата Flex Ferrum @
                                                                        boost::function спасет отца русской демократии.

                                                                        это точно :)


                                                                        Цитата Flex Ferrum @
                                                                        Можешь точно также - через boost::function передать указатель на функцию-обработчик исключения

                                                                        а данные для обработки в конструкторе передавать ? Просто они тоже разные. И возвращаются точе разные типы.
                                                                        С функциями понял а как с данными быть.
                                                                        Например мне нужно отдать ссылку на Type1, который будет измененн при успешных вычислениях.
                                                                        Но для метода2 нужно отдать Type2.

                                                                        Как тут быть ?
                                                                          Цитата zss @
                                                                          Например мне нужно отдать ссылку на Type1, который будет измененн при успешных вычислениях.
                                                                          Но для метода2 нужно отдать Type2.

                                                                          Как тут быть ?

                                                                          Прочитать доку на boost::function и boost::ref.
                                                                            Цитата Flex Ferrum @
                                                                            Прочитать доку на boost::function и boost::ref.

                                                                            Цитата zss @
                                                                            ну я не знаю что тут написано (с английским проблемма)


                                                                            только на примерах могу :(
                                                                              Цитата zss @
                                                                              ну я не знаю что тут написано (с английским проблемма)

                                                                              boost::function
                                                                                Цитата Flex Ferrum @
                                                                                boost::function

                                                                                :)

                                                                                Добавлено
                                                                                Я читал данну статью.

                                                                                Но boost::function не решит проблемму.

                                                                                Например метоы
                                                                                ExpandedWrap disabled
                                                                                  voif f1 (void);
                                                                                  bool f2 (void);
                                                                                  voif f3 (bool);
                                                                                  bool f4 (bool);
                                                                                  Type1 f5 (void);
                                                                                  voif f6 (Type1);
                                                                                  bool f7 (Type1);


                                                                                врядли их все можно запихнуть в один потоковый класс
                                                                                  Цитата zss @
                                                                                  врядли их все можно запихнуть в один потоковый класс

                                                                                  Можно, используя boost::bind.
                                                                                    Цитата Flex Ferrum @
                                                                                    Можно, используя boost::bind.

                                                                                    блин... я чего-то не понимаю

                                                                                    Вот пример бустовского потока
                                                                                    ExpandedWrap disabled
                                                                                      class BoostThread : private boost::noncopyable {
                                                                                      private :
                                                                                          boost::thread m_thread;
                                                                                       
                                                                                      public :
                                                                                          explicit BoostThread (const boost::function0<void>& func)
                                                                                              : m_thread (func) {}
                                                                                          ~BoostThread () { m_thread.join(); }
                                                                                       
                                                                                          static void sleep (unsigned msec);
                                                                                      };


                                                                                    он принимает boost::function0. Хоть упрись, но он не будет принимать boost::function1
                                                                                    Тоесть получается что для каждого метода свой потоковый класс писать ?
                                                                                    Сообщение отредактировано: zss -
                                                                                      Цитата zss @
                                                                                      Тоесть получается что для каждого метода свой потоковый класс писать ?

                                                                                      Да нет. Пишешь так:

                                                                                      ExpandedWrap disabled
                                                                                        void Foo1(int)
                                                                                        {
                                                                                        }
                                                                                         
                                                                                        //...
                                                                                        boost::thread t(boost::bind(&Foo1, 10));
                                                                                        //...

                                                                                      и все. :)
                                                                                        Цитата Flex Ferrum @
                                                                                        и все.

                                                                                        че правда чтоли :)

                                                                                        1. А как тогда быть с обработкой исключений. Здесь нельзя зарегистрировать callback.
                                                                                        или достатчно

                                                                                        ExpandedWrap disabled
                                                                                          try{
                                                                                              boost::thread t(boost::bind(&Foo1, 10));
                                                                                          }
                                                                                          catch (...) {...}


                                                                                        2. Как сбиндить
                                                                                        ExpandedWrap disabled
                                                                                          unsigned Foo1(int)
                                                                                          {
                                                                                          }


                                                                                        чтоб получить результат

                                                                                        3. и можно ли тут шаблонить ?
                                                                                          Цитата zss @
                                                                                          1. А как тогда быть с обработкой исключений. Здесь нельзя зарегистрировать callback.
                                                                                          или достатчно

                                                                                          Не. Лучше не так, а вот так:
                                                                                          ExpandedWrap disabled
                                                                                            class WorkerThread : public QThread
                                                                                            {
                                                                                            public:
                                                                                               WorkerThread(boost::function<void ()> worker, boost::function<void (const std::exception&)> xHandler) : m_Worker(worker), m_ExHandler(handler) {;}
                                                                                               int run()
                                                                                               {
                                                                                                  try
                                                                                                  {
                                                                                                     m_Worker();
                                                                                                  }
                                                                                                  catch (const std::exception& ex)
                                                                                                  {
                                                                                                     m_ExHandler(ex);
                                                                                                  }    
                                                                                               }
                                                                                            };
                                                                                            Цитата Flex Ferrum @
                                                                                            Не. Лучше не так, а вот так:

                                                                                            понятно - спасибо.

                                                                                            А как на счет п.2. Нужен свой поток ?

                                                                                            Тогда получается, что для 5 функций нужно 5 обработчиков исключений (если в обработчике не возвращать код) и 5 запускающих функций, которые создают диалоги и запускают потоки

                                                                                            N * 3 - круто...
                                                                                              Цитата zss @
                                                                                              5 обработчиков исключений (если в обработчике не возвращать код) и 5 запускающих функций, которые создают диалоги и запускают потоки

                                                                                              Хм. Ну, если другого выхода не находишь, то да...
                                                                                                Цитата Flex Ferrum @
                                                                                                Хм. Ну, если другого выхода не находишь, то да...

                                                                                                выход есть - заставить диалог работать в другом потоке. и тогда нужен только один поток для запуска диалога. Иначе... лучше вообще без диалога, но тут могут возникнуть непонятки со стороны пользователяЮ когда приложение не отвечает в течении 1 минуты и более :)

                                                                                                Добавлено
                                                                                                идея! У меня все методы долгих обработок - это слоты QAction. А что если подписать их на один метод
                                                                                                и в этом методе создать диалог и запустить потоковые метоты простым бустом ?

                                                                                                Единственное - обработка исключений в потке - это нормально ?
                                                                                                  А что ты не хочешь Qt-шные потоки юзать? Создал в основном потоке диалог, после чего запускаешь поток. Можешь в Qt-шный поток добавить сигналы о том, что поток завершен, что возникла ошибка и проч...

                                                                                                  Добавлено
                                                                                                  Я просто не могу понять - какой архитектуры ты пытаешься достигнуть? Что должно получиться в результате?
                                                                                                    Цитата Flex Ferrum @
                                                                                                    А что ты не хочешь Qt-шные потоки юзать? Создал в основном потоке диалог, после чего запускаешь поток. Можешь в Qt-шный поток добавить сигналы о том, что поток завершен, что возникла ошибка и проч...

                                                                                                    тоесть на кждый поток 2 слота. Ведь ошибки разные


                                                                                                    Цитата Flex Ferrum @
                                                                                                    Я просто не могу понять - какой архитектуры ты пытаешься достигнуть? Что должно получиться в результате?

                                                                                                    Да наверное мы друг-друга не понимаем...

                                                                                                    Идея проста - перед запуском долгой функции показать диалог, а по ее завершении убить диалог.

                                                                                                    Ну например
                                                                                                    ExpandedWrap disabled
                                                                                                      struct Client
                                                                                                      {
                                                                                                          bool start      (void) const;
                                                                                                          bool pause      (void) const;
                                                                                                          bool stop           (void) const;
                                                                                                          unsigned power      (void) const;
                                                                                                          WF_STATE state      (void) const;
                                                                                                          bool shutdown       (void);
                                                                                                          bool reboot     (void);
                                                                                                       
                                                                                                          Options options     (void) const;
                                                                                                          bool setOptions     (const Options& options) const;
                                                                                                       
                                                                                                          bool loadSettings   (const std::string& name) const;
                                                                                                          bool setSettings    (const TSettings& settings) const;
                                                                                                          TSettings settings  (void) const;
                                                                                                      };


                                                                                                    Все методы могут быть долгими. Это общение посети.
                                                                                                    QMainWindow владеет клиентом и при событии (QAction) дергает тот или иной метод
                                                                                                    ExpandedWrap disabled
                                                                                                      MainWindow::f1 ()
                                                                                                      {
                                                                                                          try
                                                                                                          {
                                                                                                              client.start();
                                                                                                          }
                                                                                                          catch (std::exception& ex)
                                                                                                          {
                                                                                                              MessageBox (...);
                                                                                                          }
                                                                                                      }
                                                                                                      MainWindow::f2 ()
                                                                                                      {
                                                                                                          try
                                                                                                          {
                                                                                                              m_options = client.options();
                                                                                                          }
                                                                                                          catch (std::exception& ex)
                                                                                                          {
                                                                                                              MessageBox (...);
                                                                                                          }
                                                                                                      }
                                                                                                      MainWindow::f3 ()
                                                                                                      {
                                                                                                          try
                                                                                                          {
                                                                                                              client.setOptions(m_options);
                                                                                                          }
                                                                                                          catch (std::exception& ex)
                                                                                                          {
                                                                                                              MessageBox (...);
                                                                                                          }
                                                                                                      }


                                                                                                    А теперь хотелось бы с диалогом
                                                                                                    ExpandedWrap disabled
                                                                                                      MainWindow::f2 ()
                                                                                                      {
                                                                                                          try
                                                                                                          {
                                                                                                              QWaitDialog dialog;
                                                                                                              dialog.show();
                                                                                                              m_options = client.options();
                                                                                                              dialog.hide();
                                                                                                          }
                                                                                                          catch (std::exception& ex)
                                                                                                          {
                                                                                                              MessageBox (...);
                                                                                                          }
                                                                                                      }


                                                                                                    вот и все. впринципе слоты имеют одну сигнатуры поэтому можно использовать массив методов или boost::bind.
                                                                                                    С этим я понял. Но вот исключения в потоке ?

                                                                                                    Если для потока создать сигнал ошибки, то можно конечно создать общий обработчик и передавать в него например сообщение об ошибке.

                                                                                                    Я правильно тебя понял ?
                                                                                                      Т. е. у тебя может быть одновременно показано несколько диалогов?

                                                                                                      Добавлено
                                                                                                      Ты, я так понимаю, что-то типа чата пишешь?
                                                                                                        Цитата Flex Ferrum @
                                                                                                        Т. е. у тебя может быть одновременно показано несколько диалогов?

                                                                                                        нет. один диалог на каждый метод.


                                                                                                        Цитата Flex Ferrum @
                                                                                                        Ты, я так понимаю, что-то типа чата пишешь?

                                                                                                        не - просто сетевое управление комплексами :)
                                                                                                          Тут смотри, какой момент. По идее (если ты потоки сделаешь на QThread), то ты можешь цеплять сигнал о возникновении ошибке сразу к диалогу. Т. е.:
                                                                                                          ExpandedWrap disabled
                                                                                                            MainWindow::f2 ()
                                                                                                            {
                                                                                                                try
                                                                                                                {
                                                                                                                    QWaitDialog dialog;
                                                                                                                    QConnectThread thread(); // тут сам придумаешь, что написать.
                                                                                                                    connect(&thread, SIGNAL(ThreadEnd()), &dialog, SLOT(ThreadEnded()));
                                                                                                                    connect(&thread, SIGNAL(ThreadError(const QString&)), &dialog, SLOT(ThreadError(const QString&)));
                                                                                                                    thread.start();
                                                                                                                    dialog.show();
                                                                                                                    thread.wait(); // или что тут должно быть?
                                                                                                                    // m_options = client.options();    
                                                                                                                    dialog.hide();
                                                                                                                }
                                                                                                                catch (std::exception& ex)
                                                                                                                {
                                                                                                                    MessageBox (...);
                                                                                                                }
                                                                                                            }


                                                                                                          Добавлено
                                                                                                          Цитата zss @
                                                                                                          нет. один диалог на каждый метод.

                                                                                                          Т. е. диалоги, по сути, модальные?
                                                                                                            а зачем тогда здесь обработка исключений ?
                                                                                                              Цитата zss @
                                                                                                              а зачем тогда здесь обработка исключений ?

                                                                                                              Не знаю. Но исключение чужого потока ты не поймаешь.
                                                                                                                Цитата Flex Ferrum @
                                                                                                                Не знаю. Но исключение чужого потока ты не поймаешь.

                                                                                                                а мне не нужно его ловить. оно ловится в самом потоке. Меня смущает смогу ли я из другого потока показать MessageBox ?
                                                                                                                  Цитата zss @
                                                                                                                  Меня смущает смогу ли я из другого потока показать MessageBox ?

                                                                                                                  Нет. Не можешь. Но ты можешь дернуть сигнал, который это сделает из основного потока.
                                                                                                                    Цитата Flex Ferrum @
                                                                                                                    Нет. Не можешь. Но ты можешь дернуть сигнал, который это сделает из основного потока.

                                                                                                                    ну впринципе выход.

                                                                                                                    Тогда получается что сигналы потока мне вообще не нужны. Я все сделаю в самом потоке - я имею ввиду откат и т.п.
                                                                                                                      Цитата zss @
                                                                                                                      Тогда получается что сигналы потока мне вообще не нужны. Я все сделаю в самом потоке - я имею ввиду откат и т.п.

                                                                                                                      В смысле? Нужны. А как ты сообщишь основному потоку (т. е. диалогу) о том, что произошла нештатная ситуация? Это раз. Второй момент - механизм сигналов/слотов в Qt потокобезопасный. По сути, это единственный корректный способ обмениваться сообщениями между потоками. При этом ты (при вызове функции connect) должен передать пятый параметр - Qt::QueuedConnection. Тогда поступающие в основной поток сигналы от рабочих потоков будут корректно буферизироваться и обрабатываться.
                                                                                                                        тоесть полубому 2 слота для обработки ?

                                                                                                                        Тогда не совсем понятно.
                                                                                                                        1.

                                                                                                                        ExpandedWrap disabled
                                                                                                                                  thread.start();
                                                                                                                                  dialog.show();
                                                                                                                                  thread.wait(); // или что тут должно быть?
                                                                                                                                  // m_options = client.options();    
                                                                                                                                  dialog.hide();


                                                                                                                        тоесть диалог закроется только после завершения потока. Если в потоке происходит исключение и я в обработчике сигналю
                                                                                                                        для показа MessageBox, то MessageBox будет поверх моего диалога, т.к. управление может еще не вернуться.

                                                                                                                        2. Аналогично и для слота ThreadEnd. Как я сообщю MainWindow::f2 что поток успешно завершился. Веть ожидание потока не дает результат его завершения.

                                                                                                                        Что-то все сложно как-то :)
                                                                                                                          Цитата zss @
                                                                                                                          тоесть диалог закроется только после завершения потока. Если в потоке происходит исключение и я в обработчике сигналю
                                                                                                                          для показа MessageBox, то MessageBox будет поверх моего диалога, т.к. управление может еще не вернуться.

                                                                                                                          Зачем? Это сообщение может отобразить сам диалог. Зачем мессаджбокс еще показывать?

                                                                                                                          Цитата zss @
                                                                                                                          Как я сообщю MainWindow::f2 что поток успешно завершился. Веть ожидание потока не дает результат его завершения.

                                                                                                                          Можешь спросить у диалога, а диалогу - передать в соответствующем сигнале. Вообще, диалог вполне может показываться модально (при твоем раскладе). Т. е.:
                                                                                                                          ExpandedWrap disabled
                                                                                                                                    QWaitDialog dialog;
                                                                                                                                    QConnectThread thread(); // тут сам придумаешь, что написать.
                                                                                                                                    connect(&thread, SIGNAL(ThreadEnd(int)), &dialog, SLOT(ThreadEnded(int)));
                                                                                                                                    connect(&thread, SIGNAL(ThreadError(const QString&)), &dialog, SLOT(ThreadError(const QString&)));
                                                                                                                                    thread.start();
                                                                                                                                    dialog.exec();

                                                                                                                          В таком случае, у тебя:
                                                                                                                          1) Функция не завершится до тех пор, пока не отработает поток.
                                                                                                                          2) Во время работы потока будет висеть диалог и ждать его завершения.
                                                                                                                          Собственно, это именно то, что тебе нужно, на сколько я смог понять.
                                                                                                                            Цитата Flex Ferrum @
                                                                                                                            Зачем? Это сообщение может отобразить сам диалог. Зачем мессаджбокс еще показывать?

                                                                                                                            бр.... я совсем запутался. диалог вообще ничего ни о чем не знает. его задача - просто например крутить часики.
                                                                                                                            Да и к тому же если он отобразит его, то поверх себя.

                                                                                                                            А зачем - для того. чтобы GUI-поток отобразил строку ошибки. Ведь для этого нужен был ThreadError ?


                                                                                                                            Цитата Flex Ferrum @
                                                                                                                            В таком случае, у тебя:
                                                                                                                            1) Функция не завершится до тех пор, пока не отработает поток.
                                                                                                                            2) Во время работы потока будет висеть диалог и ждать его завершения.
                                                                                                                            Собственно, это именно то, что тебе нужно, на сколько я смог понять.


                                                                                                                            так - нужен перерыв для обмозгования :) я окончательно запутался. Попробую что-нибудь сделать а там будет видно :)
                                                                                                                              Цитата zss @
                                                                                                                              я совсем запутался. диалог вообще ничего ни о чем не знает. его задача - просто например крутить часики.
                                                                                                                              Да и к тому же если он отобразит его, то поверх себя.

                                                                                                                              Ну а теперь предположи, что он знает о том, что запущен поток. И его задача - не только крутить часики, но и дожидаться, пока поток завершится. И либо отобразить ошибку, возникшую в процессе работы потока, либо сказать, что все в порядке и схлопнуться. Тогда все получается достаточно стройно.
                                                                                                                                Цитата Flex Ferrum @
                                                                                                                                Ну а теперь предположи, что он знает о том, что запущен поток. И его задача - не только крутить часики, но и дожидаться, пока поток завершится. И либо отобразить ошибку, возникшую в процессе работы потока, либо сказать, что все в порядке и схлопнуться. Тогда все получается достаточно стройно.

                                                                                                                                Ва запутались в показаниях :). сначала Вы говорили, что нужно диалог создавать в отдельном потоке.
                                                                                                                                После что нужно в потоке обрабатывать данные. А на последнем допросе - диалог должен знать обо всем :)

                                                                                                                                Шутка... Ну я так понял что сигналы нужны только диалогу для того. чтобы прихлопнуться или сообщить об ошибке ?
                                                                                                                                Принципе логично. Попробую и скажу что получилось.

                                                                                                                                Спасибо за долго общение :)
                                                                                                                                  Цитата zss @
                                                                                                                                  Цитата gryz @
                                                                                                                                  функция gui-потоке выполняется?

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

                                                                                                                                  Если функцию можно выполнить в другом потоке, т.е. она, например, не работает напрямую с gui, то тогда лучше так и сделать.
                                                                                                                                  О завершении другого потока можно узнать по его сигналу finished () (если это наследник QThread)
                                                                                                                                  По этому сигналу можно закрыть диалог.
                                                                                                                                  Если диалогу нужно знать что-то о вычиляющем потоке, то тогда можно сделать дополнительный сигнал в вычисляющем потоке, который будет информировать gui-поток (в частности - наш диалог) о текущем состоянии дел.
                                                                                                                                  Сообщение отредактировано: gryz -
                                                                                                                                    Цитата gryz @
                                                                                                                                    Если функцию можно выполнить в другом потоке, т.е. она, например, не работает напрямую с gui, то тогда лучше так и сделать.
                                                                                                                                    О завершении другого потока можно узнать по его сигналу finished () (если это наследник QThread)
                                                                                                                                    По этому сигналу можно закрыть диалог.
                                                                                                                                    Если диалогу нужно знать что-то о выполняемом процессе, то тогда можно сделать дополнительный сигнал в вычисляющем потоке, который будет информировать gui-поток (в частности - наш диалог) о текущем состоянии дел.

                                                                                                                                    я долго размышлял, но пока руки не дошли до этого.

                                                                                                                                    Если не сложно - простейший работающий пример со Sleep можно ?
                                                                                                                                      Цитата zss @
                                                                                                                                      я долго размышлял, но пока руки не дошли до этого.

                                                                                                                                      Если не сложно - простейший работающий пример со Sleep можно ?

                                                                                                                                      Что за Sleep, зачем он?
                                                                                                                                        Цитата gryz @
                                                                                                                                        Что за Sleep, зачем он?

                                                                                                                                        эмитация долгой функции. пусть например Sleep (50000) - 50 сек.
                                                                                                                                          диалог запускаем методом exec(), перед его запуском стартуем вычисляющий поток

                                                                                                                                          Добавлено
                                                                                                                                          завтра попробую пример написать. сейчас домой - на работе засиделся.
                                                                                                                                            Цитата gryz @
                                                                                                                                            диалог запускаем методом exec(), перед его запуском стартуем вычисляющий поток

                                                                                                                                            а слот диалога вешаем на сигнал завершения потока как сказал Flex Ferrum ?
                                                                                                                                              я имел в виду это:

                                                                                                                                              ExpandedWrap disabled
                                                                                                                                                #include <QApplication>
                                                                                                                                                #include <QThread>
                                                                                                                                                #include <QMessageBox>
                                                                                                                                                #include <QtDebug>
                                                                                                                                                 
                                                                                                                                                class MyThread : public QThread
                                                                                                                                                {
                                                                                                                                                public:
                                                                                                                                                    void run()
                                                                                                                                                    {
                                                                                                                                                        qDebug() << "thread started";
                                                                                                                                                        sleep(5);
                                                                                                                                                        qDebug() << "thread finished";
                                                                                                                                                    }
                                                                                                                                                };
                                                                                                                                                 
                                                                                                                                                int main(int argc, char *argv[])
                                                                                                                                                {
                                                                                                                                                    QApplication a(argc, argv);
                                                                                                                                                    QMessageBox * d = new QMessageBox;
                                                                                                                                                    QThread * th = new MyThread;
                                                                                                                                                    QObject::connect(th, SIGNAL(finished()), d, SLOT(accept()));
                                                                                                                                                    th->start();
                                                                                                                                                    d->exec();
                                                                                                                                                    th->wait();//если нажали ок, то надо дождаться завершения выполнения потока
                                                                                                                                                }
                                                                                                                                              Сообщение отредактировано: gryz -
                                                                                                                                                я про это понял. Тут еще возникла сложность, что нужно создавать для каждого метода свой потоковый класс и свой слот обработки.
                                                                                                                                                Много кода лишнего получается ... :)
                                                                                                                                                  Цитата zss @
                                                                                                                                                  Тут еще возникла сложность, что нужно создавать для каждого метода свой потоковый класс и свой слот обработки.

                                                                                                                                                  Зачем?
                                                                                                                                                  Можно же поместить объект в поток (если объект наследник QObject),
                                                                                                                                                  сделать его методы слотами и асинхронно вызывать их при помощи
                                                                                                                                                  QMetaObject::invokeMethod().
                                                                                                                                                  Только тут надо учесть, что возвращаемыми значениями воспользоваться неполучится.
                                                                                                                                                  Прийдется использовать сигналы для сообщении о результате, если он нужен.

                                                                                                                                                  при старте каждого метода испускать сигнал methodStarted(QString methodName),
                                                                                                                                                  при завершении метода испускать сигнал methodFinished().
                                                                                                                                                  Можно сделать сигнал methodFinished(QVarinat rez),
                                                                                                                                                  в rez будет храниться результат выполнения метода.
                                                                                                                                                    Цитата gryz @
                                                                                                                                                    Можно же поместить объект в поток (если объект наследник QObject),

                                                                                                                                                    не наследник, но никто не мешает его хранить внутри объекта-потока.
                                                                                                                                                    Цитата gryz @
                                                                                                                                                    сделать его методы слотами и асинхронно вызывать их при помощи
                                                                                                                                                    QMetaObject::invokeMethod().

                                                                                                                                                    хорошая идея...


                                                                                                                                                    Цитата gryz @
                                                                                                                                                    Только тут надо учесть, что возвращаемыми значениями воспользоваться неполучится.
                                                                                                                                                    Прийдется использовать сигналы для сообщении о результате, если он нужен.

                                                                                                                                                    Почему ?


                                                                                                                                                    Цитата gryz @
                                                                                                                                                    при старте каждого метода испускать сигнал methodStarted(QString methodName),
                                                                                                                                                    при завершении метода испускать сигнал methodFinished().
                                                                                                                                                    Можно сделать сигнал methodFinished(QVarinat rez),
                                                                                                                                                    в rez будет храниться результат выполнения метода.

                                                                                                                                                    а можно примерчик - мне кажется интересная идея.

                                                                                                                                                    З.Ы. Только не понятно что должен делать слот потока ?
                                                                                                                                                      Цитата zss @
                                                                                                                                                      Почему ?

                                                                                                                                                      Потому что это асинхронный вызов. Он происходит не сразу, а при возврате в цикл обработки сообщений.
                                                                                                                                                      Так что сразу результата никакого нет. А нам нужно продолжить выполнение.
                                                                                                                                                      В Qt 4.3 появился тип вызова (точнее, это тип соединения) Qt::BlockingQueuedConnection,
                                                                                                                                                      но он не подойдет для вызова из gui потока.

                                                                                                                                                      Добавлено
                                                                                                                                                      Вот примерчик

                                                                                                                                                      ExpandedWrap disabled
                                                                                                                                                        //client.h
                                                                                                                                                        #ifndef CLIENT_H
                                                                                                                                                        #define CLIENT_H
                                                                                                                                                        #include <QObject>
                                                                                                                                                        #include <QVariant>
                                                                                                                                                        #include <QPushButton>
                                                                                                                                                        #include <QThread>
                                                                                                                                                        #include <QMessageBox>
                                                                                                                                                        #include <QtDebug>
                                                                                                                                                         
                                                                                                                                                        class Client: public QObject
                                                                                                                                                        {
                                                                                                                                                            Q_OBJECT
                                                                                                                                                        public slots:
                                                                                                                                                            bool start()const
                                                                                                                                                            {
                                                                                                                                                                qDebug() << "start() started";
                                                                                                                                                                emit methodStarted("start()");
                                                                                                                                                                int sum = 0;//сложнейшие вычисления
                                                                                                                                                                for(int i = 0; i < 100000; ++i)
                                                                                                                                                                    for(int j = 0; j < 10000; ++j)
                                                                                                                                                                        sum += j * i;
                                                                                                                                                                bool rez = true;
                                                                                                                                                                qDebug() << "start() finished";
                                                                                                                                                                emit methodFinished(QByteArray("true"));//всегда последняя перед return операция.
                                                                                                                                                                                                        //оказалось, что QVariant нельзя передавать в
                                                                                                                                                                                                        //в соединениях типа Qt::QueuedConnection (qt4.2.2).
                                                                                                                                                                                                        //Можно упаковывать результат в QByteArray используя QDataStream.
                                                                                                                                                                                                        //туда же можно запихнуть имя метода start().
                                                                                                                                                                                                        //Еще как вариант можно использовать различные синалы
                                                                                                                                                                                                        //для различных типов возвращаемых значений.
                                                                                                                                                                return rez;
                                                                                                                                                            }
                                                                                                                                                            //...
                                                                                                                                                        signals:
                                                                                                                                                            void methodStarted(QString methodName)const;
                                                                                                                                                            void methodFinished(QByteArray rez)const;
                                                                                                                                                        };
                                                                                                                                                         
                                                                                                                                                        class RunnableThread: public QThread
                                                                                                                                                        {
                                                                                                                                                        public:
                                                                                                                                                            void run()//в QThread этот метод не определен, поэтому приходится наследоваться
                                                                                                                                                            {
                                                                                                                                                                exec();
                                                                                                                                                            }
                                                                                                                                                        };
                                                                                                                                                         
                                                                                                                                                        class DummyMainWindow: public QWidget
                                                                                                                                                        {
                                                                                                                                                            Q_OBJECT
                                                                                                                                                        public:
                                                                                                                                                            DummyMainWindow()
                                                                                                                                                            {
                                                                                                                                                                QPushButton * startBtn = new QPushButton(tr("Start"), this);
                                                                                                                                                                theClient = new Client;
                                                                                                                                                                theWorkerThread = new RunnableThread;
                                                                                                                                                                theWorkerThread->start();
                                                                                                                                                                theClient->moveToThread(theWorkerThread);
                                                                                                                                                         
                                                                                                                                                                connect(startBtn, SIGNAL(pressed()), SLOT(invokeStart()));
                                                                                                                                                                connect(theClient, SIGNAL(methodStarted(QString)), SLOT(showDialog(QString)));
                                                                                                                                                                connect(theClient, SIGNAL(methodFinished(QByteArray)), SLOT(processResult(QByteArray)));
                                                                                                                                                         
                                                                                                                                                                theInfoDialog = new QMessageBox(this);
                                                                                                                                                                theInfoDialog->setStandardButtons(QMessageBox::NoButton);
                                                                                                                                                            }
                                                                                                                                                            ~DummyMainWindow()
                                                                                                                                                            {
                                                                                                                                                                theWorkerThread->quit();
                                                                                                                                                                theWorkerThread->wait();
                                                                                                                                                                delete theWorkerThread;
                                                                                                                                                                delete theClient;
                                                                                                                                                            }
                                                                                                                                                         
                                                                                                                                                        private slots:
                                                                                                                                                            void invokeStart()
                                                                                                                                                            {
                                                                                                                                                                //можем запомнить текущий вызываемый метод в члене класса,
                                                                                                                                                                //тогда в методе processResult будем знать, какой метод был вызван,
                                                                                                                                                                //чтобы правильно интепретировать результат
                                                                                                                                                                QMetaObject::invokeMethod(theClient, "start");
                                                                                                                                                            }
                                                                                                                                                          
                                                                                                                                                            void showDialog(QString text)
                                                                                                                                                            {
                                                                                                                                                                theInfoDialog->setText(text + tr(" is running now"));
                                                                                                                                                                theInfoDialog->exec();
                                                                                                                                                            }
                                                                                                                                                         
                                                                                                                                                            void processResult(QByteArray rez)
                                                                                                                                                            {
                                                                                                                                                                theInfoDialog->accept();
                                                                                                                                                                //делаем, что хотим с rez
                                                                                                                                                            }
                                                                                                                                                                
                                                                                                                                                        private:
                                                                                                                                                            Client * theClient;
                                                                                                                                                            RunnableThread * theWorkerThread;
                                                                                                                                                            QMessageBox * theInfoDialog;
                                                                                                                                                        };
                                                                                                                                                         
                                                                                                                                                        #endif


                                                                                                                                                      ExpandedWrap disabled
                                                                                                                                                        //main.cpp
                                                                                                                                                        #include <QtGui/QApplication>
                                                                                                                                                        #include "client.h"
                                                                                                                                                         
                                                                                                                                                         
                                                                                                                                                         
                                                                                                                                                         
                                                                                                                                                        int main(int argc, char *argv[])
                                                                                                                                                        {  
                                                                                                                                                            QApplication a(argc, argv);
                                                                                                                                                            
                                                                                                                                                            DummyMainWindow mw;
                                                                                                                                                            mw.show();
                                                                                                                                                            
                                                                                                                                                            return a.exec();
                                                                                                                                                        }


                                                                                                                                                      Добавлено
                                                                                                                                                      В данной реализации в программе всегда запущено 2 потока: gui и вычисляющий.
                                                                                                                                                      В принципе, можно сделать так, чтобы вычисляющий запускался при необходимости вычислений,
                                                                                                                                                      а после - завершался.
                                                                                                                                                      Сообщение отредактировано: gryz -
                                                                                                                                                        gryz, спасибо за код, но не все подойдет

                                                                                                                                                        в #49 описано почему. Разные методы, разные сигнатуры и разные возвращаемые значения...
                                                                                                                                                          zss
                                                                                                                                                          что мешает добавить слоты аналогичные invokeStart() - для разных методов?

                                                                                                                                                          для возвращаемых значений различных типов можно использовать сигналы вида:

                                                                                                                                                          void methodFinished(int)const;
                                                                                                                                                          void methodFinished(QString)const;
                                                                                                                                                          void methodFinished(double)const;
                                                                                                                                                            В общем забросил я в свое время проект, но тут опять возвращаюсь к нему.
                                                                                                                                                            Еще раз перечитал все сообщения.

                                                                                                                                                            1.
                                                                                                                                                            gryz, если честно - не совсем понял код и как он работает :) и что есть moveToThread... ?

                                                                                                                                                            2. Flex Ferrum, ну вроде все понял, кроде некоторых моментов. Например
                                                                                                                                                            Цитата Flex Ferrum @
                                                                                                                                                            Не. Лучше не так, а вот так:

                                                                                                                                                            class WorkerThread : public QThread
                                                                                                                                                            {
                                                                                                                                                            public:
                                                                                                                                                            WorkerThread(boost::function<void ()> worker, boost::function<void (const std::exception&)> xHandler) : m_Worker(worker), m_ExHandler(handler) {;}
                                                                                                                                                            int run()
                                                                                                                                                            {
                                                                                                                                                            try
                                                                                                                                                            {
                                                                                                                                                            m_Worker();
                                                                                                                                                            }
                                                                                                                                                            catch (const std::exception& ex)
                                                                                                                                                            {
                                                                                                                                                            m_ExHandler(ex);
                                                                                                                                                            }
                                                                                                                                                            }
                                                                                                                                                            };


                                                                                                                                                            как сбиндить метод.
                                                                                                                                                            Если просто метод класса, то
                                                                                                                                                            ExpandedWrap disabled
                                                                                                                                                              boost::bind (&Class::function, this)


                                                                                                                                                            а как сбиндить для WorkerThread
                                                                                                                                                            ExpandedWrap disabled
                                                                                                                                                              void func (const std::exception& ex);


                                                                                                                                                            P.S. Попробовал данный способ
                                                                                                                                                            Цитата Flex Ferrum @
                                                                                                                                                            QWaitDialog dialog;
                                                                                                                                                            QConnectThread thread(); // тут сам придумаешь, что написать.
                                                                                                                                                            connect(&thread, SIGNAL(ThreadEnd(int)), &dialog, SLOT(ThreadEnded(int)));
                                                                                                                                                            connect(&thread, SIGNAL(ThreadError(const QString&)), &dialog, SLOT(ThreadError(const QString&)));
                                                                                                                                                            thread.start();
                                                                                                                                                            dialog.exec();


                                                                                                                                                            поток запускается, диалог отображается, после завершения потока окно закрывается (дергается слот диалого)
                                                                                                                                                            Но !!! Таймер внутри диалога не отрабатывает. Почему ? Ведь диалог отрисовывается. Его можно даже перемещать
                                                                                                                                                              Совсем не помню, чего там писал :)
                                                                                                                                                              Почитаю...

                                                                                                                                                              moveToThread - переносит объект (QObject) из данного потока в какой-то другой.
                                                                                                                                                              Каждый Qt object "живет" в каком-то потоке.
                                                                                                                                                              Это означает, что обработка вызова его слотов будет происходит в этом потоке.

                                                                                                                                                              zss

                                                                                                                                                              а ты пробовал его запускать? :)
                                                                                                                                                              Сообщение отредактировано: gryz -
                                                                                                                                                                zss

                                                                                                                                                                Так что непонятно-то? :)

                                                                                                                                                                Экземпляр класса Client - это объект, методы которого нам надо исполнить.
                                                                                                                                                                В примере его метод start() выполняет какие-то вычисления.
                                                                                                                                                                Объект должен "жить" в не GUI потоке.

                                                                                                                                                                DummyMainWindow - класс, который осуществляет взаимодействие с пользователем.
                                                                                                                                                                В его конструкторе запускается параллельный "вычисляющий" поток.
                                                                                                                                                                Создается "вычисляющий" объект. Перемещается в вычисляющий поток.

                                                                                                                                                                Далее, при помощи сигнала кнопки clicked() вызываем слот "вычисляющего" объекта invokeStart().

                                                                                                                                                                Обратная связь с GUI-потоком реализуется при помощи сигналов methodStarted() и methodFinished().

                                                                                                                                                                Все сигнал-слот соединения имеют тип Qt::QueuedConnection. Т.е. вызовы слотов происходят асинхронно.
                                                                                                                                                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                                                                                                                                                0 пользователей:


                                                                                                                                                                Рейтинг@Mail.ru
                                                                                                                                                                [ Script execution time: 0,1767 ]   [ 15 queries used ]   [ Generated: 18.05.24, 13:40 GMT ]