Как разбудить поток GUI в XCB?

Мое приложение ожидает завершения потока. Когда поток завершит свою работу, я хочу обновить графический интерфейс. Поток GUI заблокирован в xcb_wait_for_event().

Возможно ли это с XCB? Как Qt, GTK, FLTK и т. д. реализуют эту основную проблему графического интерфейса с точки зрения API XCB?


person Community    schedule 19.05.2015    source источник


Ответы (3)


В Qt вы должны подключить (поставленный в очередь) сигнал, испускаемый вашим потоком, к слоту в объекте потока GUI. Затем вызов слота обрабатывается циклом обработки событий, как и спонтанные события, например, из пользовательский ввод.

Из Майя Пош отлично статья об использовании QThread:

class Worker : public QObject {
    Q_OBJECT

public:
    Worker();
    ~Worker();

public slots:
    void process();

signals:
    void finished();
    void error(QString err);

private:
    // add your variables here
};

void Worker::process() {
    // allocate resources using new here
    qDebug("Hello World!");
    emit finished();
}

В потоке графического интерфейса:

QThread* thread = new QThread;
Worker* worker = new Worker();
worker->moveToThread(thread);
connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
connect(thread, SIGNAL(started()), worker, SLOT(process()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();

Интересующая вас строка

connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));

Теперь идите и прочитайте Как по-настоящему использовать QThreads; Полное объяснение.

person Toby Speight    schedule 19.05.2015
comment
Извините, меня интересовало, как различные наборы инструментов реализуют это поверх XCB, а не то, как это сделать с API наборов инструментов. Я хочу сделать это без какого-либо инструментария. Я изменил вопрос, надеюсь, теперь он более понятен. - person ; 19.05.2015
comment
Ах я вижу. Я напишу на это другой ответ, но оставлю его здесь на случай, если он будет полезен будущим читателям. - person Toby Speight; 19.05.2015

То, как это работает в Qt, похоже, заключается в том, что xcb_wait_for_event() многократно запускается в собственном потоке. Каждый раз, когда он получает событие, он отправляет сообщение в общую очередь сообщений QApplication. Пользовательские потоки также могут добавлять сообщения в общую очередь сообщений QApplication с помощью сигналов в очереди (см. мой другой ответ).

Пользовательское приложение теперь может считывать события из общей очереди сообщений (например, используя qApp->exec()) и получать смесь спонтанных событий пользовательского интерфейса и внутренних сигналов от других потоков.

Для дополнительного чтения я предлагаю исходники Qt5, начиная с src/plugins/platforms/xcb/qxcbconnection.cpp — посмотрите на QXcbEventReader::run.

person Toby Speight    schedule 19.05.2015
comment
Спасибо. Кажется, что реализация моей собственной очереди и размещение цикла XCB в другом потоке - единственный путь (облом). У меня все еще есть слабая надежда на более простое решение, поэтому я подожду еще немного ответов. - person ; 19.05.2015

stackoverflow.com/questions/8794089/how-to-send- ключ-событие-к-приложению-использование-xcb

Обратите внимание на предупреждение о потенциальной безопасности, как и способ использовать xtest, чтобы избежать этого. Интересно, не могли бы вы подождать сигнала? Они не такие страшные и загадочные, как кажутся непосвященным. Есть отличная книга Майкла Керриска: The Linux Programming Interface A Linux and UNIX System Programming Handbook, в которой это объясняется.

person DeeDeeK    schedule 04.04.2018