I tried to create my own browser with wxPython and CEFPython. The browser can have multiple tabs and in each tab chromeWindow should be opened. The part of the code is as the following.
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)
...
Each tab should use the cefpython.CreateBrowserSync() in the code. After I run the code, the following error occured. I have no idea about how to fix it.
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
If anyone knows about this issue, please help me.