3

我有一个带有“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()'))

然而,普遍的看法是这个“盒子”不容易被识别为可点击的。
为了提高可用性,我希望“框”在鼠标悬停在它上面时显示它是可点击的。
显然,通过连接 mouseHoverEvent 可以轻松实现对鼠标悬停的反应。

但是,“按钮指示器”必须是本机继承的,因为我的 Qt 应用程序允许用户更改样式(在 Windows XP、Windows 7、plastique、motif、cde 之外)。

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

显示 plastique 和 Win7 样式的“框”和悬停指示器的图像

当鼠标悬停在“框”上时,我希望它像组合框在顶部、中间一样做出响应。
(“响应”在美学上是原生的,并且出现在所有 Qt 按钮上,除了“CDE”和“motif”样式。)。

有没有办法用 PyQt4 实现这个?
(我想非本地解决方案将涉及 QGradient 并检查本地样式,但这很糟糕。)

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

这是我的 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

4

2 回答 2

5

大意

您可以在QLabel上面添加QPushButton(make QLabelchild of QPushButton)并在标签中显示富文本,同时可以处理点击和装饰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的解决总是紧迫的问题:

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

    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
        }
    };

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

    label->setTextInteractionFlags(Qt::NoTextInteraction);
    
于 2012-01-22T10:56:18.880 回答
3

@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 不能太小而不能隐藏部分文本。我觉得这种方式使用起来更舒服...

于 2012-06-02T08:09:06.437 回答