QLabel subclassification to show a custom mouse button indicator for a mouse

I have a QLabel with a StyledPanel Raised frame.
It can be clicked by subclassing QLabel;

class InteractiveLabel(QtGui.QLabel): def __init__(self, parent): QtGui.QLabel.__init__(self, parent) def mouseReleaseEvent(self, event): self.emit(QtCore.SIGNAL('clicked()')) 

However, the general consensus is that this “box” is not easily recognized as interactive. Striving for usability, I would like the “box” to show that it is accessible when the mouse hovers over it.
Obviously, the mouseover response is easily achieved by connecting mouseHoverEvent.

However, the “button indicator” should be naturally inherited, since my Qt application allows the user to change the style (from Windows XP, Windows 7, plastique, motif, cde).

This image shows the specific widget (lower right corner) and the mouseHover aesthetics that I want in two different styles.

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

When the mouse hovers over the "Box", I would like it to respond in the same way as the combobox in the upper, middle part.
("Answer" is aesthetically native and occurs with all Qt buttons, except for "CDE" and "motives").

Is there any way to implement this with PyQt4?
(I suppose non-native solutions will include QGradient and native style checking, but that is yucky.)

UPDATE:
lol4t0 QLabel idea over QPushButton.

Here is my python implementation with the correct signals and all the appropriate button settings. RichTextBox is a widget that you have embedded in a program.

 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) 

Thanks!


Specifications:
- python 2.7.2
- Windows 7
- PyQt4

+2
source share
2 answers

main idea

You can add a QLabel above the QPushButton (make the QLabel child of QPushButton ) and display rich text in the label, while clicks and decorations can be handled with QPushButton

Experiment

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

  • Implementation of the 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 it almost works! The only stupid mistake (or my global misunderstanding) is that when you press the button with the mouse and then release it, it remains pressed.

- So, we need to redefine mouseReleaseEvent in our label to fix the always clicked problem:

I'm sure there is a slightly more elegant solution, but I'm too lazy to find it now, so I did the 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 this problem, we need to add

     label->setTextInteractionFlags(Qt::NoTextInteraction); 
+5
source

@ 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 the text in QLabel is always displayed. QPushButton cannot be too small to hide part of the text. I think this method is more convenient to use ...

+1
source

Source: https://habr.com/ru/post/1392429/


All Articles