0

我想不通,如何使它工作。我希望你能帮助我。

我编辑了代码,使其更简单和简短——这就是为什么它只打印一些东西,但这足以显示问题。

一切运行良好,只要我按回车按钮停止功能并单击按钮(在 Tkinter 窗口中)重新启动main_function()

当我退出程序并再次运行该功能时 - 一切都很好。仅当我停止该功能并第二次运行它时才会出现此问题。

我希望我清楚地描述了问题,并且代码中的注释有帮助。

我收到的错误:

Exception in thread Thread-5:
Traceback (most recent call last):
  File "path\threading.py", line 932, in _bootstrap_inner
   self.run()
  File "path\threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "path/program.py", line 323, in fun_1
    temp_img = sct.grab(region)
  File "path\mss\windows.py", line 291, in grab
    raise ScreenShotError("gdi32.GetDIBits() failed.")

mss.exception.ScreenShotError: gdi32.GetDIBits() failed.

代码:

import threading
import keyboard
import time
import mss
import mss.tools

bot_stop = False


def main_function():   # I run this function by pressing button in tkinter window
    global bot_stop
    bot_stop = False

    # threading
    thread_1 = threading.Thread(target=fun_1)

    # start the thread if checkbox in tkinter window is ticked
    if checkbox_1.get():
        thread_1.start()

    # press enter to stop the main_function and fun_1, 'bot_stop_switch' is a callback
    keyboard.on_press_key('enter', bot_stop_switch)

    # run this loop as long as user will press "enter"
    while not bot_stop:
        print("main_function_is_running")
        time.sleep(1)


def fun_1():

    # make a screenshoot of selected region (this case: upper left main monitor corner)
    with mss.mss() as sct:
        region = {'top': 0, 'left': 0, 'width': 100, 'height': 100}
        temp_img = sct.grab(region)
        raw_bytes_1 = mss.tools.to_png(temp_img.rgb, temp_img.size)

    # check if something changed on the screen in the selected region as long as user will press "enter"
    while not bot_stop:
        temp_img = sct.grab(region)
        raw_bytes_2 = mss.tools.to_png(temp_img.rgb, temp_img.size)
        if raw_bytes_1 != raw_bytes_2:
            print("something changed in the screen corner!")
        time.sleep(0.5)


def bot_stop_switch(keyboard_event_info):
    global bot_stop

    bot_stop = True

    keyboard.unhook_all()
    print(keyboard_event_info)

4

1 回答 1

0

经过几个小时的测试,我找到了一个解决方案,但我不知道为什么它会有所作为。关键是在 main 函数内制作第一个屏幕截图temp_img = sct.grab(region)(我们从这里为第二个函数启动一个线程)。

import threading
import keyboard
import time
import mss
import mss.tools

bot_stop = False
raw_bytes_1 = None
region = {}


def main_function():   # I run this function by pressing button in tkinter window
    global bot_stop
    global raw_bytes_1
    global region

    bot_stop = False

    # make a screenshoot of selected region (this case: upper left main monitor corner)
    with mss.mss() as sct:
        region = {'top': 0, 'left': 0, 'width': 100, 'height': 100}
        temp_img = sct.grab(region)
        raw_bytes_1 = mss.tools.to_png(temp_img.rgb, temp_img.size)

    # threading
    thread_1 = threading.Thread(target=fun_1)

    # start the thread is checkbox in tkinter window is ticked
    if checkbox_1.get():
        thread_1.start()

    # press enter to stop the main_function and fun_1
    keyboard.on_press_key('enter', bot_stop_switch)

    # run this loop as long as user will press "enter"
    while not bot_stop:
        print("main_function_is_running")
        time.sleep(1)


def fun_1():
    # check if something changed on the screen in the selected region as long as user will press "enter"
    while not bot_stop:
        temp_img = sct.grab(region)
        raw_bytes_2 = mss.tools.to_png(temp_img.rgb, temp_img.size)
        if raw_bytes_1 != raw_bytes_2:
            print("something changed in the screen corner!")
        time.sleep(0.5)


main_function()
于 2020-04-07T22:56:29.270 回答