Я борюсь с wxPython в Linux. После большого количества времени и исследований я сократил свою программу до минимума, чтобы показать вам одну из проблем, с которыми я столкнулся. Я мог бы уменьшить его до довольно небольшого примера кода, используя только один датчик в окне, который обновляется таймером. Мои первые проблемы появились с кнопками, цвет фона которых должен был быть быстро изменен, что привело к странным ошибкам памяти. Поскольку полное приложение далеко не сложно, я искал простой пример - бинго! Вот приведенный код, который отлично работает в Windows и не работает на Raspberry Pi, а также виртуальные виртуальные машины VirtualBox от Raspberry Pi и Debian 9. Я пробовал wxPython 3.0.2.0 и 4.0.3, каждый с gtk2 и python 2.7 и python 3.5:
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
import wx
from threading import Timer
class MainWindow(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="Test", size=(600, 100))
panel = wx.Panel(self)
self.gauge = wx.Gauge(panel, wx.ID_ANY, 100, (10, 10), (480, 10))
self.gaugeval = 0
self.gauge.SetValue(self.gaugeval)
self.Show()
Timer(1, self.loop).start()
def loop(self):
self.gaugeval += 1
if self.gaugeval > 100:
self.gaugeval = 0
self.gauge.SetValue(self.gaugeval)
Timer(0.01, self.loop).start()
app = wx.App(False)
frame = MainWindow()
app.MainLoop()
После запуска программы требуется одна секунда, пока калибр не должен "жить" и заполнить панель слева направо, а затем снова начать с левой стороны и так далее. Однако в любой из протестированных систем Linux он замерзает очень быстро.
Что здесь происходит? Может ли кто-нибудь воспроизвести это? Я с трудом могу поверить, что такая простая функция не сработает. Большое спасибо за то, что посмотрели на эту проблему!
Я подозреваю, что ваша проблема может заключаться в использовании Timer
из модуля потоковой передачи.
Используйте wx.Timer
.
import wx
class MainWindow(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="Test", size=(600, 100))
panel = wx.Panel(self)
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.onTimer, self.timer)
self.gauge = wx.Gauge(panel, wx.ID_ANY, 100, (10, 10), (480, 10))
self.Show()
self.timer.Start(100) # fire every 10th of a second
def onTimer(self, evt):
val = self.gauge.GetValue()
val += 1
if val > 100:
val = 0
self.gauge.SetValue(val)
app = wx.App(False)
frame = MainWindow()
app.MainLoop()