PySimpleGUI зависает

Я написал код для взлома в холодной игре Boxing Simulator 2 на python 3.8.1 с PySimpleGui 4.15.1, и если я попытаюсь нажать кнопку «Пуск/Стоп», графический интерфейс зависает, но скрипт связан с кнопкой «Пуск/Стоп». все еще бежит. Но если я изменю скрипт, связанный с кнопкой Start/Stop, на что-то вроде Print('Chicken'), тогда он будет работать идеально

Вот код:

import PySimpleGUI as sg
import ctypes
import time
import pynput

sg.theme('DarkBrown1')

layout = [  [sg.Text('BOXING SIMULATOR 2 HACK', size=(20, 2), justification='center')],
            [sg.Text('', size=(10, 2), font=('Helvetica', 20), justification='center', key='_OUTPUT_')],
            [sg.T(' ' * 5), sg.Button('Start/Stop', focus=True), sg.Quit()]]

window = sg.Window('BOXING SIMULATOR 2 HACK', layout)

SendInput = ctypes.windll.user32.SendInput

PUL = ctypes.POINTER(ctypes.c_ulong)
class KeyBdInput(ctypes.Structure):
    _fields_ = [("wVk", ctypes.c_ushort),
                ("wScan", ctypes.c_ushort),
                ("dwFlags", ctypes.c_ulong),
                ("time", ctypes.c_ulong),
                ("dwExtraInfo", PUL)]

class HardwareInput(ctypes.Structure):
    _fields_ = [("uMsg", ctypes.c_ulong),
                ("wParamL", ctypes.c_short),
                ("wParamH", ctypes.c_ushort)]

class MouseInput(ctypes.Structure):
    _fields_ = [("dx", ctypes.c_long),
                ("dy", ctypes.c_long),
                ("mouseData", ctypes.c_ulong),
                ("dwFlags", ctypes.c_ulong),
                ("time",ctypes.c_ulong),
                ("dwExtraInfo", PUL)]

class Input_I(ctypes.Union):
    _fields_ = [("ki", KeyBdInput),
                 ("mi", MouseInput),
                 ("hi", HardwareInput)]

class Input(ctypes.Structure):
    _fields_ = [("type", ctypes.c_ulong),
                ("ii", Input_I)]


def PressKeyPynput(hexKeyCode):
    extra = ctypes.c_ulong(0)
    ii_ = pynput._util.win32.INPUT_union()
    ii_.ki = pynput._util.win32.KEYBDINPUT(0, hexKeyCode, 0x0008, 0, ctypes.cast(ctypes.pointer(extra), ctypes.c_void_p))
    x = pynput._util.win32.INPUT(ctypes.c_ulong(1), ii_)
    SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

def ReleaseKeyPynput(hexKeyCode):
    extra = ctypes.c_ulong(0)
    ii_ = pynput._util.win32.INPUT_union()
    ii_.ki = pynput._util.win32.KEYBDINPUT(0, hexKeyCode, 0x0008 | 0x0002, 0, ctypes.cast(ctypes.pointer(extra), ctypes.c_void_p))
    x = pynput._util.win32.INPUT(ctypes.c_ulong(1), ii_)
    SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))


HACK_running, counter = False, 0

while True:                                 
    event, values = window.read(timeout=10) 
    if event in (None, 'Quit'):            
        break
    elif event == 'Start/Stop':
        HACK_running = not HACK_running
    if HACK_running:
            PressKeyPynput(0x02)
            time.sleep(0.08)
            ReleaseKeyPynput(0x02)
            PressKeyPynput(0x11)
            time.sleep(0.5)
            ReleaseKeyPynput(0x11)
            PressKeyPynput(0x1F)
            time.sleep(0.6)
            ReleaseKeyPynput(0x1F)
            PressKeyPynput(0x02)
            time.sleep(0.08)
            ReleaseKeyPynput(0x02)
            time.sleep(300)

person CUPZYY    schedule 15.01.2020    source источник
comment
Этот точно такой же вопрос уже был опубликован. Внутренний цикл while никогда не завершается. Если вы не сделаете вызовы графического интерфейса, это будет выглядеть так, как будто программа зависает.   -  person Mike from PSG    schedule 16.01.2020


Ответы (1)


Вы не можете выполнять действительно длительные задачи в графическом интерфейсе без какой-либо операции обновления или чтения.

Я ответил на предыдущий пост, который был идентичен этому, указав на проблему как на внутренний цикл while, который никогда не завершается.

Если вам нужно, чтобы внутренний цикл выполнялся вечно, вам, по крайней мере, нужно обновить графический интерфейс. Вы можете сделать это, вызвав window.refresh, как показано ниже.

while True:                                 
    event, values = window.read(timeout=10) 
    if event in (None, 'Quit'):            
        break
    elif event == 'Start/Stop':
        HACK_running = not HACK_running
    if HACK_running:
            PressKeyPynput(0x02)
            time.sleep(0.08)
            ReleaseKeyPynput(0x02)
            PressKeyPynput(0x11)
            time.sleep(0.5)
            ReleaseKeyPynput(0x11)
            PressKeyPynput(0x1F)
            time.sleep(0.6)
            ReleaseKeyPynput(0x1F)
            PressKeyPynput(0x02)
            time.sleep(0.08)
            ReleaseKeyPynput(0x02)
            time.sleep(300)
            window.refresh()

Вы никогда не должны засыпать из цикла событий PySimpleGUI.

Лучшим подходом было бы вызвать window.read(timeout=400) вместо time.sleep(0.4). Это не позволит ОС думать, что ваша программа зависла.

person Mike from PSG    schedule 16.01.2020