簡體   English   中英

如何在 PyQt5 label 中制作 cursor

[英]How to make a cursor in a PyQt5 label

我有一個 PyQt5 window ,其中有一個 label ,其中包含文本。

那里出現的文本來自 python 字符串變量。 該字符串由用戶單擊屏幕上的按鈕構建,然后將該字符串輸出到 label 中的 window。

到目前為止,我有一個退格按鈕,可以刪除字符串中的最后一個字符,但我還希望用戶能夠單擊 label 中字符前面的位置,然后能夠刪除該字符。

所以,我想知道如何做兩件事。

  1. 如何根據用戶點擊獲取字符串中的字符位置
  2. 我已經看到了一些示例,但是一旦用戶單擊該位置,我還想在該位置顯示 cursor。

我想使用 label 小部件來執行此操作 - 而不是使用文本輸入字段。

有人有想法么?

讓 QLabel 像這樣工作很難(QLabel 比看起來更復雜)。
單擊后可以顯示 cursor,這通過設置textInteractionFlags屬性來實現的:

self.label.setTextInteractionFlags(
    QtCore.Qt.TextSelectableByMouse | QtCore.Qt.TextSelectableByKeyboard)

第一個標志是允許處理鼠標事件,而第二個標志允許在 label 獲得焦點后立即顯示 cursor(例如,在單擊它之后)。
不幸的是,這不允許您獲得 cursor position(也不能更改它); 很多方法(使用 QFontMetrics 和 QTextDocument),但您需要一個復雜的實現才能使其真正可靠。

解決方案是使用 QLineEdit 並覆蓋keyPressEvent ,即 function ,只要發生按鍵(並且它具有輸入焦點),它總是在小部件上調用。 考慮到數字輸入似乎仍然需要,只需確保event.key()對應於數字的Qt.Key枚舉,在這種情況下,調用基本實現。
您甚至可以通過正確設置其樣式表使其看起來與 QLabel 完全一樣。

class CommandLineEdit(QtWidgets.QLineEdit):
    allowedKeys = (
        QtCore.Qt.Key_0, 
        QtCore.Qt.Key_1, 
        QtCore.Qt.Key_2, 
        QtCore.Qt.Key_3, 
        QtCore.Qt.Key_4, 
        QtCore.Qt.Key_5, 
        QtCore.Qt.Key_6, 
        QtCore.Qt.Key_7, 
        QtCore.Qt.Key_8, 
        QtCore.Qt.Key_9, 
    )
    def __init__(self):
        super().__init__()
        self.setStyleSheet('''
            CommandLineEdit {
                border: none;
                background: transparent;
            }
        ''')

    def keyPressEvent(self, event):
        if event.key() in self.allowedKeys:
            super().keyPressEvent(event)

然后,如果要以編程方式設置文本,同樣基於 cursor,這里有一個基本用法:

from functools import partial

class CommandTest(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        layout = QtWidgets.QVBoxLayout(self)
        self.commandLineEdit = CommandLineEdit()
        layout.addWidget(self.commandLineEdit)
        keys = (
            'QWERTYUIOP', 
            'ASDFGHJKL', 
            'ZXCVBNM'
        )
        backspaceButton = QtWidgets.QToolButton(text='<-')
        enterButton = QtWidgets.QToolButton(text='Enter')
        self.shiftButton = QtWidgets.QToolButton(text='Shift', checkable=True)
        for row, letters in enumerate(keys):
            rowLayout = QtWidgets.QHBoxLayout()
            rowLayout.addStretch()
            layout.addLayout(rowLayout)
            for letter in letters:
                btn = QtWidgets.QToolButton(text=letter)
                rowLayout.addWidget(btn)
                btn.clicked.connect(partial(self.typeLetter, letter))
            rowLayout.addStretch()
            if row == 0:
                rowLayout.addWidget(backspaceButton)
            elif row == 1:
                rowLayout.addWidget(enterButton)
            else:
                rowLayout.addWidget(self.shiftButton)
        spaceLayout = QtWidgets.QHBoxLayout()
        layout.addLayout(spaceLayout)
        spaceLayout.addStretch()
        spaceButton = QtWidgets.QToolButton(minimumWidth=200)
        spaceLayout.addWidget(spaceButton)
        spaceLayout.addStretch()

        backspaceButton.clicked.connect(self.commandLineEdit.backspace)
        spaceButton.clicked.connect(lambda: self.typeLetter(' '))

    def typeLetter(self, letter):
        text = self.commandLineEdit.text()
        pos = self.commandLineEdit.cursorPosition()
        if not self.shiftButton.isChecked():
            letter = letter.lower()
        self.commandLineEdit.setText(text[:pos] + letter + text[pos:])

import sys
app = QtWidgets.QApplication(sys.argv)
w = CommandTest()
w.show()
sys.exit(app.exec_())

如您所見,您可以調用backspace()以清除最后一個字符(或選擇),並且在typeLetter function 中還有您需要的所有剩余功能:獲取/設置文本和 cursor Z47576760FDD4968ADDEABE0.
對於其他任何事情,只需研究完整的文檔

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM