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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: [РЕШЕНО] потоки и GUI  (Прочитано 5237 раз)
OKTA
Гость
« : Сентябрь 12, 2012, 13:39 »

Товарищи! Не могу вдуплить, в чем проблема! Поведение какое-то ну крайне своеобразное! Приведу кусок кода!
Такой вот main:
Код:
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    AppSettings aps;

    uMail *ut = new uMail(&aps);

    GUIAdapter *ga = new GUIAdapter(ut);

    QThread testThread;
    ut->moveToThread(&testThread);
    testThread.start();

    ut->run();

    return a.exec();
}

Кусочек GUIAdapter.h :
Код:
class GUIAdapter : public QObject {

    Q_OBJECT

    // Engine Object
    uMail *eg;

    QDeclarativeView *mainWin, *currentWin;
    QObject *mainWinObj;
    QObject *flipobjFirstEnter;

И кусочек GUIAdapter.cpp:
Код:
void GUIAdapter::startMainWindow(){
    //
      
    QDeclarativeView *mw = new QDeclarativeView();

    currentWin = mainWin = mw;
    currentWin->installEventFilter(this);

В чем, собственно, проблема! GUIAdapter (ga) и uMail (ut) работают в разных потоках - первый остается в главном и в нем работает графика, а второй служит "движком" и направляется в отдельный поток. Но при старте оказывается, что все объекты QDeclarativeView, объявленные в GUIAdapter.h и использованные в cpp-шнике каким-то образом перемещаются в поток с uMail - Как такое может быть??
« Последнее редактирование: Сентябрь 12, 2012, 14:12 от OKTA » Записан
Bepec
Гость
« Ответ #1 : Сентябрь 12, 2012, 13:45 »

Код:
  GUIAdapter *ga = new GUIAdapter(ut);
Записан
mutineer
Гость
« Ответ #2 : Сентябрь 12, 2012, 13:45 »

Вслед за объектом перемещаются и его чилдрены
Записан
OKTA
Гость
« Ответ #3 : Сентябрь 12, 2012, 13:49 »

Но ga при этом не перемещается в другой поток! Перемещаются только QDeclarativeView внутри! + ut передается как указатель и используется только для вызова методов uMail. Не бейте, если не понимаю чего-то)
Записан
mutineer
Гость
« Ответ #4 : Сентябрь 12, 2012, 13:51 »

void GUIAdapter::startMainWindow() в каком потоке вызывается? В том же и будет жить созданный в нем QDeclarativeView
Записан
OKTA
Гость
« Ответ #5 : Сентябрь 12, 2012, 13:56 »

Вызывается вот так:
Код:
 QObject::connect(ut, SIGNAL(startMainWindow()),
                     ga, SLOT(startMainWindow()), Qt::DirectConnection);
Коннект прописан в main, соответственно в главном потоке и вызывается! Проверяю специально -GUIAdapter ga И QApplication a В одном потоке, а uMail в отдельном!
Записан
mutineer
Гость
« Ответ #6 : Сентябрь 12, 2012, 13:59 »

Qt::DirectConnection означает что слот будет вызван прямо из места испускания сигнала. А сигнал испускается из объекта ut, который в другом потоке. Значит и слот будет вызван в том же потоке
Записан
OKTA
Гость
« Ответ #7 : Сентябрь 12, 2012, 14:01 »

Разве?? Я использовал его, искренне веря в
Код:
Qt::DirectConnection	1	The slot is invoked immediately, when the signal is emitted.
Записан
mutineer
Гость
« Ответ #8 : Сентябрь 12, 2012, 14:03 »

Слот вызовется немедленно, то есть будет непосредственный вызов слота из тела сигнала. Непосредственный вызов между потоками в C++ невозможен
Записан
OKTA
Гость
« Ответ #9 : Сентябрь 12, 2012, 14:07 »

Вот фак)) Точно) Спасибо большущее!!)) Т.е. как понимаю, используя прямое соединение слот вызывается сразу же, но из потока сигнала, а чтобы этого не происходило, надо использовать дефолтное AutoConnection?
Записан
mutineer
Гость
« Ответ #10 : Сентябрь 12, 2012, 14:08 »

Да, либо QueuedConnection, если хочешь чтобы вызов всегда проходил через EventLoop, независимо от потоков отправителя/получателя
Записан
OKTA
Гость
« Ответ #11 : Сентябрь 12, 2012, 14:12 »

Большое спасибо!)
Записан
OKTA
Гость
« Ответ #12 : Сентябрь 12, 2012, 14:51 »

Вот, если кто заглянет:

Код:
Signals and Slots Across Threads
Qt supports these signal-slot connection types:
Auto Connection (default) If the signal is emitted in the thread which the receiving object has affinity then the behavior is the same as the Direct Connection. Otherwise, the behavior is the same as the Queued Connection."
Direct Connection The slot is invoked immediately, when the signal is emitted. The slot is executed in the emitter's thread, which is not necessarily the receiver's thread.
Queued Connection The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.
Blocking Queued Connection The slot is invoked as for the Queued Connection, except the current thread blocks until the slot returns. Note: Using this type to connect objects in the same thread will cause deadlock.
Unique Connection The behavior is the same as the Auto Connection, but the connection is made only if it does not duplicate an existing connection. i.e., if the same signal is already connected to the same slot for the same pair of objects, then the connection is not made and connect() returns false.
The connection type can be specified by passing an additional argument to connect(). Be aware that using direct connections when the sender and receiver live in different threads is unsafe if an event loop is running in the receiver's thread, for the same reason that calling any function on an object living in another thread is unsafe.
QObject::connect() itself is thread-safe.
The Mandelbrot example uses a queued connection to communicate between a worker thread and the main thread. To avoid freezing the main thread's event loop (and, as a consequence, the application's user interface), all the Mandelbrot fractal computation is done in a separate worker thread. The thread emits a signal when it is done rendering the fractal.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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