1
+
# Example of embedding CEF Python browser using PyGTK library (GTK 2).
2
+
# Tested with GTK 2.24 and CEF Python v54+.
3
+
4
+
from cefpython3 import cefpython as cef
5
+
import pygtk
6
+
import gtk
7
+
import gobject
8
+
import sys
9
+
import time
10
+
11
+
# In CEF you can run message loop in two ways (see API docs for more details):
12
+
# 1. By calling cef.MessageLoop() instead of an application-provided
13
+
# message loop to get the best balance between performance and CPU
14
+
# usage. This function will block until a quit message is received by
15
+
# the system.
16
+
# 2. By calling cef.MessageLoopWork() in a timer - each call performs
17
+
# a single iteration of CEF message loop processing.
18
+
MESSAGE_LOOP_BEST = 1
19
+
MESSAGE_LOOP_TIMER = 2 # Pass --message-loop-timer flag to script to use this
20
+
g_message_loop = None
21
+
22
+
23
+
def main():
24
+
check_versions()
25
+
sys.excepthook = cef.ExceptHook # To shutdown all CEF processes on error
26
+
configure_message_loop()
27
+
cef.Initialize()
28
+
gobject.threads_init()
29
+
Gtk2Example()
30
+
if g_message_loop == MESSAGE_LOOP_BEST:
31
+
cef.MessageLoop()
32
+
else:
33
+
gtk.main()
34
+
cef.Shutdown()
35
+
36
+
37
+
def check_versions():
38
+
print("CEF Python {ver}".format(ver=cef.__version__))
39
+
print("Python {ver}".format(ver=sys.version[:6]))
40
+
print("GTK {ver}".format(ver='.'.join(map(str, list(gtk.gtk_version)))))
41
+
assert cef.__version__ >= "54.0", "CEF Python v54+ required to run this"
42
+
pygtk.require('2.0')
43
+
44
+
45
+
def configure_message_loop():
46
+
global g_message_loop
47
+
if "--message-loop-timer" in sys.argv:
48
+
print("Message loop mode: TIMER")
49
+
g_message_loop = MESSAGE_LOOP_TIMER
50
+
sys.argv.remove("--message-loop-timer")
51
+
else:
52
+
print("Message loop mode: BEST")
53
+
g_message_loop = MESSAGE_LOOP_BEST
54
+
if len(sys.argv) > 1:
55
+
print("ERROR: unknown argument passed")
56
+
sys.exit(1)
57
+
58
+
59
+
class Gtk2Example:
60
+
61
+
def __init__(self):
62
+
self.menubar_height = 0
63
+
self.exiting = False
64
+
65
+
self.main_window = gtk.Window(gtk.WINDOW_TOPLEVEL)
66
+
self.main_window.connect('focus-in-event', self.on_focus_in)
67
+
self.main_window.connect('configure-event', self.on_configure)
68
+
self.main_window.connect('destroy', self.on_exit)
69
+
self.main_window.set_size_request(width=800, height=600)
70
+
self.main_window.set_title('GTK 2 example (PyGTK)')
71
+
self.main_window.realize()
72
+
73
+
self.vbox = gtk.VBox(False, 0)
74
+
self.vbox.connect('size-allocate', self.on_vbox_size_allocate)
75
+
self.menubar = self.create_menu()
76
+
self.menubar.connect('size-allocate', self.on_menubar_size_allocate)
77
+
self.vbox.pack_start(self.menubar, False, False, 0)
78
+
self.main_window.add(self.vbox)
79
+
80
+
windowInfo = cef.WindowInfo()
81
+
windowInfo.SetAsChild(self.main_window.window.xid)
82
+
self.browser = cef.CreateBrowserSync(windowInfo, settings={},
83
+
url="https://www.google.com/")
84
+
85
+
self.vbox.show()
86
+
self.main_window.show()
87
+
self.vbox.get_window().focus()
88
+
self.main_window.get_window().focus()
89
+
if g_message_loop == MESSAGE_LOOP_TIMER:
90
+
gobject.timeout_add(10, self.on_timer)
91
+
92
+
def create_menu(self):
93
+
item1 = gtk.MenuItem('MenuBar')
94
+
item1.show()
95
+
item1_0 = gtk.Menu()
96
+
item1_1 = gtk.MenuItem('Just a menu')
97
+
item1_0.append(item1_1)
98
+
item1_1.show()
99
+
item1.set_submenu(item1_0)
100
+
menubar = gtk.MenuBar()
101
+
menubar.append(item1)
102
+
menubar.show()
103
+
return menubar
104
+
105
+
def on_timer(self):
106
+
if self.exiting:
107
+
return False
108
+
cef.MessageLoopWork()
109
+
return True
110
+
111
+
def on_focus_in(self, *_):
112
+
if self.browser:
113
+
self.browser.SetFocus(True)
114
+
return True
115
+
return False
116
+
117
+
def on_configure(self, *_):
118
+
if self.browser:
119
+
self.browser.NotifyMoveOrResizeStarted()
120
+
return False
121
+
122
+
def on_vbox_size_allocate(self, _, data):
123
+
if self.browser:
124
+
x = data.x
125
+
y = data.y + self.menubar_height
126
+
width = data.width
127
+
height = data.height - self.menubar_height
128
+
self.browser.SetBounds(x, y, width, height)
129
+
130
+
def on_menubar_size_allocate(self, _, data):
131
+
self.menubar_height = data.height
132
+
133
+
def on_exit(self, *_):
134
+
self.exiting = True
135
+
self.browser.CloseBrowser(True)
136
+
self.browser = None
137
+
if g_message_loop == MESSAGE_LOOP_BEST:
138
+
# Run some message loop work for the browser to close cleanly
139
+
for i in range(0, 10):
140
+
cef.MessageLoopWork()
141
+
time.sleep(0.01)
142
+
cef.QuitMessageLoop()
143
+
else:
144
+
gtk.main_quit()
145
+
146
+
147
+
if __name__ == '__main__':
148
+
main()
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4