0

我尝试使用 wxPython 和 CEFPython 创建自己的浏览器。浏览器可以有多个选项卡,并且在每个选项卡中都应该打开 chromeWindow。部分代码如下。

def CreateMessageLoopTimer(timerMillis):
    # This function gets called multiple times for each ChromeWindow
    # instance.
    global g_messageLoopTimer
    Debug("CreateMesageLoopTimer")
    if g_messageLoopTimer:
        return
    g_messageLoopTimer = wx.Timer()
    g_messageLoopTimer.Start(timerMillis)
    Debug("g_messageLoopTimer.GetId() = "\
            +str(g_messageLoopTimer.GetId()))

    """ !!!!!!!!!!!!!!!! THIS IS WHERE I GET THE ERROR  !!!!!!!!!!!!!!!!
    wx.EVT_TIMER(g_messageLoopTimer, g_messageLoopTimer.GetId(),\
            MessageLoopTimer)
class ChromeWindow(wx.Window):
    """
    Standalone CEF component. The class provides facilites for interacting
    with wx message loop
    """
    def __init__(self, parent, url="", useTimer=True,
                 timerMillis=DEFAULT_TIMER_MILLIS, browserSettings=None,
                 size=(-1, -1), *args, **kwargs):
        wx.Window.__init__(self, parent, id=wx.ID_ANY, size=size,
                           *args, **kwargs)
        # This timer is not used anymore, but creating it for backwards
        # compatibility. In one of external projects ChromeWindow.timer.Stop()
        # is being called during browser destruction.
        self.timer = wx.Timer()
        # On Linux absolute file urls need to start with "file://"
        # otherwise a path of "/home/some" is converted to "http://home/some".
        if platform.system() in ["Linux", "Darwin"]:
            if url.startswith("/"):
                url = "file://" + url
        self.url = url
        windowInfo = cefpython.WindowInfo()
        if platform.system() == "Windows":
            windowInfo.SetAsChild(self.GetHandle())
        elif platform.system() == "Linux":
            windowInfo.SetAsChild(self.GetGtkWidget())
        elif platform.system() == "Darwin":
            (width, height) = self.GetClientSizeTuple()
            windowInfo.SetAsChild(self.GetHandle(),
                                  [0, 0, width, height])
        else:
            raise Exception("Unsupported OS")
        if not browserSettings:
            browserSettings = {}
        # Disable plugins:
        # | browserSettings["plugins_disabled"] = True
        cefpython.Initialize()
        self.browser = cefpython.CreateBrowserSync(windowInfo,
                browserSettings=browserSettings, navigateUrl=url)
        if platform.system() == "Windows":
            self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
            self.Bind(wx.EVT_SIZE, self.OnSize)
        self._useTimer = useTimer
        if useTimer:
            CreateMessageLoopTimer(timerMillis)
        else:
            # Currently multiple EVT_IDLE events might be registered
            # when creating multiple ChromeWindow instances. This will
            # result in calling CEF message loop work multiple times
            # simultaneously causing performance penalties and possibly
            # some unwanted behavior (CEF Python Issue 129).
            Debug("WARNING: Using EVT_IDLE for CEF message  loop processing"\
                    " is not recommended")
            self.Bind(wx.EVT_IDLE, self.OnIdle)
        self.Bind(wx.EVT_CLOSE, self.OnClose)

class TabBrowser(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, style = wx.WANTS_CHARS)
        self.parent = parent
        button_close1 = wx.Button(self, label="close1", size=(30, 30), pos=(0, -30))
        self.Bind(wx.EVT_BUTTON, self.OnClose, button_close1)    
        # self._browser = html2.WebView.New(self)
        # self._browser.LoadURL("https://www.google.com")
        self._browser = ChromeWindow(self, url="https://www.google.com", useTimer=True)        
        self._navbar = NavBar(self, self._browser)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self._navbar, 0, wx.EXPAND)
        sizer.Add(self._browser, 1, wx.EXPAND)
        self.SetSizer(sizer)
        ch = DefaultClientHandler(self)
        self.SetClientHandler(ch)
        if self.navigationBar:
            self.UpdateButtonsState()

class WebFrame(wx.Frame):
    def __init__(self, parent, title, pos, size):
        super().__init__(parent, title = title, pos = pos, size = size)
        self.setup_icon()

        # Create a panel and notebook (tabs holder)
        p = wx.Panel(self)
        self.nb = fnb.FlatNotebook(p, agwStyle = fnb.FNB_SMART_TABS | fnb.FNB_NAV_BUTTONS_WHEN_NEEDED | fnb.FNB_COLOURFUL_TABS | fnb.FNB_X_ON_TAB)
        self.nb.Bind(wx.EVT_KEY_DOWN, self.onKeyPress)
        self.nb.SetWindowStyleFlag(wx.WANTS_CHARS)
        # Create the tab windows
        tab1 = TabBrowser(self.nb)
        tab2 = TabBrowser(self.nb)
        # Add the windows to tabs and name them.
        self.nb.AddPage(tab1, "New Tab 1")
        self.nb.AddPage(tab2, "New Tab 2")
        # Set noteboook in a sizer to create the layout
        sizer = wx.BoxSizer()
        sizer.Add(self.nb, 1, wx.EXPAND)
        p.SetSizer(sizer)
...

每个选项卡都应在代码中使用 cefpython.CreateBrowserSync()。运行代码后,出现以下错误。我不知道如何解决它。

D:\browser>python webbrowserApp.py
DevTools listening on ws://127.0.0.1:51216/devtools/browser/b1591854-6ec5-4e26-bcf0-1eee5da29700
webbrowserApp.py:38: wxPyDeprecationWarning: Call to deprecated item __call__. Use :meth:`EvtHandler.Bind` instead.
  MessageLoopTimer)
Traceback (most recent call last):
  File "webbrowserApp.py", line 332, in <module>
    app = MyApp()
  File "webbrowserApp.py", line 202, in __init__
    self.InitBrowser()
  File "webbrowserApp.py", line 205, in InitBrowser
    webbrowser = WebFrame(None, "My Web App", pos = (100, 100), size = (WIDTH, HEIGHT))
  File "webbrowserApp.py", line 252, in __init__
    tab1 = TabBrowser(self.nb)
  File "webbrowserApp.py", line 218, in __init__
    self._browser = ChromeWindow(self, url="https://www.google.com", useTimer=True)
  File "webbrowserApp.py", line 120, in __init__
    CreateMessageLoopTimer(timerMillis)
  File "webbrowserApp.py", line 38, in CreateMessageLoopTimer
    MessageLoopTimer)
  File "C:\Python37\lib\site-packages\wx\core.py", line 82, in deprecated_func
    return item(*args)
  File "C:\Python37\lib\site-packages\wx\core.py", line 1504, in __call__
    assert len(args) == 2 + self.expectedIDs
AssertionError

如果有人知道这个问题,请帮助我。

4

1 回答 1

0

不推荐使用该__call__接口。假设这MessageLoopTimer是您想要在计时器到期时调用的函数,那么您可能希望将该行编写为:

g_messageLoopTimer.Bind(wx.EVT_TIMER, MessageLoopTimer)
于 2020-01-07T23:39:05.457 回答