Skip to content

Commit e0f4bca

Browse files
committed
Refactor
v1.1
1 parent 7887bd0 commit e0f4bca

File tree

7 files changed

+110
-120
lines changed

7 files changed

+110
-120
lines changed

README.md

+13-17
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,22 @@
22

33
pywebview is a lightweight cross-platform wrapper around a webview component that allows to display HTML content in its own native GUI window. It gives you power of web technologies in your desktop application, eliminating the need of launching a web browser. Combined with a lightweight web framework like [Flask](http://flask.pocoo.org/), [Bottle](http://bottlepy.org/docs/dev/index.html) or [web.py](http://webpy.org), you can create beautiful cross-platform HTML5 user interfaces targeting WebKit, while hiding implementation details from the end user. If HTML is not your strong point, you might want to use [REMI](https://github.com/dddomodossola/remi), which allows you to create HTML based interfaces using Python code only.
44

5-
pywebview is lightweight and has no dependencies on an external GUI framework. It uses native GUI for creating a web component window: Win32 on Windows, Cocoa on Mac OSX and Qt4/5 or GTK3 on Linux. If you choose to freeze your application, it does not bundle a heavy GUI toolkit with it keeping the executable size small. Compatible with both Python 2 and 3.
5+
pywebview is lightweight and has no dependencies on an external GUI framework. It uses native GUI for creating a web component window: Win32 on Windows, Cocoa on Mac OSX and Qt4/5 or GTK3 on Linux. If you choose to freeze your application, it does not bundle a heavy GUI toolkit with it keeping the executable size small. Compatible with both Python 2 and 3. While Android is not supported, you can use the same codebase with solutions like [Python for Android](https://github.com/kivy/python-for-android) for creating an APK.
66

77
An example application created with pywebview can be found here https://github.com/r0x0r/traktorlibrarian
8-
If you have built an app using pywebview, please do not hesitate to tell about it.
8+
If you have built an app using pywebview, please do not hesitate to showcase it.
99

1010

1111
# License
1212

1313
The BSD license
1414

1515

16-
1716
# Installation
1817

1918
pip install pywebview
2019

20+
2121
# Contributions and bug reports
2222

2323
Help, PRs and donations are welcome. If you found a bug, please test it first in a web-browser that is used by default for your operating system to see if the problem is with your code, rather than pywebview. Feature requests are welcome, but nothing is guaranteed.
@@ -72,33 +72,29 @@ For more elaborated usage, refer to the examples in the examples folder
7272

7373
For OS X and Linux systems you get WebKit. The actual version depends on the version of installed Safari on OS X and QT / GTK on Linux. Note that WebKit bundled with QT / GTK is slightly out of date comparing to the latest Safari or Chrome.
7474

75-
For Windows, you get MSHTML (Trident) in all its glory. The version depends on the installed version of Internet Explorer. By default, when creating an embedded web component, MSHTML uses IE7 rendering mode. To overcome this feature, a registry setting is modified to use the latest installed version of Internet Explorer. Note that for Windows XP systems, you cannot get anything better than IE8. For Vista, you are limited to IE9.
75+
For Windows, you get MSHTML (Trident) in all its glory. The version depends on the installed version of Internet Explorer. For Windows XP systems, you cannot get anything better than IE8. For Vista, you are limited to IE9. For Windows 7/8/10, you will get the latest installed version. EdgeHTML is not yet supported on Windows 10, as it requires a .NET interface. This is planned for future versions for pywebvview.
7676

77-
In Windows 10, IE11 is used as a renderer. EdgeHTML does not support COM interface, but requires a .NET implementation. This is planned for future versions for pywebvview.
7877

78+
# How do I freeze my application?
7979

80-
# Cache issues
80+
Use py2app on OS X and py2exe/pyinstaller on Windows. For reference setup.py files, look in `examples/py2app_setup.py` and `examples/py2exe_setup.py`
8181

82-
Web renderer might cache your code and fail to invalidate it, when it is updated. To prevent that add the following directives to the `<HEAD>` of your HTML files
83-
84-
<meta http-equiv="pragma" content="no-cache">
85-
<meta http-equiv="cache-control" content="no-cache">
86-
<meta http-equiv="expires" content="-1">
87-
8882

89-
# How do I freeze my application?
9083

91-
Use py2app on OS X and py2exe on Windows. For reference setup.py files, look in `examples/py2app_setup.py` and `examples/py2exe_setup.py`
84+
# Changelog
9285

86+
## 1.1
87+
Released 08/06/2016
9388

89+
- `New` [OSX] Add a default application menu #35. Thanks @cuibonobo
90+
- `New` [Linux] GTK is made as default and pypi dependency added. USE_GTK environment variable is also deprecated. To use QT, set `webview.config["USE_QT"] = True`
91+
- `Fix` [Windows] Open folder of create_file_dialog now returns Unicode, instead of byte encoding.
9492

95-
# Changelog
9693

9794
## 1.0.2
9895
Released 19/05/2016
9996

100-
- `Fix` [Windows] Fix a dead-lock that sometimes occurs on a window creation, when used with a HTTP server running in a
101-
separate thread.
97+
- `Fix` [Windows] Fix a dead-lock that sometimes occurs on a window creation, when used with a HTTP server running in a separate thread.
10298

10399

104100
## 1.0.1

setup.py

+27-25
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,40 @@
44

55
install_requires = []
66
if platform.system() == "Windows":
7-
install_requires = ['comtypes', 'pypiwin32']
7+
install_requires = ["comtypes", "pypiwin32"]
88
elif platform.system() == "Darwin":
9-
install_requires = ['pyobjc']
9+
install_requires = ["pyobjc"]
10+
elif platform.system() == "Linux":
11+
install_requires = ["pygobject"]
1012

1113
setup(
12-
name='pywebview',
13-
author='Roman Sirokov',
14+
name="pywebview",
15+
author="Roman Sirokov",
1416
author_email = "[email protected]",
1517
description = ("A cross-platform lightweight native wrapper around a web view component"),
1618
url = "http://github.com/r0x0r/pywebview",
17-
download_url = 'https://github.com/r0x0r/pywebview/archive/1.0.2.tar.gz',
18-
keywords = ['gui', 'webkit', 'html', 'web'],
19+
download_url = "https://github.com/r0x0r/pywebview/archive/1.1.tar.gz",
20+
keywords = ["gui", "webkit", "html", "web"],
1921
install_requires = install_requires,
20-
version='1.0.2',
21-
packages=['webview',],
22-
license='New BSD license',
22+
version="1.1",
23+
packages=["webview",],
24+
license="New BSD license",
2325
classifiers=[
24-
'Intended Audience :: Developers',
25-
'License :: OSI Approved :: BSD License',
26-
'Operating System :: OS Independent',
27-
'Environment :: MacOS X',
28-
'Environment :: Win32 (MS Windows)',
29-
'Environment :: X11 Applications :: GTK',
30-
'Environment :: X11 Applications :: Qt',
31-
'Programming Language :: Python',
32-
'Programming Language :: Python :: 2',
33-
'Programming Language :: Python :: 2.7',
34-
'Programming Language :: Python :: 3',
35-
'Programming Language :: Python :: 3.4',
36-
'Programming Language :: Python :: 3.5',
37-
'Topic :: Software Development :: Libraries :: Application Frameworks',
38-
'Topic :: Software Development :: Libraries :: Python Modules',
39-
'Topic :: Software Development :: User Interfaces'
26+
"Intended Audience :: Developers",
27+
"License :: OSI Approved :: BSD License",
28+
"Operating System :: OS Independent",
29+
"Environment :: MacOS X",
30+
"Environment :: Win32 (MS Windows)",
31+
"Environment :: X11 Applications :: GTK",
32+
"Environment :: X11 Applications :: Qt",
33+
"Programming Language :: Python",
34+
"Programming Language :: Python :: 2",
35+
"Programming Language :: Python :: 2.7",
36+
"Programming Language :: Python :: 3",
37+
"Programming Language :: Python :: 3.4",
38+
"Programming Language :: Python :: 3.5",
39+
"Topic :: Software Development :: Libraries :: Application Frameworks",
40+
"Topic :: Software Development :: Libraries :: Python Modules",
41+
"Topic :: Software Development :: User Interfaces"
4042
],
4143
)

webview/__init__.py

+55-27
Original file line numberDiff line numberDiff line change
@@ -25,33 +25,49 @@
2525
FOLDER_DIALOG = 20
2626
SAVE_DIALOG = 30
2727

28-
if platform.system() == "Darwin":
29-
import webview.cocoa as gui
30-
elif platform.system() == "Linux":
3128

32-
try:
33-
#Try QT first unless USE_GTK variable is defined
34-
if not os.environ.get('USE_GTK'):
35-
import webview.qt as gui
36-
except Exception as e:
37-
logger.warning("QT not found")
38-
import_error = True
39-
else:
40-
import_error = False
29+
config = {
30+
"USE_QT": False
31+
}
32+
33+
_initialized = False
34+
35+
36+
def _initialize_imports():
37+
global _initialized, gui
38+
39+
if not _initialized:
40+
if platform.system() == "Darwin":
41+
import webview.cocoa as gui
42+
elif platform.system() == "Linux":
43+
44+
try:
45+
#Try QT first unless USE_GTK variable is defined
46+
if not config["USE_QT"]:
47+
import webview.gtk as gui
48+
logger.info("Using GTK")
49+
except ImportError as e:
50+
logger.warning("GTK not found")
51+
import_error = True
52+
else:
53+
import_error = False
4154

42-
if import_error or os.environ.get('USE_GTK'):
43-
try:
44-
# If QT is not found, then try GTK
45-
import webview.gtk as gui
46-
except Exception as e:
47-
# Panic
48-
logger.error("GTK not found")
49-
raise Exception("You must have either QT or GTK with Python extensions installed in order to this library.")
55+
if import_error or config["USE_QT"]:
56+
try:
57+
# If GTK is not found, then try QT
58+
import webview.qt as gui
59+
logger.info("Using QT")
60+
except ImportError as e:
61+
# Panic
62+
logger.error("QT not found")
63+
raise Exception("You must have either QT or GTK with Python extensions installed in order to this library.")
5064

51-
elif platform.system() == "Windows":
52-
import webview.win32 as gui
53-
else:
54-
raise Exception("Unsupported platform. Only Windows, Linux and OS X are supported.")
65+
elif platform.system() == "Windows":
66+
import webview.win32 as gui
67+
else:
68+
raise Exception("Unsupported platform. Only Windows, Linux and OS X are supported.")
69+
70+
_initialized = True
5571

5672

5773

@@ -65,10 +81,15 @@ def create_file_dialog(dialog_type=OPEN_DIALOG, directory='', allow_multiple=Fal
6581
:param save_filename: Default filename for save file dialog.
6682
:return:
6783
"""
84+
6885
if not os.path.exists(directory):
6986
directory = ''
7087

71-
return gui.create_file_dialog(dialog_type, directory, allow_multiple, save_filename)
88+
try:
89+
return gui.create_file_dialog(dialog_type, directory, allow_multiple, save_filename)
90+
except NameError:
91+
raise Exception("Create a web view window first, before invoking this function")
92+
7293

7394

7495
def load_url(url):
@@ -77,7 +98,10 @@ def load_url(url):
7798
created with create_window(). Otherwise an exception is thrown.
7899
:param url: url to load
79100
"""
80-
gui.load_url(url)
101+
try:
102+
gui.load_url(url)
103+
except NameError:
104+
raise Exception("Create a web view window first, before invoking this function")
81105

82106

83107
def create_window(title, url, width=800, height=600, resizable=True, fullscreen=False, min_size=(200, 100)):
@@ -91,14 +115,18 @@ def create_window(title, url, width=800, height=600, resizable=True, fullscreen=
91115
:param resizable True if window can be resized, False otherwise. Default is True.
92116
:return:
93117
"""
118+
_initialize_imports()
94119
gui.create_window(_make_unicode(title), _transform_url(url), width, height, resizable, fullscreen, min_size)
95120

96121

97122
def destroy_window():
98123
"""
99124
Destroy a web view window
100125
"""
101-
gui.destroy_window()
126+
try:
127+
gui.destroy_window()
128+
except NameError:
129+
raise Exception("Create a web view window first, before invoking this function")
102130

103131
def _make_unicode(string):
104132
"""

webview/cocoa.py

+6-15
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,14 @@ def __init__(self, title, url, width, height, resizable, fullscreen, min_size):
9797

9898
self.load_url(url)
9999

100+
# Add the default Cocoa application menu
101+
self._add_app_menu()
102+
100103
if fullscreen:
101104
NSWindowCollectionBehaviorFullScreenPrimary = 128
102105
self.window.setCollectionBehavior_(NSWindowCollectionBehaviorFullScreenPrimary)
103106
self.window.toggleFullScreen_(None)
104107

105-
# Add the default Cocoa application menu
106-
self._add_app_menu()
107-
108108
def show(self):
109109
self.window.display()
110110
self.window.orderFrontRegardless()
@@ -237,21 +237,12 @@ def create_window(title, url, width, height, resizable, fullscreen, min_size):
237237

238238

239239
def create_file_dialog(dialog_type, directory, allow_multiple, save_filename):
240-
if BrowserView.instance is not None:
241-
return BrowserView.instance.create_file_dialog(dialog_type, directory, allow_multiple, save_filename)
242-
else:
243-
raise Exception("Create a web view window first, before invoking this function")
240+
return BrowserView.instance.create_file_dialog(dialog_type, directory, allow_multiple, save_filename)
244241

245242

246243
def load_url(url):
247-
if BrowserView.instance is not None:
248-
BrowserView.instance.load_url(url)
249-
else:
250-
raise Exception("Create a web view window first, before invoking this function")
244+
BrowserView.instance.load_url(url)
251245

252246

253247
def destroy_window():
254-
if BrowserView.instance is not None:
255-
BrowserView.instance.destroy()
256-
else:
257-
raise Exception("Create a web view window first, before invoking this function")
248+
BrowserView.instance.destroy()

webview/gtk.py

+3-12
Original file line numberDiff line numberDiff line change
@@ -118,21 +118,12 @@ def create_window(title, url, width, height, resizable, fullscreen, min_size):
118118

119119

120120
def destroy_window():
121-
if BrowserView.instance is not None:
122-
BrowserView.instance.destroy()
123-
else:
124-
raise Exception("Create a web view window first, before invoking this function")
121+
BrowserView.instance.destroy()
125122

126123

127124
def load_url(url):
128-
if BrowserView.instance is not None:
129-
BrowserView.instance.load_url(url)
130-
else:
131-
raise Exception("Create a web view window first, before invoking this function")
125+
BrowserView.instance.load_url(url)
132126

133127

134128
def create_file_dialog(dialog_type, directory, allow_multiple, save_filename):
135-
if BrowserView.instance is not None:
136-
return BrowserView.instance.create_file_dialog(dialog_type, directory, allow_multiple, save_filename)
137-
else:
138-
raise Exception("Create a web view window first, before invoking this function")
129+
return BrowserView.instance.create_file_dialog(dialog_type, directory, allow_multiple, save_filename)

webview/qt.py

+3-12
Original file line numberDiff line numberDiff line change
@@ -148,21 +148,12 @@ def create_window(title, url, width, height, resizable, fullscreen, min_size):
148148

149149

150150
def load_url(url):
151-
if BrowserView.instance is not None:
152-
BrowserView.instance.load_url(url)
153-
else:
154-
raise Exception("Create a web view window first, before invoking this function")
151+
BrowserView.instance.load_url(url)
155152

156153

157154
def destroy_window():
158-
if BrowserView.instance is not None:
159-
BrowserView.instance.destroy_()
160-
else:
161-
raise Exception("Create a web view window first, before invoking this function")
155+
BrowserView.instance.destroy_()
162156

163157

164158
def create_file_dialog(dialog_type, directory, allow_multiple, save_filename):
165-
if BrowserView.instance is not None:
166-
return BrowserView.instance.create_file_dialog(dialog_type, directory, allow_multiple, save_filename)
167-
else:
168-
raise Exception("Create a web view window first, before invoking this function")
159+
return BrowserView.instance.create_file_dialog(dialog_type, directory, allow_multiple, save_filename)

webview/win32.py

+3-12
Original file line numberDiff line numberDiff line change
@@ -282,24 +282,15 @@ def create_window(title, url, width, height, resizable, fullscreen, min_size):
282282

283283

284284
def create_file_dialog(dialog_type, directory, allow_multiple, save_filename):
285-
if BrowserView.instance is not None:
286-
return BrowserView.instance.create_file_dialog(dialog_type, directory, allow_multiple, save_filename)
287-
else:
288-
raise Exception("Create a web view window first, before invoking this function")
285+
return BrowserView.instance.create_file_dialog(dialog_type, directory, allow_multiple, save_filename)
289286

290287

291288
def load_url(url):
292-
if BrowserView.instance is not None:
293-
BrowserView.instance.load_url(url)
294-
else:
295-
raise Exception("Create a web view window first, before invoking this function")
289+
BrowserView.instance.load_url(url)
296290

297291

298292
def destroy_window():
299-
if BrowserView.instance is not None:
300-
BrowserView.instance.destroy()
301-
else:
302-
raise Exception("Create a web view window first, before invoking this function")
293+
BrowserView.instance.destroy()
303294

304295

305296
def _set_ie_mode():

0 commit comments

Comments
 (0)