首頁 > 軟體

基於PyQt5實現一個無線網聯結器

2022-08-04 14:02:18

最近開啟電腦wifi連線老是出現各種問題,於是突發奇想,我自己能不能做一個wifi連線的小工具豈不是就沒有這些麻煩了,居然成功了。

為了方便不會python的朋友也能夠使用,於是我用pyqt5將其做成了介面化的小工具,希望可以幫助到和我有一樣困惑的小夥伴。

另外,也可以幫助大家瞭解到pyqt5 ui的使用過程,最後我將wifi連線小工具打包成了exe的應用程式,大家可以直接下載使用。

1、準備

準備工作就是介紹一下使用到的第三方的非標準庫,第一個使用到的就是pywifi模組,
使用這個模組來完成對wifi的控制操作。

不過在執行的過程中遇到了一個問題,就是安裝好pywifi模組以後還會提示缺少comtypes,不過沒有影響我們將這個庫安裝就好了。

pip install pywifi -i https://pypi.tuna.tsinghua.edu.cn/simple

pip install comtypes -i https://pypi.tuna.tsinghua.edu.cn/simple

安裝好需要的第三方非標準庫,將需要的python模組內容匯入到我們的程式碼塊中就OK了。

import time

from pywifi import const, PyWiFi, Profile

接下來就是PyQt5模組了,這個模組之前已經使用好多回了,直接使用pip的方式安裝。安裝好PyQt5模組後,將其匯入到python程式碼塊中。

from PyQt5.QtWidgets import *

from PyQt5.QtGui import *

from PyQt5.QtCore import *

import sys

import traceback

2、UI應用

要製作wifi無線網連線小工具,需要先將UI介面部分寫好,話不多說,我們直接建立一個class來專門編寫關於UI介面的部分,開始介紹之前先來看一下我們已經寫好的UI介面效果。

wifi聯結器主介面.png

class WifiUI(QWidget):
    def __init__(self):
        super(WifiUI, self).__init__()
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle('wifi 聯結器  來源公眾號:Python 集中營')
        self.setWindowIcon(QIcon('wifi.png'))
        self.setFixedSize(500, 300)

        self.brower = QTextBrowser()
        self.brower.setFont(QFont('宋體', 8))
        self.brower.setReadOnly(True)
        self.brower.setPlaceholderText('處理程序展示區域...')
        self.brower.ensureCursorVisible()

        self.check_status_btn = QPushButton()
        self.check_status_btn.setText('檢查連線狀態')
        self.check_status_btn.clicked.connect(self.check_status_btn_click)

        self.wifi_list_btn = QPushButton()
        self.wifi_list_btn.setText('獲取wifi列表')
        self.wifi_list_btn.clicked.connect(self.wifi_list_btn_click)

        self.wifi_ssid_in = QLineEdit()
        self.wifi_ssid_in.setPlaceholderText('wifi 名稱')

        self.wifi_pwd_in = QLineEdit()
        self.wifi_pwd_in.setPlaceholderText('wifi 密碼')

        self.conn_btn = QPushButton()
        self.conn_btn.setText('開始連線wifi')
        self.conn_btn.clicked.connect(self.connect_wifi)

        hbox = QHBoxLayout()
        hbox.addWidget(self.brower)
        vbox = QVBoxLayout()
        vbox.addWidget(self.check_status_btn)
        vbox.addWidget(self.wifi_list_btn)
        vbox.addWidget(self.wifi_ssid_in)
        vbox.addWidget(self.wifi_pwd_in)
        vbox.addStretch(1)
        vbox.addWidget(self.conn_btn)
        hbox.addLayout(vbox)

        self.setLayout(hbox)

        self.wifi_list_thread = WiFiThread()
        self.wifi_list_thread.message.connect(self.show_message)
        self.wifi_list_thread.finished.connect(self.finished_wifilist)

        self.wifi_conn_thread = CoonThread(self)
        self.wifi_conn_thread.message.connect(self.show_message)
        self.wifi_conn_thread.finished.connect(self.finished_conn)

    def finished_wifilist(self, finished):
        if finished is True:
            self.wifi_list_btn.setEnabled(True)
            self.wifi_list_btn.setText('獲取wifi列表')

    def finished_conn(self, finished):
        if finished is True:
            self.conn_btn.setEnabled(True)
            self.conn_btn.setText('開始連線wifi')

    def show_message(self, text):
        cursor = self.brower.textCursor()
        cursor.movePosition(QTextCursor.End)
        self.brower.append(text)
        self.brower.setTextCursor(cursor)
        self.brower.ensureCursorVisible()

    def check_status_btn_click(self):
        wifi = PyWiFi()
        interface = wifi.interfaces()[0]

        if interface.status() in [const.IFACE_CONNECTED, const.IFACE_INACTIVE]:
            self.show_message('當前計算機已連線wifi!')
        else:
            self.show_message('當前計算機未連線wifi!')

    def wifi_list_btn_click(self):
        self.wifi_list_btn.setEnabled(False)
        self.wifi_list_btn.setText('正在獲取...')
        self.wifi_list_thread.start()

    def connect_wifi(self):
        self.conn_btn.setEnabled(False)
        self.conn_btn.setText('正在連線...')
        self.wifi_conn_thread.start()

3、業務執行緒

使用PyQt5中的QThread子執行緒來專門開發業務相關的程式碼塊,實現使用名稱、密碼連線wifi的功能。然後將該執行緒加入到UI介面的主執行緒中單獨執行即可。這裡將wifi連線和掃描wifi業務分為了兩個子執行緒來做,分別是WiFiThread、CoonThread兩個執行緒。

class WiFiThread(QThread):
    message = pyqtSignal(str)
    finished = pyqtSignal(bool)

    def __init__(self):
        super(WiFiThread, self).__init__()
        self.working = True

    def __del__(self):
        self.working = False
        self.wait()

    def run(self):
        wifi = PyWiFi()
        interface = wifi.interfaces()[0]

        interface.scan()
        self.message.emit('正在掃描wifi列表...')
        time.sleep(3)
        wifis = interface.scan_results()
        self.message.emit('wifi列表掃描完成!')

        for i in wifis:
            self.message.emit('wifi 名稱:{}'.format(i.ssid))
            self.message.emit('wifi 裝置mac地址:{}'.format(i.bssid))

        self.finished.emit(True)


class CoonThread(QThread):
    message = pyqtSignal(str)
    finished = pyqtSignal(bool)

    def __init__(self, parent=None):
        super(CoonThread, self).__init__(parent)
        self.working = True
        self.parent = parent

    def __del__(self):
        self.working = False
        self.wait()

    def run(self):
        try:
            wifi = PyWiFi()
            interface = wifi.interfaces()[0]

            if interface.status() == const.IFACE_CONNECTED:
                interface.disconnect()
                time.sleep(3)

            profile = Profile()  # 組態檔
            profile.ssid = self.parent.wifi_ssid_in.text().strip()  # wifi名稱
            self.message.emit('wifi 名稱:{}'.format(self.parent.wifi_ssid_in.text().strip()))
            profile.auth = const.AUTH_ALG_OPEN  # 需要密碼
            profile.akm.append(const.AKM_TYPE_WPA2PSK)  # 加密型別
            profile.cipher = const.CIPHER_TYPE_CCMP  # 加密單元
            profile.key = self.parent.wifi_pwd_in.text().strip()  # wifi密碼
            self.message.emit('wifi 密碼:{}'.format(self.parent.wifi_pwd_in.text().strip()))

            interface.remove_all_network_profiles()  # 刪除其它組態檔
            tmp_profile = interface.add_network_profile(profile)  # 載入組態檔
            interface.connect(tmp_profile)

            time.sleep(5)

            if interface.status() == const.IFACE_CONNECTED:
                self.message.emit('wifi名稱:{}連線成功!'.format(self.parent.wifi_ssid_in.text().strip()))
            else:
                self.message.emit('wifi名稱:{}連線失敗!'.format(self.parent.wifi_ssid_in.text().strip()))

            time.sleep(1)
            self.finished.emit(True)
        except Exception as e:
            traceback.print_exc()
            self.message.emit('wifi 連線出現異常!')
            self.finished.emit(True)

4、主函數

最後,使用main主函數將整個應用啟動即可看到整個頁面應用直接使用相應的功能連線wifi。

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = WifiUI()
    main.show()
    sys.exit(app.exec_())

以上程式碼塊部分乃是無線網聯結器小工具的全部程式碼塊,不用單獨再獲取原始碼。將文章的全部帶那塊挨個copy到一個.py的python檔案中直接執行即可。

到此這篇關於基於PyQt5實現一個無線網聯結器的文章就介紹到這了,更多相關PyQt5無線網聯結器內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com