对QLabel进行子类化以显示本机“鼠标悬停按钮指示器”

时间:2012-01-22 09:47:20

标签: qt pyqt subclass mouseover qlabel

我有一个带有'StyledPanel,凸起'框架的QLabel 它是可点击的,通过继承QLabel;

class InteractiveLabel(QtGui.QLabel):
    def __init__(self, parent):  
        QtGui.QLabel.__init__(self, parent)

    def mouseReleaseEvent(self, event):  
        self.emit(QtCore.SIGNAL('clicked()'))

然而,一般意见认为这个'Box'不容易识别为可点击 为了实现可用性,我希望“Box”显示当鼠标悬停在它上面时它是可点击的。
显然,通过连接mouseHoverEvent可以轻松实现对鼠标悬停的反应。

但是,'按钮指示符'必须是原生继承的,因为我的Qt应用程序允许用户更改样式(不包括Windows XP,Windows 7,plastique,motif,cde)。

此图像以两种不同的风格显示特定的小部件(右下角)和我想要的mouseHover美学。

Image showing the 'Box' and the hover indicators of the plastique and Win7 styles

当鼠标悬停在'Box'上时,我希望它像顶部,中间的组合框一样响应。
('响应'是美学本土的,与所有Qt按钮一起出现,除了'CDE'和'motif'styles。)。

有没有办法用PyQt4实现这个?
(我认为非原生解决方案会涉及QGradient并检查本机风格,但这很令人讨厌。)

更新:
lol4t0关于QLabel超过QPushButton的想法。

这是我的pythonic实现,信号正常工作,所有适当的按钮美学。 RichTextBox是您将嵌入到程序中的小部件。

from PyQt4 import QtCore, QtGui

class RichTextButton(QtGui.QPushButton):
    def __init__(self, parent=None):  
        QtGui.QPushButton.__init__(self, parent)
        self.UnitText = QtGui.QLabel(self)
        self.UnitText.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
        self.UnitText.setAlignment(QtCore.Qt.AlignCenter)
        self.UnitText.setMouseTracking(False)
        self.setLayout(QtGui.QVBoxLayout())
        self.layout().setMargin(0)
        self.layout().addWidget(self.UnitText)

谢谢!


规格:
- python 2.7.2
- Windows 7
- PyQt4

2 个答案:

答案 0 :(得分:5)

主要想法

您可以在QLabel上方添加QPushButtonQLabel生成QPushButton子项)并在标签中显示富文本,而点击和装饰可以使用{{1 }}

实验

好吧,我是一名QPushButton程序员,但没有什么复杂的,我希望你理解代码

  • 实施主要想法

    C++

    几乎有效!唯一一个愚蠢的错误(或我的全球误解)是当你用鼠标按下按钮然后释放它时,仍然按下

- 所以,我们似乎需要在QLabel * label = new QLabel(pushButton); label->setText("<strong>sss</strong>"); label->setAlignment(Qt::AlignCenter); label->setMouseTracking(false); pushButton->setLayout(new QVBoxLayout(pushButton)); pushButton->layout()->setMargin(0); pushButton->layout()->addWidget(label); 中重新实现mouseReleaseEvent来修复始终按下问题:

我很确定,有一个更优雅的解决方案,但我现在懒得找到它,所以,我做了以下:

label

  • 正如 @Roku 所说,为了解决这个问题,我们必须添加

        class TransperentLabel: public QLabel
        {
        public:
            TransperentLabel(QWidget* parent):QLabel(parent) {}
        protected:
            void mouseReleaseEvent(QMouseEvent *ev)
            {
                /*
                QApplication::sendEvent(parent(), ev); -- does not help :(
                */
                static_cast<QPushButton*>(parent())->setDown(false);
                static_cast<QPushButton*>(parent())->click(); //fixing click signal issues
            }
        };
    

答案 1 :(得分:1)

@ Lol4t0 ,我的方法有一些改进......

这是我的头文件:

#ifndef QLABELEDPUSHBUTTON_H
#define QLABELEDPUSHBUTTON_H

#include <QPushButton>

class QLabel;

class QLabeledPushButton : public QPushButton
{
    Q_OBJECT

    QLabel * m_label;

public:
    QLabeledPushButton(QWidget * parent = 0);

    QString text() const;
    void setText(const QString & text);

protected:
    void resizeEvent(QResizeEvent * event);
};

#endif // QLABELEDPUSHBUTTON_H

还有我的cpp文件:

#include <QLabel>
#include <QVBoxLayout>
#include <QResizeEvent>
#include "QLabeledPushButton.h"

QLabeledPushButton::QLabeledPushButton(QWidget * parent)
    : QPushButton(parent)
    , m_label(new QLabel(this))
{
    m_label->setWordWrap(true);
    m_label->setMouseTracking(false);
    m_label->setAlignment(Qt::AlignCenter);
    m_label->setTextInteractionFlags(Qt::NoTextInteraction);
    m_label->setGeometry(QRect(4, 4, width()-8, height()-8));
}

QString QLabeledPushButton::text() const
{
    return m_label->text();
}

void QLabeledPushButton::setText(const QString & text)
{
    m_label->setText(text);
}

void QLabeledPushButton::resizeEvent(QResizeEvent * event)
{
    if (width()-8 < m_label->sizeHint().width())
        setMinimumWidth(event->oldSize().width());
    if (height()-8 < m_label->sizeHint().height())
        setMinimumHeight(event->oldSize().height());

    m_label->setGeometry(QRect(4, 4, width()-8, height()-8));
}

因此,QLabel上的文字始终可见。 QPushButton不能太小,不能隐藏部分文字。我觉得这种方式使用起来更舒服......