Skip to content

Instantly share code, notes, and snippets.

@jl2
Created December 9, 2011 01:43
Show Gist options
  • Save jl2/1449725 to your computer and use it in GitHub Desktop.
Save jl2/1449725 to your computer and use it in GitHub Desktop.
A Javascript REPL using PyQt's QtScript
#!/usr/bin/python3
import sys
from PyQt4 import QtGui
from PyQt4 import QtCore
from PyQt4 import QtScript
from PyQt4.QtScript import QScriptEngine, QScriptValue
def my_exit(context, eng):
exit(0)
show_val = None
def my_print(context, eng):
if context.argumentCount() == 0:
print("")
else:
na = context.argumentCount()
args = list()
for i in range(na):
args.append( str(context.argument(i).toVariant()))
pval = ' '.join(args)
global show_val
print(pval)
show_val(pval)
return QScriptValue("Okay")
class JsRepl(QtGui.QMainWindow):
def __init__(self, parent=None):
super(JsRepl, self).__init__(parent)
self.setWindowTitle("Javascript REPL")
self.resize(800, 800)
self.se = QScriptEngine()
self.add_custom_functions()
self.historyIndex = -1
self.history = list()
global show_val
show_val = lambda x: self.results.append(x)
self.central = QtGui.QWidget()
lay = QtGui.QVBoxLayout()
self.results = QtGui.QTextEdit('')
self.results.setReadOnly(True)
self.inputField = QtGui.QLineEdit('')
self.inputField.editingFinished.connect(self.eval_script)
self.inputField.installEventFilter(self)
lay.addWidget(self.results)
lay.addWidget(self.inputField)
self.central.setLayout(lay)
self.setCentralWidget(self.central)
self.show()
self.inputField.setFocus(True)
def add_custom_functions(self):
# Add exit function
exf = self.se.newFunction(my_exit)
self.se.globalObject().setProperty('exit', exf)
prf = self.se.newFunction(my_print)
self.se.globalObject().setProperty('print', prf)
def eval_script(self):
js = self.inputField.text()
if len(js)==0:
return
self.history.append(js)
self.historyIndex = len(self.history)
self.results.append(js)
res = self.se.evaluate(js)
self.inputField.setText('')
if res.isValid():
if res.isFunction():
self.results.append(' Function')
else:
self.results.append(' ' + str(res.toVariant()))
else:
self.results.append(' Error')
def prev_cmd(self):
if len(self.history)==0:
return
self.historyIndex -= 1
if self.historyIndex >= 0:
self.inputField.setText(self.history[self.historyIndex])
else:
self.inputField.setText(self.history[0])
self.historyIndex = 0
def next_cmd(self):
if len(self.history)==0:
return
self.historyIndex += 1
if self.historyIndex < len(self.history):
self.inputField.setText(self.history[self.historyIndex])
else:
self.inputField.setText('')
self.historyIndex = len(self.history)
def eventFilter(self, obj, event):
if self.inputField == obj:
if event.type() == QtCore.QEvent.KeyPress and event.key() in{ QtCore.Qt.Key_Up,QtCore.Qt.Key_Down}:
if event.key() == QtCore.Qt.Key_Up:
self.prev_cmd()
elif event.key() == QtCore.Qt.Key_Down:
self.next_cmd()
else:
self.historyIndex = len(self.history)-1
return True
else:
return False
return False
def main(args):
app = QtGui.QApplication([])
tv = JsRepl()
sys.exit(app.exec_())
if __name__ == '__main__':
main(sys.argv[1:])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment