当前位置: 首页 > 知识库问答 >
问题:

python3 - 奇怪的问题,部分快捷键失效,QPlainTextEdit有bug吗?

令狐凌
2024-08-23

按照网上打造了一个代码编辑器,奇怪的是,下拉菜单粘贴和键盘ctrl+v有效,而下拉菜单复制和键盘ctrl+c无效,我没有写任何这方面的代码,难道是QPlainTextEdit的bug?
class QPlainTextEditLineNum(QPlainTextEdit):

def __init__(self, parent=None):
    super().__init__(parent)
    self.setLineWrapMode(QPlainTextEdit.NoWrap)  # 不自动换行
    self.lineNumberArea = LineNumPaint(self)
    self.document().blockCountChanged.connect(self.update_line_num_width)
    self.document().cursorPositionChanged.connect(self.highlightCurrentLine)    # 高亮当前行
    self.verticalScrollBar().sliderMoved.connect(self.scroll_event)  # 滚动条移动更新行号
    self.update_line_num_width()
    self.highlightCurrentLine()

def highlightCurrentLine(self):
    extraSelections = QTextEdit.extraSelections(QTextEdit())
    if not self.isReadOnly():
        selection = QTextEdit.ExtraSelection()
        lineColor = QColor(Qt.yellow).lighter(160)
        selection.format.setBackground(lineColor)
        selection.format.setProperty(QTextFormat.FullWidthSelection, True)
        selection.cursor = self.textCursor()
        selection.cursor.clearSelection()
        extraSelections.append(selection)
    self.setExtraSelections(extraSelections)
def wheelEvent(self, d: QWheelEvent) -> None:
    self.scroll_event(d)
    super().wheelEvent(d)

def scroll_event(self, event: QWheelEvent=None):
    self.lineNumberArea.update()

def keyPressEvent(self, e: QKeyEvent) -> None:
    super().keyPressEvent(e)
    self.lineNumberArea.update()

def mousePressEvent(self, e: 'QMouseEvent') -> None:
    super().mousePressEvent(e)
    self.update()
    self.highlightCurrentLine()

def lineNumberAreaWidth(self):
    block_count = self.document().blockCount()
    max_value = max(1, block_count)
    d_count = len(str(max_value))
    _width = self.fontMetrics().width('9') * d_count + 5
    return _width

def update_line_num_width(self):
    self.setViewportMargins(self.lineNumberAreaWidth(), 0, 0, 0)

def resizeEvent(self, event):
    super().resizeEvent(event)
    cr = self.contentsRect()
    self.lineNumberArea.setGeometry(QRect(cr.left(), cr.top(), self.lineNumberAreaWidth(), cr.height()))

def lineNumberAreaPaintEvent(self, event):
    cursor = QTextCursor(self.document())
    painter = QPainter(self.lineNumberArea)

    painter.fillRect(event.rect(), Qt.lightGray)
    line_height = self.fontMetrics().lineSpacing()  # 包含行间距的行高

    block_number = self.cursorForPosition(QPoint(0, int(line_height / 2))).blockNumber()
    first_visible_block = self.document().findBlock(block_number)
    blockNumber = block_number
    cursor.setPosition(self.cursorForPosition(QPoint(0, int(line_height / 2))).position())
    rect = self.cursorRect()
    scroll_compensation = rect.y() - int(rect.y() / line_height) * line_height
    top = scroll_compensation
    last_block_number = self.cursorForPosition(QPoint(0, self.height() - 1)).blockNumber()

    height = self.fontMetrics().height()
    block = first_visible_block
    while block.isValid() and (top <= event.rect().bottom()) and blockNumber <= last_block_number:
        # cur_line_count = block.lineCount()
        if block.isVisible():
            number = str(blockNumber + 1)
            painter.setPen(Qt.black)
            # print((0, top, self.lineNumberArea.width(), height), number)
            painter.drawText(0, top, self.lineNumberArea.width(), height, Qt.AlignCenter, number)
        block = block.next()
        top = top + line_height
        blockNumber += 1

class LineNumPaint(QWidget):

def __init__(self, q_edit):
    super().__init__(q_edit)
    self.q_edit_line_num = q_edit

def sizeHint(self):
    return QSize(self.q_edit.lineNumberAreaWidth(), 0)

def paintEvent(self, event):
    self.q_edit_line_num.lineNumberAreaPaintEvent(event)

谢谢大神回复。
代码就是从网上复制来的,小白一个,暂时解决不了问题,继续求助网络
补充问题:
cut CTRL+X键页可以删去选择文本,就是系统剪切板内容没有变化,系统剪切板只可读不可写,有写保护系变量要打开吗?

一直没有留意,发现copy时出现
OleSetClipboard: Failed to set mime data (text/plain, text/html, application/vnd.oasis.opendocument.text) on clipboard: COM error 0xffffffff800401f0 CO_E_NOTINITIALIZED (Unknown error 0x0800401f0) (参数错误。)
有说是
它不能在子线程或者非gui线程下用,怎么办?
有说
image.png

看到这样一段网文,不知道怎样做,太小白了
文本的选择由QTextCursor类处理,该类提供创建选择,检索文本内容或删除选择的功能。您可以使用textCursor()方法检索与用户可见光标对应的对象。如果你想在QPlainTextEdit中设置一个选择,只需在QTextCursor对象上创建一个选择,然后使用setCursor()将该游标设置为可见光标。选择可以通过copy()复制到剪贴板,也可以用cut()剪切到剪贴板。

共有1个答案

赵元白
2024-08-23

QPlainTextEdit 本身通常不包含直接导致复制(Ctrl+C)和粘贴(Ctrl+V)快捷键失效的已知bug。在你的代码中,并没有直接处理快捷键逻辑的部分,因为 Qt 的 QPlainTextEdit 已经内置了对这些常用快捷键的支持。然而,你的代码可能间接地影响了这些快捷键的正常工作,尤其是在你重写了 keyPressEvent 方法时。

以下是一些可能导致问题的原因及解决方案:

  1. 事件传递问题
    keyPressEvent 方法中,你调用了 super().keyPressEvent(e),这通常是正确的做法,以确保父类(即 QPlainTextEdit)能接收到按键事件。然而,如果在你的 keyPressEvent 方法中有任何代码在调用 super() 之前或之后错误地处理了事件,那么它可能会影响快捷键的响应。

    解决方案
    确保 super().keyPressEvent(e) 是你 keyPressEvent 方法中处理按键事件的最后一个调用,除非你有特别的理由需要在这之前或之后拦截某些事件。

  2. 焦点问题
    如果 QPlainTextEdit 在某些情况下失去了焦点,那么它可能无法响应快捷键。然而,在你的代码示例中,并没有直接显示可能导致焦点丢失的代码。

    解决方案
    检查你的应用程序中是否有其他地方(如其他控件或窗口)可能在不应该的时候获取了焦点。

  3. 操作系统或Qt版本问题
    在某些特定版本的操作系统或Qt库中,可能存在已知的bug或兼容性问题。

    解决方案
    更新你的Qt库到最新版本,或者检查Qt的bug跟踪系统以查看是否有相关的已知问题。

  4. 其他自定义代码
    如果你的应用程序中有其他自定义代码(未在你的代码示例中显示),这些代码可能会干扰快捷键的正常工作。

    解决方案
    逐步排除或注释掉其他可能相关的代码部分,以确定是否由这些代码引起的问题。

  5. 键盘布局或输入法问题
    在某些情况下,用户的键盘布局或输入法设置可能会影响快捷键的响应。

    解决方案
    检查并测试不同的键盘布局和输入法设置,以确定是否由这些因素引起的问题。

如果以上方法都不能解决问题,建议进一步调试你的应用程序,特别是关注 keyPressEvent 方法中的事件处理逻辑,以及任何可能影响控件焦点的代码。此外,使用Qt的调试工具(如Qt Creator的调试器)可以帮助你更深入地了解事件的传递和处理过程。

 类似资料:
  • 本文向大家介绍PHPstorm快捷键(分享),包括了PHPstorm快捷键(分享)的使用技巧和注意事项,需要的朋友参考一下 如下所示: Eclipse快捷键 Ctrl+1 快速修复 Ctrl+D: 删除当前行 Ctrl+Alt+↓ 复制当前行到下一行(复制增加) Ctrl+Alt+↑ 复制当前行到上一行(复制增加) Alt+↓ 当前行和下面一行交互位置 Alt+↑ 当前行和上面一行交互位置 Alt

  • 问题内容: 所有键都用双引号引起来。整个元素都是一个对象。 Firefox运行良好,但Chrome报告“无效的JSON”。 为什么? 这是完整的代码。 编辑 :Chrome(FirebugLite)的JSON输出: Firefox的JSON输出(Firebug): 我使用http://jsonlint.com/进行了检查,并显示“有效JSON” 编辑 : 从Chrome浏览器查看的来源: 问题答案

  • 我已经在Android Studio中编写了它,也在同一个项目中与Kotlin一起工作。这是我的java代码的错误列表(按照Android Studio扔给我的顺序): 无法解析符号“重写” 无法解析方法“在创建时(?)” 无法解析符号“Saved InstanceState” 无法解析方法“在创建时(?)” 无法解析符号“Saved InstanceState” 无法解析方法“Set Conte

  • 查看快捷键,在设置界面中搜索 “keymap”: 设置自己的快捷键 比如将代码变更 commit ,webstorm 默认是没有配置快捷键的,我们设置个 shift + c 。 搜索 commit : 找到操作项后,添加个新的快捷键,如果快捷键有冲突,webstorm 会有提示。 默认配置下的常用快捷键 mac book 下文的 ctrl 替换成 command 键。 查找/代替 快捷键 说明 c

  • Sketch 有一系列为数不多但相当实用的快捷键,他们能大大提高你的工作效率。   通用快捷键   ・control+h: 触发选区手柄 ・control+l: 触发自动参考线 ・control+g: 触发网格 ・Space: 抓手工具 ・Enter: 编辑所选图层 ・⌘+3: 滚动至所选图层 ・⌘+2: 放大所选图层 ・Z: 放大工具。按住 Z 键,用鼠标单击拖拽出一个区域放大。缩小啧使用 Z

  • Navicat 主窗口 键 动作 CTRL+G 设置位置文件夹 CTRL+#(# 代 表 0 至 9) 从收藏夹列表打开对象窗口 F6 命令列界面 CTRL+H 历史日志 CTRL+Q 新建查询 F12 仅显示活跃对象 常规 键 动作 CTRL+N 新建对象 SHIFT+CTRL+#(# 代 表 0 至 9) 添加收藏夹 F8 Navicat 主窗口 CTRL+TAB 或 SHIFT+CTRL+T