如何防止 gui 在 wxpython 中冻结?
How can I prevent gui freezing in wxpython?
[问题]
如果我单击触发函数的按钮,则 gui 将冻结,直到函数结束。
[代码]
import wx
app = wx.App(redirect=False)
top = wx.Frame(None)
top.Maximize(True) # Set to maximize the application
sizer = wx.GridBagSizer()
def testFunction(event):
import pyautogui
import time
pyautogui.FAILSAFE = False
for i in range(2):
pyautogui.hotkey('win','r')
time.sleep (0.5)
pyautogui.typewrite('cmd.exe')
time.sleep (0.5)
pyautogui.hotkey('enter')
time.sleep (0.5)
time.sleep (3)
addButton = wx.Button( top, -1, "Start", style=wx.BU_EXACTFIT )
sizer.Add(addButton, (6, 8), (2, 14), wx.EXPAND)
top.Bind(wx.EVT_BUTTON, testFunction, addButton)
top.Sizer = sizer
top.Sizer.Fit(top)
top.Show()
app.MainLoop()
[当前]
gui 冻结,直到函数结束。
[期望]
gui 不应冻结。
注意:我认为这与线程有关,但我不能完全理解这个概念。
使用 wx.CallLater
将在给定时间后调用带有参数的给定可调用对象。函数 testFunction
的结构应该更改为:
def testFunction(event):
import pyautogui
pyautogui.FAILSAFE = False
def step1(i):
pyautogui.hotkey('win','r')
wx.CallLater(500, step2, i)
def step2(i):
pyautogui.typewrite('cmd.exe')
wx.CallLater(500, step3, i)
def step3(i):
pyautogui.hotkey('enter')
if i <= 1:
return
wx.CallLater(3500, step1, i-1)
step1(2)
我对 ex 不太熟悉,但也许这有帮助
import wx
import threading
app = wx.App(redirect=False)
top = wx.Frame(None)
top.Maximize(True) # Set to maximize the application
sizer = wx.GridBagSizer()
def testFunction(event):
import pyautogui
import time
pyautogui.FAILSAFE = False
for i in range(2):
pyautogui.hotkey('win','r')
time.sleep (0.5)
pyautogui.typewrite('cmd.exe')
time.sleep (0.5)
pyautogui.hotkey('enter')
time.sleep (0.5)
time.sleep (3)
t1 = threading.Thread(target=testFunction, args=[])
addButton = wx.Button( top, -1, "Start", style=wx.BU_EXACTFIT )
sizer.Add(addButton, (6, 8), (2, 14), wx.EXPAND)
top.Bind(wx.EVT_BUTTON, t1, addButton)
top.Sizer = sizer
top.Sizer.Fit(top)
top.Show()
app.MainLoop()
好吧,这对我有用:
# -*- coding: utf-8 -*-
import wx
app = wx.App(redirect=False)
top = wx.Frame(None)
top.Maximize(False) # Set to maximize the application
sizer = wx.GridBagSizer()
def testFunction(event):
import time
for i in range(2):
print ('win','r')
time.sleep (0.5)
print ('cmd.exe')
time.sleep (0.5)
print ('enter')
time.sleep (0.5)
print 'sleep'
time.sleep (3)
print u"Iteración %d".format(i+1)
def thread_start(event):
import threading
th = threading.Thread(target=testFunction, args=(event,))
th.start()
addButton = wx.Button( top, -1, "Start", style=wx.BU_EXACTFIT )
sizer.Add(addButton, (6, 8), (2, 14), wx.EXPAND)
# top.Bind(wx.EVT_BUTTON, testFunction, addButton)
top.Bind(wx.EVT_BUTTON, thread_start, addButton)
top.Sizer = sizer
top.Sizer.Fit(top)
top.Show()
app.MainLoop()
你有一个不闪烁的图形用户界面。
您可以从它开始并添加输入变量(例如获取和识别您的线程,这样您就可以知道正在调用哪个线程)。
我删除了 py2autogui 库,因为我没有安装它(并且对于示例来说不是必需的)。
[问题] 如果我单击触发函数的按钮,则 gui 将冻结,直到函数结束。
[代码]
import wx
app = wx.App(redirect=False)
top = wx.Frame(None)
top.Maximize(True) # Set to maximize the application
sizer = wx.GridBagSizer()
def testFunction(event):
import pyautogui
import time
pyautogui.FAILSAFE = False
for i in range(2):
pyautogui.hotkey('win','r')
time.sleep (0.5)
pyautogui.typewrite('cmd.exe')
time.sleep (0.5)
pyautogui.hotkey('enter')
time.sleep (0.5)
time.sleep (3)
addButton = wx.Button( top, -1, "Start", style=wx.BU_EXACTFIT )
sizer.Add(addButton, (6, 8), (2, 14), wx.EXPAND)
top.Bind(wx.EVT_BUTTON, testFunction, addButton)
top.Sizer = sizer
top.Sizer.Fit(top)
top.Show()
app.MainLoop()
[当前] gui 冻结,直到函数结束。
[期望] gui 不应冻结。 注意:我认为这与线程有关,但我不能完全理解这个概念。
使用 wx.CallLater
将在给定时间后调用带有参数的给定可调用对象。函数 testFunction
的结构应该更改为:
def testFunction(event):
import pyautogui
pyautogui.FAILSAFE = False
def step1(i):
pyautogui.hotkey('win','r')
wx.CallLater(500, step2, i)
def step2(i):
pyautogui.typewrite('cmd.exe')
wx.CallLater(500, step3, i)
def step3(i):
pyautogui.hotkey('enter')
if i <= 1:
return
wx.CallLater(3500, step1, i-1)
step1(2)
我对 ex 不太熟悉,但也许这有帮助
import wx
import threading
app = wx.App(redirect=False)
top = wx.Frame(None)
top.Maximize(True) # Set to maximize the application
sizer = wx.GridBagSizer()
def testFunction(event):
import pyautogui
import time
pyautogui.FAILSAFE = False
for i in range(2):
pyautogui.hotkey('win','r')
time.sleep (0.5)
pyautogui.typewrite('cmd.exe')
time.sleep (0.5)
pyautogui.hotkey('enter')
time.sleep (0.5)
time.sleep (3)
t1 = threading.Thread(target=testFunction, args=[])
addButton = wx.Button( top, -1, "Start", style=wx.BU_EXACTFIT )
sizer.Add(addButton, (6, 8), (2, 14), wx.EXPAND)
top.Bind(wx.EVT_BUTTON, t1, addButton)
top.Sizer = sizer
top.Sizer.Fit(top)
top.Show()
app.MainLoop()
好吧,这对我有用:
# -*- coding: utf-8 -*-
import wx
app = wx.App(redirect=False)
top = wx.Frame(None)
top.Maximize(False) # Set to maximize the application
sizer = wx.GridBagSizer()
def testFunction(event):
import time
for i in range(2):
print ('win','r')
time.sleep (0.5)
print ('cmd.exe')
time.sleep (0.5)
print ('enter')
time.sleep (0.5)
print 'sleep'
time.sleep (3)
print u"Iteración %d".format(i+1)
def thread_start(event):
import threading
th = threading.Thread(target=testFunction, args=(event,))
th.start()
addButton = wx.Button( top, -1, "Start", style=wx.BU_EXACTFIT )
sizer.Add(addButton, (6, 8), (2, 14), wx.EXPAND)
# top.Bind(wx.EVT_BUTTON, testFunction, addButton)
top.Bind(wx.EVT_BUTTON, thread_start, addButton)
top.Sizer = sizer
top.Sizer.Fit(top)
top.Show()
app.MainLoop()
你有一个不闪烁的图形用户界面。 您可以从它开始并添加输入变量(例如获取和识别您的线程,这样您就可以知道正在调用哪个线程)。
我删除了 py2autogui 库,因为我没有安装它(并且对于示例来说不是必需的)。