Python - Kivy:如何在 Kivy 中打印应用程序本身的输出,而不是在控制台中打印?

问题描述 投票:0回答:1

因此,我尝试使用 python 创建一个相当简单且高效的 PORT SCANNER,其中有一个 GUI 作为我副学士学位的最终项目。 因为我的目标是成为一名道德黑客,所以我没有专注于从开发的角度学习编程,但我想在这种情况下我别无选择。

我看过有关如何使用 TkinterKivy 编写 python GUI 应用程序的教程,到目前为止我已经根据这些教程编写了代码

PS:这既不是干净的代码,也不是高效的代码,所以我希望专业人士能够接受初学者的代码。

这是我的.py文件

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.lang import Builder
from kivy.uix.textinput import TextInput
import socket
import threading
import time


Builder.load_file(r"DemoPortScanner.kv")

def port_scan(port):
    for port in range(port_start, port_end):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            conn = sock.connect_ex((target_ip, port))
            if conn == 0:
                def printer(self):
                    i = 0
                    while self.is_printing:
                        self.root_widget.ids.result.text += f'Port {port}' + 'is Open!' + '\n'
                        i += 1
                    time.sleep(1)

                def do_print(self):
                    if not self.is_printing:
                        self.is_printing = True
                        self.print_thread = threading.Thread(target=self.printer)
                        self.print_thread.start()
                    else:
                        self.is_printing = False
                        self.print_thread.join()
                        self.print_thread = None
            else:
                pass

        except:
            print("Connection couldn't be made")

class MyLayout(Widget):
    def start_scan(self):

        global target
        target = self.ids.target_url.text
        target = str(target)

        global target_ip
        target_ip = socket.gethostbyname(target)
        print(target_ip)

        global port_start
        port_start = self.ids.port_start.text
        port_start = int(port_start)
        print(port_start)
        
        global port_end
        port_end = self.ids.port_end.text
        port_end = int(port_end)
        print(port_end)
        self.ids.result.text = ""

        port_scan(self)

class DemoPortScannerApp(App):
    def build(self):
        return MyLayout()


if __name__ == '__main__':
    DemoPortScannerApp().run()

这是我的.kv 文件

<MyLayout>
    BoxLayout:
        orientation: 'vertical'
        size: root.width, root.height

        GridLayout:
            rows: 1

            TextInput:
                id: target_url
                text: "www.python.org"
                halign: "center"
                font_size: 28
                size_hint: (1, 1)
                multiline : False

            GridLayout:
                cols: 1
                rows: 2
                
                TextInput: 
                    id: port_start
                    text: '1'
                    halign: "left"
                    font_size: 28
                    size_hint: (1,1)
                    multiline: False
                
                TextInput:
                    id: port_end
                    text: "500"
                    halign: "left"
                    font_size: 28
                    size_hint: (1,1)
                    multiline: False
            
            GridLayout:
                cols: 1
                Button:
                    text: "Start Scan"
                    size_hint: (1,1)
                    font_size: 28
                    on_press: root.start_scan()

        GridLayout:
            cols: 1
            rows: 1

            TextInput:
                id: result
                text: "Open ports will be shown in here"
                halign: "center"
                font_size: 28
                size_hint: (1, 1)
                multiline : True

综上所述,我的程序并不完整,无论是从它的设计部分,还是从它的功能来看。

无论如何,我的主要问题和问题是:

如何在应用程序本身中显示输出(打开端口)?

因为我能够在控制台中打印它,但是当涉及到显示它的应用程序时, 通过文本输入或标签,我离它还很远。

PS:这是我在 stackoverflow 上的第一个问题,所以我希望你不要介意如果我写得不好,而且我的英语可能很糟糕,因为我不是母语人士

感谢您阅读本文,我希望您能指导我

python kivy
1个回答
0
投票
  1. 您必须在 .py 和 .kv 中声明您的类,否则您的代码将无法工作。例如在 .py

    class MyLayout(BoxLayout):
       pass
    

    .kv

    <MyLayout>:
        id: mylayout
        name: 'mylayout'
        etc....
    
  2. 你有

    port_scan
    作为全局方法,但是在
    MyApp.run()
    过程中你没有在任何地方调用它,所以它不会调用。

  3. 更改为:

    class port_scan(Widget):
        ....add code here
    

    然后将小部件添加到布局中,例如在

    .kv

    <MyLayout>:
        id: mylayout
        name: 'mylayout'
        MyWidget:
    
© www.soinside.com 2019 - 2024. All rights reserved.