windows下c++扫描连接wifi_实现用c++在win7下,扫描可用的本地连接-程序员宅基地

技术标签: Qt  qt  windows wifi  

Windows下使用Wifi Native Api在应用程序内部控制wifi,官方文档链接https://docs.microsoft.com/zh-cn/windows/win32/nativewifi/native-wifi-api-sample,主要注意以下几点:

  • 连接wifi使用wlan_connection_mode_profile时,如果被连接的wifi有配置文件,那么连接参数直接使用配置文件名称即可,如果没有配置文件,要先WlanSetProfile成功后才能创建连接,不同的加密方式有不同的配置文件样本,常用的WPA2样本WPA2-Personal Profile Sample
  • 官方的配置文件样本有个坑,官方的xml demo里面命名空间是https,实际使用的是http才能WlanSetProfile成功,否则会报ERROR_BAD_PROFILE错误
  • 连接wifi前需要断开当前已经连接的wifi
  • WlanRegisterNotification的回调函数接收通知是系统全局的,也就是说在系统设置里面操作wifi也能通知回调,并且是异步回调

下面是根据官方文档和demo写的demo,结合Qt
WifiHelper.h

#pragma once

#include <Windows.h>
#include <wlanapi.h>
#include <objbase.h>
#include <wtypes.h>

#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "wlanapi.lib")

#include <qobject.h>

struct EntryInfo {
    
    QString profile;
    QString ssid;
    bool connectable;
    long signalQuality;//信号质量
    int rssi;
    bool securityEnabled;//启动网络安全
    QString authAlgorithm;//认证算法
    QString cipherAlgorithm;//加密算法
    DWORD dwFlags;
    QString status;//当前状态
    //
    DOT11_SSID dot11_ssid;
    DOT11_BSS_TYPE dot11BssType;
    DOT11_AUTH_ALGORITHM dot11DefaultAuthAlgorithm;
    DOT11_CIPHER_ALGORITHM dot11DefaultCipherAlgorithm;
};

struct WifiInfo {
    
    QString description;
    GUID guid;
    QString guidStr;
    QString status;
    QList<EntryInfo> entryList;
};

class WifiHelper : public QObject {
    
    Q_OBJECT

public:
    WifiHelper(QString profileTemplateStr, QObject* parent = nullptr);
    ~WifiHelper();

    void loadWifiInfo(); 
    void scanWifiList(int interfaceIndex);
    void reloadWifiList(int interfaceIndex);
    void connectWifi(int interfaceIndex, int entryInfoIndex, QString passwordIfNeed);
    void disconnectWifi(int interfaceIndex);

signals:
    void getNewInterfaceGuid(QString guidStr);
    void interfaceListRefreshed(const QList<WifiInfo>& wifiList);
    void wifiListRefreshed(const WifiInfo& wifiInfo);
    void printErr(QString title, QString content);

private:
    QList<WifiInfo> wifiList;
    HANDLE hClient = NULL;
    PWLAN_INTERFACE_INFO_LIST pIfList = NULL;
    QString profileTemplateStr;

private:
    void findActiveWireless(WifiInfo& wifiInfo);
    void connectWifi(const GUID& interfaceGuid, const EntryInfo& entryInfo, QString password);
    void disconnectWifi(const GUID& interfaceGuid);
    bool setProfile(const GUID& interfaceGuid, const EntryInfo& entryInfo, QString password);
    QString getProfileStr(const EntryInfo& entryInfo, QString password);
    QString getProfileStr(const GUID& interfaceGuid, QString profileName);

private slots:
    void reloadWifiListInMainThread(QString guidStr);
};

WifiHelper.cpp

#include "WifiHelper.h"
#include <qdebug.h>

void WlanNotificationCallback(PWLAN_NOTIFICATION_DATA Arg1, PVOID Arg2) {
    
    if (Arg1 != NULL) {
    
        switch (Arg1->NotificationSource) {
    
            case WLAN_NOTIFICATION_SOURCE_ACM:
                const auto wifi_list_refresh = [&] {
    
                    auto obj = static_cast<WifiHelper*>(Arg2);
                    if (obj != nullptr) {
    
                        WCHAR GuidString[39] = {
     0 };
                        int iRet = StringFromGUID2(Arg1->InterfaceGuid, (LPOLESTR)&GuidString, sizeof(GuidString) / sizeof(*GuidString));
                        obj->getNewInterfaceGuid(QString::fromStdWString(GuidString));
                    }
                };
                switch (Arg1->NotificationCode) {
    
                    case wlan_notification_acm_connection_complete:
                        {
    
                            if (Arg1->dwDataSize < sizeof(WLAN_CONNECTION_NOTIFICATION_DATA)) {
    
                                break;
                            }
                            auto data = (PWLAN_CONNECTION_NOTIFICATION_DATA)Arg1->pData;
                            QString ssid = QByteArray((char*)data->dot11Ssid.ucSSID, data->dot11Ssid.uSSIDLength);
                            if (data->wlanReasonCode == WLAN_REASON_CODE_SUCCESS) {
    
                                qDebug() << QString("%1 connection successed!").arg(ssid);
                                wifi_list_refresh();
                            } else {
    
                                wchar_t reasonCodeStr[1024] = {
     0 };
                                WlanReasonCodeToString(data->wlanReasonCode, 1024, reasonCodeStr, NULL);
                                auto obj = static_cast<WifiHelper*>(Arg2);
                                if (obj != nullptr) {
    
                                    obj->printErr(QString("%1 connection failed!").arg(ssid), QString::fromWCharArray(reasonCodeStr));
                                }
                            }
                        }
                        break;
                    case wlan_notification_acm_scan_complete:
                    case wlan_notification_acm_disconnected:
                        wifi_list_refresh();
                        break;
                    default:
                        break;
                }
                break;
        }
    }
    qDebug() << "notifycode = " << Arg1->NotificationCode;
}

WifiHelper::WifiHelper(QString profileTemplateStr, QObject* parent)
    : QObject(parent) 
    , profileTemplateStr(profileTemplateStr)
    , pIfList(NULL)
{
    
    DWORD dwMaxClient = 2;
    DWORD dwCurVersion = 0;
    DWORD dwResult = WlanOpenHandle(dwMaxClient, NULL, &dwCurVersion, &hClient);
    Q_ASSERT(dwResult == ERROR_SUCCESS);

    DWORD dwNotifSourcePre;
    dwResult = WlanRegisterNotification(hClient, WLAN_NOTIFICATION_SOURCE_ACM, TRUE, (WLAN_NOTIFICATION_CALLBACK)WlanNotificationCallback, this, NULL, &dwNotifSourcePre);

    connect(this, &WifiHelper::getNewInterfaceGuid, this, &WifiHelper::reloadWifiListInMainThread);
}


WifiHelper::~WifiHelper() {
    
    if (pIfList != NULL) {
    
        WlanFreeMemory(pIfList);
        pIfList = NULL;
    }
    WlanCloseHandle(hClient, NULL);
}

void WifiHelper::loadWifiInfo() {
    
    wifiList.clear();

    if (pIfList != NULL) {
    
        WlanFreeMemory(pIfList);
        pIfList = NULL;
    }

    DWORD dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList);
    Q_ASSERT(dwResult == ERROR_SUCCESS);

    for (int i = 0; i < (int)pIfList->dwNumberOfItems; i++) {
    
        PWLAN_INTERFACE_INFO pIfInfo = (WLAN_INTERFACE_INFO*)&pIfList->InterfaceInfo[i];

        WifiInfo wifiInfo;
        wifiInfo.description = QString::fromStdWString(pIfInfo->strInterfaceDescription);

        WCHAR GuidString[39] = {
     0 };
        int iRet = StringFromGUID2(pIfInfo->InterfaceGuid, (LPOLESTR)&GuidString, sizeof(GuidString) / sizeof(*GuidString));
        wifiInfo.guid = pIfInfo->InterfaceGuid;
        wifiInfo.guidStr = iRet == 0 ? "StringFromGUID2 failed" : QString::fromStdWString(GuidString);

        switch (pIfInfo->isState) {
    
            case wlan_interface_state_not_ready:
                wifiInfo.status = "Not ready";
                break;
            case wlan_interface_state_connected:
                wifiInfo.status = "Connected";
                break;
            case wlan_interface_state_ad_hoc_network_formed:
                wifiInfo.status = "First node in a ad hoc network";
                break;
            case wlan_interface_state_disconnecting:
                wifiInfo.status = "Disconnecting";
                break;
            case wlan_interface_state_disconnected:
                wifiInfo.status = "Not connected";
                break;
            case wlan_interface_state_associating:
                wifiInfo.status = "Attempting to associate with a network";
                break;
            case wlan_interface_state_discovering:
                wifiInfo.status = "Auto configuration is discovering settings for the network";
                break;
            case wlan_interface_state_authenticating:
                wifiInfo.status = "In process of authenticating";
                break;
            default:
                wifiInfo.status = "Unknown state " + QString::number(pIfInfo->isState);
                break;
        }
        wifiList << wifiInfo;
    }

    findActiveWireless(wifiList[0]);
    wifiListRefreshed(wifiList.at(0));
    interfaceListRefreshed(wifiList);
}

void WifiHelper::scanWifiList(int interfaceIndex) {
    
    WLAN_RAW_DATA wlanRawData = {
     0 };
    DWORD dwResult = WlanScan(hClient, &wifiList[interfaceIndex].guid, NULL, &wlanRawData, NULL);
    Q_ASSERT(dwResult == ERROR_SUCCESS);
}

void WifiHelper::reloadWifiList(int interfaceIndex) {
    
    findActiveWireless(wifiList[interfaceIndex]);
    wifiListRefreshed(wifiList.at(interfaceIndex));
}

void WifiHelper::connectWifi(int interfaceIndex, int entryInfoIndex, QString passwordIfNeed) {
    
    connectWifi(wifiList.at(interfaceIndex).guid,
                wifiList.at(interfaceIndex).entryList.at(entryInfoIndex),
                passwordIfNeed
    );
}

void WifiHelper::disconnectWifi(int interfaceIndex) {
    
    disconnectWifi(wifiList.at(interfaceIndex).guid);
}

void WifiHelper::reloadWifiListInMainThread(QString guidStr) {
    
    for (int i = 0; i < wifiList.size(); i++) {
    
        if (wifiList.at(i).guidStr == guidStr) {
    
            findActiveWireless(wifiList[i]);
            wifiListRefreshed(wifiList.at(i));
            break;
        }
    }
}

void WifiHelper::connectWifi(const GUID& interfaceGuid, const EntryInfo& entryInfo, QString password) {
    
    if (entryInfo.dwFlags & WLAN_AVAILABLE_NETWORK_CONNECTED) {
    
        return;
    }

    disconnectWifi(interfaceGuid);

    wchar_t profile[WLAN_MAX_NAME_LENGTH] = {
    };
    if (!(entryInfo.dwFlags & WLAN_AVAILABLE_NETWORK_HAS_PROFILE)) {
    
        setProfile(interfaceGuid, entryInfo, password);
    }
    entryInfo.ssid.toWCharArray(profile);
    auto fstr = getProfileStr(interfaceGuid, entryInfo.ssid);

    WLAN_CONNECTION_PARAMETERS parameter;
    parameter.strProfile = profile;
    parameter.pDot11Ssid = NULL;
    parameter.pDesiredBssidList = NULL;
    parameter.wlanConnectionMode = wlan_connection_mode_profile;
    parameter.dot11BssType = entryInfo.dot11BssType;
    parameter.dwFlags = WLAN_CONNECTION_HIDDEN_NETWORK;

    DWORD dwResult = WlanConnect(hClient, &interfaceGuid, &parameter, NULL);
    if (dwResult != ERROR_SUCCESS) {
    
        if (dwResult == ERROR_INVALID_PARAMETER) {
    
            printErr(u8"无法连接", u8"不支持的连接!修改profile模板!");
        } else {
    
            Q_ASSERT(dwResult == ERROR_SUCCESS);
        }
    }
}

void WifiHelper::disconnectWifi(const GUID & interfaceGuid) {
    
    DWORD dwResult = WlanDisconnect(hClient, &interfaceGuid, NULL);
    Q_ASSERT(dwResult == ERROR_SUCCESS);
}

bool WifiHelper::setProfile(const GUID& interfaceGuid, const EntryInfo& entryInfo, QString password) {
    
    wchar_t profile[2048] = {
     0 };
    QString profileStr = getProfileStr(entryInfo, password);
    profileStr.toWCharArray(profile);
    DWORD dwReasonCode;
    wchar_t reasonCodeStr[1024] = {
     0 };
    DWORD dwResult = WlanSetProfile(hClient, &interfaceGuid, 0, profile, NULL, TRUE, NULL, &dwReasonCode);
    if (dwResult != ERROR_SUCCESS) {
    
        WlanReasonCodeToString(dwReasonCode, 1024, reasonCodeStr, NULL);
    }
    return dwResult == ERROR_SUCCESS;
}

QString WifiHelper::getProfileStr(const EntryInfo& entryInfo, QString password) {
    
    QString templateContent = profileTemplateStr;
    templateContent.replace("{ssid}", entryInfo.ssid);
    templateContent.replace("{password}", password);
    switch (entryInfo.dot11DefaultAuthAlgorithm) {
    
        case DOT11_AUTH_ALGO_80211_OPEN:
            templateContent.replace("{authentication}", "open");
            break;
        case DOT11_AUTH_ALGO_80211_SHARED_KEY:
            templateContent.replace("{authentication}", "shared");
            break;
        case DOT11_AUTH_ALGO_WPA:
            templateContent.replace("{authentication}", "WPA");
            break;
        case DOT11_AUTH_ALGO_WPA_PSK:
            templateContent.replace("{authentication}", "WPAPSK");
            break;
        case DOT11_AUTH_ALGO_WPA_NONE:
            templateContent.replace("{authentication}", "none");
            break;
        case DOT11_AUTH_ALGO_RSNA:
            templateContent.replace("{authentication}", "WPA2");
            break;
        case DOT11_AUTH_ALGO_RSNA_PSK:
            templateContent.replace("{authentication}", "WPA2PSK");
            break;
        default:
            break;
    }
    switch (entryInfo.dot11DefaultCipherAlgorithm) {
    
        case DOT11_CIPHER_ALGO_NONE:
            templateContent.replace("{encryption}", "none");
            break;
        case DOT11_CIPHER_ALGO_WEP40:
            templateContent.replace("{encryption}", "WEP");
            break;
        case DOT11_CIPHER_ALGO_TKIP:
            templateContent.replace("{encryption}", "TKIP");
            break;
        case DOT11_CIPHER_ALGO_CCMP:
            templateContent.replace("{encryption}", "AES");
            break;
        case DOT11_CIPHER_ALGO_WEP104:
            templateContent.replace("{encryption}", "WEP");
            break;
        case DOT11_CIPHER_ALGO_WEP:
            templateContent.replace("{encryption}", "WEP");
            break;
        default:
            break;
    }
    return templateContent;
}

QString WifiHelper::getProfileStr(const GUID & interfaceGuid, QString profileName) {
    
    wchar_t profile[WLAN_MAX_NAME_LENGTH] = {
    };
    profileName.toWCharArray(profile);
    DWORD dwFlags, dwGrantedAccess;
    LPWSTR pProfileXml = NULL;
    DWORD dwResult = WlanGetProfile(hClient, &interfaceGuid, profile, NULL, &pProfileXml, &dwFlags, &dwGrantedAccess);
    if (dwResult == ERROR_SUCCESS) {
    
        return QString::fromWCharArray(pProfileXml);
    }
    return QString();
}

void WifiHelper::findActiveWireless(WifiInfo& wifiInfo) {
    

    PWLAN_AVAILABLE_NETWORK_LIST pBssList = NULL;
    PWLAN_AVAILABLE_NETWORK pBssEntry = NULL;

    wifiInfo.entryList.clear();
    DWORD dwResult = WlanGetAvailableNetworkList(hClient, &wifiInfo.guid, 0, NULL, &pBssList);
    if (dwResult == ERROR_SUCCESS) {
    
        QHash<QString, EntryInfo> entryList;
        for (int j = 0; j < pBssList->dwNumberOfItems; j++) {
    
            pBssEntry = (WLAN_AVAILABLE_NETWORK *)& pBssList->Network[j];

            EntryInfo entryInfo;
            entryInfo.profile = QString::fromWCharArray(pBssEntry->strProfileName);
            entryInfo.dot11_ssid = pBssEntry->dot11Ssid;
            entryInfo.ssid = QByteArray((char*)pBssEntry->dot11Ssid.ucSSID, pBssEntry->dot11Ssid.uSSIDLength);
            entryInfo.connectable = pBssEntry->bNetworkConnectable;
            entryInfo.signalQuality = pBssEntry->wlanSignalQuality;

            int iRSSI = 0;
            if (pBssEntry->wlanSignalQuality == 0)
                iRSSI = -100;
            else if (pBssEntry->wlanSignalQuality == 100)
                iRSSI = -50;
            else
                iRSSI = -100 + (pBssEntry->wlanSignalQuality / 2);

            entryInfo.rssi = iRSSI;
            entryInfo.dot11BssType = pBssEntry->dot11BssType;
            entryInfo.securityEnabled = pBssEntry->bSecurityEnabled;

            entryInfo.dot11DefaultAuthAlgorithm = pBssEntry->dot11DefaultAuthAlgorithm;
            switch (pBssEntry->dot11DefaultAuthAlgorithm) {
    
                case DOT11_AUTH_ALGO_80211_OPEN:
                    entryInfo.authAlgorithm = "802.11 Open";
                    break;
                case DOT11_AUTH_ALGO_80211_SHARED_KEY:
                    entryInfo.authAlgorithm = "802.11 Shared";
                    break;
                case DOT11_AUTH_ALGO_WPA:
                    entryInfo.authAlgorithm = "WPA";
                    break;
                case DOT11_AUTH_ALGO_WPA_PSK:
                    entryInfo.authAlgorithm = "WPA-PSK";
                    break;
                case DOT11_AUTH_ALGO_WPA_NONE:
                    entryInfo.authAlgorithm = "WPA-None";
                    break;
                case DOT11_AUTH_ALGO_RSNA:
                    entryInfo.authAlgorithm = "RSNA";
                    break;
                case DOT11_AUTH_ALGO_RSNA_PSK:
                    entryInfo.authAlgorithm = "RSNA with PSK";
                    break;
                default:
                    entryInfo.authAlgorithm = "Other";
                    break;
            }

            entryInfo.dot11DefaultCipherAlgorithm = pBssEntry->dot11DefaultCipherAlgorithm;
            switch (pBssEntry->dot11DefaultCipherAlgorithm) {
    
                case DOT11_CIPHER_ALGO_NONE:
                    entryInfo.cipherAlgorithm = "None";
                    break;
                case DOT11_CIPHER_ALGO_WEP40:
                    entryInfo.cipherAlgorithm = "WEP-40";
                    break;
                case DOT11_CIPHER_ALGO_TKIP:
                    entryInfo.cipherAlgorithm = "TKIP";
                    break;
                case DOT11_CIPHER_ALGO_CCMP:
                    entryInfo.cipherAlgorithm = "CCMP";
                    break;
                case DOT11_CIPHER_ALGO_WEP104:
                    entryInfo.cipherAlgorithm = "WEP-104";
                    break;
                case DOT11_CIPHER_ALGO_WEP:
                    entryInfo.cipherAlgorithm = "WEP";
                    break;
                default:
                    entryInfo.cipherAlgorithm = "Other";
                    break;
            }
            entryInfo.dwFlags = pBssEntry->dwFlags;
            if (pBssEntry->dwFlags & WLAN_AVAILABLE_NETWORK_CONNECTED) {
    
                entryInfo.status = u8"已连接";
            } else if (pBssEntry->dwFlags & WLAN_AVAILABLE_NETWORK_HAS_PROFILE) {
    
                entryInfo.status = u8"已保存";
            } else {
    
                entryInfo.status = u8"未连接";
                if (entryList.contains(entryInfo.ssid)) {
    
                    continue;
                }
            }
            entryList.insert(entryInfo.ssid, entryInfo);
        }
        for (EntryInfo info : entryList.values()) {
    
            wifiInfo.entryList << info;
        }

    } else {
    
        qDebug() << "WlanGetAvailableNetworkList failed with error: " << dwResult;
    }

    if (pBssList != NULL) {
    
        WlanFreeMemory(pBssList);
        pBssList = NULL;
    }
}

上面是工具类,下面使用一个widget显示和交互

//WifiConnectTest.h
#pragma once

#include <QtWidgets/QWidget>
#include "ui_WifiConnectTest.h"

#include <qstandarditemmodel.h>

#include "WifiHelper.h"

class WifiConnectTest : public QWidget
{
    
    Q_OBJECT

public:
    WifiConnectTest(QWidget *parent = Q_NULLPTR);
    ~WifiConnectTest();

private:
    Ui::WifiConnectTestClass ui; 
    WifiHelper* wifiHelper;

    void addTableHeader(QStandardItemModel* model);

private slots:
    void loadWifiEntryList(const WifiInfo& wifiInfo);
    void loadWifiInterfaceList(const QList<WifiInfo>& wifiList);
    void showErrMessageBox(QString title, QString content);
};

WifiConnectTest.cpp
#include "WifiConnectTest.h"
#include <qfile.h>
#include <qdebug.h>
#include <qmessagebox.h>

WifiConnectTest::WifiConnectTest(QWidget *parent)
    : QWidget(parent)
{
    
    ui.setupUi(this);

    auto model = new QStandardItemModel(this);
    ui.tableView->setModel(model);
    ui.tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui.tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui.tableView->setSelectionMode(QAbstractItemView::SingleSelection);
    addTableHeader(model);

    connect(ui.scan_adapter, &QPushButton::clicked, [&]() {
    
        wifiHelper->loadWifiInfo();
    });
    
    connect(ui.scan_wifi, &QPushButton::clicked, [&]() {
    
        int currentAdapterIndex = ui.interfaceDescription->currentIndex();
        if (currentAdapterIndex >= 0) {
    
            wifiHelper->scanWifiList(currentAdapterIndex);
        }
    });

    connect(ui.interfaceDescription, qOverload<int>(&QComboBox::currentIndexChanged), [&](int index) {
    
        if (index >= 0) {
    
            wifiHelper->reloadWifiList(index);
        }
    });

    connect(ui.connect_tag, &QPushButton::clicked, [&]() {
    
        int interfaceIndex = ui.interfaceDescription->currentIndex();
        if (interfaceIndex >= 0) {
    
            int row = ui.tableView->currentIndex().row();
            if (row >= 0) {
    
                wifiHelper->connectWifi(interfaceIndex, row,
                                        ui.tableView->model()->index(row, ui.tableView->model()->columnCount() - 1).data(Qt::DisplayRole).toString());
            }
        }
    });

    connect(ui.disconnect_tag, &QPushButton::clicked, [&]() {
    
        int interfaceIndex = ui.interfaceDescription->currentIndex();
        if (interfaceIndex >= 0) {
    
            wifiHelper->disconnectWifi(interfaceIndex);
        }
    });

    QFile file(":/WifiConnectTest/Resources/profile_template.xml");
    file.open(QIODevice::ReadOnly);
    QString templateContent = file.readAll();
    file.close();

    wifiHelper = new WifiHelper(templateContent, this);
    connect(wifiHelper, &WifiHelper::interfaceListRefreshed, this, &WifiConnectTest::loadWifiInterfaceList);
    connect(wifiHelper, &WifiHelper::wifiListRefreshed, this, &WifiConnectTest::loadWifiEntryList);
    connect(wifiHelper, &WifiHelper::printErr, this, &WifiConnectTest::showErrMessageBox);

}

WifiConnectTest::~WifiConnectTest() {
    
    
}

void WifiConnectTest::addTableHeader(QStandardItemModel * model) {
    
    QStringList titles;
    titles << "ssid" << u8"是否可连接" << u8"信号质量" << "rssi" << u8"启动网络安全" << u8"认证算法" << u8"加密算法" << u8"状态" << u8"密码";
    model->setColumnCount(titles.size());
    for (int i = 0; i < titles.size(); i++) {
    
        model->setHeaderData(i, Qt::Horizontal, titles[i], Qt::DisplayRole);
    }
}

void WifiConnectTest::loadWifiEntryList(const WifiInfo& wifiInfo) {
    
    auto tabModel = static_cast<QStandardItemModel*>(ui.tableView->model());
    tabModel->clear();
    addTableHeader(tabModel);

    ui.interfaceStatus->setText(wifiInfo.status);
    for (int i = 0; i < wifiInfo.entryList.size(); i++) {
    
        auto entryInfo = wifiInfo.entryList.at(i);

        QStandardItem* item;
        int col = 0;

        item = new QStandardItem(entryInfo.ssid);
        tabModel->setItem(i, col++, item);

        item = new QStandardItem(entryInfo.connectable ? "yes" : "no");
        tabModel->setItem(i, col++, item);

        item = new QStandardItem(QString::number(entryInfo.signalQuality));
        tabModel->setItem(i, col++, item);

        item = new QStandardItem(QString("%1 dBm").arg(entryInfo.rssi));
        tabModel->setItem(i, col++, item);

        item = new QStandardItem(entryInfo.securityEnabled ? "yes" : "no");
        tabModel->setItem(i, col++, item);

        item = new QStandardItem(entryInfo.authAlgorithm);
        tabModel->setItem(i, col++, item);

        item = new QStandardItem(entryInfo.cipherAlgorithm);
        tabModel->setItem(i, col++, item);

        item = new QStandardItem(entryInfo.status);
        tabModel->setItem(i, col++, item);

        item = new QStandardItem;
        tabModel->setItem(i, col++, item);
    }
}

void WifiConnectTest::loadWifiInterfaceList(const QList<WifiInfo>& wifiList) {
    
    ui.interfaceDescription->clear();
    for (const auto& i : wifiList) {
    
        ui.interfaceDescription->addItem(i.description);
    }
}

void WifiConnectTest::showErrMessageBox(QString title, QString content) {
    
    QMessageBox::warning(NULL, title, content);
}

界面:
界面

demo工程在这里下载

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/baidu_30570701/article/details/103207045

智能推荐

攻防世界_难度8_happy_puzzle_攻防世界困难模式攻略图文-程序员宅基地

文章浏览阅读645次。这个肯定是末尾的IDAT了,因为IDAT必须要满了才会开始一下个IDAT,这个明显就是末尾的IDAT了。,对应下面的create_head()代码。,对应下面的create_tail()代码。不要考虑爆破,我已经试了一下,太多情况了。题目来源:UNCTF。_攻防世界困难模式攻略图文

达梦数据库的导出(备份)、导入_达梦数据库导入导出-程序员宅基地

文章浏览阅读2.9k次,点赞3次,收藏10次。偶尔会用到,记录、分享。1. 数据库导出1.1 切换到dmdba用户su - dmdba1.2 进入达梦数据库安装路径的bin目录,执行导库操作  导出语句:./dexp cwy_init/[email protected]:5236 file=cwy_init.dmp log=cwy_init_exp.log 注释:   cwy_init/init_123..._达梦数据库导入导出

js引入kindeditor富文本编辑器的使用_kindeditor.js-程序员宅基地

文章浏览阅读1.9k次。1. 在官网上下载KindEditor文件,可以删掉不需要要到的jsp,asp,asp.net和php文件夹。接着把文件夹放到项目文件目录下。2. 修改html文件,在页面引入js文件:<script type="text/javascript" src="./kindeditor/kindeditor-all.js"></script><script type="text/javascript" src="./kindeditor/lang/zh-CN.js"_kindeditor.js

STM32学习过程记录11——基于STM32G431CBU6硬件SPI+DMA的高效WS2812B控制方法-程序员宅基地

文章浏览阅读2.3k次,点赞6次,收藏14次。SPI的详情简介不必赘述。假设我们通过SPI发送0xAA,我们的数据线就会变为10101010,通过修改不同的内容,即可修改SPI中0和1的持续时间。比如0xF0即为前半周期为高电平,后半周期为低电平的状态。在SPI的通信模式中,CPHA配置会影响该实验,下图展示了不同采样位置的SPI时序图[1]。CPOL = 0,CPHA = 1:CLK空闲状态 = 低电平,数据在下降沿采样,并在上升沿移出CPOL = 0,CPHA = 0:CLK空闲状态 = 低电平,数据在上升沿采样,并在下降沿移出。_stm32g431cbu6

计算机网络-数据链路层_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输-程序员宅基地

文章浏览阅读1.2k次,点赞2次,收藏8次。数据链路层习题自测问题1.数据链路(即逻辑链路)与链路(即物理链路)有何区别?“电路接通了”与”数据链路接通了”的区别何在?2.数据链路层中的链路控制包括哪些功能?试讨论数据链路层做成可靠的链路层有哪些优点和缺点。3.网络适配器的作用是什么?网络适配器工作在哪一层?4.数据链路层的三个基本问题(帧定界、透明传输和差错检测)为什么都必须加以解决?5.如果在数据链路层不进行帧定界,会发生什么问题?6.PPP协议的主要特点是什么?为什么PPP不使用帧的编号?PPP适用于什么情况?为什么PPP协议不_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输

软件测试工程师移民加拿大_无证移民,未受过软件工程师的教育(第1部分)-程序员宅基地

文章浏览阅读587次。软件测试工程师移民加拿大 无证移民,未受过软件工程师的教育(第1部分) (Undocumented Immigrant With No Education to Software Engineer(Part 1))Before I start, I want you to please bear with me on the way I write, I have very little gen...

随便推点

Thinkpad X250 secure boot failed 启动失败问题解决_安装完系统提示secureboot failure-程序员宅基地

文章浏览阅读304次。Thinkpad X250笔记本电脑,装的是FreeBSD,进入BIOS修改虚拟化配置(其后可能是误设置了安全开机),保存退出后系统无法启动,显示:secure boot failed ,把自己惊出一身冷汗,因为这台笔记本刚好还没开始做备份.....根据错误提示,到bios里面去找相关配置,在Security里面找到了Secure Boot选项,发现果然被设置为Enabled,将其修改为Disabled ,再开机,终于正常启动了。_安装完系统提示secureboot failure

C++如何做字符串分割(5种方法)_c++ 字符串分割-程序员宅基地

文章浏览阅读10w+次,点赞93次,收藏352次。1、用strtok函数进行字符串分割原型: char *strtok(char *str, const char *delim);功能:分解字符串为一组字符串。参数说明:str为要分解的字符串,delim为分隔符字符串。返回值:从str开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。其它:strtok函数线程不安全,可以使用strtok_r替代。示例://借助strtok实现split#include <string.h>#include <stdio.h&_c++ 字符串分割

2013第四届蓝桥杯 C/C++本科A组 真题答案解析_2013年第四届c a组蓝桥杯省赛真题解答-程序员宅基地

文章浏览阅读2.3k次。1 .高斯日记 大数学家高斯有个好习惯:无论如何都要记日记。他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?高斯出生于:1777年4月30日。在高斯发现的一个重要定理的日记_2013年第四届c a组蓝桥杯省赛真题解答

基于供需算法优化的核极限学习机(KELM)分类算法-程序员宅基地

文章浏览阅读851次,点赞17次,收藏22次。摘要:本文利用供需算法对核极限学习机(KELM)进行优化,并用于分类。

metasploitable2渗透测试_metasploitable2怎么进入-程序员宅基地

文章浏览阅读1.1k次。一、系统弱密码登录1、在kali上执行命令行telnet 192.168.26.1292、Login和password都输入msfadmin3、登录成功,进入系统4、测试如下:二、MySQL弱密码登录:1、在kali上执行mysql –h 192.168.26.129 –u root2、登录成功,进入MySQL系统3、测试效果:三、PostgreSQL弱密码登录1、在Kali上执行psql -h 192.168.26.129 –U post..._metasploitable2怎么进入

Python学习之路:从入门到精通的指南_python人工智能开发从入门到精通pdf-程序员宅基地

文章浏览阅读257次。本文将为初学者提供Python学习的详细指南,从Python的历史、基础语法和数据类型到面向对象编程、模块和库的使用。通过本文,您将能够掌握Python编程的核心概念,为今后的编程学习和实践打下坚实基础。_python人工智能开发从入门到精通pdf

推荐文章

热门文章

相关标签