2011-09-17 13 views
7

द्वारा संसाधित की जाती है, माता-पिता प्रक्रिया स्ट्रिंग "Message\n" को बाल प्रक्रिया stdin पर लिखती है। लेकिन बाल प्रक्रिया इसे प्राप्त नहीं करती है। कोड में समस्या कहां है?बाल प्रक्रिया stdin को डेटा प्रक्रिया नहीं मिलती है, जो मूल प्रक्रिया

क्यूटी 4.7.3

जनक प्रक्रिया कोड:

// class TestParent : public QMainWindow 
void TestParent::createChildProcess() 
{ 
    childProcess = new QProcess(this); 
    connect(childProcess, SIGNAL(started()), 
     this, SLOT(childProcessStarted())); 
    connect(childProcess, SIGNAL(bytesWritten(qint64)), 
     this, SLOT(bytesWritten(qint64))); 
    childProcess->start("TestChild.exe", QProcess::ReadWrite); 
} 

void TestParent::writeToChildProcessOutput() 
{ 
    qint64 bytesWritten = childProcess->write("Message\n"); 
    qDebug() << "ret: " << bytesWritten << " bytes written"; 
} 

void TestParent::bytesWritten() 
{ 
    qDebug() << "slot: " << bytesWritten << " bytes written"; 
} 

बाल प्रक्रिया कोड:

// class TestChild : public QMainWindow 
void TestChild::TestChild() 
    // QFile TestChild::input; 
    connect(&input, SIGNAL(readyRead()), 
     this, SLOT(readInput())); 
    input.open(0, QIODevice::ReadOnly); // stdin 
} 

void TestChild::readInput() 
{ 
    QString line; 
    line.append('('); 
    line.append(QString::number(input.bytesAvailable())) 
    line.append(')'); 
    line.append(input.readAll()); 

    list.append(line); // add line to QListView 
} 
+0

है एक QProcess टेस्ट चाइल्ड? और इनपुट एक QIODevice है, उपclass नहीं है? – Chris

+0

@ क्रिस: नहीं, टेस्ट चाइल्ड - बाल प्रक्रिया की मुख्य विंडो वस्तु। मूल प्रक्रिया में हम 'childProcess' ऑब्जेक्ट का उपयोग करके बच्चे को बनाते हैं। मेरी गलती: 'इनपुट' QFile है, धन्यवाद। –

उत्तर

0

मैं क्या लगता है कि आप कर रही करने के लिए वास्तविक QProcess वस्तु से पढ़ने की आवश्यकता है (इस मामले में बाल प्रसंस्करण, अगर मैं सही ढंग से समझता हूं)।

ध्यान दें कि QProcess वास्तव में QIODevice का एक उपवर्ग है, और यह भी निम्नलिखित कार्यों का विशेष ध्यान दें:

QProcess::setReadChannel() 
QProcess::readAllStandardOutput() 

आप के बजाय readyRead() अपने QProcess वस्तु का संकेत करने में सक्षम एक QFile बनाने होना चाहिए stdin पढ़ने के प्रयास में। इसका कारण यह नहीं है कि आपका क्यूफाइल आपके मेनविंडो के समान प्रक्रिया से जुड़ा हुआ है, न कि आपके बच्चे की प्रक्रिया।

+0

नहीं। 'बाल प्रसंस्करण' मूल प्रक्रिया में एक नियंत्रण वस्तु है। बाल प्रक्रिया 'stdin' ('testParent :: writeToChildProcessOutput()') में' childProcess' ऑब्जेक्ट पैरेंट प्रोसेस प्रिंट स्ट्रिंग का उपयोग करना)। और बच्चे की प्रक्रिया को उस स्ट्रिंग को 'stdin' से पढ़ना चाहिए। तो बाल प्रक्रिया में 'क्यूफाइल इनपुट' ऑब्जेक्ट के 'तैयार रीड()' सिग्नल को उत्सर्जित किया जाना चाहिए (लेकिन वहां कोई 'तैयार रीड()' सिग्नल उत्सर्जित नहीं है, 'TestChild :: readInput() 'स्लॉट नहीं कहा जाता है)। –

1

प्रलेखन का कहना है कि QFile सिग्नल readyRead() सिग्नल उत्सर्जित नहीं करता है।

लेकिन QWinEventNotifiersrc/corelib/kernel/qwineventnotifier_p.h(link) में GetStdHandle(STD_INPUT_HANDLE) के साथ काम कर सकता है।

एक अन्य विकल्प के लिए एक समर्पित धागा अंदर एक अवरुद्ध पाश के साथ इनपुट के लिए प्रतीक्षा करने के लिए है:

QTextStream cin(stdin, QIODevice::ReadOnly); 
while(!cin.atEnd()) 
{ 
    QString line = cin.readLine(); 
    emit newLine(line); 
} 

तुम भी अन्य आरपीसी पद्धति (उदा QLocalSocket, QSharedMemory) पर दिखाई दे सकता है।

+0

धन्यवाद, QWinEventNotifier का प्रयास करेंगे। लेकिन समस्या अभी भी मौजूद है: मैंने एक टाइमर शुरू किया है जो प्रत्येक एक्स एमएस लॉग-फ़ाइल 'input.bytesAvailable() 'पर लिखता है, और यह हमेशा' 0' लिखता है।क्या 'बाइट्स उपलब्ध()' उपयोग यहां भी गलत है? –

+0

'QSharedMemory' ने कोशिश नहीं की। लेकिन 'QLocalSocket',' QLocalServer' (विंडोज़ में पाइप नामित) के बारे में: मुझे अभी भी पाइप नामों का आदान-प्रदान करना है (प्रत्येक 'QLocalServer' के लिए 1)। क्या stdin/stdout के अलावा पाइप नाम भेजने के लिए कोई और आसान तरीका है? –

+1

1. आप सी/सी ++ मानक पुस्तकालयों के साथ स्टडीन बफर में नहीं देख सकते हैं, इसलिए यह आश्चर्यचकित नहीं होगा अगर क्यूटी इसे अनुमति नहीं देता है। 2. आप उप-प्रक्रिया तर्क के रूप में पाइप नाम भेज सकते हैं। – alexisdm

6

stdin/stdout घटनाओं के लिए क्यूटी ईवेंट लूप में पोर्टेबल हुकअप करने का कोई तरीका नहीं है। गैर-विंडोज प्लेटफ़ॉर्म पर निम्न कार्य:

QSocketNotifier *n1 = new QSocketNotifier(0, QSocketNotifier::Read, this); 
connect(n1, SIGNAL(activated(int)), this, SLOT(readInputChannel())); 

QSocketNotifier *n2 = new QSocketNotifier(0, QSocketNotifier::Exception, this); 
connect(n2, SIGNAL(activated(int)), this, SLOT(brokenInputChannel())); 

"0" फ़ाइल डिस्क्रिप्टर (stdin) है।

मैं एक अवरुद्ध धागा कि stdin से पढ़ता है और एक संकेत उत्पन्न करता है के माध्यम से विंडोज पर ऊपर और फिर अनुकरण कुछ इसी तरह का प्रयोग करेंगे: तो

class StdinThread : public QThread 
{ 
    Q_OBJECT 
signals: 
    void incomingData(QByteArray data); 

public: 
    void run(void) 
    { 
     char buf[1024]; 
     while (1) 
     { 
      int sz = fread(buf, 1, 1024, stdin); 
      if (sz == 0) 
       return; 
      emit incomingData(QByteArray(buf, sz)); 
     } 
    } 
}; 

, बच्चे की प्रक्रिया में:

StdinThread *t = new StdinThread(this); 
connect(t, SIGNAL(incomingData(QByteArray)), this, SLOT(processInputData(QByteArray))); 
connect(t, SIGNAL(finished()), this, SLOT(brokenInputChannel())); 
t->run(); 
+0

+1। यह सहायक है, धन्यवाद। क्या आप नहीं जानते कि 'QProcess :: write' (stdin पाइपिंग) विंडोज पर काम करता है या नहीं? दूसरे शब्दों में: क्या मैं बाल प्रक्रिया के stdin को लिख सकता हूं? –

+0

हाँ आप कर सकते हैं। विंडोज पाइपिंग का समर्थन करता है। बफरिंग पर ध्यान दें। –

संबंधित मुद्दे