我有一个wxPython框架,我希望定期访问网页并使用值更新框架上的小部件。
我知道有wx.Timer,但是我已经在使用它来更新另一个小部件。
我的尝试(以下)崩溃:
Pango:ERROR:/build/pango1.0-Ne8X8r/pango1.0-1.40.1/./pango/pango-layout.c:3925:pango_layout_check_lines: assertion failed: (!layout->log_attrs)
这是我正在使用的代码:
import datetime
import wx
import requests
from bs4 import BeautifulSoup
from threading import Thread, Event
class MainFrame(wx.Frame):
def __init__(self):
super(MainFrame, self).__init__(None)
self.Bind(wx.EVT_CLOSE, self.on_quit_click)
self.Size = (400, 200)
self.panel = MainPanel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.panel)
self.SetSizer(sizer)
self.Center()
self.Show()
self._on_clock_timer(None)
self.clock_timer = wx.Timer(self, -1)
self.clock_timer.Start(1000)
self.Bind(wx.EVT_TIMER, self._on_clock_timer)
self.stop_flag = Event()
thread = ScraperThread(self, 1, self.stop_flag)
thread.start()
def _on_clock_timer(self, event):
date_text = datetime.datetime.now().strftime('%a, %d %b %Y, %H:%M:%S')
self.SetTitle(date_text)
def on_quit_click(self, event):
del event
self.stop_flag.set()
wx.CallAfter(self.Destroy)
class ScraperThread(Thread):
def __init__(self, parent, period, event):
super(ScraperThread, self).__init__()
self.stopped = event
self.period = period
self.parent = parent
def run(self):
while not self.stopped.wait(self.period):
response = requests.get('http://google.com')
soup = BeautifulSoup(response.text, 'html.parser')
all_tags = soup.find_all('span')
for tag in all_tags:
if 'Advertising' in tag.text:
print(tag.text[:50])
self.parent.panel.lbl_value.SetLabel(tag.text[:50])
class MainPanel(wx.Panel):
def __init__(self, parent):
super(MainPanel, self).__init__(parent)
self.lbl_value = wx.StaticText(self, label='value')
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.lbl_value, flag=wx.ALL|wx.ALIGN_CENTER, border=5)
self.SetSizer(sizer)
if __name__ == '__main__':
wx_app = wx.App()
MainFrame()
wx_app.MainLoop()
我猜您需要这样的东西:
class MainFrame(wx.Frame):
def __init__(self):
# previous code up to self.Show()
self._on_clock_timer(None)
self.clock_timer = wx.Timer(self, -1)
self.clock_timer.Start(1000)
self.Bind(wx.EVT_TIMER, self._on_clock_timer, self.clock_timer)
self.scrape_timer = wx.Timer(self, -1)
self.scrape_timer.Start(1000)
self.Bind(wx.EVT_TIMER, self._on_scrape, self.scrape_timer)
def _on_scrape(self, event):
response = requests.get('http://google.com')
soup = BeautifulSoup(response.text, 'html.parser')
all_tags = soup.find_all('span')
for tag in all_tags:
if 'Advertising' in tag.text:
print(tag.text[:50])
self.panel.lbl_value.SetLabel(tag.text[:50])
然后您可以删除ScraperThread
现在唯一要做的是,您需要确保_on_scrape()
快速完成,否则您将积压计时器事件。
或者,您也可以这样做:self.scrape_timer.Start(1000, oneShot = True)
并让_on_scrape()
也以该行结束,这样每个http请求之间会有一秒钟的延迟。