带有HTML链接的QTextDocument问题

时间:2015-06-06 16:45:08

标签: python pyqt5 qtextdocument

我正在使用PyQt5构建一个简单的Marquee小部件来显示一些应该从左向右滚动的新闻。新闻文本应该包含链接,因此用户可以点击它们并阅读完整的新闻帖子(在网站上)。我正在使用QTextDocument在HTML中呈现新闻标题(连同href网址):当HTML呈现完美时,我无法点击生成的href标记。下面是我正在使用的代码:

class MarqueeLabel(QLabel):
    px = 0
    py = 0 
    paused = False
    qthread = None
    refresh_msec = 30 
    textDocument = None
    textWidth = 0
    timer = None

    def __init__(self, parent=None):
        QLabel.__init__(self, parent)
        self.initUI()

    def initUI(self):
        self.setFixedSize(433, 40)
        self.setStyleSheet("""
        QLabel {
            background: transparent;
            color: #484848;
        }
        """)

    def parseFeed(self):

        class FeedParser(QThread):

            msignal = pyqtSignal(list, list)

            def run(self):
                try:
                    feed = feedparser.parse(URL)
                except Exception, e:
                    pass
                else:
                    feedhtml = []
                    feedtext = []
                    for item in feed['entries']:
                        feedhtml.append('%(TEXT)s (<a href="%(LINK)s">read more</a>)' % dict(LINK=item['link'], TEXT=item['title']))
                        feedtext.append('%s (read more)' % item['title'])
                    self.msignal.emit(feedhtml, feedtext)

        self.qthread = FeedParser(self)
        self.qthread.msignal.connect(self.setMarqueeText)
        self.qthread.finished.connect(self.start)
        self.qthread.start()

    @pyqtSlot(list, list)
    def setMarqueeText(self, feedhtml, feedtext):
        ## FIXME: the 1.1 multiplier should not be here, but without the text goes on 2 lines!
        plaintext = ' - '.join(feedtext)
        self.textWidth = self.fontMetrics().boundingRect(plaintext).width() * 1.1
        self.textDocument = QTextDocument(self)
        self.textDocument.setUndoRedoEnabled(False)
        self.textDocument.setUseDesignMetrics(True)
        self.textDocument.setTextWidth(self.textWidth)
        self.textDocument.setHtml(' - '.join(feedhtml))
        self.px = self.width()
        self.py = self.height() - self.fontMetrics().boundingRect(plaintext).height() - 6

    def start(self):
        if self.textDocument:
            self.timer = QTimer(self)
            self.timer.timeout.connect(self.scrollText)
            self.timer.start(self.refresh_msec)

    def event(self, event):
        if event.type() == QEvent.Enter:
            self.paused = True
        elif event.type() == QEvent.Leave:
            self.paused = False
        return QLabel.event(self, event)

    def paintEvent(self, QPaintEvent):
        if self.textDocument:
            p = QPainter(self)
            p.translate(self.px, self.py)
            self.textDocument.drawContents(p, QRectF(self.rect()))

    def scrollText(self):
        if not self.paused:
            if -self.px > self.textWidth:
                self.px = self.width()
            else:
                self.px -= 1
        self.repaint()

这是一个截图,显示HTML正确呈现,尽管点击URL什么都没做?任何提示?

screenshot

1 个答案:

答案 0 :(得分:0)

由于您使用QLabel,这应该是微不足道的。只需使用合适的Qt::TextInteractionFlags即可。在您的情况下,Qt::LinksAccessibleByMouse

文档清楚地告诉你:

enum  Qt::TextInteractionFlags
flags Qt::TextInteractionFlags

...
Qt::LinksAccessibleByMouse      4   Links can be highlighted and activated with the mouse.
Qt::LinksAccessibleByKeyboard   8   Links can be focused using tab and activated with enter.
...