簡體   English   中英

如何使用 PySimpleGUI - 線程關閉循環?

[英]How to close loop using PySimpleGUI - Threading?

我有一個運行 while 循環的程序(使用 pyautogui 和 pysimplegui)。 我想讓用戶手動取消循環/停止程序。

目前(在 Mac 上)如果我嘗試以任何方式與主要的 pyautogui window 交互,我會得到一個旋轉的沙灘球。

我相信線程可能是答案,但經過大量搜索和測試后,我似乎無法讓它在我的代碼中工作。

下面是有問題的循環:

window=sg.Window('Meetup Auto Message', layout1, element_justification='c')
while True:
    event, values = window.read()
    if event in (sg.WIN_CLOSED, '  Cancel  '):
          break
    if event == '    Ok    ':
        messageOptions = [values['textBox1'], values['textBox2'], values['textBox3'], values['textBox4'], values['textBox5']]
         
        for i, (nameList, profileLink) in enumerate(zip(nameList, profileLink)):
            message = "Hi " + f'{nameList}' + ", " + "\n" + f'{choice(messageOptions)}'

            webbrowser.open(profileLink)
            time.sleep(15)
            pyautogui.press("tab")
            pyautogui.write(message, interval=random.uniform(0.03, 0.15))

            with pyautogui.hold("command"):
                pyautogui.press("w")
                window['-PROG-'].update(i+1)
            if i == 10:
                time.sleep(300)
            
        
window.close()

並參考完整代碼:

import webbrowser
import pyautogui
import random
from random import choice
import time
import PySimpleGUI as sg
import threading

font = ("Arial", 13)

layout = [  [sg.Text('Select your .txt profiles file. Must be a list of URLs with each URL on a new line', font=("Arial", 16))],
            [sg.Combo(sorted(sg.user_settings_get_entry('-filenames-', [])), default_value=sg.user_settings_get_entry('-last filename-', ''), size=(50, 1), key='-FILENAME-', font="Arial, 16"), sg.FileBrowse(font="Arial, 16"), sg.B('Clear History', font="Arial, 16")],
            [sg.Button('  Ok  ', bind_return_key=True, font="Arial, 16", button_color='green'),  sg.Button('Cancel', font="Arial, 16")] ]

window = sg.Window('Meetup Auto Message - Profiles selection', layout)

while True:
    event, values = window.read()

    if event in (sg.WIN_CLOSED, 'Cancel'):
        break
    if event == '  Ok  ':
        # If OK, then need to add the filename to the list of files and also set as the last used filename
        sg.user_settings_set_entry('-filenames-', list(set(sg.user_settings_get_entry('-filenames-', []) + [values['-FILENAME-'], ])))
        sg.user_settings_set_entry('-last filename-', values['-FILENAME-'])
        lastFile=values['-FILENAME-']
        break
    elif event == 'Clear History':
        sg.user_settings_set_entry('-filenames-', [])
        sg.user_settings_set_entry('-last filename-', '')
        window['-FILENAME-'].update(values=[], value='')

window.close()

profileLink = open(lastFile).read().splitlines()

profileLink = [item.replace("+","name=") for item in profileLink]
newLinks = [item.replace("%","name=") for item in profileLink]
nameList = [i.split("name=")[1] for i in newLinks]
num_lines = sum(1 for line in open(lastFile))
BAR_MAX = num_lines

layout1 = [ [sg.Text('This program will take your messages, rotate them, add random delays and automatically message people from your profile list. You won\'t be able to use your computer while the program is running.', font="Arial, 18")],
            [sg.Text('Enter your messages below just the content, we handle the "Hi Name" part.', font="Arial, 18")],
            [sg.Multiline(size=(100,10), key='textBox1', font=font)],
            [sg.Multiline(size=(100,10), key='textBox2', font=font)],
            [sg.Multiline(size=(100,10), key='textBox3', font=font)],
            [sg.Multiline(size=(100,10), key='textBox4', font=font)],
            [sg.Multiline(size=(100,10), key='textBox5', font=font)],
            [sg.Button('    Ok    ', bind_return_key=True, font="Arial, 24", button_color='green'),  sg.Button('  Cancel  ', font="Arial, 24")],
            [sg.Text('Progress Bar', font="Arial, 15")],
            [sg.ProgressBar(BAR_MAX, orientation='h', size=(20,20), key='-PROG-')] ]





window=sg.Window('Meetup Auto Message', layout1, element_justification='c')
while True:
    event, values = window.read()
    if event in (sg.WIN_CLOSED, '  Cancel  '):
          break
    if event == '    Ok    ':
        messageOptions = [values['textBox1'], values['textBox2'], values['textBox3'], values['textBox4'], values['textBox5']]
         
        for i, (nameList, profileLink) in enumerate(zip(nameList, profileLink)):
            message = "Hi " + f'{nameList}' + ", " + "\n" + f'{choice(messageOptions)}'

            webbrowser.open(profileLink)
            time.sleep(15)
            pyautogui.press("tab")
            pyautogui.write(message, interval=random.uniform(0.03, 0.15))

            with pyautogui.hold("command"):
                pyautogui.press("w")
                window['-PROG-'].update(i+1)
            if i == 10:
                time.sleep(300)
            
        
window.close()

如果你能告訴我如何實現 GUI 來打破循環,獎勵積分::)

編輯:我嘗試將 while 循環重構為函數,允許我在函數上使用 try: except: ……運氣不好。 這樣做時我得到未定義的值。 所以我把事件,值 window.open 放在 function 之外...嘗試聲明全局變量等等...這導致程序在點擊清除按鈕時崩潰並出現“無法讀取設置文件”錯誤我的程序。

在這里不知所措。

你被計算機科學的一個難題絆倒了。 它會有諸如“異步”、“並行執行”、“搶占”等術語。 當面對這個普遍化的難題時,我建議您依靠久經考驗的真實解決方案。

欺騙。

如果您的具體示例,您等待幾毫秒以查看按鈕是否被按下就足夠了。 通常,PySimpleGui 的read會一直等待直到事件發生。 您需要一個超時參數,特別是event, values = window.read(timeout=10) 您可能還想閱讀這篇文章以獲取更多信息。

繼續編碼。 記筆記。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM