PyQt5 实现类似海康的设备搜索工具

简述

        使用IP地址组播技术,实现海康的设备搜索功能,只要设备接入局域网就能够被搜索到。效果图.

 

功能代码:

1. scan_device_ui.py 布局文件

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'scan_device.ui'
#
# Created by: PyQt5 UI code generator 5.15.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(849, 633)
        self.verticalLayout_2 = QtWidgets.QVBoxLayout(Form)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setContentsMargins(-1, 10, -1, 10)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.scan_device = QtWidgets.QPushButton(Form)
        self.scan_device.setObjectName("scan_device")
        self.horizontalLayout.addWidget(self.scan_device)
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        self.verticalLayout_2.addLayout(self.horizontalLayout)
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.device_list = QtWidgets.QTableWidget(Form)
        self.device_list.setObjectName("device_list")
        self.device_list.setColumnCount(0)
        self.device_list.setRowCount(0)
        self.horizontalLayout_3.addWidget(self.device_list)
        self.formLayout = QtWidgets.QFormLayout()
        self.formLayout.setObjectName("formLayout")
        self.label_mac = QtWidgets.QLabel(Form)
        self.label_mac.setObjectName("label_mac")
        self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_mac)
        self.et_mac = QtWidgets.QLineEdit(Form)
        self.et_mac.setObjectName("et_mac")
        self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.et_mac)
        self.label_ip = QtWidgets.QLabel(Form)
        self.label_ip.setObjectName("label_ip")
        self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_ip)
        self.et_ip = QtWidgets.QLineEdit(Form)
        self.et_ip.setObjectName("et_ip")
        self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.et_ip)
        self.label_mask = QtWidgets.QLabel(Form)
        self.label_mask.setObjectName("label_mask")
        self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_mask)
        self.et_mask = QtWidgets.QLineEdit(Form)
        self.et_mask.setObjectName("et_mask")
        self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.et_mask)
        self.label_gateway = QtWidgets.QLabel(Form)
        self.label_gateway.setObjectName("label_gateway")
        self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_gateway)
        self.et_gateway = QtWidgets.QLineEdit(Form)
        self.et_gateway.setObjectName("et_gateway")
        self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.et_gateway)
        spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.formLayout.setItem(5, QtWidgets.QFormLayout.FieldRole, spacerItem1)
        self.reset_ip = QtWidgets.QPushButton(Form)
        self.reset_ip.setObjectName("reset_ip")
        self.formLayout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.reset_ip)
        self.reboot_device = QtWidgets.QPushButton(Form)
        self.reboot_device.setObjectName("reboot_device")
        self.formLayout.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.reboot_device)
        spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.formLayout.setItem(8, QtWidgets.QFormLayout.FieldRole, spacerItem2)
        self.label_cmd = QtWidgets.QLabel(Form)
        self.label_cmd.setObjectName("label_cmd")
        self.formLayout.setWidget(9, QtWidgets.QFormLayout.LabelRole, self.label_cmd)
        self.et_remote_cmd = QtWidgets.QLineEdit(Form)
        self.et_remote_cmd.setObjectName("et_remote_cmd")
        self.formLayout.setWidget(9, QtWidgets.QFormLayout.FieldRole, self.et_remote_cmd)
        self.exec_remote_cmd = QtWidgets.QPushButton(Form)
        self.exec_remote_cmd.setObjectName("exec_remote_cmd")
        self.formLayout.setWidget(10, QtWidgets.QFormLayout.FieldRole, self.exec_remote_cmd)
        self.et_cmd_result = QtWidgets.QTextEdit(Form)
        self.et_cmd_result.setObjectName("et_cmd_result")
        self.formLayout.setWidget(11, QtWidgets.QFormLayout.FieldRole, self.et_cmd_result)
        self.horizontalLayout_3.addLayout(self.formLayout)
        self.horizontalLayout_3.setStretch(0, 2)
        self.horizontalLayout_3.setStretch(1, 1)
        self.verticalLayout_2.addLayout(self.horizontalLayout_3)
        self.verticalLayout_2.setStretch(1, 1)

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.scan_device.setText(_translate("Form", "搜索设备"))
        self.label_mac.setText(_translate("Form", "MAC地址:"))
        self.label_ip.setText(_translate("Form", "IP地址:"))
        self.label_mask.setText(_translate("Form", "子网掩码:"))
        self.label_gateway.setText(_translate("Form", "网关地址:"))
        self.reset_ip.setText(_translate("Form", "重新设置"))
        self.reboot_device.setText(_translate("Form", "重启设备"))
        self.label_cmd.setText(_translate("Form", "远程命令:"))
        self.exec_remote_cmd.setText(_translate("Form", "执行远程命令(慎用)"))

2. main.py 主文件

from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QTableWidgetItem, QTableWidget, QAbstractItemView
from PyQt5.QtCore import Qt, pyqtSignal, QObject
from PyQt5.QtGui import QFont, QImage, QPixmap, QIcon
import sys
import socket
import threading
import scan_device_ui


class signal(QObject):
    # 自定义一个信号
    signal = pyqtSignal(str)

    # 定义一个发送信号的函数
    def emit(self, text):
        self.signal.emit(text)

class QDeviceWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.ui = ui = scan_device_ui.Ui_Form()
        self.ui.setupUi(self)
        self.setWindowTitle("海帆-设备配置助手 V1.0")
        self.ui.scan_device.clicked.connect(self.scan_device)
        self.ui.reset_ip.clicked.connect(self.reset_ip_info)
        self.ui.reboot_device.clicked.connect(self.reboot_device)
        self.ui.exec_remote_cmd.clicked.connect(self.exec_remote_cmd)

        self.MULTICAST_ANY = "0.0.0.0"
        self.MULTICAST_IP = "239.255.255.250"
        self.MULTICAST_PORT = 35880

        self.update_ui = signal()
        self.update_ui.signal.connect(self.update_list_ui)

        self.start_listening()
        self.init_tables()
        self.count_index = 0
        self.list_content = []

    def init_tables(self):
        self.ui.device_list.setColumnCount(5)
        self.ui.device_list.setHorizontalHeaderLabels(['ID', 'MAC地址', 'IP地址', '子网掩码', '网关'])
        self.ui.device_list.setSelectionBehavior(QAbstractItemView.SelectRows)

        self.ui.device_list.itemClicked.connect(self.table_item_click)
        pass

    def table_item_click(self, item):
        print("item click = ", item.row())
        content = self.list_content[item.row()]

        self.ui.et_mac.setText(content[1])
        self.ui.et_ip.setText(content[2])
        self.ui.et_mask.setText(content[3])
        self.ui.et_gateway.setText(content[4])

        pass

    def start_listening(self):
        # 创建UDP socket
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
        # 允许端口复用
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # 绑定监听多播数据包的端口
        self.socket.bind((self.MULTICAST_ANY, self.MULTICAST_PORT))
        # 声明该socket为多播类型
        self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255)
        # 加入多播组,组地址由第三个参数制定
        self.socket.setsockopt(
            socket.IPPROTO_IP,
            socket.IP_ADD_MEMBERSHIP,
            socket.inet_aton(self.MULTICAST_IP) + socket.inet_aton(self.MULTICAST_ANY)
        )
        self.socket.setblocking(False)

        self.receive_thread = threading.Thread(target=self.receive_message_worker, args=())
        self.receive_thread.start()
        pass

    def receive_message_worker(self):
        print("start recive message thread ...")
        while True:
            try:
                data, address = self.socket.recvfrom(2048)
            except Exception as e:
                # print(e)
                pass
            else:
                data = data.decode()
                print(data)
                self.update_ui.emit(data)
        pass

    def scan_device(self):
        print("scan device start ...")
        self.list_content = []
        self.count_index = 0
        self.ui.device_list.clearContents()

        self.socket.sendto("list".encode(), (self.MULTICAST_IP, self.MULTICAST_PORT))
        pass

    def update_list_ui(self, content):
        if content.startswith("client"):
            print("client = ", content)
            self.ui.device_list.setRowCount(self.count_index + 1)
            contents = content.split("-")
            item1 = QTableWidgetItem(str(self.count_index + 1))
            self.ui.device_list.setItem(self.count_index, 0, item1)
            item2 = QTableWidgetItem(contents[1])
            self.ui.device_list.setItem(self.count_index, 1, item2)
            item3 = QTableWidgetItem(contents[2])
            self.ui.device_list.setItem(self.count_index, 2, item3)
            if len(contents) > 3:
                item4 = QTableWidgetItem(contents[3])
                self.ui.device_list.setItem(self.count_index, 3, item4)
                item5 = QTableWidgetItem(contents[4])
                self.ui.device_list.setItem(self.count_index, 4, item5)
            self.count_index += 1

            self.list_content.append([str(self.count_index + 1), contents[1], contents[2], contents[3], contents[4]])
        if content.startswith("cmdstr"):
            content = content.split("#")[1]
            self.ui.et_cmd_result.setText(content)
        pass

    def reset_ip_info(self):
        mac = self.ui.et_mac.text()
        ip = self.ui.et_ip.text()
        mask = self.ui.et_mask.text()
        gateway = self.ui.et_gateway.text()
        cmd = "modifyip-{}-{}-{}-{}".format(mac, ip, mask, gateway)
        print("reset ip param = " + cmd)
        self.socket.sendto(cmd.encode(), (self.MULTICAST_IP, self.MULTICAST_PORT))
        pass

    def reboot_device(self):
        mac = self.ui.et_mac.text()
        cmd = "reboot-{}".format(mac)
        print("reset ip param = " + cmd)
        self.socket.sendto(cmd.encode(), (self.MULTICAST_IP, self.MULTICAST_PORT))

    def exec_remote_cmd(self):
        mac = self.ui.et_mac.text()
        cmdstr = self.ui.et_remote_cmd.text()
        cmd = "exec#{}#{}#".format(mac, cmdstr)
        print("reset ip param = " + cmd)
        self.socket.sendto(cmd.encode(), (self.MULTICAST_IP, self.MULTICAST_PORT))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = QDeviceWidget()
    # w.setWindowState(Qt.WindowMaximized)
    w.show()
    sys.exit(app.exec_())

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值