Subclassing QLabel to show native 'Mouse Hover Button indicator'

后端 未结 2 814
既然无缘
既然无缘 2021-01-03 09:49

I have a QLabel with a \'StyledPanel, raised\' frame.
It is clickable, by subclassing QLabel;

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


        
相关标签:
2条回答
  • 2021-01-03 10:21

    Main idea

    You can add QLabelabove QPushButton (make QLabel child of QPushButton) and show rich text in label, while clicks and decorations can be processed with QPushButton

    Experiment

    Well, I am a C++ programmer, but there is nothing complicated, I hope, you understand the code

    • Implementing main idea:

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

      And this almost works! The only one silly bug (or my global misunderstanding) is that when you press button with mouse and then release it, it remains pressed.

    - So, it seems we need to reimplement mouseReleaseEvent in our label to fix always pressed issue:

    I'm pretty sure, there is a bit more elegant solution, but I'm too lazy to find it now, so, I made following:

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

    • As @Roku said, to fix that issue, we have to add

      label->setTextInteractionFlags(Qt::NoTextInteraction);
      
    0 讨论(0)
  • 2021-01-03 10:31

    @Lol4t0, i have some improvements for your method...

    This is my header file:

    #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
    

    And there is my cpp file:

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

    So text on QLabel is always visible. QPushButton can't be too small to hide part of text. I think this way is more comfortable to use...

    0 讨论(0)
提交回复
热议问题