PyQt - sellectAll 然后退格键删除不起作用

发布于 2024-12-25 18:15:40 字数 2152 浏览 1 评论 0原文

我有一个文本编辑器,可以将拉丁键盘按键转换为俄语字符。我重新实现了 QTextEdit 类:

class MyTextEdit(QTextEdit):
def __init__(self, *args):
    QTextEdit.__init__(self, *args)

leftMousePressedSignal = pyqtSignal(QPoint)
rightMousePressedSignal = pyqtSignal(QPoint, QEvent)
mouseMovedSignal = pyqtSignal(QPoint)
mouseDoubleClickedSignal = pyqtSignal(QPoint)
keyPressedSignal = pyqtSignal(QEvent)

def mousePressEvent(self, event):
    pos = event.pos()
    if event.button() == Qt.LeftButton:
        self.leftMousePressedSignal.emit(pos)
    elif event.button() == Qt.RightButton:
        self.rightMousePressedSignal.emit(pos, event)

def mouseMoveEvent(self, event):
    if event.buttons() & Qt.LeftButton:
        pos = event.pos()
        self.mouseMovedSignal.emit(pos)

def mouseDoubleClickEvent(self, event):
    if event.button() == Qt.LeftButton:
        pos = event.pos()
        self.mouseDoubleClickedSignal.emit(pos)

def keyPressEvent(self, event):
    if event.type() == QEvent.KeyPress:
        self.keyPressedSignal.emit(event)

然后将其与重新实现的 keyPressEvent 一起使用。因此,我还必须重新实现 Backspace 操作:

    self.textEdit = MyTextEdit(self)
    ...
    self.textEdit.keyPressedSignal.connect(self.OnKeyPressed)
    self.actionSelectAll.triggered.connect(self.textEdit.selectAll)
    ...

def OnKeyPressed(self, event):
    key = event.key()
    txt = str(event.text())
    if key == Qt.Key_Backspace:
        if self.cursor.hasSelection():
            self.cursor.movePosition(QTextCursor.NoMove, QTextCursor.KeepAnchor, self.cursor.selectionStart() - self.cursor.selectionStart())
        else:
            self.cursor.movePosition(QTextCursor.PreviousCharacter, QTextCursor.KeepAnchor, 1)
        self.textEdit.setTextCursor(self.cursor)
        self.textEdit.cut()
    elif key == Qt.Key_A and (event.modifiers() & Qt.ControlModifier):
        self.textEdit.selectAll()

现在,如果未选择任何内容并按 Backspace,它会删除光标左侧的单个字符。当用鼠标选择一个单词并按 Backspace 时,它​​会删除该单词。当用鼠标选择几个单词或整个文本并按 Backspace 时,它​​会删除整个选择。所以,它工作得很好。当我按下“全选”按钮(或 Ctrl+A)时,它会选择整个文本。但如果我随后按 Backspace,它只会删除光标左侧的 1 个字符,而不是整个文本。

如果您能告诉我我在这里做错了什么,我将不胜感激。谢谢。

I have a text editor which converts latin keybord keypresses to russian characters. I have reimplemented a QTextEdit class:

class MyTextEdit(QTextEdit):
def __init__(self, *args):
    QTextEdit.__init__(self, *args)

leftMousePressedSignal = pyqtSignal(QPoint)
rightMousePressedSignal = pyqtSignal(QPoint, QEvent)
mouseMovedSignal = pyqtSignal(QPoint)
mouseDoubleClickedSignal = pyqtSignal(QPoint)
keyPressedSignal = pyqtSignal(QEvent)

def mousePressEvent(self, event):
    pos = event.pos()
    if event.button() == Qt.LeftButton:
        self.leftMousePressedSignal.emit(pos)
    elif event.button() == Qt.RightButton:
        self.rightMousePressedSignal.emit(pos, event)

def mouseMoveEvent(self, event):
    if event.buttons() & Qt.LeftButton:
        pos = event.pos()
        self.mouseMovedSignal.emit(pos)

def mouseDoubleClickEvent(self, event):
    if event.button() == Qt.LeftButton:
        pos = event.pos()
        self.mouseDoubleClickedSignal.emit(pos)

def keyPressEvent(self, event):
    if event.type() == QEvent.KeyPress:
        self.keyPressedSignal.emit(event)

which I then use with the reimplemented keyPressEvent. So I had to reimplement the Backspace action as well:

    self.textEdit = MyTextEdit(self)
    ...
    self.textEdit.keyPressedSignal.connect(self.OnKeyPressed)
    self.actionSelectAll.triggered.connect(self.textEdit.selectAll)
    ...

def OnKeyPressed(self, event):
    key = event.key()
    txt = str(event.text())
    if key == Qt.Key_Backspace:
        if self.cursor.hasSelection():
            self.cursor.movePosition(QTextCursor.NoMove, QTextCursor.KeepAnchor, self.cursor.selectionStart() - self.cursor.selectionStart())
        else:
            self.cursor.movePosition(QTextCursor.PreviousCharacter, QTextCursor.KeepAnchor, 1)
        self.textEdit.setTextCursor(self.cursor)
        self.textEdit.cut()
    elif key == Qt.Key_A and (event.modifiers() & Qt.ControlModifier):
        self.textEdit.selectAll()

Now, if nothing's selected and I press Backspace, it deletes a single character to the left of the cursor. When a word is selected with a mouse and I press Backspace, it deletes the word. When a few words or the whole text is selected with the mouse and I press Backspace, it deletes the whole selection. So, it works fine. When I press a Select All button (or Ctrl+A) - it selects the whole text. But if I then press Backspace it only deletes 1 character to the left of the cursor, not the whole text.

I will greatly appreciate it if you cold tell me what I'm doing wrong here. Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心在旅行 2025-01-01 18:15:40

为什么要重新实现选择和删除行为,以及为什么 MyTextEdit 中没有这样做?如果你只需要

将拉丁键盘按键转换为俄语字符

您只能执行此转换,并让 QTextEdit 进行其他工作(选择、删除、复制等)。

我会这样写:

class TransliterationEdit(QTextEdit):
    latin_alphabet = unicode(string.ascii_letters)  # or dict with transliteration table

    def translateLetter(self, letter):
        return u'Ъ'  # just example, you need translate letter somehow

    def keyPressEvent(self, event):
        text = unicode(event.text())
        if text and text in self.latin_alphabet:
            self.insertPlainText(self.translateLetter(text))
            event.ignore()
        else:
            QTextEdit.keyPressEvent(self, event)

更新

这是我对TextEdit的粗略实现,它将拉丁按键转换为俄语字符,希望它会有所帮助。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from PyQt4.QtGui import *
from transliterator import SMTransliterator
# transliterator available at https://gist.github.com/1600988


class TransliterationEdit(QTextEdit):

    def __init__(self, *args, **kwargs):
        QTextEdit.__init__(self, *args, **kwargs)
        self._transliterator = SMTransliterator()

    def keyPressEvent(self, event):
        text = unicode(event.text())

        if not self._transliterator.add_letter(text):
            if text and self._transliterator.result:
                self.insertPlainText(self._transliterator.result)
            return QTextEdit.keyPressEvent(self, event)

        if self._transliterator.need_next:
            return  # skip it

        self.insertPlainText(self._transliterator.result)


if __name__ == '__main__':      
    app = QApplication(sys.argv)
    window = TransliterationEdit()
    window.show()
    sys.exit(app.exec_())

音译器位于 gist

Why are you reimplimenting selection and deleting behaviour, and why it's done not in MyTextEdit? If you just need to

convert latin keybord keypresses to russian characters

you can only do this conversion, and let other work (selection, deliting, copying, etc) for QTextEdit.

I'd write it like this:

class TransliterationEdit(QTextEdit):
    latin_alphabet = unicode(string.ascii_letters)  # or dict with transliteration table

    def translateLetter(self, letter):
        return u'Ъ'  # just example, you need translate letter somehow

    def keyPressEvent(self, event):
        text = unicode(event.text())
        if text and text in self.latin_alphabet:
            self.insertPlainText(self.translateLetter(text))
            event.ignore()
        else:
            QTextEdit.keyPressEvent(self, event)

UPDATE

Here's my rough implementation of TextEdit which converts Latin keypresses to Russian characters, hope it will help.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from PyQt4.QtGui import *
from transliterator import SMTransliterator
# transliterator available at https://gist.github.com/1600988


class TransliterationEdit(QTextEdit):

    def __init__(self, *args, **kwargs):
        QTextEdit.__init__(self, *args, **kwargs)
        self._transliterator = SMTransliterator()

    def keyPressEvent(self, event):
        text = unicode(event.text())

        if not self._transliterator.add_letter(text):
            if text and self._transliterator.result:
                self.insertPlainText(self._transliterator.result)
            return QTextEdit.keyPressEvent(self, event)

        if self._transliterator.need_next:
            return  # skip it

        self.insertPlainText(self._transliterator.result)


if __name__ == '__main__':      
    app = QApplication(sys.argv)
    window = TransliterationEdit()
    window.show()
    sys.exit(app.exec_())

transliterator available at gist

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文