【问题标题】:PyQt5: A Label Within A Label?PyQt5:标签中的标签?
【发布时间】:2020-05-22 08:03:37
【问题描述】:

我想让标签的部分文本可点击,例如网站上的内嵌超链接。我知道如何使单个标签可点击,但我不确定如何仅使部分标签可点击并仍然保持一致的格式。

我已将我第一次尝试的代码放在下面,并包含输出图像。

我看到的两个问题是标签之间的明显空间(即使是最后的 QStretchItem 也无法修复)和自动换行的问题。

任何帮助将不胜感激。谢谢!

from PyQt5.QtWidgets import *

app = QApplication([])

class MainWindow(QWidget):    
  def __init__(self, *args, **kwargs):
    super(MainWindow, self).__init__(*args, **kwargs)

    self.setWindowTitle('Title')
    self.setGeometry(1200, 200, 350, 500)
    self.layout = QVBoxLayout()
    self.setLayout(self.layout)

    # Dummy list to print
    place_list = { '2000': 'An event happened.', 
                  '2005': 'An event at {this place} happened long ago.', 
                  '2010': 'Another event happened at {a different place}, but it was not fun.' }
    # Initialize Grid of Notes
    grid = QGridLayout()

    # Create Headers for each column
    grid.addWidget(QLabel('Date'), 0, 0)
    grid.addWidget(QLabel('Note'), 0, 1)

    index = 1

    # Iterate through each entry in place_list
    for year in place_list:
      # Add index of entry (by year)
      grid.addWidget(QLabel(year), index, 0)

      # Get text of entry
      note = place_list[year]

      # Look for "{}" to indicate link
      if '{' in note:
        # Get location of link within the entry
        start = note.find('{')
        end = note.find('}')

        # Create a label for the text before the link
        lab_1 = QLabel(note[:start])
        lab_1.setWordWrap(True)

        # Create a label for the link
        # NOTE: It's a QLabel for formatting purposes only
        lab_2 = QLabel(note[start+1:end])
        lab_2.setWordWrap(True)

        # Create a label for the text after the link
        lab_3 = QLabel(note[end+1:])
        lab_3.setWordWrap(True)

        # Combine the labels in one layout
        note_lab = QHBoxLayout()
        note_lab.addWidget(lab_1)
        note_lab.addWidget(lab_2)
        note_lab.addWidget(lab_3)

        # Add the layout as the entry
        grid.addLayout(note_lab, index, 1)

      else:
        # Create the label for the whole entry if no link indicator is found
        note_lab = QLabel(note)
        note_lab.setWordWrap(True)
        grid.addWidget(note_lab, index, 1)

    # Go to next row in grid
    index += 1

    self.layout.addLayout(grid)

window = MainWindow()

window.show()
app.exec_()

【问题讨论】:

  • 可能有点矫枉过正,但也许使用 QWebEngineView 并将其缩小到标签大小。将 HTML 设置为标签文本,并在可点击部分周围使用锚标记。然后使用它通过 JS 调用 python func,使用 QWebChannel,如此答案中所述:stackoverflow.com/a/45362917

标签: python python-3.x pyqt5


【解决方案1】:

我认为最好的解决方案是继承 QLabel 并覆盖 mousePressEvent 方法。

def mousePressEvent(event):
    # event.pos() or .x() and .y() to find the position of the click.

如果您在自定义 QLabel 初始化时在所需区域创建 QRect,您也可以使用 QRect.contains() 方法轻松检查单击是否在矩形内。

其他有用的方法是mouseReleaseEventmouseDoubleClickEvent.

一般来说,当您向小部件添加/更改功能时,请先查看子类。

【讨论】:

  • 通常,我会继承 QLabel 并覆盖事件过滤器。您是否建议我在我希望可点击的标签部分上添加一个 QRect 并覆盖其事件过滤器?这很有趣。我唯一的问题是如何正确定位 QRect 而不会很复杂,通常标签的大小是自动完成的。
  • 抱歉延迟回复,但我的意思是你可以继承 QLabel,并有一个 QRect 变量可以在 mousePressEvent 函数中使用来检查事件位置是否在正确的位置。不幸的是,是的,我不知道准确放置矩形的好方法,特别是如果你有自动换行,或者如果你使用多种字体。因此,对于此类标签,可能必须手动完成。否则,您可以尝试仅通过计数字符来猜测矩形的位置。
猜你喜欢
  • 1970-01-01
  • 2017-09-17
  • 2014-10-27
  • 2018-11-07
  • 2018-12-29
  • 2021-07-19
  • 1970-01-01
  • 2018-08-05
  • 1970-01-01
相关资源
最近更新 更多