传递了一个参数并设法在函数内部更新了它 - Python

Passed a parameter and managed to update that inside the function - Python

我看到了 PySimpleGUI 的示例演示代码,但我仍然不确定 window 变量

window 作为参数传递给 the_thread() 函数,它设法以某种方式对 window 变量执行一些操作,例如 window.write_event_value 是在主函数里面。

我在 main 中有一个 cp(values) 证明它已被添加。

谁能告诉我这怎么可能?

import threading
import time
import PySimpleGUI as sg


THREAD_EVENT = '-THREAD-'

cp = sg.cprint

def the_thread(window):

    i = 0
    while True:
        time.sleep(1)
        cp('This keeps on running')
        window.write_event_value('-THREAD-', (threading.current_thread().name, i))      # Data sent is a tuple of thread name and counter
        cp('This is cheating from the thread', c='white on green')
        i += 1


def main():

    layout = [  [sg.Text('Output Area - cprint\'s route to here', font='Any 15')],
                [sg.Multiline(size=(65,20), key='-ML-', autoscroll=True, reroute_stdout=True, write_only=True, reroute_cprint=True)],
                [sg.T('Input so you can see data in your dictionary')],
                [sg.Input(key='-IN-', size=(30,1))],
                [sg.B('Start A Thread'), sg.B('Dummy'), sg.Button('Exit')]  ]

    window = sg.Window('Window Title', layout)

    while True:             # Event Loop
        event, values = window.read()
        
        if event == sg.WIN_CLOSED or event == 'Exit':
            break
        if event.startswith('Start'):
            threading.Thread(target=the_thread, args=(window,), daemon=True).start()
        if event == THREAD_EVENT:
            cp(f'Data from the thread ', colors='white on purple', end='')
            cp(f'{values[THREAD_EVENT]}', colors='white on red')

        cp(values)
    window.close()


if __name__ == '__main__':
    main()

抱歉我是菜鸟,看起来它在一个单独的函数上被修改的原因是因为它是一个可变对象。

仍然不确定问题是什么。 尝试解释这个脚本。

  1. 定义window
  2. 的布局
    layout = [  [sg.Text('Output Area - cprint\'s route to here', font='Any 15')],
                [sg.Multiline(size=(65,20), key='-ML-', autoscroll=True, reroute_stdout=True, write_only=True, reroute_cprint=True)],
                [sg.T('Input so you can see data in your dictionary')],
                [sg.Input(key='-IN-', size=(30,1))],
                [sg.B('Start A Thread'), sg.B('Dummy'), sg.Button('Exit')]  ]
  1. 通过
  2. 定义一个window
window = sg.Window('Window Title', layout)
  1. While 循环处理由 window 上的鼠标或键盘输入操作生成的事件。这里,window.read() 会在更新前创建 window 的 GUI,如果 GUI 还没有完成,然后更新 window
  2. 的 GUI
    while True:             # Event Loop
        event, values = window.read()
    ...       
  1. 如果单击 window 的关闭按钮事件,或单击 'Exit' 按钮的事件,则从 while 循环中断。
        if event == sg.WIN_CLOSED or event == 'Exit':
            break
  1. 如果单击了按钮 'Start A Thread',则通过调用函数 the_thread(window) 来启动一个新线程。
        if event.startswith('Start'):
            threading.Thread(target=the_thread, args=(window,), daemon=True).start()
  1. 线程函数每休眠一秒发送一个事件'-THREAD-',值为(threading.current_thread().name, i)。一般来说,你不应该在主线程中更新 window 的 GUI,因为当你的代码 运行 时可能会遇到麻烦,向主线程发送一个事件来处理 GUI 更新,所以我删除了所有 cp 在这里打电话。
def the_thread(window):

    i = 0
    while True:
        time.sleep(1)
        window.write_event_value('-THREAD-', (threading.current_thread().name, i))      # Data sent is a tuple of thread name and counter
        i += 1
  1. 更新元素或 window,并在线程生成事件 -THREAD- 时将消息打印到 sg.Multiline
        if event == THREAD_EVENT:
            cp(f'Data from the thread ', colors='white on purple', end='')
            cp(f'{values[THREAD_EVENT]}', colors='white on red')
  1. 从 while 循环中断后,关闭 window 并退出。
    window.close()