Qt(4.8.2)GUI - 拥有主循环而不是QApplication :: exec()

时间:2015-05-13 06:44:11

标签: c++ qt

我想问一下,如果可以使用自定义主循环而不是运行a.exec():

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Window r;
    r.showFullScreen();
    return a.exec(); 
}

类似的东西:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Window r;
    r.showFullScreen();

    while(a.processOneEvent()) {
        read_event_from_legacy_system
    }

    return 0; 
}

在GTK中,我可以使用 gtk_main_iteration_do(),所以我觉得Qt中可能有类似的东西?

或者是否有其他正确的方法可以从特定的遗留系统中读取自定义事件?

编辑:从FIFO读取的事件不是系统事件(例如X11),它们只是一个通过FIFO发送以实现ipc的结构。

3 个答案:

答案 0 :(得分:3)

因此,您希望使用Qt

对FIFO或管道文件描述符(在Linux上)做出反应

使用Qt5,您可能会使用QAbstractSocketQIoDevice及其readyRead信号

使用Qt4,您应该使用QSocketNotifier及其activated信号(因此请从连接到该信号的Qt插槽中调用read_event_from_legacy_system)。它可以轮询任何文件描述符,包括fifo(7)

无需更改应用程序的事件循环(即使理论上您可能会继承QApplication,但我不建议这样做)。一旦你正确设置了你的东西,Qt事件循环将poll额外的文件描述符,你的代码应该read它。

答案 1 :(得分:0)

虽然这可能不是您问题的最佳解决方案,但您可以编写自己的主循环:

QApplication app(argc, argv);
QMainWindow wnd;

wnd.show();

while(wnd.isVisible())
{
    app.processEvents();

    // perform your own actions here
}

您可以使用自己的破坏条件,而不是wnd.isVisible()。

答案 2 :(得分:0)

我提出了以下解决方案:

<强> PipeReader.hpp

#ifndef PIPEREADER_HPP
#define PIPEREADER_HPP

#include <QObject>
#include <QSocketNotifier>

class PipeReader : public QObject
{
    Q_OBJECT
public:
    PipeReader(int fd, QObject *parent = 0);
    ~PipeReader();
private:
    QSocketNotifier *notifier;
    int m_fd;
signals:
    void dataReceived();
private slots:
    void readFromFd();
};

#endif  /* PIPEREADER_HPP */

<强> PipeReader.cpp

#include <PipeReader.hpp>
#include <QObject>

PipeReader::PipeReader(int fd, QObject *parent)
: QObject(parent), notifier(NULL), m_fd(fd)
{
    notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
    QObject::connect(notifier, SIGNAL(activated(int)), this, SLOT(readFromFd()));
}

PipeReader::~PipeReader()
{

}

void PipeReader::readFromFd()
{
    qDebug("readFromFd");
    int ret_val = read(m_fd, &event, sizeof(Event), 10);

    emit dataReceived();
}

<强>的main.cpp

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyWindow w;

    if ((fd = open(SPECIAL_FD, O_RDONLY | O_SYNC)) < 0) {
        exit(0);
    }

    PipeReader reader(fd);

    w.showFullScreen();
    return a.exec();
}

我从特定文件描述符中读取所有事件。如果要在MyWindow中使用事件,只需将信号dataReceived()与MyWindow的公共插槽连接即可。