错误的构造或循环崩溃?

Posted

技术标签:

【中文标题】错误的构造或循环崩溃?【英文标题】:Wrong construction or maybe loop crashes? 【发布时间】:2013-05-18 10:02:58 【问题描述】:

我正在尝试实现我的项目目标并将我的模块连接到带有按钮的窗口应用程序中。我不知道到目前为止我错过了什么,但肯定有问题,因为当我的程序运行时,主框架崩溃了,没有响应,Shell 输出工作但不可能输入任何东西......我想我应该向您展示所有代码,因为我不知道确切的部分是错误的。我使用 boa 构造函数来节省一些时间来创建框架。 启动应用程序如下所示:

应用1:

import wx

import Frame1

modules ='Frame1': [1, 'Main frame of Application', u'Frame1.py'],
 u'botcordxy': [0, u'x, y values', u'botcordxy.py']

class BoaApp(wx.App):
    def OnInit(self):
        self.main = Frame1.create(None)
        self.main.Show()
        self.SetTopWindow(self.main)
        return True

def main():
    application = BoaApp(0)
    application.MainLoop()

if __name__ == '__main__':
    main()

我不确定,但我认为上面的内容是正确的,如果不是,请告诉我。

Frame1.py:

import wx

def create(parent):
    return Frame1(parent)

[wxID_FRAME1, wxID_FRAME1BUTTON1, wxID_FRAME1PANEL1, 
] = [wx.NewId() for _init_ctrls in range(3)]

class Frame1(wx.Frame):
    def _init_ctrls(self, prnt):
        wx.Frame.__init__(self, id=wxID_FRAME1, name=u'Frame1', parent=prnt,
              pos=wx.Point(-1, 291), size=wx.Size(250, 480),
              style=wx.DEFAULT_FRAME_STYLE, title=u'ZulithBot')
        self.SetClientSize(wx.Size(242, 446))
        self.Bind(wx.EVT_BUTTON, self.Firefox, id=wxID_FRAME1BUTTON1)

        self.panel1 = wx.Panel(id=wxID_FRAME1PANEL1, name='panel1', parent=self,
              pos=wx.Point(0, 0), size=wx.Size(242, 446),
              style=wx.TAB_TRAVERSAL)

        self.button1 = wx.Button(id=wxID_FRAME1BUTTON1,
              label=u'Start Firefox', name='button1', parent=self.panel1,
              pos=wx.Point(80, 24), size=wx.Size(88, 23), style=0)

    def Firefox(self, event):
        import botcordxy
    def __init__(self, parent):
        self._init_ctrls(parent)

现在,最后一个:

botcordxy.py

import selenium
from selenium import webdriver
import time

##The name of website has been changed just in care.

driver = webdriver.Firefox()
driver.get('http://example.com//')

def repeat():
    while 1 == 1:
        botloc = driver.find_element_by_id('botloc').text
        botX,botY = map(int,botloc.split(','))
        print botX
        print botY
        print botloc

def checker():
    if driver.current_url == 'http://logged.example.com//':
        repeat()
    else:
        time.sleep(5)
        checker()

checker()

至于最后一部分,从这里开始走楼梯,很多问题,很多编辑,大量时间投入到活动中......

当我运行程序并登录Webdriver浏览器时,然后Shell显示我想要获取的值:

32
59
32,59
31
59
31,59
31
58
31,58

一遍又一遍地打印 botloc、botx 和 boty,所以应用程序仍在破坏,但它被冻结,直到我使用 ctrl + C 才能控制,Frame1 完全不可用...... 是不是有很多东西不见了? def 响应循环可以这样操作吗?你能帮我解决这个问题吗?

【问题讨论】:

【参考方案1】:

在编写 wxPython 应用程序时,您必须确保您定义的任何事件处理函数能够快速返回,否则应用程序将无法处理任何其他事件,例如重新绘制框架,并且您的程序将变得无响应。

问题是这个事件处理程序...

def Firefox(self, event):
    import botcordxy

...最终导致这个无限循环运行...

while 1 == 1:
    botloc = driver.find_element_by_id('botloc').text
    botX,botY = map(int,botloc.split(','))
    print botX
    print botY
    print botloc

...所以控制将永远不会返回到主事件循环,并且主框架看起来会被冻结。

一个快速的“肮脏”解决方案是使用wx.Yield() 暂时将控制权交给循环内的事件处理程序,就像这样......

import wx
while 1 == 1:
    botloc = driver.find_element_by_id('botloc').text
    botX,botY = map(int,botloc.split(','))
    print botX
    print botY
    print botloc
    wx.Yield()

...让应用程序有机会处理其他事件,但您最好使用wx.Timer 定期调用您的driver.find_element_by_id(...)

【讨论】:

非常感谢。关于 wx.Timer... 可以用 wx.Timer 创建类似的东西: if key_pressed_arrowup: then update botloc from div again? @Mezulith 好吧,如果您只想每次按键执行一次更新,那么您真的不需要计时器。目前还不清楚你要做什么,但看起来你只是需要一些东西来打破while 循环,一旦你得到botloc 的正确值,而不是无限期地运行它。 我完全同意你所说的,我不需要 wx.Timer,我需要的中断应该基于以下内容:如果 botloc = last botloc then break,我不确定,但我认为我应该使用 botloc 值创建存储,然后在按下箭头键后再次启动事件......但奇怪的是新错误即将到来 `botX,botY = map(int,botloc.split(',')) ValueError: invalid literal for int() with base 10: ''` 我必须在 shell 中手动运行 repeat(),如何解决? @Mezulith 如果您遇到新问题,最好打开一个新问题,将其限制在您遇到问题的代码部分。 已经自己解决了新问题,谢谢你的好回答。

以上是关于错误的构造或循环崩溃?的主要内容,如果未能解决你的问题,请参考以下文章

bug的严重级别和优先级

“纯虚函数调用”崩溃从何而来?

C++:循环菜单切换

Python 和 matplotlib:当我尝试导入时,它发送一个无效的循环器构造错误

分段错误和神秘的循环行为

Unity 在函数调用后崩溃。是数组索引错误吗? [复制]