लक्ष्य रास्पबेरी पाई 4 के लिए एक क्यूटी एप्लिकेशन लिखना था जिसका उपयोग विभिन्न डब्ल्यूएलएएन एक्सेस पॉइंट्स के बीच स्विच करने और संबंधित क्रेडेंशियल्स को स्टोर करने के लिए किया जा सकता है।
मैंने रास्पबेरी पाई 4 पर क्यूटी में वर्णित एक रास्पबियन-बस्टर-लाइट छवि और एक क्यूटी इंस्टॉलेशन का उपयोग किया।
इसके अलावा, मैंने नेटवर्कमैनेजर स्थापित किया है, जिसका उपयोग शेल कमांड (एनएमसीएलआई ...) द्वारा किया जा सकता है। नेटवर्क कनेक्शन बनाएँ, कॉन्फ़िगर करें और प्रबंधित करें.
इस बारे में जानकारी https://wiki.debian.org/de/NetworkManager या https://developer.gnome.org/NetworkManager/stable/nmcli.html के तहत मिल सकती है
नेटवर्कमैनेजर एक कमांड प्रदान करता है जिसका उपयोग निगरानी प्रक्रिया शुरू करने के लिए किया जा सकता है, जो तब विभिन्न इंटरफेस (wlan0 या eth0) में परिवर्तन पर टिप्पणी करता है (उदाहरण के लिए अनुपलब्ध, डिस्कनेक्ट, कनेक्टिंग, कनेक्ट, ...)।
मैं जीयूआई में नेटवर्क स्थानों की विभिन्न स्थितियों को प्रदर्शित करने के लिए इस निगरानी का उपयोग करना चाहता था। 2 समस्याएं सामने आईं:

  • यदि कई एनएमसीएलआई कमांड जल्दी से जारी किए गए थे, तो विभिन्न स्थितियों के बारे में प्रतिक्रिया समय की देरी के साथ पहुंची और जीयूआई में लाइव प्रदर्शित नहीं की जा सकी।
  • एनएमसीएलआई कमांड की प्रतिक्रिया अलग-अलग स्लॉट में भेजी गई थी और इस प्रकार इसे खराब तरीके से समन्वित किया जा सकता था।

निगरानी समारोह

सबसे पहले, हमें निगरानी फ़ंक्शन (मॉनिटरडिवाइस) और सार्वजनिक स्लॉट फ़ंक्शन की आवश्यकता होती है, जो मॉनिटरिंग आउटपुट को इंटरसेप्ट और मूल्यांकन करता है और फिर जीयूआई को स्थिति संदेश भेजता है, उदाहरण के लिए।
"मॉनिटरडिवाइस" फ़ंक्शन में, जो एप्लिकेशन शुरू होने पर स्वचालित रूप से शुरू होता है, एनएमसीएलआई कमांड को सूडो के साथ शुरू किया जाता है: सुडो एनएमसीएलआई मॉनिटर।
कथन "setProcessChannelMode (QProcess:: मर्ज ्ड चैनल)" में कहा गया है कि "मानक आउटपुट" और "मानक त्रुटि" एक चैनल में एक साथ प्रदर्शित होते हैं और इस प्रकार एक फ़ंक्शन के साथ मूल्यांकन किया जा सकता है।
लाइन "कनेक्ट (device_monitoring_process, सिग्नल (रेडीरीडस्टैंडर्डआउटपुट ()), यह, एसएलओटी (प्रोसेसआउटपुट ())" का उपयोग तब किया जाता है जब कोई संदेश प्रदर्शित होता है (रेडीरीडस्टैंडर्ड आउटपुट), इसे "प्रोसेसआउटपुट" स्लॉट पर भेजा जाता है।

void CmdLauncher::monitorDevices() {
QStringList device_monitoring_on = {"nmcli", "monitor"};
device_monitoring_process = new QProcess(this);
device_monitoring_process->setProcessChannelMode(QProcess::MergedChannels);
device_monitoring_process->start("sudo", device_monitoring_on);
connect(device_monitoring_process, SIGNAL(readyReadStandardOutput()), this, SLOT(processOutput()));
}

</:code1:>

मूल्यांकन समारोह

संदेशों का मूल्यांकन तब "प्रोसेसआउटपुट" फ़ंक्शन में किया जाता है। क्यूप्रोसेस प्रेषक प्रक्रिया सभी एनएमसीएलआई आदेशों के सभी संदेशों को इंटरसेप्ट करती है - न केवल निगरानी कमांड के।

void CmdLauncher::processOutput() {
QProcess* senderProcess = qobject_cast<QProcess*>(sender());
senderProcess->setReadChannel(QProcess::StandardOutput);
QString message = QString::fromLocal8Bit(senderProcess->readAllStandardOutput());

qDebug() << "CmdLauncher::processOutput message: " << message << endl;
if (message.contains("Error:")) {
    message.remove(QString("\n"));
    error_messages = message;
    emit getErrorMessagesChanged();
    if (message.contains(QString("Error: unknown connection"))) {
        secrets_required = true;
        emit getSecretsRequiredChanged();
    }
}
// wifi
if (message.contains("wlan0: connected") || message.contains("wlan0:connected")) {
    wifi_device_state = "Wifi-Connected";
    emit getWifiDeviceStateChanged();
    error_messages = "";
    emit getErrorMessagesChanged();
    rescanWifi();
    testInternetConnection();
}

}

</:code2:>

एक और nmcli प्रक्रिया प्रारंभ करें

यदि अब आप नीचे दिए गए फ़ंक्शन के साथ एक और एनएमसीएलआई कमांड शुरू करते हैं, तो आउटपुट को उपरोक्त निगरानी फ़ंक्शन द्वारा इंटरसेप्ट किया जाता है और फिर "आउटपुट प्रोसेस" में मूल्यांकन और आगे संसाधित किया जा सकता है।
यह फ़ंक्शन किसी मौजूदा नेटवर्क कनेक्शन पर स्विच करता है और इसे प्रारंभ करता है। "set_wifi_process->WatchForReadyRead()" या "set_wifi_process->VeteForFinished()" को शामिल नहीं करना महत्वपूर्ण है, क्योंकि तब तक सभी संदेशों का आउटपुट अवरुद्ध हो जाएगा जब तक कि यह प्रक्रिया समाप्त नहीं हो जाती।

void CmdLauncher::setWifi(QString ssid) {
    error_messages = "";
    emit getErrorMessagesChanged();

    QString uuid = "";
    for (int i = 0 ; i  networkConnections.length() ; i++) {
        QStringList connections = networkConnections[i].split(":");
        if (connections[1] == ssid)
        {
            uuid = connections[2];
        }
    }

    QStringList args_wifi_exist = {"nmcli", "connection", "up", uuid};
    set_wifi_process = new QProcess(this);
    set_wifi_process->setProcessChannelMode(QProcess::MergedChannels);
    set_wifi_process->start("sudo", args_wifi_exist);
    connect(set_wifi_process, SIGNAL(readyReadStandardOutput()), this, SLOT(processOutput()));
}

लाइन "कनेक्ट (set_wifi_process), सिग्नल (रेडीरीडस्टैंडर्डआउटपुट ()), यह, एसएलओटी (प्रोसेसआउटपुट ())" इस प्रक्रिया के आउटपुट संदेशों को "प्रोसेसआउटपुट" पर वापस अग्रेषित करती है और वहां फिर से एक केंद्रीय स्थान पर मूल्यांकन किया जा सकता है। </:code3:>

Walter Prechtl

Walter Prechtl

पर अपडेट किया गया: 12. मार्च 2024
पढ़ने का समय: 4 मिनट