wxpython增加MainLoop持续时间



我之前发布了一个类似的Q,但我删除了它,并在一个更简单的程序中重现了这个问题,我将在这里发布这个程序,希望其他人能重现这个问题并帮助我找到解决方案。

我将wxPython与定制的MainLoop一起使用,问题是随着时间的推移,某条指令的执行时间在增加,我不知道为什么。我在https://github.com/wxWidgets/wxPython-Classic/blob/master/samples/mainloop/mainloop.py

该程序旨在从一个大目录中读取图像,并按顺序保存许多屏幕截图,最多可达20000张。每个MainLoop迭代都应该转移到目录中的一个新图像。每次迭代,该图像都被设置为wxpython面板中的背景。在这个例子中,我将其简化为只从ini上的路径读取一个图像,然后在每次迭代中不断将wxPython面板的bg设置为该图像,而不是按顺序读取多个图像。

问题是,面板类内的代码块的执行时间会随着时间的推移而快速增加,该部分设置面板的背景图像。在每次迭代20次之后,这个块的执行时间似乎稳定地增加了15ms。这是我的程序代码。它可以很容易地复制,您所要做的就是将img路径更改为计算机上的某个img。

import time
import os
import gc
import wx
# APP
class MyApp(wx.App):
def __init__(self):
self.img_file_path = 'your_path.png'
super().__init__(clearSigInt=True)
def MainLoop(self):
evtloop = wx.GUIEventLoop()
#old = wx.EventLoop.GetActive()
wx.EventLoop.SetActive(evtloop)
while self.keepGoing:
# this is the only instruction in the customized main loop that I added,
# everything else is straight out of the example
self.frame.panel.set_background_image_to_ss(self.img_file_path)
while evtloop.Pending():
evtloop.Dispatch()
# i also changed the sleep from 0.1s in the example to 0.03.
# either way the execution time increases over time.
time.sleep(0.03)
evtloop.ProcessIdle()
wx.EventLoop.SetActive(old)

def OnInit(self):
self.frame = MyFrame(self)
self.frame.Show(True)
self.SetTopWindow(self.frame)
self.keepGoing = True
return True
# FRAME
class MyFrame(wx.Frame):
def __init__(self, app_obj, title="CM1", pos=(100, 100), size=(760,800)):
super().__init__(None, title=title, pos=pos, size=wx.Size(size))
self.init_panel(app_obj)
def init_panel(self, app_obj):
self.panel = MyPanel(self, app_obj)
# PANEL            
class MyPanel(wx.Panel):
def __init__(self, parent, app_obj):
super().__init__(parent=parent)
self.app_obj = app_obj
self.bg_img = -1
# PROBLEM METHOD 
def set_background_image_to_ss(self, path):
bmp1 = wx.Image(path, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
# I'm benchmarking the execution time of the following if/else statement
# for some reason this increases over time
curr_milliseconds_loop = time.time() * 1000
if self.bg_img == -1:
self.bitmap1 = wx.StaticBitmap(self, -1, bmp1, (0, 0))
else:
self.bitmap1.Destroy()
self.bitmap1.SetBitmap(wx.Bitmap(path))
print("SET BG BITMAP MS=", time.time() * 1000 - curr_milliseconds_loop)

app = MyApp()
app.MainLoop()

这里是终端中可能前100次迭代的一些结果输出:

SET BG BITMAP MS= 15.666748046875
SET BG BITMAP MS= 0.0
SET BG BITMAP MS= 0.0
SET BG BITMAP MS= 0.0
SET BG BITMAP MS= 15.400390625
SET BG BITMAP MS= 15.609619140625
SET BG BITMAP MS= 0.0
SET BG BITMAP MS= 15.399658203125
SET BG BITMAP MS= 15.40478515625
SET BG BITMAP MS= 15.408203125
SET BG BITMAP MS= 15.404296875
SET BG BITMAP MS= 15.400390625
SET BG BITMAP MS= 0.0
SET BG BITMAP MS= 0.0
SET BG BITMAP MS= 15.4013671875
SET BG BITMAP MS= 0.0
SET BG BITMAP MS= 0.0
SET BG BITMAP MS= 16.65966796875
SET BG BITMAP MS= 15.408935546875
SET BG BITMAP MS= 15.398193359375
SET BG BITMAP MS= 15.401611328125
SET BG BITMAP MS= 0.0
SET BG BITMAP MS= 15.589111328125
SET BG BITMAP MS= 0.0
SET BG BITMAP MS= 15.52734375
SET BG BITMAP MS= 15.4091796875
SET BG BITMAP MS= 15.39404296875
SET BG BITMAP MS= 15.388671875
SET BG BITMAP MS= 15.382080078125
SET BG BITMAP MS= 15.400390625
SET BG BITMAP MS= 31.01318359375
SET BG BITMAP MS= 15.3837890625
SET BG BITMAP MS= 15.407958984375
SET BG BITMAP MS= 15.37744140625
SET BG BITMAP MS= 15.6201171875
SET BG BITMAP MS= 15.388916015625
SET BG BITMAP MS= 15.400146484375
SET BG BITMAP MS= 15.401611328125
SET BG BITMAP MS= 15.388427734375
SET BG BITMAP MS= 15.61328125
SET BG BITMAP MS= 15.61474609375
SET BG BITMAP MS= 15.537841796875
SET BG BITMAP MS= 15.378662109375
SET BG BITMAP MS= 15.5322265625
SET BG BITMAP MS= 15.625732421875
SET BG BITMAP MS= 15.623779296875
SET BG BITMAP MS= 15.376708984375
SET BG BITMAP MS= 15.40576171875
SET BG BITMAP MS= 15.56689453125
SET BG BITMAP MS= 15.4033203125
SET BG BITMAP MS= 15.41259765625
SET BG BITMAP MS= 15.607666015625
SET BG BITMAP MS= 15.623291015625
SET BG BITMAP MS= 15.621826171875
SET BG BITMAP MS= 15.5947265625
SET BG BITMAP MS= 15.5625
SET BG BITMAP MS= 15.5693359375
SET BG BITMAP MS= 15.62109375
SET BG BITMAP MS= 31.192138671875
SET BG BITMAP MS= 31.173828125
SET BG BITMAP MS= 31.23779296875
SET BG BITMAP MS= 31.18017578125
SET BG BITMAP MS= 15.62060546875
SET BG BITMAP MS= 15.563720703125
SET BG BITMAP MS= 15.61083984375
SET BG BITMAP MS= 31.21728515625
SET BG BITMAP MS= 31.23828125
SET BG BITMAP MS= 31.23486328125
SET BG BITMAP MS= 31.23779296875
SET BG BITMAP MS= 31.23583984375
SET BG BITMAP MS= 31.236572265625
SET BG BITMAP MS= 31.23388671875
SET BG BITMAP MS= 31.23876953125
SET BG BITMAP MS= 31.27392578125
SET BG BITMAP MS= 31.236083984375
SET BG BITMAP MS= 31.23876953125
SET BG BITMAP MS= 31.18408203125
SET BG BITMAP MS= 31.235107421875
SET BG BITMAP MS= 15.621337890625
SET BG BITMAP MS= 15.616943359375
SET BG BITMAP MS= 15.62353515625
SET BG BITMAP MS= 15.62255859375
SET BG BITMAP MS= 15.62353515625
SET BG BITMAP MS= 15.622802734375
SET BG BITMAP MS= 15.619873046875
SET BG BITMAP MS= 31.2353515625
SET BG BITMAP MS= 31.229248046875
SET BG BITMAP MS= 31.2265625
SET BG BITMAP MS= 31.226806640625
SET BG BITMAP MS= 31.14990234375
SET BG BITMAP MS= 31.271728515625
SET BG BITMAP MS= 31.23095703125
SET BG BITMAP MS= 31.229736328125
SET BG BITMAP MS= 31.273193359375
SET BG BITMAP MS= 31.2353515625
SET BG BITMAP MS= 31.194091796875
SET BG BITMAP MS= 31.235107421875
SET BG BITMAP MS= 31.23828125
SET BG BITMAP MS= 31.232421875
SET BG BITMAP MS= 31.2373046875
SET BG BITMAP MS= 31.23291015625
SET BG BITMAP MS= 31.2353515625
SET BG BITMAP MS= 31.236572265625
SET BG BITMAP MS= 31.235107421875
SET BG BITMAP MS= 31.231201171875
SET BG BITMAP MS= 31.239501953125
SET BG BITMAP MS= 31.2041015625
SET BG BITMAP MS= 31.238525390625
SET BG BITMAP MS= 31.231201171875
SET BG BITMAP MS= 31.231201171875
SET BG BITMAP MS= 31.2314453125
SET BG BITMAP MS= 31.2333984375
SET BG BITMAP MS= 31.19775390625
SET BG BITMAP MS= 31.22412109375
SET BG BITMAP MS= 31.2421875
SET BG BITMAP MS= 46.819580078125
SET BG BITMAP MS= 46.85400390625
SET BG BITMAP MS= 46.846435546875
SET BG BITMAP MS= 31.23193359375
SET BG BITMAP MS= 46.853759765625
SET BG BITMAP MS= 31.2265625
SET BG BITMAP MS= 46.853759765625
SET BG BITMAP MS= 46.85595703125
SET BG BITMAP MS= 46.84912109375
SET BG BITMAP MS= 46.844970703125
SET BG BITMAP MS= 46.85107421875
SET BG BITMAP MS= 46.8525390625
SET BG BITMAP MS= 46.853271484375
SET BG BITMAP MS= 46.845703125
SET BG BITMAP MS= 46.794921875
SET BG BITMAP MS= 46.889404296875
SET BG BITMAP MS= 46.845458984375
SET BG BITMAP MS= 46.851806640625
SET BG BITMAP MS= 46.841064453125
SET BG BITMAP MS= 46.849853515625
SET BG BITMAP MS= 46.85107421875
SET BG BITMAP MS= 31.239501953125
SET BG BITMAP MS= 46.842529296875
SET BG BITMAP MS= 46.8466796875
SET BG BITMAP MS= 46.846435546875
SET BG BITMAP MS= 46.841064453125
SET BG BITMAP MS= 46.8544921875
SET BG BITMAP MS= 46.818603515625
SET BG BITMAP MS= 46.843017578125
SET BG BITMAP MS= 46.89453125
SET BG BITMAP MS= 46.789306640625
SET BG BITMAP MS= 46.848388671875
SET BG BITMAP MS= 46.843994140625
SET BG BITMAP MS= 46.8505859375
SET BG BITMAP MS= 46.849609375
SET BG BITMAP MS= 46.8486328125
SET BG BITMAP MS= 46.841796875
SET BG BITMAP MS= 46.89404296875
SET BG BITMAP MS= 46.79248046875
SET BG BITMAP MS= 46.853515625
SET BG BITMAP MS= 46.772705078125
SET BG BITMAP MS= 46.79248046875
SET BG BITMAP MS= 46.845703125
SET BG BITMAP MS= 46.81884765625
SET BG BITMAP MS= 46.848388671875
SET BG BITMAP MS= 46.845458984375
SET BG BITMAP MS= 46.853271484375
SET BG BITMAP MS= 46.8486328125
SET BG BITMAP MS= 46.842529296875
SET BG BITMAP MS= 46.84521484375
SET BG BITMAP MS= 46.845458984375
SET BG BITMAP MS= 46.8017578125
SET BG BITMAP MS= 46.8505859375
SET BG BITMAP MS= 46.857666015625
SET BG BITMAP MS= 46.853515625
SET BG BITMAP MS= 46.847900390625
SET BG BITMAP MS= 62.470458984375
SET BG BITMAP MS= 46.868408203125
SET BG BITMAP MS= 46.84228515625
SET BG BITMAP MS= 46.847412109375
SET BG BITMAP MS= 46.8515625
SET BG BITMAP MS= 46.837158203125
SET BG BITMAP MS= 62.46875
SET BG BITMAP MS= 62.46923828125
SET BG BITMAP MS= 62.474853515625
SET BG BITMAP MS= 46.85302734375
SET BG BITMAP MS= 62.447021484375
SET BG BITMAP MS= 62.474365234375
SET BG BITMAP MS= 62.471923828125
SET BG BITMAP MS= 62.43212890625
SET BG BITMAP MS= 46.848876953125
SET BG BITMAP MS= 62.472412109375
SET BG BITMAP MS= 62.468505859375
SET BG BITMAP MS= 62.51220703125
SET BG BITMAP MS= 62.41455078125
SET BG BITMAP MS= 62.417236328125
SET BG BITMAP MS= 62.47021484375
SET BG BITMAP MS= 62.501953125
SET BG BITMAP MS= 62.4287109375
SET BG BITMAP MS= 46.843994140625
SET BG BITMAP MS= 62.46630859375
SET BG BITMAP MS= 62.476806640625
SET BG BITMAP MS= 62.467041015625
SET BG BITMAP MS= 69.049560546875
SET BG BITMAP MS= 69.44189453125
SET BG BITMAP MS= 67.87939453125
SET BG BITMAP MS= 60.30517578125
SET BG BITMAP MS= 46.8681640625

我希望有人能帮助我重现这个问题,并帮助我理解为什么基准set_background_image_to_ss方法需要更长的时间。在没有那么多迭代之后,执行时间的增加真的破坏了我的程序。谢谢

我想我找到了解决方案。

在初始化第一个图像后,我从未将self.bg_img设置为不等于-1,因此在添加新图像之前,else子句没有执行,上一个图像也没有被销毁。改变这一点似乎已经解决了问题。

感谢那些对此进行评论的人。

所有图像的大小是否相同
我已将位图创建移到面板的init中,只在set_background_image_to_ss中保留SetBitmap和图像转换
同时,我制作了一个伪列表,列出了20000张大小大致相同的图像,但没有看到速度的任何真正下降。

import time
import glob
import wx
# APP
class MyApp(wx.App):
def __init__(self):
# 2 images roughly the same size
self.images = glob.glob('./image3/*.png')
# falsify 20000 images
self.images = self.images * 10000
self.loop_count = 0
super().__init__(clearSigInt=True)
def MainLoop(self):
evtloop = wx.GUIEventLoop()
#old = wx.EventLoop.GetActive()
wx.EventLoop.SetActive(evtloop)
for i in self.images:
# this is the only instruction in the customized main loop that I added,
# everything else is straight out of the example
self.frame.panel.set_background_image_to_ss(i)
while evtloop.Pending():
evtloop.Dispatch()
# i also changed the sleep from 0.1s in the example to 0.03.
# either way the execution time increases over time.
time.sleep(0.01)
evtloop.ProcessIdle()
#wx.EventLoop.SetActive(old)

def OnInit(self):
self.frame = MyFrame(self)
self.frame.Show(True)
self.SetTopWindow(self.frame)
self.keepGoing = True
return True
# FRAME
class MyFrame(wx.Frame):
def __init__(self, app_obj, title="CM1", pos=(100, 100), size=(760,800)):
super().__init__(None, title=title, pos=pos, size=wx.Size(size))
self.init_panel(app_obj)
def init_panel(self, app_obj):
self.panel = MyPanel(self, app_obj)
# PANEL
class MyPanel(wx.Panel):
def __init__(self, parent, app_obj):
super().__init__(parent=parent)
self.loop = app_obj.loop_count
self.bmp1 = wx.Image(app_obj.images[0], wx.BITMAP_TYPE_ANY).ConvertToBitmap()
self.bitmap1 = wx.StaticBitmap(self, -1, self.bmp1, (0, 0))
# PROBLEM METHOD
def set_background_image_to_ss(self, path):
self.bmp1 = wx.Image(path, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
curr_milliseconds_loop = time.time() * 1000
self.bitmap1.SetBitmap(self.bmp1)
self.loop += 1
print("Loop:",self.loop,"SET BG BITMAP MS=", time.time() * 1000 - curr_milliseconds_loop)

app = MyApp()
app.MainLoop()

启动时的速度:

Loop: 155 SET BG BITMAP MS= 1.70263671875
Loop: 156 SET BG BITMAP MS= 2.387939453125
Loop: 157 SET BG BITMAP MS= 2.416748046875
Loop: 158 SET BG BITMAP MS= 1.94580078125
Loop: 159 SET BG BITMAP MS= 1.8955078125
Loop: 160 SET BG BITMAP MS= 1.4580078125
Loop: 161 SET BG BITMAP MS= 2.04833984375
Loop: 162 SET BG BITMAP MS= 2.198486328125
Loop: 163 SET BG BITMAP MS= 1.79150390625
Loop: 164 SET BG BITMAP MS= 5.07958984375
Loop: 165 SET BG BITMAP MS= 1.69580078125

末端速度:

Loop: 19925 SET BG BITMAP MS= 2.36962890625
Loop: 19926 SET BG BITMAP MS= 2.014892578125
Loop: 19927 SET BG BITMAP MS= 1.75390625
Loop: 19928 SET BG BITMAP MS= 1.5390625
Loop: 19929 SET BG BITMAP MS= 1.9013671875
Loop: 19930 SET BG BITMAP MS= 2.01953125
Loop: 19931 SET BG BITMAP MS= 1.921875
Loop: 19932 SET BG BITMAP MS= 1.669677734375
Loop: 19933 SET BG BITMAP MS= 1.630126953125
Loop: 19934 SET BG BITMAP MS= 2.14501953125
Loop: 19935 SET BG BITMAP MS= 2.1103515625

最新更新