如何在QLineEdit中设置插入符号闪烁光标的颜色

问题描述 投票:0回答:2

如何设置QLineEdit中插入符号闪烁光标的颜色? 我有一个问题,如何更改 QLineEdit 中插入符号闪烁光标的颜色。

qt cursor qt5 qlineedit
2个回答
0
投票

这是我使用 QLineEdit 提出的解决方案。它使用paintEvent 生成自定义插入符。我已经思考这个问题大约两年了,在偶然发现这个问题后,决定尝试寻找解决方案。

我的解决方案假设您正在为该字段分配字体。在此小部件中,我使用 Hasklig Nerd 字体。 在此下载

也许有一种不太复杂的方法可以解决这个问题,但这对我有用。如果您更改字体,您可能需要重新评估一些数学才能使插入符号步骤感觉良好。

from PySide2.QtCore import Qt, QRect
from PySide2.QtGui import QPainter, QColor, QFont, QFontMetricsF
from PySide2.QtWidgets import QWidget, QLineEdit, QCommonStyle, QStyle, QStyleOption


_WIDGET_HEIGHT: int = 24


class CaretStyle(QCommonStyle):

    def __init__(self, width: int = None):
        """
        This allows us to set the width of the default widget input caret.

        Args:
            width (int): The width of the input caret in pixels.
        """
        super().__init__()
        self._width = 5 if width is None else width

    def pixelMetric(self, pixel_metric: QStyle, option: QStyleOption = None, widget: QWidget = None):
        if pixel_metric == QStyle.PM_TextCursorWidth:
            return self._width
        else:
            return QCommonStyle.pixelMetric(self, pixel_metric, option, widget)


def remap_value(value: float, old: tuple, new: tuple) -> float:
    """Range remaps a value using old and new min/max."""
    old_min, old_max = old
    new_min, new_max = new
    return (new_max - new_min) * (value - old_min) / (old_max - old_min) + new_min


class StringInput(QLineEdit):
    _caret_pos_x: float = 0.0
    _caret_pos_y: float = 1 + _WIDGET_HEIGHT * 0.2
    _font_metric: QFontMetricsF = None

    def __init__(self, *args, **kwargs):
        """
        QLineEdit with custom input field caret.
        """
        super().__init__(parent=kwargs.get("parent", None))
        self.setObjectName("ParmInput")

        self.setFixedHeight(24)
        self.setFocusPolicy(Qt.StrongFocus)

        # hide the default caret by scaling it to 0
        self.setStyle(CaretStyle(width=0))

        # accessing font details is important for accurate
        # caret positioning
        font = QFont("Hasklug NF", 9, QFont.Thin)
        font.setHintingPreference(QFont.HintingPreference.PreferNoHinting)
        self._font_metric = QFontMetricsF(font)
        self.setFont(font)

        # align the text within the field
        self.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)

        # we need this so we can update the caret in the field as the user
        # does stuff.
        self.cursorPositionChanged.connect(self._update_caret_pos_x)

    def _update_caret_pos_x_x(self):
        """Calculate the position of the caret based on cursor position."""
        text: str = self.text()
        step: float = self._font_metric.averageCharWidth() - 1

        # if the field is empty set the character to teh step value.
        # this puts the caret where the first char would be. this also
        # prevents divide by 0 if no text is in the field.
        if len(text) < 1:
            self._caret_pos_x = step
            return

        cursor_pos: int = self.cursorPosition()
        text_width: int = self._font_metric.width(text)
        char_count: len(text)

        # remap the cursor position based on the current text in the field.
        self._caret_pos_x = remap_value(cursor_pos, 0, 1, 0, text_width) / char_count + step

    def get_caret_pos_x(self) -> float:
        """Queries the current position of the caret."""
        return self._caret_pos_x

    def focusInEvent(self, event) -> None:
        """We update the caret position upon focus, based on where the user clicked."""
        self._update_caret_pos_x()

    def focusOutEvent(self, event) -> None:
        """Clear the current text selection if the field loses focus."""
        self.setSelection(0, 0)

    def paintEvent(self, event):
        """This creates a custom caret for the input field."""
        super().paintEvent(event)

        # easy out if the widget doesnt have focus
        if not self.hasFocus():
            return

        width: float = 2.0
        height: float = _WIDGET_HEIGHT/1.5

        painter: QPainter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        painter.setPen(Qt.NoPen)

        caret = QRect(self.get_caret_pos_x(), self._caret_pos_y, width, height)
        painter.setBrush(QColor(231, 167, 38, 150))
        painter.drawRect(caret)

        painter.end()

-2
投票

有一种方法你可以尝试一下。 理论上它看起来应该可以工作(未经测试。查找编译时错误。)

首先获取您要设置的图标图像。 然后加载图像以获得

QPixmap
对象。

QPixmap myPixmap;
myPixmap.load("<<YOURIMAGEPATH>>/cursoricon.png");

现在使用以下命令将颜色设置为

QPixmap
https://doc.qt.io/qt-5/qpixmap.html#fill

myPixmap.fill(QColor(0,255,0));

现在使用

QCursor
对象创建一个
QPixmap
对象 https://doc.qt.io/qt-5/qcursor.html#QCursor-3

QCursor cursor = QCursor(myPixmap);

然后将光标设置到您的线条编辑对象。

pLineEdit->setCursor(cursor);

其实setCursor函数,一开始我以为它只适用于鼠标光标。 但文档称它也适用于编辑器小部件。 https://doc.qt.io/qt-5/qwidget.html#cursor-prop

编辑器小部件可能使用 I 形光标

© www.soinside.com 2019 - 2024. All rights reserved.