我编写了一个字符设备驱动程序,现在正在编写一个 Qt“包装器”,其中的一部分是在设备通过轮询机制变得可读时获取要触发的信号。我曾尝试这样做:
QFile file("/dev/testDriver");
if(file.open(QFile::ReadOnly)) {
QSocketNotifier sn(file.handle(), , QSocketNotifier::Read);
sn.setEnabled(true);
connect(&sn, SIGNAL(activated(int)), &this, SLOT(readyRead()));
}
但是readyRead从未被调用,我的驱动程序也从未报告调用了它的poll方法。
我能够让以下代码工作,所以我知道我的驱动程序正在工作
QFile file("/dev/testDriver");
if(file.open(QFile::ReadOnly)) {
struct pollfd fd;
fd.fd = file.handle();
fd.events = POLLIN;
struct pollfd fds[] = {fd};
int ready;
qDebug() << "Started poll";
ready = poll(fds, 1, -1);
qDebug() << "Poll returned: " << ready;
QTextStream in(&file);
QTextStream out(stdout);
out << in.readAll();
}
这会正确等待我的驱动程序调用wake_up,并且我可以看到来自驱动程序的两个轮询调用。一个用于初始轮询注册,另一个用于唤醒发生时。
这样做我可能必须生成一个单独的线程,它所做的只是轮询该设备并抛出信号和循环。
可以这样使用QSocketNotifier吗? QFile::handle() 的文档似乎表明它应该是。
我还会提到 QSocketNotifier 可用于使用以下内容来监视 stdin
#include "ConsoleReader.h"
#include <QTextStream>
#include <unistd.h> //Provides STDIN_FILENO
ConsoleReader::ConsoleReader(QObject *parent) :
QObject(parent),
notifier(STDIN_FILENO, QSocketNotifier::Read)
{
connect(¬ifier, SIGNAL(activated(int)), this, SLOT(text()));
}
void ConsoleReader::text()
{
QTextStream qin(stdin);
QString line = qin.readLine();
emit textReceived(line);
}
---标题
#pragma once
#include <QObject>
#include <QSocketNotifier>
class ConsoleReader : public QObject
{
Q_OBJECT
public:
explicit ConsoleReader(QObject *parent = 0);
signals:
void textReceived(QString message);
public slots:
void text();
private:
QSocketNotifier notifier;
};
一旦
QSocketNotifer
区块结束,您的 if
就会被摧毁。它没有机会报告任何事情。
只要您希望监视该文件,您就必须保持该套接字通知程序处于活动状态。最简单的方法可能是在您的一个班级中保留一名
QSocketNotifer*
成员。