eclipse python pyqt5 编写主机存活探测工具

2 篇文章 0 订阅
2 篇文章 0 订阅

  配置我就不说了,在我上一个博客里面说过的,直接上代码

 Ui_host_alive_MainWindow

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

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QMessageBox, QApplication
from PyQt5.QtCore import QBasicTimer
import sys, easygui, os
import pinger
from queue import Queue

class Ui_host_alive_MainWindow(QtWidgets.QWidget):
        
    def setupUi(self, host_alive_MainWindow):
        self.address = []
        self.address_res = []
        self.address_fail = []
        self.que = Queue()
        self.total_num = 1
        self.count_num = 0
        self.success_num = 0
        self.fail_num = 0
        
        # 主窗口设置
        host_alive_MainWindow.setObjectName("host_alive_MainWindow")
        host_alive_MainWindow.resize(800, 555)
        host_alive_MainWindow.setFixedSize(MainWindow.width(), MainWindow.height())
        
        # 字体设置
        font = QtGui.QFont()
        font.setPointSize(10)
        host_alive_MainWindow.setFont(font)
        
        # 设置ping标签
        self.centralwidget = QtWidgets.QWidget(host_alive_MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.ping_label = QtWidgets.QLabel(self.centralwidget)
        self.ping_label.setGeometry(QtCore.QRect(10, 9, 51, 31))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.ping_label.setFont(font)
        self.ping_label.setObjectName("ping_label")
        
        # 设置ping栏    
        self.ping_lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.ping_lineEdit.setGeometry(QtCore.QRect(60, 10, 151, 31))
        self.ping_lineEdit.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu)
        self.ping_lineEdit.setObjectName("ping_lineEdit")
        
        # 设置加载按钮
        self.load_Button = QtWidgets.QPushButton(self.centralwidget)
        self.load_Button.setGeometry(QtCore.QRect(220, 10, 51, 28))
        self.load_Button.setObjectName("load_Button")
        self.load_Button.clicked.connect(self.on_click_load)
        
        # 设置加载文件按钮
        self.loadfile_Button = QtWidgets.QPushButton(self.centralwidget)
        self.loadfile_Button.setGeometry(QtCore.QRect(280, 10, 91, 28))
        self.loadfile_Button.setObjectName("loadfile_Button")
        self.loadfile_Button.clicked.connect(self.on_click_load_file)
        
        # 设置清除按钮
        self.clear_Button = QtWidgets.QPushButton(self.centralwidget)
        self.clear_Button.setGeometry(QtCore.QRect(380, 10, 51, 28))
        self.clear_Button.setObjectName("clear_Button")
        self.clear_Button.clicked.connect(self.on_click_clear)
        
        # 设置多线程标签
        self.thread_label = QtWidgets.QLabel(self.centralwidget)
        self.thread_label.setGeometry(QtCore.QRect(440, 9, 81, 31))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.thread_label.setFont(font)
        self.thread_label.setObjectName("thread_label")
        
        # 设置多线程数目
        self.thread_spinBox = QtWidgets.QSpinBox(self.centralwidget)
        self.thread_spinBox.setGeometry(QtCore.QRect(510, 10, 46, 28))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.thread_spinBox.setFont(font)
        self.thread_spinBox.setMaximum(500)
        self.thread_spinBox.setProperty("value", 10)
        self.thread_spinBox.setObjectName("thread_spinBox")
        
        # 设置开始按钮
        self.action_Button = QtWidgets.QPushButton(self.centralwidget)
        self.action_Button.setGeometry(QtCore.QRect(570, 10, 93, 28))
        self.action_Button.setObjectName("action_Button")
        self.action_Button.clicked.connect(self.on_click_action)
        
        # 设置输出按钮
        self.output_value_Button = QtWidgets.QPushButton(self.centralwidget)
        self.output_value_Button.setGeometry(QtCore.QRect(680, 10, 93, 28))
        self.output_value_Button.setObjectName("output_value_Button")
        self.output_value_Button.clicked.connect(self.on_click_output_value)
        
        # 设置输入ip地址标签
        self.input_ip_label = QtWidgets.QLabel(self.centralwidget)
        self.input_ip_label.setGeometry(QtCore.QRect(10, 210, 71, 31))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.input_ip_label.setFont(font)
        self.input_ip_label.setFocusPolicy(QtCore.Qt.NoFocus)
        self.input_ip_label.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.input_ip_label.setTextFormat(QtCore.Qt.AutoText)
        self.input_ip_label.setObjectName("input_ip_label")
        
        # 设置输入ip栏
        self.input_ip_textEdit = QtWidgets.QTextEdit(self.centralwidget)
        self.input_ip_textEdit.setGeometry(QtCore.QRect(80, 60, 181, 341))
        self.input_ip_textEdit.setLineWrapColumnOrWidth(0)
        self.input_ip_textEdit.setReadOnly(True)
        self.input_ip_textEdit.setObjectName("input_ip_textEdit")
        
        # 设置输出ip地址标签
        self.output_ip_label = QtWidgets.QLabel(self.centralwidget)
        self.output_ip_label.setGeometry(QtCore.QRect(270, 210, 71, 31))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.output_ip_label.setFont(font)
        self.output_ip_label.setFocusPolicy(QtCore.Qt.NoFocus)
        self.output_ip_label.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.output_ip_label.setTextFormat(QtCore.Qt.AutoText)
        self.output_ip_label.setObjectName("output_ip_label")
        
        # 设置输出ip栏
        self.output_ip_textEdit = QtWidgets.QTextEdit(self.centralwidget)
        self.output_ip_textEdit.setGeometry(QtCore.QRect(340, 60, 181, 341))
        self.output_ip_textEdit.setReadOnly(True)
        self.output_ip_textEdit.setObjectName("output_ip_textEdit")
        
        # 设置进度
        self.progressBar = QtWidgets.QProgressBar(self.centralwidget)
        self.progressBar.setGeometry(QtCore.QRect(60, 470, 731, 23))
        self.progressBar.setMinimum(0)
        self.progressBar.setMaximum(100)
        self.progressBar.setProperty("value", 0)
        self.progressBar.setObjectName("progressBar")
        self.timer = QBasicTimer()
        self.timer.start(0, self)
        
        # 设置进程标签
        self.progress_label = QtWidgets.QLabel(self.centralwidget)
        self.progress_label.setGeometry(QtCore.QRect(10, 465, 51, 31))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.progress_label.setFont(font)
        self.progress_label.setObjectName("progress_label")
        
        # 设置失败ip标签
        self.fail_ip_label = QtWidgets.QLabel(self.centralwidget)
        self.fail_ip_label.setGeometry(QtCore.QRect(530, 210, 71, 31))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.fail_ip_label.setFont(font)
        self.fail_ip_label.setFocusPolicy(QtCore.Qt.NoFocus)
        self.fail_ip_label.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.fail_ip_label.setTextFormat(QtCore.Qt.AutoText)
        self.fail_ip_label.setObjectName("fail_ip_label")
        
        # 设置失败ip栏
        self.fail_ip_textEdit = QtWidgets.QTextEdit(self.centralwidget)
        self.fail_ip_textEdit.setGeometry(QtCore.QRect(600, 60, 181, 341))
        self.fail_ip_textEdit.setReadOnly(True)
        self.fail_ip_textEdit.setObjectName("fail_ip_textEdit")
        
        # 设置输入数的标签
        self.input_num_label = QtWidgets.QLabel(self.centralwidget)
        self.input_num_label.setGeometry(QtCore.QRect(180, 410, 41, 16))
        self.input_num_label.setObjectName("input_num_label")
        
        # 设置输入地址数的标签
        self.input_ip_num_label = QtWidgets.QLabel(self.centralwidget)
        self.input_ip_num_label.setGeometry(QtCore.QRect(230, 410, 31, 16))
        self.input_ip_num_label.setObjectName("input_ip_num_label")
        
        # 设置输出数的标签
        self.output_ip_num_label = QtWidgets.QLabel(self.centralwidget)
        self.output_ip_num_label.setGeometry(QtCore.QRect(490, 410, 31, 16))
        self.output_ip_num_label.setObjectName("output_ip_num_label")
        
        # 设置输出地址数的标签
        self.output_num_label = QtWidgets.QLabel(self.centralwidget)
        self.output_num_label.setGeometry(QtCore.QRect(440, 410, 41, 16))
        self.output_num_label.setObjectName("output_num_label")
        
        # 设置失败数的标签
        self.fail_ip_num_label = QtWidgets.QLabel(self.centralwidget)
        self.fail_ip_num_label.setGeometry(QtCore.QRect(750, 410, 31, 16))
        self.fail_ip_num_label.setObjectName("fail_ip_num_label")
        
        # 设置失败地址数的标签
        self.fail_num_label = QtWidgets.QLabel(self.centralwidget)
        self.fail_num_label.setGeometry(QtCore.QRect(700, 410, 41, 16))
        self.fail_num_label.setObjectName("fail_num_label")
        
        host_alive_MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(host_alive_MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 26))
        self.menubar.setObjectName("menubar")
        host_alive_MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(host_alive_MainWindow)
        self.statusbar.setObjectName("statusbar")
        host_alive_MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(host_alive_MainWindow)
        QtCore.QMetaObject.connectSlotsByName(host_alive_MainWindow)
    
    # 加载按钮函数
    def on_click_load(self, event):
        temp_address = self.ping_lineEdit.text()
        self.address_res = []
        self.address_fail = []
        if temp_address not in self.address:
            if self.input_ip_textEdit.toPlainText() == None:
                self.input_ip_textEdit.setText(temp_address)
            else:
                self.input_ip_textEdit.append(temp_address)
            self.address.append(temp_address)
        else:
            QMessageBox.information(self, '信息', '已自动去重!', QMessageBox.Ok, QMessageBox.Ok)
        self.ping_lineEdit.clear()
        self.flush_data()
    
    # 加载文件按钮函数
    def on_click_load_file(self, event):
        file_path = easygui.fileopenbox(default='*.txt')
        tab_num = 0
        temp_lists = []
        temp_address = ''
        try:
            with open(file_path) as old_file:
                os.path.basename(file_path)
                temp_address = old_file.read()
        except:
            pass
        if "\r" in temp_address:
            temp_lists = (temp_address.split("\r"))
        elif "\n" in temp_address:
            temp_lists = (temp_address.split("\n"))
        elif temp_address == None:
            return
        else:
            pass  
        for addre in temp_lists:
            if addre not in self.address:
                if self.input_ip_textEdit.toPlainText() == None:
                    self.input_ip_textEdit.setText(addre)
                else:
                    self.input_ip_textEdit.append(addre)
                self.address.append(addre)
            else:
                tab_num = tab_num + 1
        if tab_num != 0:
            QMessageBox.information(self, '信息', '已自动去重!', QMessageBox.Ok, QMessageBox.Ok)
        self.flush_data()
            
    # 清除按钮函数
    def on_click_clear(self):
        self.input_ip_textEdit.clear()
        self.address = []
        self.address_res = []
        self.address_fail = []
        
    # 进度条   
    def timerEvent(self, event):
        step = self.count_num / self.total_num * 100
        self.progressBar.setValue(step)
        if step == 100:
            self.timer.stop()
        
    # 开始探测按钮函数 
    def on_click_action(self, event):
        self.output_ip_textEdit.clear()
        self.fail_ip_textEdit.clear()
        thread_num = self.thread_spinBox.text()
        for address in self.address:
            self.count_num = self.count_num + 1
            pinger_value = pinger.Pinger()
            flag = pinger_value.verbose_ping(dest_addr=address)
            if flag == True:
                self.success_num = self.success_num + 1
                if self.output_ip_textEdit.toPlainText() == None:
                    self.output_ip_textEdit.setText(address)
                else:
                    self.output_ip_textEdit.append(address)                        
                self.address_res.append(address)
                self.output_ip_textEdit.update()
            else:
                self.fail_num = self.fail_num + 1
                if self.fail_ip_textEdit.toPlainText() == None:
                    self.fail_ip_textEdit.setText(address)
                else:
                    self.fail_ip_textEdit.append(address)
                self.address_fail.append(address)
                self.fail_ip_textEdit.update()
            QApplication.processEvents()  # 逐步打印
            self.flush_data()
    
    # 输出成文件函数
    def on_click_output_value(self, event):
        file = open('address.txt', mode='a')
        for address_value in self.address_res:
            file.write(address_value + "\n")
        file.close()
        QMessageBox.information(self, '信息', '已在当前文件夹生成address.txt文件!', QMessageBox.Ok, QMessageBox.Ok)
        
    def flush_data(self):
        self.total_num = len(self.address)
        self.input_ip_num_label.setText(str(self.total_num))
        self.input_ip_num_label.update()
        
        self.output_ip_num_label.setText(str(len(self.address_res)))
        self.output_ip_num_label.update()
        
        self.fail_ip_num_label.setText(str(len(self.address_fail)))
        self.fail_ip_num_label.update()
    
    # 自动生成----控件的初始化值
    def retranslateUi(self, host_alive_MainWindow):
        _translate = QtCore.QCoreApplication.translate
        host_alive_MainWindow.setWindowTitle(_translate("host_alive_MainWindow", "主机存活探测工具  --by zichen"))
        self.ping_label.setText(_translate("host_alive_MainWindow", "Ping:"))
        self.load_Button.setText(_translate("host_alive_MainWindow", "加载"))
        self.loadfile_Button.setText(_translate("host_alive_MainWindow", "导入文件"))
        self.clear_Button.setText(_translate("host_alive_MainWindow", "清除"))
        self.thread_label.setText(_translate("host_alive_MainWindow", "线程数:"))
        self.action_Button.setText(_translate("host_alive_MainWindow", "开始探测"))
        self.output_value_Button.setText(_translate("host_alive_MainWindow", "导出结果"))
        self.input_ip_label.setText(_translate("host_alive_MainWindow", "输入栏"))
        self.output_ip_label.setText(_translate("host_alive_MainWindow", "输出栏"))
        self.progress_label.setText(_translate("host_alive_MainWindow", "进度:"))
        self.fail_ip_label.setText(_translate("host_alive_MainWindow", "失败栏"))
        self.input_num_label.setText(_translate("host_alive_MainWindow", "数目:"))
        self.input_ip_num_label.setText(_translate("host_alive_MainWindow", "0"))
        self.output_ip_num_label.setText(_translate("host_alive_MainWindow", "0"))
        self.output_num_label.setText(_translate("host_alive_MainWindow", "数目:"))
        self.fail_ip_num_label.setText(_translate("host_alive_MainWindow", "0"))
        self.fail_num_label.setText(_translate("host_alive_MainWindow", "数目:"))


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_host_alive_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

外部引用的pinger类

# !coding=utf-8
# by kyan001
import sys
import socket
import struct
import select
import time
import threading

__version__ = "1.4.1"

if sys.platform == "win32":
    # On Windows, the best timer is time.clock()
    default_timer = time.perf_counter
else:
    # On most other platforms the best timer is time.time()
    default_timer = time.time

# From /usr/include/linux/icmp.h; your milage may vary.
ICMP_ECHO_REQUEST = 8  # Seems to be the same on Solaris.


class Pinger(object):

    def checksum(self, source_string):
        """
        I'm not too confident that this is right but testing seems
        to suggest that it gives the same answers as in_cksum in ping.c
        """
        sum = 0
        countTo = len(source_string)
        count = 0
        while count < countTo:
            thisVal = source_string[count + 1] * 256 + source_string[count]
            sum = sum + thisVal
            count = count + 2
    
        if countTo < len(source_string):
            sum = sum + ord(source_string[len(source_string) - 1])
    
        sum = (sum >> 16) + (sum & 0xffff)
        sum = sum + (sum >> 16)
        answer = ~sum
        answer = answer & 0xffff
    
        # Swap bytes. Bugger me if I know why.
        answer = answer >> 8 | (answer << 8 & 0xff00)
    
        return answer
    
    def receive_one_ping(self, my_socket, ID, timeout):
        """
        receive the ping from the socket.
        """
        timeLeft = timeout
        while True:
            startedSelect = default_timer()
            whatReady = select.select([my_socket], [], [], timeLeft)
            howLongInSelect = (default_timer() - startedSelect)
            if whatReady[0] == []:  # Timeout
                return
    
            timeReceived = default_timer()
            recPacket, addr = my_socket.recvfrom(1024)
            icmpHeader = recPacket[20:28]
            type, code, checksum, packetID, sequence = struct.unpack(
                "bbHHh", icmpHeader
            )
            # Filters out the echo request itself.
            # This can be tested by pinging 127.0.0.1
            # You'll see your own request
            if type != 8 and packetID == ID:
                bytesInDouble = struct.calcsize("d")
                timeSent = struct.unpack("d", recPacket[28:28 + bytesInDouble])[0]
                return timeReceived - timeSent
    
            timeLeft = timeLeft - howLongInSelect
            if timeLeft <= 0:
                return
    
    def send_one_ping(self, my_socket, dest_addr, ID):
        """
        Send one ping to the given >dest_addr<.
        """
        dest_addr = socket.gethostbyname(dest_addr)
    
        # Header is type (8), code (8), checksum (16), id (16), sequence (16)
        my_checksum = 0
    
        # Make a dummy header with a 0 checksum.
        # ID: Low-endian identifier, bbHHh: network byte order
        header = struct.pack("bbHHh", ICMP_ECHO_REQUEST, 0, my_checksum, ID, 1)
        bytesInDouble = struct.calcsize("d")
        data = (192 - bytesInDouble) * "Q"
        data = struct.pack("d", default_timer()) + data.encode()
    
        # Calculate the checksum on the data and the dummy header.
        my_checksum = self.checksum(header + data)
    
        # Now that we have the right checksum, we put that in. It's just easier
        # to make up a new header than to stuff it into the dummy.
        header = struct.pack("bbHHh", ICMP_ECHO_REQUEST, 0, socket.htons(my_checksum), ID, 1)
        packet = header + data
        my_socket.sendto(packet, (dest_addr, 1))  # Don't know about the 1
    
    def ping(self, dest_addr, timeout=0.5, unit="s", src_addr=None, ttl=64):
        """
        Send one ping to destination address with the given timeout.
        Args:
            dest_addr: Str. The destination address. Ex. "192.168.1.1"/"example.com"
            timeout: Int. Timeout in seconds. Default is 4s, same as Windows CMD.
            unit: Str. The unit of returned value. Default is "s" for seconds, "ms" for milliseconds.
            src_addr: Str. The IP address to ping from. Ex. "192.168.1.20"
            ttl: Int. The Time-To-Live of the outgoing packet. Default is 64, same as in Linux and macOS.
        Returns:
            The delay in seconds/milliseconds or None on timeout.
        """
        my_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
        my_socket.setsockopt(socket.SOL_IP, socket.IP_TTL, ttl)
        if src_addr:
            my_socket.bind((src_addr, 0))
        my_ID = threading.current_thread().ident & 0xFFFF
        self.send_one_ping(my_socket, dest_addr, my_ID)
        delay = self.receive_one_ping(my_socket, my_ID, timeout)  # in seconds
        my_socket.close()
        if delay is None:
            return None
        if unit == "ms":
            delay *= 1000  # in milliseconds
        return delay
    
    def verbose_ping(self, dest_addr, count=1, *args, **kwargs):
        """
        Send pings to destination address with the given timeout and display the result.
        Args:
            dest_addr: Str. The destination address. Ex. "192.168.1.1"/"example.com"
            count: Int. How many pings should be sent. Default is 4, same as Windows CMD.
            *: And all the other arguments available in ping().
        Returns:
            Formatted ping results printed.
        """
        timeout = kwargs.get("timeout")
        src_addr = kwargs.get("src_addr")
        unit = kwargs.setdefault("unit", "ms")
        for i in range(count):
            output_text = "ping '{}'".format(dest_addr)
            output_text += " from '{}'".format(src_addr) if src_addr else ""
            output_text += " ... "
            print(output_text, end="")
            try:
                delay = self.ping(dest_addr, *args, **kwargs)
            except socket.gaierror as e:
                # print("Failed. (socket error: '{}')".format(e))
                return False
                break
            if delay is None:
                # print("Timeout > {}s".format(timeout) if timeout else "Timeout")
                return False
            else:
                # print("{value}{unit}".format(value=int(delay), unit=unit))
                return True
            print()
该类是来源于github上的kyan001编写的,这里日常感谢一下,之前的stock编程我就没用了,我用了python自带的python2转python3工具转换后,有问题,我就干脆在github另找一个,修改了一下,原来的代码如下:https://github.com/kyan001/ping3

多线程问题

这里并没有使用多线程,因为qt对threading不支持,它有自带的多线程Qthread,这个坑,困扰我一天(因为这个没报错,主窗口动不动就退出,debug也没用看出什么问题).我就不打算用多线程了,等以后再把坑填上

福利

知乎学习pyqt5:https://zhuanlan.zhihu.com/xdbcb8?utm_source=wechat_session&utm_medium=social&from=singlemessage

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值