pyqt 中的代码编辑器示例

2024-07-04

我尝试学习一些Qt(PyQt)。为此,我使用了代码编辑器示例 http://doc.qt.io/qt-4.8/qt-widgets-codeeditor-example.html的文档。当前行的突出显示效果很好。但行号不显示。

实际上LineNumberArea.paintEvent甚至没有被调用。后来也没有CodeEditor.lineNumberAreaPaintEvent。据我了解,数字栏的paintEvent应该定期调用。或者至少当有一个updateRequest或滚动事件(由调用CodeEditor.updateLineNumberArea).

以下是我将代码从 C++ 移植到 Python 的方法:

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *

import numpy as np

class LineNumberArea(QWidget):
    def __init__(self, editor):
        super().__init__()
        self.editor = editor


    def sizeHint(self):
        return Qsize(self.editor.lineNumberAreaWidth(), 0)


    def paintEvent(self, event):
        print('LineNumberArea.paintEvent')
        self.editor.lineNumberAreaPaintEvent(event)


class CodeEditor(QPlainTextEdit):
    def __init__(self):
        super().__init__()
        self.lineNumberArea = LineNumberArea(self)

        self.connect(self, SIGNAL('blockCountChanged(int)'), self.updateLineNumberAreaWidth)
        self.connect(self, SIGNAL('updateRequest(QRect,int)'), self.updateLineNumberArea)
        self.connect(self, SIGNAL('cursorPositionChanged()'), self.highlightCurrentLine)

        self.updateLineNumberAreaWidth(0)


    def lineNumberAreaWidth(self):
        """ This method has been slightly modified (use of log and uses actual
        font rather than standart.) """
        n_lines = self.blockCount()
        digits = np.ceil(np.log10(n_lines)) + 1
        return digits * QFontMetrics(self.font()).width('9') + 3


    def updateLineNumberAreaWidth(self, _):
        print('CodeEditor.updateLineNumberAreaWidth: margin = {}'.format(self.lineNumberAreaWidth()))
        self.setViewportMargins(self.lineNumberAreaWidth(), 0, 0, 0)


    def updateLineNumberArea(self, rect, dy):
        print('CodeEditor.updateLineNumberArea: rect = {}, dy = {}'.format(rect, dy))

        if dy:
            self.lineNumberArea.scroll(0, dy)
        else:
            self.lineNumberArea.update(0, rect.y(), self.lineNumberArea.width(),
                                       rect.height())

        print('CodeEditor.updateLineNumberArea: rect.contains(self.viewport().rect()) = {}'.format(rect.contains(self.viewport().rect())))
        if rect.contains(self.viewport().rect()):
            self.updateLineNumberAreaWidth(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):
        print('CodeEditor.lineNumberAreaPaintEvent')
        painter(self.lineNumberArea)
        painter.fillRect(event.rect(), Qt.lightGray)

        block = self.firstVisibleBlock()
        blockNumber = block.blockNumber()
        top = self.blockBoundingGeometry(block).translated(self.contentOffset()).top()
        bottom = top + self.blockBoundingRect(block).height()

        # Just to make sure I use the right font
        height = QFontMetrics(self.font()).height()
        while block.isValid() and (top <= event.rect().bottom()):
            if block.isVisible() and (bottom >= event.rect().top()):
                number = str(blockNumber + 1)
                painter.setPen(Qt.black)
                painter.drawText(0, top, lineNumberArea.width(), height,
                                 Qt.AlignRight, number)

            block = block.next()
            top = bottom
            bottom = top + self.blockBoundingRect(block).height()
            blockNumber += 1


    def highlightCurrentLine(self):
        extraSelections = []

        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)


if __name__ == "__main__":
    app = QApplication(sys.argv)

    txt = CodeEditor()
    txt.show()

    sys.exit(app.exec_())

任何帮助将不胜感激。

如果重要的话: 蟒蛇:3.4.3,PyQt:4.8.6,操作系统:RHEL 6


你的例子看起来大部分是正确的。缺少绘制事件的问题是由于未在LineNumberArea小部件。所以你只需要:

class LineNumberArea(QWidget):
    def __init__(self, editor):
        super().__init__(editor)

另外,lineNumberAreaPaintEvent方法有一些问题,但很容易修复:

def lineNumberAreaPaintEvent(self, event):
    # missing constructor
    painter = QPainter(self.lineNumberArea)
    ...
    # no need to use QFontMetrics
    height = self.fontMetrics().height()
    ...
            # missing self
            painter.drawText(0, top, self.lineNumberArea.width(), height,
                             Qt.AlignRight, number)

我不确定你想用你的实现来做什么lineNumberAreaWidth,因为它似乎没有给出正确的结果。不过,最初的实现完全按照预期工作(而且速度也快得多):

def lineNumberAreaWidth(self):
    digits = 1
    count = max(1, self.blockCount())
    while count >= 10:
        count /= 10
        digits += 1
    space = 3 + self.fontMetrics().width('9') * digits
    return space
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

pyqt 中的代码编辑器示例 的相关文章

随机推荐

  • ValueError:在 ECB 模式下数据必须与块边界对齐

    我正在使用以下代码在 ECB 模式下尝试 aes 128 加密 from Crypto Cipher import AES key abcdefghijklmnop cipher AES new key encode utf8 AES MO
  • Google 登录使用新的 GoogleSignInOptions 获取访问令牌

    我的 Android 应用程序当前使用 GoogleAuthUtil 来登录用户并获取access token它被传递到后端 下面的代码片段显示创建 GoogleApiClient 并使用 GoogleAuthUtil 获取令牌 mGoog
  • 优化xstream的加载速度

    当我尝试从 XML 文件执行加载时 我感觉 xstream 加载速度达不到我的要求 为了 一个有 10k 条目的 数据库 需要几分钟 以下是我用来序列化的整个数据结构 列表的大小 符号和代码 将为 大约 10k 条目 有什么方法我可以尝试
  • 使用 QProcessEnvironment 更改 cmd.exe 的 PATH 环境变量

    我想从设置了特定路径的 Qt 应用程序启动 cmd exe 我在 QProcessEnvironment 中插入 Path 并将该环境设置为 QProcess 然后我开始分离 cmd 在命令提示符上 路径与调用应用程序的路径相同 而不是我刚
  • CRM2011工作流程:如果工作流程条件中使用的字段在工作流程启动后更新,会发生什么情况?

    示例 假设我有一个工作流程 会在保修结束日期前 2 天发送电子邮件 此工作流在实体 创建 时触发 step 1 wait condition process timeout lt warrantyendate 2 after wait se
  • 使用 Microsoft Excel 绘制 CDF 图表

    我不太确定是否可以在这里或上问这个问题超级用户 https superuser com 我想知道如何绘制CDF http en wikipedia org wiki Cumulative distribution function从我的Ex
  • SQlite - Android - 外键语法

    我一直在尝试让外键在我的 Android SQLite 数据库中工作 我尝试过以下语法 但它给了我强制关闭 private static final String TASK TABLE CREATE create table TASK TA
  • 清单合并 - Android studio 0.8.1 升级构建错误:属性“manifestFile”不存在

    我刚刚升级到 Android Studio 0 8 1 并升级了构建工具等 来自 Android Studio 0 6 但后来我得到了这个构建错误 发现任务配置有问题 processDevelopmentDebugResources 文件
  • 张量流批量稀疏乘法

    我想将稀疏张量乘以密集张量 但在批次内进行 例如 我有一个稀疏张量 其相应的密集形状为 20 65536 65536 其中 20 是批量大小 我想将批次中的每个 65536 65536 与具有密集表示的张量形状 20 65536 中的相应
  • 收据在打印文档中有重叠文本

    我正在 POS 项目中创建打印收据并附上输出的图片 我的问题是描述 数量 价格 金额的重叠 如何在这段代码的下一行显示数量 价格和金额 e Graphics DrawString Description new Font trebuchet
  • Java 类卡枚举示例。修改

    任何帮助深表感谢 我正在使用 java 网站上的类卡示例来尝试构建游戏 http java sun com j2se 1 5 0 docs guide language enums html http java sun com j2se 1
  • OpenCV 图像处理——C++、C、Python

    我正在考虑在一个项目中尝试 OpenCV 并注意到它有 C C 和 Python 我正在尝试确定是否应该使用 C C 还是 Python 并且希望使用具有最佳 OpenCV 支持的任何语言 仅从查看各种文档的索引页来看 C 绑定可能比其他绑
  • 读取 NFC 标签时出现奇怪的字符

    我正在尝试使用 Android 读取 NFC 标签 我是一名养蜂人 这是为了在我接近蜂巢时识别它们 我已经在这里搜索过 但阅读标签时仍然遇到问题 我想阅读文本 但是当它阅读时 在所需文本之前有一个类似正方形的字符和显示为 十 的字符 这是我
  • 让 Android 源中的应用程序编译到 system/app 而不是 data/app 中?

    我正在从源代码编译 Android ROM 并且我有几个可以编译的应用程序 但会编译到手机上的数据 应用程序中 它们可以通过手机设置卸载 我希望它们不可能从手机中卸载 并编译到系统 应用程序而不是数据 应用程序中 有什么建议吗 编辑 错别字
  • 为什么我无法初始化 Map? [复制]

    这个问题在这里已经有答案了 我想存储一组int String值 但是ints 不一定是增量的 这意味着数据可以是 lt 1 first gt lt 3 second gt lt 9 third gt 所以我正在尝试创建与Dictionary
  • Gulp Sass - 如何正确命名输出 css?

    我正在阅读有关 sass 的教程here https scotch io tutorials getting started with sass然后我尝试了其他方法 但在本教程中无法得到答案 这就是问题所在 我的 gulpfile js 中
  • 如何仅针对一项特定修改器更改应用动画?

    如何只申请 animation to offset同时保持其他修改器更改不受其影响 添加 animation偏移后也会使字体大小发生变化 Main view var body some View GeometryReader geo in
  • Androidx 模块,android:attr/ttcIndex 和 android:attr/fontVariationSettings 未找到

    我正在将所有支持 appcompat 库迁移到 androidx 所有更新后 由于此错误 我无法构建我的项目 app processDebugManifest UP TO DATE AGPBI kind error text error r
  • 处理 jQuery 中的所有事件类型

    在使用 jQuery 的应用程序中 我希望每次触发任何类型的事件 包括自定义事件 时都记录到控制台 无论如何 是否可以在不修改 jQuery 源代码并且不绑定到每个可能的事件类型的长列表的情况下执行此操作 var oldTrigger jQ
  • pyqt 中的代码编辑器示例

    我尝试学习一些Qt PyQt 为此 我使用了代码编辑器示例 http doc qt io qt 4 8 qt widgets codeeditor example html的文档 当前行的突出显示效果很好 但行号不显示 实际上LineNum