我有一个 PyQT 小部件解释器在工作,代码来自 here如下:
import os
import re
import sys
import code
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class MyInterpreter(QWidget):
def __init__(self, parent):
super(MyInterpreter, self).__init__(parent)
hBox = QHBoxLayout()
self.setLayout(hBox)
self.textEdit = PyInterp(self)
# this is how you pass in locals to the interpreter
self.textEdit.initInterpreter(locals())
self.resize(650, 300)
self.centerOnScreen()
hBox.addWidget(self.textEdit)
hBox.setMargin(0)
hBox.setSpacing(0)
def centerOnScreen(self):
# center the widget on the screen
resolution = QDesktopWidget().screenGeometry()
self.move((resolution.width() / 2) - (self.frameSize().width() / 2),
(resolution.height() / 2) - (self.frameSize().height() / 2))
class PyInterp(QTextEdit):
class InteractiveInterpreter(code.InteractiveInterpreter):
def __init__(self, locals):
code.InteractiveInterpreter.__init__(self, locals)
def runIt(self, command):
code.InteractiveInterpreter.runsource(self, command)
def __init__(self, parent):
super(PyInterp, self).__init__(parent)
sys.stdout = self
sys.stderr = self
self.refreshMarker = False # to change back to >>> from ...
self.multiLine = False # code spans more than one line
self.command = '' # command to be ran
self.printBanner() # print sys info
self.marker() # make the >>> or ... marker
self.history = [] # list of commands entered
self.historyIndex = -1
self.interpreterLocals = {}
# setting the color for bg and text
palette = QPalette()
palette.setColor(QPalette.Base, QColor(0, 0, 0))
palette.setColor(QPalette.Text, QColor(0, 255, 0))
self.setPalette(palette)
self.setFont(QFont('Courier', 12))
# initilize interpreter with self locals
self.initInterpreter(locals())
def printBanner(self):
self.write(sys.version)
self.write(' on ' + sys.platform + '\n')
self.write('PyQt4 ' + PYQT_VERSION_STR + '\n')
msg = 'Type !hist for a history view and !hist(n) history index recall'
self.write(msg + '\n')
def marker(self):
if self.multiLine:
self.insertPlainText('... ')
else:
self.insertPlainText('>>> ')
def initInterpreter(self, interpreterLocals=None):
if interpreterLocals:
# when we pass in locals, we don't want it to be named "self"
# so we rename it with the name of the class that did the passing
# and reinsert the locals back into the interpreter dictionary
selfName = interpreterLocals['self'].__class__.__name__
interpreterLocalVars = interpreterLocals.pop('self')
self.interpreterLocals[selfName] = interpreterLocalVars
else:
self.interpreterLocals = interpreterLocals
self.interpreter = self.InteractiveInterpreter(self.interpreterLocals)
def updateInterpreterLocals(self, newLocals):
className = newLocals.__class__.__name__
self.interpreterLocals[className] = newLocals
def write(self, line):
self.insertPlainText(line)
self.ensureCursorVisible()
def clearCurrentBlock(self):
# block being current row
length = len(self.document().lastBlock().text()[4:])
if length == 0:
return None
else:
# should have a better way of doing this but I can't find it
[self.textCursor().deletePreviousChar() for x in xrange(length)]
return True
def recallHistory(self):
# used when using the arrow keys to scroll through history
self.clearCurrentBlock()
if self.historyIndex <> -1:
self.insertPlainText(self.history[self.historyIndex])
return True
def customCommands(self, command):
if command == '!hist': # display history
self.append('') # move down one line
# vars that are in the command are prefixed with ____CC and deleted
# once the command is done so they don't show up in dir()
backup = self.interpreterLocals.copy()
history = self.history[:]
history.reverse()
for i, x in enumerate(history):
iSize = len(str(i))
delta = len(str(len(history))) - iSize
line = line = ' ' * delta + '%i: %s' % (i, x) + '\n'
self.write(line)
self.updateInterpreterLocals(backup)
self.marker()
return True
if re.match('!hist\(\d+\)', command): # recall command from history
backup = self.interpreterLocals.copy()
history = self.history[:]
history.reverse()
index = int(command[6:-1])
self.clearCurrentBlock()
command = history[index]
if command[-1] == ':':
self.multiLine = True
self.write(command)
self.updateInterpreterLocals(backup)
return True
return False
def keyPressEvent(self, event):
if event.key() == Qt.Key_Escape:
# proper exit
self.interpreter.runIt('exit()')
if event.key() == Qt.Key_Down:
if self.historyIndex == len(self.history):
self.historyIndex -= 1
try:
if self.historyIndex > -1:
self.historyIndex -= 1
self.recallHistory()
else:
self.clearCurrentBlock()
except:
pass
return None
if event.key() == Qt.Key_Up:
try:
if len(self.history) - 1 > self.historyIndex:
self.historyIndex += 1
self.recallHistory()
else:
self.historyIndex = len(self.history)
except:
pass
return None
if event.key() == Qt.Key_Home:
# set cursor to position 4 in current block. 4 because that's where
# the marker stops
blockLength = len(self.document().lastBlock().text()[4:])
lineLength = len(self.document().toPlainText())
position = lineLength - blockLength
textCursor = self.textCursor()
textCursor.setPosition(position)
self.setTextCursor(textCursor)
return None
if event.key() in [Qt.Key_Left, Qt.Key_Backspace]:
# don't allow deletion of marker
if self.textCursor().positionInBlock() == 4:
return None
if event.key() in [Qt.Key_Return, Qt.Key_Enter]:
# set cursor to end of line to avoid line splitting
textCursor = self.textCursor()
position = len(self.document().toPlainText())
textCursor.setPosition(position)
self.setTextCursor(textCursor)
line = str(self.document().lastBlock().text())[4:] # remove marker
line.rstrip()
self.historyIndex = -1
if self.customCommands(line):
return None
else:
try:
line[-1]
self.haveLine = True
if line[-1] == ':':
self.multiLine = True
self.history.insert(0, line)
except:
self.haveLine = False
if self.haveLine and self.multiLine: # multi line command
self.command += line + '\n' # + command and line
self.append('') # move down one line
self.marker() # handle marker style
return None
if self.haveLine and not self.multiLine: # one line command
self.command = line # line is the command
self.append('') # move down one line
self.interpreter.runIt(self.command)
self.command = '' # clear command
self.marker() # handle marker style
return None
if self.multiLine and not self.haveLine: # multi line done
self.append('') # move down one line
self.interpreter.runIt(self.command)
self.command = '' # clear command
self.multiLine = False # back to single line
self.marker() # handle marker style
return None
if not self.haveLine and not self.multiLine: # just enter
self.append('')
self.marker()
return None
return None
# allow all other key events
super(PyInterp, self).keyPressEvent(event)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MyInterpreter(None)
win.show()
sys.exit(app.exec_())
有没有一种简单的方法可以让一些制表符补全只针对本地符号?
最佳答案
我想你指的是 rlcompleter的完成者对象。
你可以这样使用它:
from rlcompleter import Completer
line = str(...)
completer = Completer(self.interpreter.locals)
suggestion = completer.complete(line, 0)
self.insertPlainText(suggestion)
数字参数表示第 n 个建议,您可以对其进行迭代,直到它返回 None。
例如,假设我们有
>>> my_data = '012345'
然后
>>> completer.complete('my_', 0)
'my_data'
>>> completer.complete('my_data.s', 0)
'my_data.split('
>>> completer.complete('my_data.s', 1)
'my_data.splitlines('
请注意,虽然上面的代码使用了 interpreter.locals,但您可以应用更广泛的搜索(但一定要提供字典)。
关于python - 在嵌入式 Python 解释器中启用代码完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12431555/
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has
我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的
几个月前,我读了一篇关于rubygem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:
我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。
在启用Rack::Deflater来gzip我的响应主体时偶然发现了一些奇怪的东西。也许我遗漏了一些东西,但启用此功能后,响应被压缩,但是资源的ETag在每个请求上都会发生变化。这会强制应用程序每次都响应,而不是发送304。这在没有启用Rack::Deflater的情况下有效,我已经验证页面源没有改变。我正在运行一个使用thin作为Web服务器的Rails应用程序。Gemfile.lockhttps://gist.github.com/2510816有没有什么方法可以让我从Rack中间件获得更多的输出,这样我就可以看到发生了什么?提前致谢。 最佳答案
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht