I would like to ask, if it is possible to use a custom main loop instead of running a.exec():
我想问一下,如果可以使用自定义主循环而不是运行a.exec():
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Window r;
r.showFullScreen();
return a.exec();
}
something like:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Window r;
r.showFullScreen();
while(a.processOneEvent()) {
read_event_from_legacy_system
}
return 0;
}
In GTK I could use gtk_main_iteration_do() so I thought there is maybe something similar in Qt?
在GTK中我可以使用gtk_main_iteration_do()所以我认为在Qt中可能有类似的东西?
Or is there any other correct way to read custom events from a specific legacy system?
或者是否有其他正确的方法来从特定的遗留系统中读取自定义事件?
EDIT: The events which a read from the FIFOs are not system events (such as X11) they are just a struct which is sent via a FIFO to realize ipc.
编辑:从FIFO读取的事件不是系统事件(例如X11),它们只是一个通过FIFO发送以实现ipc的结构。
3 个解决方案
#1
So you want to react on a FIFO -or pipe- file descriptor (on Linux) using Qt
因此,您希望使用Qt对FIFO -or管道文件描述符(在Linux上)做出反应
With Qt5 you would probably use QAbstractSocket or QIoDevice and its readyRead signal
使用Qt5,您可能会使用QAbstractSocket或QIoDevice及其readyRead信号
With Qt4 you should use QSocketNotifier and its activated signal (so call your read_event_from_legacy_system
from a Qt slot connected to that signal). It can poll any file descriptor, including a fifo(7)
使用Qt4,您应该使用QSocketNotifier及其激活的信号(因此从连接到该信号的Qt插槽调用read_event_from_legacy_system)。它可以轮询任何文件描述符,包括fifo(7)
There is no need to change the application's event loop (even if in theory you might subclass QApplication but I don't recommend doing that). Once you set up correctly your thing, Qt event loop will poll
the additional file descriptor, and your code should read
it.
无需更改应用程序的事件循环(即使理论上您可能是子类QApplication但我不建议这样做)。一旦你正确设置了你的东西,Qt事件循环将轮询其他文件描述符,你的代码应该读取它。
#2
Although this might not be the best solution for your problem, you can write your own main loop like this:
虽然这可能不是您问题的最佳解决方案,但您可以编写自己的主循环,如下所示:
QApplication app(argc, argv);
QMainWindow wnd;
wnd.show();
while(wnd.isVisible())
{
app.processEvents();
// perform your own actions here
}
Instead of wnd.isVisible() you can of course use your own breaking condition.
你可以使用自己的破坏条件代替wnd.isVisible()。
#3
I have come up with following solution:
我想出了以下解决方案:
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();
}
I get all events read from a specific file descriptor. If you want to use the events in MyWindow just connect the signal dataReceived() with a public slot of MyWindow.
我从特定的文件描述符中读取所有事件。如果要在MyWindow中使用事件,只需将信号dataReceived()与MyWindow的公共插槽连接即可。
#1
So you want to react on a FIFO -or pipe- file descriptor (on Linux) using Qt
因此,您希望使用Qt对FIFO -or管道文件描述符(在Linux上)做出反应
With Qt5 you would probably use QAbstractSocket or QIoDevice and its readyRead signal
使用Qt5,您可能会使用QAbstractSocket或QIoDevice及其readyRead信号
With Qt4 you should use QSocketNotifier and its activated signal (so call your read_event_from_legacy_system
from a Qt slot connected to that signal). It can poll any file descriptor, including a fifo(7)
使用Qt4,您应该使用QSocketNotifier及其激活的信号(因此从连接到该信号的Qt插槽调用read_event_from_legacy_system)。它可以轮询任何文件描述符,包括fifo(7)
There is no need to change the application's event loop (even if in theory you might subclass QApplication but I don't recommend doing that). Once you set up correctly your thing, Qt event loop will poll
the additional file descriptor, and your code should read
it.
无需更改应用程序的事件循环(即使理论上您可能是子类QApplication但我不建议这样做)。一旦你正确设置了你的东西,Qt事件循环将轮询其他文件描述符,你的代码应该读取它。
#2
Although this might not be the best solution for your problem, you can write your own main loop like this:
虽然这可能不是您问题的最佳解决方案,但您可以编写自己的主循环,如下所示:
QApplication app(argc, argv);
QMainWindow wnd;
wnd.show();
while(wnd.isVisible())
{
app.processEvents();
// perform your own actions here
}
Instead of wnd.isVisible() you can of course use your own breaking condition.
你可以使用自己的破坏条件代替wnd.isVisible()。
#3
I have come up with following solution:
我想出了以下解决方案:
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();
}
I get all events read from a specific file descriptor. If you want to use the events in MyWindow just connect the signal dataReceived() with a public slot of MyWindow.
我从特定的文件描述符中读取所有事件。如果要在MyWindow中使用事件,只需将信号dataReceived()与MyWindow的公共插槽连接即可。