单击按钮后程序停止响应

2024-02-28

我正在尝试制作我的第一个程序,一个端口扫描器,显示远程服务器上的所有开放端口,我已经让它在 CLI 中工作(感谢互联网),但决定制作一个 GUI (Qt5)它。我希望textbox2在输入IP地址并单击“扫描!”后输出所有打开的端口,并且显然程序在单击它后不会崩溃。这是复制问题的相关代码

from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QPushButton, QAction, QLineEdit, QMessageBox, QPlainTextEdit, QVBoxLayout, QLabel
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot, Qt
import socket
import time
import sys

class App(QMainWindow):

    def __init__(self):
        super().__init__()
        self.title = 'PPort'
        self.left = 10
        self.top = 10
        self.width = 800
        self.height = 400
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.label = QLabel('Enter Target Address:', self)
        self.label.move(50, -110)
        self.label.resize(300, 300)

        self.label2 = QLabel('Output:', self)
        self.label2.move(50, 80)
        self.label2.resize(300, 300)

        self.textbox = QLineEdit(self)
        self.textbox.move(50, 60)
        self.textbox.resize(540, 30)

        self.textbox2 = QPlainTextEdit(self)
        self.textbox2.move(50, 250)
        self.textbox2.resize(700, 100)
        self.textbox2.setReadOnly(True)

        self.button = QPushButton('Scan!', self)
        self.button.move(620, 60)
        self.button.clicked.connect(self.on_click)
        self.show()

    @pyqtSlot()

    def on_click(self):
        textboxValue = self.textbox.text()
        socket.gethostbyname(textboxValue)
        try:
            for port in range(1, 1025):
                socketprofile = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                result = socketprofile.connect_ex((textboxValue, port))
                if result == 0:
                    self.textbox2.appendPlainText('Port {} Is open'.format(port))
                socketprofile.close()
        except socket.gaierror:
            self.textbox2.appendPlainText('Hostname could not be resolved')
            time.sleep(5)
            sys.exit()
        except socket.error:
            self.textbox2.appendPlainText("Couldn't connect to server")
            time.sleep(5)
            sys.exit()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

textbox2 中没有显示错误,令我奇怪的是,即使我替换self.textbox2.appendPlainText使用 print() ,它仍然不会在 vscode 终端中输出任何错误消息。但是,输入无效的 IP 地址会显示 gaierror(无法解析主机),并且不是在 textbox2 中,而是在终端中,相比之下,如果输入有效的 IP 地址(8.8.8.8、192.168.0.1),它总是崩溃。我怀疑我错误地使用了 if/for/try 使其循环,但我真的看不出我做错了什么,因为我几乎不知道作为新手我在做什么。


for 循环或睡眠等耗时任务会阻塞 GUI 事件循环,导致窗口冻结。在这些情况下,解决方案是在另一个线程中执行该任务并通过信号在线程之间发送信息

import sys
import time
import socket
from functools import partial

from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QThread, QTimer
from PyQt5.QtWidgets import (
    QApplication,
    QGridLayout,
    QLabel,
    QLineEdit,
    QMainWindow,
    QPlainTextEdit,
    QPushButton,
    QWidget,
)


class SocketWorker(QObject):
    messageChanged = pyqtSignal(str)

    @pyqtSlot(str)
    def start_task(self, ip):
        socket.gethostbyname(ip)
        try:
            for port in range(0, 65536):
                socketprofile = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                result = socketprofile.connect_ex((ip, port))
                if result == 0:
                    self.messageChanged.emit("Port {} Is open".format(port))
                socketprofile.close()
        except socket.gaierror:
            self.messageChanged.emit("Hostname could not be resolved")
            time.sleep(5)
            sys.exit()
        except socket.error:
            self.messageChanged.emit("Couldn't connect to server")
            time.sleep(5)
            sys.exit()


class App(QMainWindow):
    def __init__(self):
        super().__init__()
        self.title = "PPort"
        self.left = 10
        self.top = 10
        self.width = 800
        self.height = 400
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.textbox = QLineEdit()
        self.button = QPushButton("Scan!")
        self.textbox2 = QPlainTextEdit(readOnly=True)

        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        grid_layout = QGridLayout(central_widget)
        grid_layout.addWidget(QLabel("Enter Target Address:"), 0, 0)
        grid_layout.addWidget(self.textbox, 1, 0)
        grid_layout.addWidget(self.button, 1, 1)
        grid_layout.addWidget(QLabel("Output:"), 2, 0)
        grid_layout.addWidget(self.textbox2, 3, 0, 1, 2)

        self.button.clicked.connect(self.on_click)

        thread = QThread(self)
        thread.start()
        self.socker_worker = SocketWorker()
        self.socker_worker.moveToThread(thread)
        self.socker_worker.messageChanged.connect(self.textbox2.appendPlainText)

    @pyqtSlot()
    def on_click(self):
        textboxValue = self.textbox.text()
        wrapper = partial(self.socker_worker.start_task, textboxValue)
        QTimer.singleShot(0, wrapper)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    ex = App()
    ex.show()
    sys.exit(app.exec_())
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单击按钮后程序停止响应 的相关文章

随机推荐

  • 节点 8.6 javascript 承诺:UnhandledPromiseRejectionWarning

    我有一个错误 节点 6186 UnhandledPromiseRejectionWarning 未处理的承诺拒绝 拒绝 ID 1 三p 节点 6186 DEP0018 DeprecationWarning 未处理的承诺拒绝已被弃用 将来 未
  • 当某些内容存储为数组时,Rails where 子句

    我正在运行 Rails 4 2 带有 PG 数据库 我有一个项目存储在数据库中 例如 模型Item something gt 1 2 3 我想得到Item where something include gt 3 显然这是行不通的 但是你打
  • 创建表语法在 hsql 中不起作用

    我是 hsqldb 新手 我正在开发简单的应用程序来获取用户的一些输入 因此搜索嵌入式数据库并发现 hsqldb 是满足我的要求的解决方案 我有一些创建表语法 但它抛出异常 此查询使用 Netbeans 数据库服务执行 Query CREA
  • iOS - Facebook 登录错误 - 构建 URL 时出现未知错误(com.facebook.sdk.core 错误 3)

    我正在使用 Facebook 登录我的 iOS 应用程序 该应用程序是为 iOS 8 及更高版本开发的 正在使用最新的Facebook SDK 我已遵循 Facebook 官方指南中描述的所有基本步骤 但是 当我单击登录按钮时 出现以下错误
  • 如何组织大型 Node.js 项目

    组织大型 Node js 项目有哪些好方法 例如 一个同时使用express js 和socket io 的应用程序 这将包括应用程序逻辑结构和文件系统 目前 我发现自己将大量代码放入一个主 js 文件中 并将代码放入一个巨大的全局对象中
  • Rails 3.1 强制使用 .html 而不是无扩展名

    我的一位客户希望他的新 Rails 应用程序看起来更像他的传统网站 他想知道我是否可以强制 url 具有文件扩展名 最好是 html 我不想对扩展进行硬编码routes rb as match controller action id ht
  • 难以通过网络蓝牙连接热敏打印机

    现在我正在开发能够连接热敏打印机的网络 我正在使用 Angular 框架 并且我使用库成功将热敏打印机与 USB 连接ng thermal printer 但我希望我的网络也能够通过网络蓝牙 BLE 蓝牙低功耗 连接热敏打印机 据我所知 B
  • 转换为乔姆斯基范式

    我确实需要你的帮助 我有这些作品 1 A gt aAb 2 A gt bAa 3 A gt 我应该应用乔姆斯基范式 CNF 为了应用上述规则 我应该 消除 产生式 消除单一生产 删除无用的符号 我立即陷入困境 原因是 A 是一个可为空的符号
  • 它仍然适用于在 RedHat7 上使用 pexpect 还是有替代方法来执行命令并响应提示?

    我尝试在 Redhat7 中使用 pexpect for ansible 但无法安装它 我只得到 pexpect noarch 2 3 11 el7 RHEL7 版本 或者 pexpect 是否有替代方法来执行命令并响应提示 看起来像的版本
  • 给定python代码的打印语句语法错误的原因是什么[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 编辑问题以包括期望的行为 特定问题或错误以及重现问题所需的最短代码 help minimal reproducible example 这
  • 将 Meteor 部署到 Android 设备时找不到构建工具修订版 24.0.1

    我错误地完全删除了 Android SDK 文件夹 之前我已经使用cordova phonegap多次将meteor部署到android设备上 当通过 Android Studio 重新安装 SDK 并尝试在设备中运行 Meteor 时 我
  • SQLAlchemy over MySQLdb 的目的

    为什么人们使用 SQLAlchemy 而不是 MySQLdb 它有什么优点 您不使用 SQLAlchemy 来代替 MySQLdb 您使用 SQLAlchemy 来访问 MySQLdb oursql 我听说更好并且性能更好的另一个 MySQ
  • Xcode 未反映来自 React-Native 的最新应用程序代码

    EDIT 好吧 事实证明这不是 AppStore 的问题 我从 Xcode 发布模式运行了应用程序 并且在模拟器上运行了相同的旧版本 我不知道为什么 但 Xcode 没有运行最新的 jsbundle 现在我发现this https stac
  • 在 Dart 中获取与正则表达式匹配的所有子字符串的最佳方法

    我想获取与字符串中的正则表达式匹配的子字符串列表 做这个的最好方式是什么 dart core 中的 RegExp 对象有Iterable
  • 用java下载包含资源(如图像)的完整网页

    有没有办法下载 html 网页及其所有资源 例如 图像 CSS 我知道如何使用 html 解析器通过遍历所有相关标签来做到这一点 但是没有easy way That is最简单的方法 困难的方法是编写自己的网络库 html 解析器等
  • SwiftUI 中 ObservedObject 和 StateObject 有什么区别

    如果我有一个ObservableObject在 SwiftUI 中我可以将其称为 ObservedObject class ViewModel ObservableObject Published var someText Hello Wo
  • 如何轻松分析 Oracle 包的执行是否存在性能问题?

    我在 11g R2 DB 中有一个 pl sql 包 它有相当多的相关过程和函数 我执行一个顶级函数 它做了很多事情 当前每秒处理 对于 Oracle 的 PL SQL 分层分析器 DBMS HPROF 来说 这似乎是一项不错的工作 作为一
  • 优化 iPhone OpenGL ES 填充率

    我的 iPhone 上有一个 Open GL ES 游戏 我的帧率很糟糕 20fps 在 iPhone 3G 上使用 Xcode OpenGL ES 性能工具 它显示 渲染器利用率 95 至 99 瓷砖利用率 27 我正在绘制很多非常大的图
  • 随机迭代所有排列

    我导入了一个大数组 我想随机迭代所有行排列 该代码被设计为在某个数组产生所需的解决方案时中断 到目前为止的尝试涉及正常的迭代扰动过程 import numpy as np import itertools file np loadtxt m
  • 单击按钮后程序停止响应

    我正在尝试制作我的第一个程序 一个端口扫描器 显示远程服务器上的所有开放端口 我已经让它在 CLI 中工作 感谢互联网 但决定制作一个 GUI Qt5 它 我希望textbox2在输入IP地址并单击 扫描 后输出所有打开的端口 并且显然程序