【问题标题】:PyQt4 : making certain text on QTextEdit uneditablePyQt4:使 QTextEdit 上的某些文本不可编辑
【发布时间】:2017-12-21 07:55:29
【问题描述】:

有什么方法可以使 QTextEdit 上的某些文本永久化。诸如 cmd.exe 之类的应用程序会显示当前用户目录,而屏幕的其余部分则可供输入。我尝试插入 QLabel 但无法这样做,这是我的代码,我目前正在通过单独的行编辑来获取用户输入。

更新 我查看了 Ipython QtConsole,其中行号不断显示,我该怎么做,我正在查看源代码,但如果有人已经知道它,请告诉我。这是 ipython 笔记本的 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()

【问题讨论】:

  • 你用os.popen()做什么?您希望永久显示什么文字?你想要的出口是什么?
  • 我只希望 os.getcwd() 是永久性的,我正在尝试构建一个类似于应用程序 os.popen() 的 cmd 用于运行用户提供的命令。
  • 请给我一个真实的例子,例如QLineEdit中将放置哪些条目以及QTextEdit中您想要什么输出。
  • self.te.append(self.lbl +str(os.popen(mytext).read())) 更改为self.te.append(self.lbl.text() +str(os.popen(mytext).read()))
  • 我添加了一张图片来帮助解释我正在尝试构建的内容@eyllanesc

标签: python pyqt4 qtconsole


【解决方案1】:

一个简单的解决方案是创建一个继承自 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()

【讨论】:

  • 有什么办法可以消除行编辑,只在显示当前工作目录后进行一个文本编辑,我可以在不可编辑的 getcwd() 标签/文本之后插入命令跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-10
  • 2018-08-17
  • 2023-02-19
相关资源
最近更新 更多