Skip to content

Commit 11600e0

Browse files
authored
Merge pull request #9 from atitus/master
tSupport for displaying a VPython program (canvas) in a PyQT
2 parents ca59049 + fdae97d commit 11600e0

File tree

6 files changed

+74
-8
lines changed

6 files changed

+74
-8
lines changed

vpython/no_notebook.py

100644100755
Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from .vpython import GlowWidget, baseObj, vector, canvas
1+
from .vpython import GlowWidget, baseObj, vector, canvas, _browsertype
22
from ._notebook_helpers import _in_spyder, _undo_vpython_import_in_spyder
33

44
from http.server import BaseHTTPRequestHandler, HTTPServer
@@ -13,6 +13,8 @@
1313
import txaio
1414
import copy
1515
import socket
16+
import multiprocessing
17+
1618

1719
import signal
1820
from urllib.parse import unquote
@@ -148,7 +150,7 @@ def onOpen(self):
148150
# in favor of "async def onMessage...", and "yield from" with "await".
149151
# Attempting to use the older Python 3.4 syntax was not successful, so this
150152
# no-notebook version of VPython requires Python 3.5.3 or later.
151-
#@asyncio.coroutine
153+
# @asyncio.coroutine
152154
# def onMessage(self, data, isBinary): # data includes canvas update, events, pick, compound
153155
# data includes canvas update, events, pick, compound
154156
async def onMessage(self, data, isBinary):
@@ -231,10 +233,32 @@ def onClose(self, wasClean, code, reason):
231233
else:
232234
__server = HTTPServer(('', __HTTP_PORT), serveHTTP)
233235
# or webbrowser.open_new_tab()
234-
_webbrowser.open('http://localhost:{}'.format(__HTTP_PORT))
236+
if _browsertype == 'default': # uses default browser
237+
_webbrowser.open('http://localhost:{}'.format(__HTTP_PORT))
238+
235239
except:
236240
pass
237241

242+
243+
if platform.python_implementation() == 'PyPy' and _browsertype == 'pyqt':
244+
raise RuntimeError('The pyqt browser cannot be used PyPy. Please use '
245+
'the default browser instead by removing '
246+
'set_browser("pyqt") from your code.')
247+
248+
249+
def start_Qapp(port):
250+
# creates a python browser with PyQt5
251+
# runs qtbrowser.py in a separate process
252+
filepath = os.path.dirname(__file__)
253+
filename = filepath + '/qtbrowser.py'
254+
os.system('python ' + filename + ' http://localhost:{}'.format(port))
255+
256+
257+
# create a browser in its own process
258+
if _browsertype == 'pyqt':
259+
__m = multiprocessing.Process(target=start_Qapp, args=(__HTTP_PORT,))
260+
__m.start()
261+
238262
__w = threading.Thread(target=__server.serve_forever)
239263
__w.start()
240264

vpython/qtbrowser.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import sys
2+
import PyQt5.QtCore
3+
import PyQt5.QtWebEngineWidgets
4+
from PyQt5.QtWidgets import QApplication
5+
6+
7+
if len(sys.argv) > 1:
8+
9+
if sys.argv[1]:
10+
11+
app = QApplication(sys.argv)
12+
13+
web = PyQt5.QtWebEngineWidgets.QWebEngineView()
14+
web.load(PyQt5.QtCore.QUrl(sys.argv[1]))
15+
web.show()
16+
17+
sys.exit(app.exec_())
18+
19+
else:
20+
print("Please give a URL as the first command-line argument "
21+
"when running the program.")
22+
23+
else:
24+
print("Please give a URL as the first command-line argument "
25+
"when running the program.")

vpython/vpython.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
'event_return', 'extrusion', 'faces', 'frame', 'gcurve', 'gdots',
2525
'ghbars', 'gobj', 'graph', 'gvbars', 'helix', 'label',
2626
'local_light', 'menu', 'meta_canvas', 'points', 'pyramid',
27-
'quad', 'radio', 'ring', 'simple_sphere', 'sleep', 'slider', 'sphere',
27+
'quad', 'radio', 'ring', 'set_browser', 'simple_sphere', 'sleep', 'slider', 'sphere',
2828
'standardAttributes', 'text', 'textures', 'triangle', 'vertex',
2929
'wtext', 'winput', 'keysdown']
3030

@@ -97,7 +97,7 @@
9797
'right':'q', 'top':'r', 'bottom':'s', '_cloneid':'t',
9898
'logx':'u', 'logy':'v', 'dot':'w', 'dot_radius':'x',
9999
'markers':'y', 'legend':'z', 'label':'A', 'delta':'B', 'marker_color':'C',
100-
'size_units':'D', 'userpan':'E', 'scroll':'F'}
100+
'size_units':'D', 'userpan':'E', 'scroll':'F', 'integrate_selected':'G'}
101101

102102
# methods are X in {'m': '23X....'}
103103
# pos is normally updated as an attribute, but for interval-based trails, it is updated (multiply) as a method
@@ -2027,6 +2027,7 @@ def setup(self, args):
20272027
self._legend = False
20282028
self._interval = -1
20292029
self._graph = None
2030+
self._integrate_selected = False
20302031
objName = args['_objName']
20312032
del args['_objName']
20322033
self._constructing = True ## calls are from constructor
@@ -2247,6 +2248,13 @@ def __init__(self, **args):
22472248
args['_objName'] = "gdots"
22482249
super(gdots, self).setup(args)
22492250

2251+
@property
2252+
def integrate_selected(self): return self._integrate_selected
2253+
@integrate_selected.setter
2254+
def integrate_selected(self,val):
2255+
self._integrate_selected = val
2256+
self.addattr('integrate_selected')
2257+
22502258
class gvbars(gobj):
22512259
def __init__(self, **args):
22522260
args['_objName'] = "gvbars"
@@ -4131,3 +4139,12 @@ def keysdown():
41314139
for k in keysdownlist: # return a copy of keysdownlist
41324140
keys.append(k)
41334141
return keys
4142+
4143+
# global variable for type of web browser to display vpython
4144+
_browsertype = 'default'
4145+
def set_browser(type='default'):
4146+
global _browsertype
4147+
if type=='pyqt':
4148+
_browsertype='pyqt'
4149+
else:
4150+
_browsertype='default'

vpython/vpython_libraries/glow.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vpython/vpython_libraries/glowcomm.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@
393393
'p':'left', 'q':'right', 'r':'top', 's':'bottom', 't':'_cloneid',
394394
'u':'logx', 'v':'logy', 'w':'dot', 'x':'dot_radius',
395395
'y':'markers', 'z':'legend', 'A':'label','B':'delta', 'C':'marker_color',
396-
'D':'size_units', 'E':'userpan', 'F':'scroll'}
396+
'D':'size_units', 'E':'userpan', 'F':'scroll', 'G':'integrate_selected'}
397397

398398
// methods are X in {'m': '23X....'}
399399
var methods = {'a':'select', 'b':'pos', 'c':'start', 'd':'stop', 'f':'clear', // unused eghijklmnopvxyzCDFAB

vpython/vpython_libraries/glowcomm.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ var attrsb = {'a':'userzoom', 'b':'userspin', 'c':'range', 'd':'autoscale', 'e':
443443
'p':'left', 'q':'right', 'r':'top', 's':'bottom', 't':'_cloneid',
444444
'u':'logx', 'v':'logy', 'w':'dot', 'x':'dot_radius',
445445
'y':'markers', 'z':'legend', 'A':'label','B':'delta', 'C':'marker_color',
446-
'D':'size_units', 'E':'userpan', 'F':'scroll'}
446+
'D':'size_units', 'E':'userpan', 'F':'scroll', 'G':integrate_selected}
447447

448448
// methods are X in {'m': '23X....'}
449449
var methods = {'a':'select', 'b':'pos', 'c':'start', 'd':'stop', 'f':'clear', // unused eghijklmnopvxyzCDFAB

0 commit comments

Comments
 (0)