简体   繁体   English

PyQt5:一个 Label 在一个 Label 内?

[英]PyQt5: A Label Within A Label?

I'd like to make part of the text of a label clickable, like an inline hyperlink on a website.我想让 label 的部分文本可点击,就像网站上的内联超链接一样。 I know how to make an individual label clickable, but I'm not sure how to only make part of the label clickable and still maintain a consistent format.我知道如何使单个 label 可单击,但我不确定如何仅使 label 的一部分可单击并仍保持一致的格式。

I've placed the code for my first attempt below and included an image of the output.我已将第一次尝试的代码放在下面,并包含 output 的图像。

The two issues I see are the noticeable space between the labels (which even a QStretchItem at the end doesn't fix) and the issues with word wrapping.我看到的两个问题是标签之间的明显空间(即使是最后的 QStretchItem 也无法修复)和自动换行的问题。

Any help would be greatly appreciated.任何帮助将不胜感激。 Thank you!谢谢!

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_()

The best solution I believe is to subclass QLabel and override the mousePressEvent method.我认为最好的解决方案是继承 QLabel 并覆盖 mousePressEvent 方法。

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

If you create a QRect in the area that you want in the initialization of your custom QLabel, you can easily check if the click is inside the rectangle by using the QRect.contains() method as well.如果您在自定义 QLabel 初始化中所需的区域中创建 QRect,您也可以使用QRect.contains()方法轻松检查单击是否在矩形内。

Other useful methods for this would be mouseReleaseEvent and mouseDoubleClickEvent.其他有用的方法是mouseReleaseEventmouseDoubleClickEvent.

And in general, when you are adding/changing functionality to widgets, look to subclass first.通常,当您向小部件添加/更改功能时,请先查看子类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM