X Tutup
Skip to content

Commit 7ff8973

Browse files
committed
Added Qt example on Linux (Issue 88).
Exposed some of the GTK API to WindowUtils.
1 parent 8915d8f commit 7ff8973

File tree

5 files changed

+334
-56
lines changed

5 files changed

+334
-56
lines changed

cefpython/cef3/linux/binaries_64bit/pyqt-todo.py renamed to cefpython/cef3/linux/binaries_32bit/pyqt.py

Lines changed: 76 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,6 @@
1-
# This example is throwing segmentation faults when run on Linux,
2-
# the problem seems to be in a call to CreateBrowserSync(),
3-
# the backtrace leads to CefBrowserHostImpl::PlatformCreateWindow().
4-
# Full backtrace:
5-
"""
6-
0x00007ffff1ee52a0 in CefBrowserHostImpl::PlatformCreateWindow() ()
7-
from /home/czarek/cefpython/cefpython/cef3/linux/binaries_64bit/libcef.so
8-
(gdb) backtrace
9-
#0 0x00007ffff1ee52a0 in CefBrowserHostImpl::PlatformCreateWindow() ()
10-
from /home/czarek/cefpython/cefpython/cef3/linux/binaries_64bit/libcef.so
11-
#1 0x00007ffff1e24930 in CefBrowserHostImpl::Create(CefWindowInfo const&, CefStructBase<CefBrowserSettingsTraits> const&, CefRefPtr<CefClient>, content::WebContents*, scoped_refptr<CefBrowserInfo>, _GtkWidget*) ()
12-
from /home/czarek/cefpython/cefpython/cef3/linux/binaries_64bit/libcef.so
13-
#2 0x00007ffff1e251ec in CefBrowserHost::CreateBrowserSync(CefWindowInfo const&, CefRefPtr<CefClient>, CefStringBase<CefStringTraitsUTF16> const&, CefStructBase<CefBrowserSettingsTraits> const&) ()
14-
from /home/czarek/cefpython/cefpython/cef3/linux/binaries_64bit/libcef.so
15-
#3 0x00007ffff1dc9fec in cef_browser_host_create_browser_sync ()
16-
from /home/czarek/cefpython/cefpython/cef3/linux/binaries_64bit/libcef.so
17-
#4 0x00007fffe8136e4f in CefBrowserHost::CreateBrowserSync(CefWindowInfo const&, CefRefPtr<CefClient>, CefStringBase<CefStringTraitsUTF16> const&, CefStructBase<CefBrowserSettingsTraits> const&) ()
18-
from /home/czarek/cefpython/cefpython/cef3/linux/binaries_64bit/cefpython_py27.so
19-
#5 0x00007fffe8111cce in __pyx_pf_14cefpython_py27_16CreateBrowserSync (
20-
__pyx_v_windowInfo=<cefpython_py27.WindowInfo at remote 0xdc7fb0>,
21-
__pyx_v_browserSettings=<optimized out>, __pyx_v_navigateUrl=
22-
'file:///home/czarek/cefpython/cefpython/cef3/linux/binaries_64bit/example.html', __pyx_self=<optimized out>) at cefpython.cpp:65142
23-
#6 0x00007fffe8114ea6 in __pyx_pw_14cefpython_py27_17CreateBrowserSync (
24-
"""
25-
26-
# An example of embedding CEF Python in PyQt4 application.
27-
28-
# On Ubuntu install the "python-qt4" package.
29-
# Tested with version 4.9.1-2ubuntu1.
1+
# An example of embedding the CEF browser in a PyQt4 application.
2+
# Tested with PyQt "4.9.1".
3+
# Command for installing PyQt4: "sudo apt-get install python-qt4".
304

315
# The official CEF Python binaries come with tcmalloc hook
326
# disabled. But if you've built custom binaries and kept tcmalloc
@@ -38,22 +12,20 @@
3812
import ctypes, os, sys
3913
libcef_so = os.path.join(os.path.dirname(os.path.abspath(__file__)),\
4014
'libcef.so')
41-
# Import a local module if exists, otherwise import from
42-
# an installed package.
4315
if os.path.exists(libcef_so):
16+
# Import local module
4417
ctypes.CDLL(libcef_so, ctypes.RTLD_GLOBAL)
4518
if 0x02070000 <= sys.hexversion < 0x03000000:
4619
import cefpython_py27 as cefpython
4720
else:
4821
raise Exception("Unsupported python version: %s" % sys.version)
4922
else:
23+
# Import from package
5024
from cefpython3 import cefpython
5125

5226
from PyQt4 import QtGui
5327
from PyQt4 import QtCore
5428

55-
TEST_RESPONSE_READING = False
56-
5729
def GetApplicationPath(file=None):
5830
import re, os, platform
5931
# If file is None return current directory without trailing slash.
@@ -94,7 +66,7 @@ def ExceptHook(excType, excValue, traceObject):
9466
fp.write("\n[%s] %s\n" % (
9567
time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg))
9668
except:
97-
print("cefpython: WARNING: failed writing to error file: %s" % (
69+
print("[wxpython.py] WARNING: failed writing to error file: %s" % (
9870
errorFile))
9971
# Convert error message to ascii before printing, otherwise
10072
# you may get error like this:
@@ -126,31 +98,65 @@ def createMenu(self):
12698
aboutmenu = menubar.addMenu("&About")
12799

128100
def focusInEvent(self, event):
129-
cefpython.WindowUtils.OnSetFocus(
130-
int(self.centralWidget().winId()), 0, 0, 0)
101+
# cefpython.WindowUtils.OnSetFocus(
102+
# int(self.centralWidget().winId()), 0, 0, 0)
103+
pass
131104

132105
def closeEvent(self, event):
133106
self.mainFrame.browser.CloseBrowser()
134107

135-
class MainFrame(QtGui.QWidget):
108+
class MainFrame(QtGui.QX11EmbedContainer):
136109
browser = None
110+
plug = None
137111

138112
def __init__(self, parent=None):
139113
super(MainFrame, self).__init__(parent)
114+
115+
# QX11EmbedContainer provides an X11 window. The CEF
116+
# browser can be embedded only by providing a GtkWidget
117+
# pointer. So we're embedding a GtkPlug inside the X11
118+
# window. In latest CEF trunk it is possible to embed
119+
# the CEF browser by providing X11 window id. So it will
120+
# be possible to remove the GTK dependency from CEF
121+
# Python in the future.
122+
gtkPlugPtr = cefpython.WindowUtils.gtk_plug_new(\
123+
int(self.winId()))
124+
print("[pyqt.py] MainFrame: GDK Native Window id: "+str(self.winId()))
125+
print("[pyqt.py] MainFrame: GTK Plug ptr: "+str(gtkPlugPtr))
126+
127+
"""
128+
Embedding GtkPlug is also possible with the pygtk module.
129+
---------------------------------------------------------
130+
self.plug = gtk.Plug(self.winId())
131+
import re
132+
m = re.search("GtkPlug at 0x(\w+)", str(self.plug))
133+
hexId = m.group(1)
134+
gtkPlugPtr = int(hexId, 16)
135+
...
136+
plug.show()
137+
self.show()
138+
---------------------------------------------------------
139+
"""
140+
140141
windowInfo = cefpython.WindowInfo()
141-
windowInfo.SetAsChild(int(self.winId()))
142+
# Need to pass to CEF the GtkWidget* pointer
143+
windowInfo.SetAsChild(gtkPlugPtr)
142144
# Linux requires adding "file://" for local files,
143145
# otherwise /home/some will be replaced as http://home/some
144146
self.browser = cefpython.CreateBrowserSync(windowInfo,
145147
browserSettings={},
146148
navigateUrl="file://"+GetApplicationPath("example.html"))
149+
150+
cefpython.WindowUtils.gtk_widget_show(gtkPlugPtr)
147151
self.show()
148152

149153
def moveEvent(self, event):
150-
cefpython.WindowUtils.OnSize(int(self.winId()), 0, 0, 0)
154+
# cefpython.WindowUtils.OnSize(int(self.winId()), 0, 0, 0)
155+
pass
151156

152157
def resizeEvent(self, event):
153-
cefpython.WindowUtils.OnSize(int(self.winId()), 0, 0, 0)
158+
# cefpython.WindowUtils.OnSize(int(self.winId()), 0, 0, 0)
159+
pass
154160

155161
class CefApplication(QtGui.QApplication):
156162
timer = None
@@ -183,22 +189,39 @@ def stopTimer(self):
183189
self.timer.stop()
184190

185191
if __name__ == '__main__':
186-
print("PyQt version: %s" % QtCore.PYQT_VERSION_STR)
187-
print("QtCore version: %s" % QtCore.qVersion())
192+
print("[pyqt.py] PyQt version: %s" % QtCore.PYQT_VERSION_STR)
193+
print("[pyqt.py] QtCore version: %s" % QtCore.qVersion())
188194

195+
# Intercept python exceptions. Exit app immediately when exception
196+
# happens on any of the threads.
189197
sys.excepthook = ExceptHook
190198

191-
settings = {}
192-
settings["debug"] = True # cefpython messages in console and in log_file
193-
settings["log_file"] = GetApplicationPath("debug.log")
194-
settings["log_severity"] = cefpython.LOGSEVERITY_INFO
195-
settings["release_dcheck_enabled"] = True # Enable only when debugging
196-
settings["locales_dir_path"] = cefpython.GetModuleDirectory()+"/locales"
197-
settings["resources_dir_path"] = cefpython.GetModuleDirectory()
198-
settings["browser_subprocess_path"] = "%s/%s" % (
199-
cefpython.GetModuleDirectory(), "subprocess")
200-
201-
cefpython.Initialize(settings)
199+
# Application settings
200+
settings = {
201+
"debug": True, # cefpython debug messages in console and in log_file
202+
"log_severity": cefpython.LOGSEVERITY_INFO, # LOGSEVERITY_VERBOSE
203+
"log_file": GetApplicationPath("debug.log"), # Set to "" to disable.
204+
"release_dcheck_enabled": True, # Enable only when debugging.
205+
# This directories must be set on Linux
206+
"locales_dir_path": cefpython.GetModuleDirectory()+"/locales",
207+
"resources_dir_path": cefpython.GetModuleDirectory(),
208+
"browser_subprocess_path": "%s/%s" % (
209+
cefpython.GetModuleDirectory(), "subprocess"),
210+
# This option is required for the GetCookieManager callback
211+
# to work. It affects renderer processes, when this option
212+
# is set to True. It will force a separate renderer process
213+
# for each browser created using CreateBrowserSync.
214+
"unique_request_context_per_browser": True
215+
}
216+
217+
# Command line switches set programmatically
218+
switches = {
219+
# "proxy-server": "socks5://127.0.0.1:8888",
220+
# "enable-media-stream": "",
221+
# "--invalid-switch": "" -> Invalid switch name
222+
}
223+
224+
cefpython.Initialize(settings, switches)
202225

203226
app = CefApplication(sys.argv)
204227
mainWindow = MainWindow()

0 commit comments

Comments
 (0)
X Tutup