2011-07-29 47 views
7

我寫了一個字符設備驅動程序,現在正在編寫一個QT「包裝器」,其中的一部分是當設備通過輪詢機制可讀時觸發信號。我曾試圖做的事:使用QSocketNotifier在char設備上進行選擇。

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從來沒有叫我的司機從來沒有報道調用其調查方法。

我能得到下面的代碼來工作,所以我知道我的司機正在

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()的文檔似乎表明它應該是。

+0

你有沒有得到這個工作看標準輸入?我寫了類似的東西,但是我不能'file-> read(buf,1)'來工作。它會掛起。然而,'read(file-> handle(),buf,1)'工作得很好。 – Harvey

+0

@哈維是的,我檢查的答案爲我工作。原來是一個簡單的編碼錯誤。也檢查我的答案,看看它是否有幫助。 – jjcf89

+0

爲了修改我以前的評論,這是我對設備驅動程序工作方式的一個誤解。這兩段代碼都起作用了,只是在我使用其中一個因素導致我進行錯誤連接時,其他因素導致整個測試失敗。 – Harvey

回答

7

只要if塊結束,您的QSocketNotifer就會被銷燬。它沒有任何舉報的機會。

只要您希望監控該文件,您就必須保持該套接字通知程序處於活動狀態。這樣做的最簡單方法可能是讓一個QSocketNotifer*成員保留在您的某個類中。

+0

謝謝你。去吧,它可能是如此簡單的事情。 QSocketNotifier現在工作得很好。 – jjcf89

+0

您可以添加QFile作爲QSocketNotifier的父項,然後當QFile被刪除時,QSocketNotifier – RDP

13

我還會提到,在QSocketNotifier可用於使用以下

#include "ConsoleReader.h" 
#include <QTextStream> 

#include <unistd.h> //Provides STDIN_FILENO 

ConsoleReader::ConsoleReader(QObject *parent) : 
    QObject(parent), 
    notifier(STDIN_FILENO, QSocketNotifier::Read) 
{ 
    connect(&notifier, 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; 
}; 
+0

也是如此,謝謝您從標準輸入讀取的優雅方式。但是,imo有兩個問題: 1. std :: getline(std :: cin,line);應該用來代替QTextStream。原因是QTextStream使用了某種緩衝,當將帶有\ n的文本粘貼到終端時(有些文本會丟失),這是有問題的。可能一個QTextStream成員也可以工作。 2.最好在ConsoleReader作爲父節點的堆上創建通告程序。這樣一來,如果將來需要的話,它將自動地與ConsoleReader一起移動到一個新的線程中。請記住,stdin不是線程安全的。 – Adam

相關問題