Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 27 additions & 3 deletions vpython/no_notebook.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .vpython import GlowWidget, baseObj, vector, canvas
from .vpython import GlowWidget, baseObj, vector, canvas, _browsertype
from ._notebook_helpers import _in_spyder, _undo_vpython_import_in_spyder

from http.server import BaseHTTPRequestHandler, HTTPServer
Expand All @@ -13,6 +13,8 @@
import txaio
import copy
import socket
import multiprocessing


import signal
from urllib.parse import unquote
Expand Down Expand Up @@ -148,7 +150,7 @@ def onOpen(self):
# in favor of "async def onMessage...", and "yield from" with "await".
# Attempting to use the older Python 3.4 syntax was not successful, so this
# no-notebook version of VPython requires Python 3.5.3 or later.
#@asyncio.coroutine
# @asyncio.coroutine
# def onMessage(self, data, isBinary): # data includes canvas update, events, pick, compound
# data includes canvas update, events, pick, compound
async def onMessage(self, data, isBinary):
Expand Down Expand Up @@ -231,10 +233,32 @@ def onClose(self, wasClean, code, reason):
else:
__server = HTTPServer(('', __HTTP_PORT), serveHTTP)
# or webbrowser.open_new_tab()
_webbrowser.open('http://localhost:{}'.format(__HTTP_PORT))
if _browsertype == 'default': # uses default browser
_webbrowser.open('http://localhost:{}'.format(__HTTP_PORT))

except:
pass


if platform.python_implementation() == 'PyPy' and _browsertype == 'pyqt':
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@atitus -- does this look OK to you for PyPy error handling? It doesn't avoid an error but it does give a fairly explicit error message. I'm a little reluctant to have PyPy automagically ignore the pyqt browser setting because I imagine it will lead to confusion about why the regular browser is opening, but it would be straightforward to make that happen.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's fine with me. I don't know for sure that using PyPy and the pyqt browser are incompatible. I just know that the way I originally implemented pyqt in no_notebook.py was solely for non-PyPy cases. It's possible that you or someone else might implement pyqt in a way that is compatible with PyPy.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK; I'll merge tomorrow morning to give folks a bit of time to make comments.

raise RuntimeError('The pyqt browser cannot be used PyPy. Please use '
'the default browser instead by removing '
'set_browser("pyqt") from your code.')


def start_Qapp(port):
# creates a python browser with PyQt5
# runs qtbrowser.py in a separate process
filepath = os.path.dirname(__file__)
filename = filepath + '/qtbrowser.py'
os.system('python ' + filename + ' http://localhost:{}'.format(port))


# create a browser in its own process
if _browsertype == 'pyqt':
__m = multiprocessing.Process(target=start_Qapp, args=(__HTTP_PORT,))
__m.start()

__w = threading.Thread(target=__server.serve_forever)
__w.start()

Expand Down
25 changes: 25 additions & 0 deletions vpython/qtbrowser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import sys
import PyQt5.QtCore
import PyQt5.QtWebEngineWidgets
from PyQt5.QtWidgets import QApplication


if len(sys.argv) > 1:

if sys.argv[1]:

app = QApplication(sys.argv)

web = PyQt5.QtWebEngineWidgets.QWebEngineView()
web.load(PyQt5.QtCore.QUrl(sys.argv[1]))
web.show()

sys.exit(app.exec_())

else:
print("Please give a URL as the first command-line argument "
"when running the program.")

else:
print("Please give a URL as the first command-line argument "
"when running the program.")
21 changes: 19 additions & 2 deletions vpython/vpython.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
'event_return', 'extrusion', 'faces', 'frame', 'gcurve', 'gdots',
'ghbars', 'gobj', 'graph', 'gvbars', 'helix', 'label',
'local_light', 'menu', 'meta_canvas', 'points', 'pyramid',
'quad', 'radio', 'ring', 'simple_sphere', 'sleep', 'slider', 'sphere',
'quad', 'radio', 'ring', 'set_browser', 'simple_sphere', 'sleep', 'slider', 'sphere',
'standardAttributes', 'text', 'textures', 'triangle', 'vertex',
'wtext', 'winput', 'keysdown']

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

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

@property
def integrate_selected(self): return self._integrate_selected
@integrate_selected.setter
def integrate_selected(self,val):
self._integrate_selected = val
self.addattr('integrate_selected')

class gvbars(gobj):
def __init__(self, **args):
args['_objName'] = "gvbars"
Expand Down Expand Up @@ -4118,3 +4126,12 @@ def keysdown():
for k in keysdownlist: # return a copy of keysdownlist
keys.append(k)
return keys

# global variable for type of web browser to display vpython
_browsertype = 'default'
def set_browser(type='default'):
global _browsertype
if type=='pyqt':
_browsertype='pyqt'
else:
_browsertype='default'
2 changes: 1 addition & 1 deletion vpython/vpython_libraries/glow.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion vpython/vpython_libraries/glowcomm.html
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@
'p':'left', 'q':'right', 'r':'top', 's':'bottom', 't':'_cloneid',
'u':'logx', 'v':'logy', 'w':'dot', 'x':'dot_radius',
'y':'markers', 'z':'legend', 'A':'label','B':'delta', 'C':'marker_color',
'D':'size_units', 'E':'userpan', 'F':'scroll'}
'D':'size_units', 'E':'userpan', 'F':'scroll', 'G':'integrate_selected'}

// methods are X in {'m': '23X....'}
var methods = {'a':'select', 'b':'pos', 'c':'start', 'd':'stop', 'f':'clear', // unused eghijklmnopvxyzCDFAB
Expand Down
2 changes: 1 addition & 1 deletion vpython/vpython_libraries/glowcomm.js
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ var attrsb = {'a':'userzoom', 'b':'userspin', 'c':'range', 'd':'autoscale', 'e':
'p':'left', 'q':'right', 'r':'top', 's':'bottom', 't':'_cloneid',
'u':'logx', 'v':'logy', 'w':'dot', 'x':'dot_radius',
'y':'markers', 'z':'legend', 'A':'label','B':'delta', 'C':'marker_color',
'D':'size_units', 'E':'userpan', 'F':'scroll'}
'D':'size_units', 'E':'userpan', 'F':'scroll', 'G':integrate_selected}

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