【问题标题】:View the function of external py files in the textbox (while the function is running)在文本框中查看外部py文件的函数(函数运行时)
【发布时间】:2021-07-22 23:20:57
【问题描述】:

这是一个图形窗口,可以抓取并显示图标之间的任何错误。有两个从其他 py 文件中调用的抓取脚本(msg1 和 msg2),更准确地说,它们的抓取功能(Selenium)被调用。抓取正确完成,

我想在文本框中查看抓取,所以我想在文本框中查看 python 控制台中发生的情况。我想在文本框中显示的是 msg1 和 msg2 (这将是两个抓取 py 文件)。我补充说,我想在抓取期间(实时)显示抓取,而不是在函数结束时显示:在函数运行时

如何在文本框中查看 msg1 和 msg2?

from tkinter import *
from tkinter import ttk
import tkinter as tk

from File import Scraping_Nome_Campionati
from File import Scraping_Nome_Squadre_MIO

from File.Scraping_Nome_Campionati import scraping_nome_campionati_e_tor
from File.Scraping_Nome_Squadre_MIO import scraping_nome_squadre_e_tor


def draw_graph():
    test_scraping=tk.Toplevel()
    test_scraping.title("aaaa")
    test_scraping.geometry("1100x900")
    test_scraping.configure(bg='#282828')

    def do_scraping():
        #Start the scraping functions of the two py files and search for errors 
        #msg1 and msg2 recall the two scraping py files, because they check for scraping errors by showing the green icon and the red icon
        msg1 = Scraping_Nome_Campionati.scraping_nome_campionati_e_tor()
        if msg1:
            message1.configure(text=msg1)
            message1.configure(foreground="red")
            vuoto_elenco_campionati.config(image=render7)
    
        else:
            vuoto_elenco_campionati.config(image=render8)
            message1.configure(foreground="green")


        msg2 = Scraping_Nome_Squadre_MIO.scraping_nome_squadre_e_tor()
        if msg2:
            message2.configure(text=msg2)
            message2.configure(foreground="red")
            vuoto_elenco_squadre.config(image=render7)

        else:
            vuoto_elenco_squadre.config(image=render8)
            message2.configure(foreground="green")


    text = tk.Text(test_scraping,width=80,height=50,  background="black", foreground="white")
    text.pack()
    text.place(x=450, y=20)


    button = Button(test_scraping, text="Avvia", bg='#e95420', foreground='white', command=do_scraping)
    button.place(x=116, y=512)

【问题讨论】:

  • 放入一个线程并使用队列与主线程通信(也可以使用多处理)然后有一种更新功能(使用.after()方法)从队列中获取数据并插入它在小部件中
  • @matiiss 你能用代码告诉我答案吗?我不太明白。谢谢和抱歉。

标签: python python-3.x selenium-webdriver tkinter


【解决方案1】:

这是一个使用multiprocessing 模块的基本示例:

from tkinter import Tk, Text
from multiprocessing import Process, Queue
from queue import Empty
import time


def update_text(widget, queue):
    try:
        data = queue.get(block=False)
        if data == '--END--':
            return
    except Empty:
        pass
    else:
        widget.insert('end', data)
    root.after(100, update_text, widget, queue)


def do_in_parallel_1(queue):
    for i in range(10):
        queue.put(i)
        time.sleep(1)
    queue.put('--END--')


def do_in_parallel_2(queue):
    for i in range(10, 20):
        queue.put(i)
        time.sleep(1)
    queue.put('--END--')


if __name__ == '__main__':

    root = Tk()

    queue1 = Queue()
    text1 = Text()
    text1.pack()
    update_text(text1, queue1)
    Process(target=do_in_parallel_1, args=(queue1,)).start()

    queue2 = Queue()
    text2 = Text()
    text2.pack()
    update_text(text2, queue2)
    Process(target=do_in_parallel_2, args=(queue2,)).start()

    root.mainloop()

重要
将所有可执行代码放在if __name__ == '__main__': 块中,因为在创建新进程时,它基本上会创建一个副本并执行其中的所有内容,这可能会导致问题并且实际上会引发错误。


旁注:时间模块仅用于演示

更新功能:
在这种情况下,首先定义一个“更新”函数update_text() 函数。它所做的只是首先try: 从队列中获取数据(以及if data == '--END--': return,一旦进程完成(如果一切设置正确)基本上停止此功能)它有一个参数block 设置为False 这基本上意味着如果 Queue 中没有任何内容然后继续但是这会引发 Empty 异常,该异常由 except Empty: 处理并且它基本上什么都不做,所以如果有异常它只使用 @ 987654335@ 在 100 毫秒内再次调用此函数(循环)(这样的“循环”不会阻塞 .mainloop()),但是如果没有异常,则还要更新传递的小部件(在这种情况下应该是 tkinter.Text小部件)

现在是另外两个函数:
好吧,它们非常简单,而且基本相同(只是将不同的数字放入队列中),但基本上您必须了解的是,当函数运行时,您应该将要出现的数据放在 Text 小部件中的 @ 987654339@ 使用.put() 方法,但是当函数完成时,在此之前你应该.put()“标志”,它将告诉“更新”函数进程已经完成并且它们都将停止(不浪费资源)

真正开始的部分:
这发生在if __name__ == '__main__': 内部(显然,您可以在外部定义其他函数,只是不要在外部调用它们(除非在另一个函数中),因为从外部调用的任何东西也会被所有进程执行)
所以现在有两个相同的进程(可以使用循环,但只有两个,所以真的不需要),首先启动一个Queue 类:queue1 = Queue() 然后创建一个文本小部件,然后打包它,然后启动 update_text() 函数(也传递参数),然后启动进程Process(target=do_in_parallel_1, args=(queue1,)).start()(起初我想知道为什么它不起作用,最后注意到我没有start()ed 进程)然后对另一个函数重复该过程.

杂项
基本上对你来说,而不是do_in_parallel_n() 函数,你将拥有你的抓取功能,但原理是一样的,只要记住把queue.put() 放在那里和你想要传递的对象里面(被抓取的东西或某事)

有用的来源:

如果您有任何问题,请随时提问!

【讨论】:

  • 感谢您的友好回复,但我不太明白如何将它与我的问题代码一起使用。我是 Python 新手,从未使用过多处理模块,所以我会有点困惑。抱歉,如果我打扰您,但您能否在回复中告诉我(也许通过创建您的答案的上传 2)如何将我的代码应用于它?谢谢
  • @JamesD.Com 看到有两个函数:do_in_parallel_1do_in_parallel_2 所以你要做的就是用你的函数替换它们,很简单(显然然后在任何地方更改名称),以及任何地方您期望从抓取中获得某物,放置一个队列并将预期的字符串或其他任何内容放入该队列(不要忘记添加队列参数)
  • @JamesD.Com 好的,输入你的问题(编辑并放在底部某处)一个独立的抓取功能,然后我可以为你调整它,也仔细阅读我写的内容和类型问题是,如果您不理解,那么在这种情况下,至少意味着您应该首先理解它,好吧,我在答案中放了一些资料,以便您可以使用这些资料来帮助自己理解部分代码
  • 谢谢。我明天试试,我会告诉你的。现在已经晚了。再次感谢
  • 感谢您的友好回复,但我无法将其应用于我在问题中发布的代码,因为我的代码有点特殊:我有一个函数 (do_scraping) 调用另外两个函数(外部 py 文件)。你一直很善良,但我不能。您能否上传 2 个答案并将我的代码与您的代码合并?我会非常感激。谢谢你,对不起。我会投票并接受你的回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-08
  • 1970-01-01
  • 2017-01-20
  • 2023-04-06
  • 1970-01-01
相关资源
最近更新 更多