PyQt4:使 QTextEdit 上的某些文本不可编辑
PyQt4 : making certain text on QTextEdit uneditable
有什么方法可以使 QTextEdit 上的某些文本永久化。 cmd.exe 等应用程序,其中显示当前用户目录,屏幕的其余部分用于输入。我尝试插入 QLabel 但无法插入,这是我的代码,我目前正在通过单独的行编辑获取用户输入。
UPDATE 我查看了 Ipython QtConsole,其中不断显示行号,我该怎么做,我正在查看源代码,但如果有人谁已经知道了,请告诉。这是 ipython notebook 的 QtConsole,我正在尝试复制它。
import os
import sys
import PyQt4
import PyQt4.QtCore
from PyQt4.QtGui import *
def main():
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
# create objects
label = QLabel(self.tr("Enter command and press Return"))
self.le = QLineEdit()
self.te = QTextEdit()
self.lbl = QLabel(str(os.getcwd())+"> ")
# layout
layout = QVBoxLayout(self)
layout.addWidget(label)
layout.addWidget(self.le)
layout.addWidget(self.te)
self.setLayout(layout)
# styling
self.te.setReadOnly(True)
# create connection
self.mytext = str(self.le.text())
self.connect(self.le, PyQt4.QtCore.SIGNAL("returnPressed(void)"),
self.display)
def display(self):
mytext = str(self.le.text())
self.te.append(self.lbl +str(os.popen(mytext).read()))
self.le.setText("")
if __name__ == "__main__":
main()
一个简单的解决方案是创建一个 class 继承自 QTextEdit 并覆盖并添加必要的属性,如下所示:
class TextEdit(QTextEdit):
def __init__(self, *args, **kwargs):
QTextEdit.__init__(self, *args, **kwargs)
self.staticText = os.getcwd()
self.counter = 1
self.setReadOnly(True)
def append(self, text):
n_text = "{text} [{number}] > ".format(text=self.staticText, number=self.counter)
self.counter += 1
QTextEdit.append(self, n_text+text)
完整代码:
import os
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class TextEdit(QTextEdit):
def __init__(self, *args, **kwargs):
QTextEdit.__init__(self, *args, **kwargs)
self.staticText = os.getcwd()
self.counter = 1
self.setReadOnly(True)
def append(self, text):
n_text = "{text} [{number}] > ".format(text=self.staticText, number=self.counter)
self.counter += 1
QTextEdit.append(self, n_text+text)
class MyWindow(QWidget):
def __init__(self, *args, **kwargs):
QWidget.__init__(self, *args, **kwargs)
label = QLabel(self.tr("Enter command and press Return"), self)
self.le = QLineEdit(self)
self.te = TextEdit(self)
# layout
layout = QVBoxLayout(self)
layout.addWidget(label)
layout.addWidget(self.le)
layout.addWidget(self.te)
self.setLayout(layout)
self.connect(self.le, SIGNAL("returnPressed(void)"), self.display)
# self.le.returnPressed.connect(self.display)
def display(self):
command = str(self.le.text())
resp = str(os.popen(command).read())
self.te.append(resp)
self.le.clear()
def main():
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
要模拟 QtConsole,我们必须重写 QTextEdit 的一些方法,捕获一些事件,并验证它不会消除前缀,如下所示:
import os
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class TextEdit(QTextEdit):
def __init__(self, *args, **kwargs):
QTextEdit.__init__(self, *args, **kwargs)
self.staticText = os.getcwd()
self.counter = 1
self.prefix = ""
self.callPrefix()
self.setContextMenuPolicy(Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.onCustomContextMenuRequest)
def onCustomContextMenuRequest(self, point):
menu = self.createStandardContextMenu()
for action in menu.actions():
if "Delete" in action.text():
action.triggered.disconnect()
menu.removeAction(action)
elif "Cu&t" in action.text():
action.triggered.disconnect()
menu.removeAction(action)
elif "Paste" in action.text():
action.triggered.disconnect()
act = menu.exec_(point)
if act:
if "Paste" in act.text():
self.customPaste()
def customPaste(self):
self.moveCursor(QTextCursor.End)
self.insertPlainText(QApplication.clipboard().text())
self.moveCursor(QTextCursor.End)
def clearCurrentLine(self):
cs = self.textCursor()
cs.movePosition(QTextCursor.StartOfLine)
cs.movePosition(QTextCursor.EndOfLine)
cs.select(QTextCursor.LineUnderCursor)
text = cs.removeSelectedText()
def isPrefix(self, text):
return self.prefix == text
def getCurrentLine(self):
cs = self.textCursor()
cs.movePosition(QTextCursor.StartOfLine)
cs.movePosition(QTextCursor.EndOfLine)
cs.select(QTextCursor.LineUnderCursor)
text = cs.selectedText()
return text
def keyPressEvent(self, event):
if event.key() == Qt.Key_Return:
command = self.getCurrentLine()[len(self.prefix):]
self.execute(command)
self.callPrefix()
return
elif event.key() == Qt.Key_Backspace:
if self.prefix == self.getCurrentLine():
return
elif event.matches(QKeySequence.Delete):
return
if event.matches(QKeySequence.Paste):
self.customPaste()
return
elif self.textCursor().hasSelection():
t = self.toPlainText()
self.textCursor().clearSelection()
QTextEdit.keyPressEvent(self, event)
self.setPlainText(t)
self.moveCursor(QTextCursor.End)
return
QTextEdit.keyPressEvent(self, event)
def callPrefix(self):
self.prefix = "{text} [{number}] >".format(text=self.staticText, number=self.counter)
self.counter += 1
self.append(self.prefix)
def execute(self, command):
resp = os.popen(command).read()
self.append(resp)
class MyWindow(QWidget):
def __init__(self, *args, **kwargs):
QWidget.__init__(self, *args, **kwargs)
label = QLabel(self.tr("Enter command and press Return"), self)
self.te = TextEdit(self)
# layout
layout = QVBoxLayout(self)
layout.addWidget(label)
layout.addWidget(self.te)
self.setLayout(layout)
def main():
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
有什么方法可以使 QTextEdit 上的某些文本永久化。 cmd.exe 等应用程序,其中显示当前用户目录,屏幕的其余部分用于输入。我尝试插入 QLabel 但无法插入,这是我的代码,我目前正在通过单独的行编辑获取用户输入。
UPDATE 我查看了 Ipython QtConsole,其中不断显示行号,我该怎么做,我正在查看源代码,但如果有人谁已经知道了,请告诉。这是 ipython notebook 的 QtConsole,我正在尝试复制它。
import os
import sys
import PyQt4
import PyQt4.QtCore
from PyQt4.QtGui import *
def main():
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
# create objects
label = QLabel(self.tr("Enter command and press Return"))
self.le = QLineEdit()
self.te = QTextEdit()
self.lbl = QLabel(str(os.getcwd())+"> ")
# layout
layout = QVBoxLayout(self)
layout.addWidget(label)
layout.addWidget(self.le)
layout.addWidget(self.te)
self.setLayout(layout)
# styling
self.te.setReadOnly(True)
# create connection
self.mytext = str(self.le.text())
self.connect(self.le, PyQt4.QtCore.SIGNAL("returnPressed(void)"),
self.display)
def display(self):
mytext = str(self.le.text())
self.te.append(self.lbl +str(os.popen(mytext).read()))
self.le.setText("")
if __name__ == "__main__":
main()
一个简单的解决方案是创建一个 class 继承自 QTextEdit 并覆盖并添加必要的属性,如下所示:
class TextEdit(QTextEdit):
def __init__(self, *args, **kwargs):
QTextEdit.__init__(self, *args, **kwargs)
self.staticText = os.getcwd()
self.counter = 1
self.setReadOnly(True)
def append(self, text):
n_text = "{text} [{number}] > ".format(text=self.staticText, number=self.counter)
self.counter += 1
QTextEdit.append(self, n_text+text)
完整代码:
import os
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class TextEdit(QTextEdit):
def __init__(self, *args, **kwargs):
QTextEdit.__init__(self, *args, **kwargs)
self.staticText = os.getcwd()
self.counter = 1
self.setReadOnly(True)
def append(self, text):
n_text = "{text} [{number}] > ".format(text=self.staticText, number=self.counter)
self.counter += 1
QTextEdit.append(self, n_text+text)
class MyWindow(QWidget):
def __init__(self, *args, **kwargs):
QWidget.__init__(self, *args, **kwargs)
label = QLabel(self.tr("Enter command and press Return"), self)
self.le = QLineEdit(self)
self.te = TextEdit(self)
# layout
layout = QVBoxLayout(self)
layout.addWidget(label)
layout.addWidget(self.le)
layout.addWidget(self.te)
self.setLayout(layout)
self.connect(self.le, SIGNAL("returnPressed(void)"), self.display)
# self.le.returnPressed.connect(self.display)
def display(self):
command = str(self.le.text())
resp = str(os.popen(command).read())
self.te.append(resp)
self.le.clear()
def main():
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
要模拟 QtConsole,我们必须重写 QTextEdit 的一些方法,捕获一些事件,并验证它不会消除前缀,如下所示:
import os
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class TextEdit(QTextEdit):
def __init__(self, *args, **kwargs):
QTextEdit.__init__(self, *args, **kwargs)
self.staticText = os.getcwd()
self.counter = 1
self.prefix = ""
self.callPrefix()
self.setContextMenuPolicy(Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.onCustomContextMenuRequest)
def onCustomContextMenuRequest(self, point):
menu = self.createStandardContextMenu()
for action in menu.actions():
if "Delete" in action.text():
action.triggered.disconnect()
menu.removeAction(action)
elif "Cu&t" in action.text():
action.triggered.disconnect()
menu.removeAction(action)
elif "Paste" in action.text():
action.triggered.disconnect()
act = menu.exec_(point)
if act:
if "Paste" in act.text():
self.customPaste()
def customPaste(self):
self.moveCursor(QTextCursor.End)
self.insertPlainText(QApplication.clipboard().text())
self.moveCursor(QTextCursor.End)
def clearCurrentLine(self):
cs = self.textCursor()
cs.movePosition(QTextCursor.StartOfLine)
cs.movePosition(QTextCursor.EndOfLine)
cs.select(QTextCursor.LineUnderCursor)
text = cs.removeSelectedText()
def isPrefix(self, text):
return self.prefix == text
def getCurrentLine(self):
cs = self.textCursor()
cs.movePosition(QTextCursor.StartOfLine)
cs.movePosition(QTextCursor.EndOfLine)
cs.select(QTextCursor.LineUnderCursor)
text = cs.selectedText()
return text
def keyPressEvent(self, event):
if event.key() == Qt.Key_Return:
command = self.getCurrentLine()[len(self.prefix):]
self.execute(command)
self.callPrefix()
return
elif event.key() == Qt.Key_Backspace:
if self.prefix == self.getCurrentLine():
return
elif event.matches(QKeySequence.Delete):
return
if event.matches(QKeySequence.Paste):
self.customPaste()
return
elif self.textCursor().hasSelection():
t = self.toPlainText()
self.textCursor().clearSelection()
QTextEdit.keyPressEvent(self, event)
self.setPlainText(t)
self.moveCursor(QTextCursor.End)
return
QTextEdit.keyPressEvent(self, event)
def callPrefix(self):
self.prefix = "{text} [{number}] >".format(text=self.staticText, number=self.counter)
self.counter += 1
self.append(self.prefix)
def execute(self, command):
resp = os.popen(command).read()
self.append(resp)
class MyWindow(QWidget):
def __init__(self, *args, **kwargs):
QWidget.__init__(self, *args, **kwargs)
label = QLabel(self.tr("Enter command and press Return"), self)
self.te = TextEdit(self)
# layout
layout = QVBoxLayout(self)
layout.addWidget(label)
layout.addWidget(self.te)
self.setLayout(layout)
def main():
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()