1- # Example of embedding CEF browser using PyQt/PySide libraries.
2- # This example has two widgets: a navigation bar and a browser.
1+ # Example of embedding CEF browser using PyQt4, PyQt5 and
2+ # PySide libraries. This example has two widgets: a navigation
3+ # bar and a browser.
34#
45# Tested configurations:
6+ # - PyQt 5.8.2 on Linux
57# - PyQt 4.11 (qt 4.8) on Windows/Linux
68# - PySide 1.2 (qt 4.8) on Windows/Linux/Mac
79# - CEF Python v55.4+
810#
9- # Issues on Mac (tested with PySide) :
11+ # Issues with PySide 1.2 on Mac :
1012# - Keyboard focus issues when switching between controls (Issue #284)
1113# - Mouse cursor never changes when hovering over links (Issue #311)
1214# - Sometimes process hangs when quitting app
1719import platform
1820import sys
1921
22+ # GLOBALS
23+ PYQT4 = False
24+ PYQT5 = False
25+ PYSIDE = False
26+
2027# PyQt imports
21- if "pyqt " in sys .argv :
22- # noinspection PyUnresolvedReferences
28+ if "pyqt4 " in sys .argv :
29+ PYQT4 = True
2330 from PyQt4 .QtGui import *
24- # noinspection PyUnresolvedReferences
2531 from PyQt4 .QtCore import *
32+ elif "pyqt5" in sys .argv :
33+ PYQT5 = True
34+ from PyQt5 .QtGui import *
35+ from PyQt5 .QtCore import *
36+ from PyQt5 .QtWidgets import *
2637# PySide imports
2738elif "pyside" in sys .argv :
28- # noinspection PyUnresolvedReferences
39+ PYSIDE = True
2940 import PySide
30- # noinspection PyUnresolvedReferences
3141 from PySide import QtCore
32- # noinspection PyUnresolvedReferences
3342 from PySide .QtGui import *
34- # noinspection PyUnresolvedReferences
3543 from PySide .QtCore import *
3644else :
3745 print ("USAGE:" )
38- print (" qt4.py pyqt" )
46+ print (" qt4.py pyqt4" )
47+ print (" qt4.py pyqt5" )
3948 print (" qt4.py pyside" )
4049 sys .exit (1 )
4150
5362
5463# OS differences
5564CefWidgetParent = QWidget
56- if LINUX :
57- # noinspection PyUnresolvedReferences
65+ if LINUX and (PYQT4 or PYSIDE ):
5866 CefWidgetParent = QX11EmbedContainer
5967
6068
@@ -78,27 +86,26 @@ def check_versions():
7886 print ("[qt4.py] CEF Python {ver}" .format (ver = cef .__version__ ))
7987 print ("[qt4.py] Python {ver} {arch}" .format (
8088 ver = platform .python_version (), arch = platform .architecture ()[0 ]))
81- # PyQt version
82- if "pyqt" in sys .argv :
83- # noinspection PyUnresolvedReferences
89+ if PYQT4 or PYQT5 :
8490 print ("[qt4.py] PyQt {v1} (qt {v2})" .format (
8591 v1 = PYQT_VERSION_STR , v2 = qVersion ()))
86- # PySide version
87- elif "pyside" in sys .argv :
92+ elif PYSIDE :
8893 print ("[qt4.py] PySide {v1} (qt {v2})" .format (
8994 v1 = PySide .__version__ , v2 = QtCore .__version__ ))
9095 # CEF Python version requirement
91- assert cef .__version__ >= "55.4" , "CEF Python v55.+ required to run this"
96+ assert cef .__version__ >= "55.4" , "CEF Python v55.4 + required to run this"
9297
9398
9499class MainWindow (QMainWindow ):
95100 def __init__ (self ):
96101 super (MainWindow , self ).__init__ (None )
97102 self .cef_widget = None
98103 self .navigation_bar = None
99- if "pyqt" in sys .argv :
100- self .setWindowTitle ("PyQt example" )
101- elif "pyside" in sys .argv :
104+ if PYQT4 :
105+ self .setWindowTitle ("PyQt4 example" )
106+ elif PYQT5 :
107+ self .setWindowTitle ("PyQt5 example" )
108+ elif PYSIDE :
102109 self .setWindowTitle ("PySide example" )
103110 self .setFocusPolicy (Qt .StrongFocus )
104111 self .setupLayout ()
@@ -119,6 +126,10 @@ def setupLayout(self):
119126 self .setCentralWidget (frame )
120127 # Browser can be embedded only after layout was set up
121128 self .cef_widget .embedBrowser ()
129+ if LINUX and PYQT5 :
130+ self .container = QWidget .createWindowContainer (
131+ self .cef_widget .hidden_window , parent = self )
132+ layout .addWidget (self .container , 1 , 0 )
122133
123134 def closeEvent (self , event ):
124135 # Close browser (force=True) and free CEF reference
@@ -137,6 +148,7 @@ def __init__(self, parent=None):
137148 super (CefWidget , self ).__init__ (parent )
138149 self .parent = parent
139150 self .browser = None
151+ self .hidden_window = None # Required for PyQt5 on Linux
140152 self .show ()
141153
142154 def focusInEvent (self , event ):
@@ -154,6 +166,8 @@ def focusOutEvent(self, event):
154166 self .browser .SetFocus (False )
155167
156168 def embedBrowser (self ):
169+ if LINUX and PYQT5 :
170+ self .hidden_window = QWindow ()
157171 window_info = cef .WindowInfo ()
158172 rect = [0 , 0 , self .width (), self .height ()]
159173 window_info .SetAsChild (self .getHandle (), rect )
@@ -163,11 +177,16 @@ def embedBrowser(self):
163177 self .browser .SetClientHandler (FocusHandler (self ))
164178
165179 def getHandle (self ):
166- # PySide bug: QWidget.winId() returns <PyCObject object at 0x02FD8788>
167- # There is no easy way to convert it to int.
180+ # PyQt5 on Linux
181+ if self .hidden_window :
182+ return int (self .hidden_window .winId ())
168183 try :
184+ # PyQt4 and PyQt5
169185 return int (self .winId ())
170186 except :
187+ # PySide:
188+ # | QWidget.winId() returns <PyCObject object at 0x02FD8788>
189+ # | Converting it to int using ctypes.
171190 if sys .version_info [0 ] == 2 :
172191 # Python 2
173192 ctypes .pythonapi .PyCObject_AsVoidPtr .restype = (
@@ -214,7 +233,6 @@ def __init__(self, args):
214233
215234 def createTimer (self ):
216235 timer = QTimer ()
217- # noinspection PyUnresolvedReferences
218236 timer .timeout .connect (self .onTimer )
219237 timer .start (10 )
220238 return timer
@@ -280,25 +298,21 @@ def __init__(self, cef_widget):
280298
281299 # Back button
282300 self .back = self .createButton ("back" )
283- # noinspection PyUnresolvedReferences
284301 self .back .clicked .connect (self .onBack )
285302 layout .addWidget (self .back , 0 , 0 )
286303
287304 # Forward button
288305 self .forward = self .createButton ("forward" )
289- # noinspection PyUnresolvedReferences
290306 self .forward .clicked .connect (self .onForward )
291307 layout .addWidget (self .forward , 0 , 1 )
292308
293309 # Reload button
294310 self .reload = self .createButton ("reload" )
295- # noinspection PyUnresolvedReferences
296311 self .reload .clicked .connect (self .onReload )
297312 layout .addWidget (self .reload , 0 , 2 )
298313
299314 # Url input
300315 self .url = QLineEdit ("" )
301- # noinspection PyUnresolvedReferences
302316 self .url .returnPressed .connect (self .onGoUrl )
303317 layout .addWidget (self .url , 0 , 3 )
304318
0 commit comments