Need to check the right-click event from a QButtonGroup
-
Hi,
I currently use the following code to generate a buttongroup to place pushbuttons like a grid. This is working well. But I can't figure out how to manage the right click event .MyClass::MyClass(QWidget * parentWidget) { setParent(parentWidget) ; QVBoxLayout *layout = new QVBoxLayout() ; QHBoxLayout *Hlayout = new QHBoxLayout() ; Glayout = new QGridLayout() ; Glayout->setSpacing(0) ; Hlayout->addStretch(1) ; Hlayout->addLayout(Glayout) ; Hlayout->addStretch(1) ; layout->addLayout(Hlayout) ; layout->addStretch(1) ; Populate(Glayout,Rows,Cols); } void MyClass::Populate(QGridLayout *layout, const int rows, const int cols) { for ( int i = 0; i < rows; ++ i) { for ( int j = 0; j < cols; ++j) { QPushButton* btn = new QPushButton(" ") ; btn->setFixedWidth(20); btn->setStyleSheet("background-color:grey;") ; layout->addWidget(btn,i,j) ; this->addButton(btn) ; } } } void MyClass::buttonClick(QAbstractButton* button) { int BtnID= abs(this->id(button)) -2 ; }
-
@doubitchou hi,
that really dempends on what you want to do with that right click event.If you want to differentiate between left/right middle mous button beeing pressed, you will most likly have to Write your own subclass of QPushButton
But from the code you posted, I believe you simply want the ID of whichever button was pressed.
That is a lot easier and super simple with c11 Lambda functionality:
lets use your code:
void MyClass::Populate(QGridLayout *layout, const int rows, const int cols) { int id = 0; //<< New for ( int i = 0; i < rows; ++ i) { for ( int j = 0; j < cols; ++j) { QPushButton* btn = new QPushButton(" ") ; btn->setFixedWidth(20); btn->setStyleSheet("background-color:grey;") ; layout->addWidget(btn,i,j) ; this->addButton(btn) ; //New connect(btn, &QPushButton::clicked, btn, [=]{buttonClick(id);}); id++; } } }
and your buttonClick function needs to be adjusted:
void MyClass::buttonClick(int id) { int BtnID= id; }
-
Hi,
Instead of using QPushButton object directly, create a class inherited by QPushButton and re implement mousePressEvent(QMouseEvent *event) there you can get type of event happens .
event->button();
-
@J.Hilk
The code I've posted already retrieve the ID of the button. what I'd need is just to define an action (change the color the current button to be exact) for right click event on any button.As you and @Venkatesh-V proposedn I'd need to subclassing pushbutton: could you please show me a snippet of that ?
-
that should be easy enough:
#ifndef CBUTTON_H #define CBUTTON_H #include <QPushButton> #include <QMouseEvent> #include <QStyle> class cButton : public QPushButton { Q_OBJECT Q_PROPERTY(bool rightClicked READ wasRightClicked WRITE changeState) public: explicit cButton(QWidget * parent = 0) : QPushButton(parent){ } ~cButton(){} bool wasRightClicked(){return rightClicked;} public slots: void changeState(bool b){ rightClicked = b; style()->unpolish(this); style()->polish(this); } signals: void rightClicked(); protected: virtual void mousePressEvent(QMouseEvent *e)Q_DECL_OVERRIDE{ if(e->button() == Qt::RightButton){ emit rightClicked(); changeState(true); }else{ changeState(false); } QPushButton::mousePressEvent(e); } private: bool rightClicked = false; } #endif
the change in your code:
#include "cButton" void MyClass::Populate(QGridLayout *layout, const int rows, const int cols) { for ( int i = 0; i < rows; ++ i) { for ( int j = 0; j < cols; ++j) { cButton* btn = new cButton(" ") ; btn->setFixedWidth(20); btn->setStyleSheet("QPushButton{background-color:grey;}" "QPushButton[rightClicked = true]{background-color:red;}") ; layout->addWidget(btn,i,j) ; this->addButton(btn) ; } } }
-
I have issue using :
explicit MatrixButton(QWidget * parent = 0) : QPushButton(parent){}
error : prototype for 'MatrixButton::MatrixButton()' does not match any in class 'MatrixButton'
MatrixButton::MatrixButton()
^and not sure if the renaming of the clicked is correct, but it needed renaming as most have the same name. I think this could be ok :
#ifndef MATRIXBUTTON_H #define MATRIXBUTTON_H #include <QPushButton> #include <QMouseEvent> #include <QStyle> class MatrixButton : public QPushButton { Q_OBJECT Q_PROPERTY(bool rightClicked READ wasRightClicked WRITE changeState) public: explicit MatrixButton(QWidget * parent = 0) : QPushButton(parent){} ~MatrixButton(){} bool wasRightClicked(){return _rightClicked;} public slots: void changeState(bool b) { _rightClicked = b; style()->unpolish(this); style()->polish(this); } signals: void rightClicked(); protected: virtual void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE { if(e->button() == Qt::RightButton) { emit rightClicked(); changeState(true); } else { changeState(false); } QPushButton::mousePressEvent(e); } private: bool _rightClicked = false; }; #endif // MATRIXBUTTON_H
-
@doubitchou
you'll need to changeQ_PROPERTY(bool rightClicked READ wasRightClicked WRITE changeState)
to
Q_PROPERTY(bool _rightClicked READ wasRightClicked WRITE changeState)
to be comform to your renaming
this was intended as a header file only, class do you have a MatrixButton.cpp file ? that would explain a double MatrixButton::MatrixButton() definition
-
indeed better, anyway even if this is the same code I use for the default grey button color, nothing happen on right click.
void GuiMatrix::Populate(QGridLayout *layout, const int rows, const int cols) { for ( int i = 0; i < rows; ++ i) { for ( int j = 0; j < cols; ++j) { // QPushButton* btn = new QPushButton(" ") ; MatrixButton *btn= new MatrixButton(); btn->setFixedWidth(20); btn->setStyleSheet("QPushButton{background-color:grey;}" "QPushButton[rightClicked = true]{background-color:red;}") ; layout->addWidget(btn,i,j) ; this->addButton(btn) ; } } }
I have also tried :
btn->setStyleSheet("QPushButton{background-color:grey;}" "QPushButton:pressed{background-color:red;}") ;
-
@doubitchou
First of, you changed the variable name, so you'll need to change your stylesheet too,//from btn->setStyleSheet("QPushButton{background-color:grey;}" "QPushButton[rightClicked = true]{background-color:red;}") //to btn->setStyleSheet("QPushButton{background-color:grey;}" "QPushButton[_rightClicked = true]{background-color:red;}")
just tested it in a small sample project, with this btn construction:
MatrixButton *btn = new MatrixButton(); btn->setStyleSheet("QPushButton{background-color:red;}" "QPushButton[_rightClicked = true]{background-color:white;}"); btn->show();
works as expected. If this still does not work for you, than you probably have a stylesheet in a parent widget overwriting your background-color.
-
I see what you mean, in a way it's working. Until the click event, the white color is done.
But after the click who change the color, ie :void MyClass::buttonClick(QAbstractButton* button) { button->setStyleSheet("background-color: #ffa500;") ; }
the white from the right click doesn't appear anymore. even though this is not a parent, and this is done the same way (background-color) . Does your small example change the color on the click event and can put the white color back for the right-click ?
-
@doubitchou
Yes the example does that. The color is changed back when you click with any Mousebutton but the right one or when your call manuallychangeState
button->changeState(false);
with this
void MyClass::buttonClick(QAbstractButton* button)
{
button->setStyleSheet("background-color: #ffa500;") ;
}you overwrite the stylesheet you previously set, and
"QPushButton[_rightClicked = true]{background-color:white;}"
has no effect any longer because it is no longer appplied to the button. -
I see. Sorry, I don't really have much knowledge about Stylesheets.
enlightened by what you said, this is obvious now.
Anyway it's far from obvious to see how to be able to either change the color by click or by right click ?I try to put back the same code you provide, when the click event appears ?
-
Well it seems right, I don't know if this is the best implementation but it's working. I have to overwrite that way
QString ColorString = "QPushButton{background-color: " + QString("#%1").arg(BtnColorValue, 6, 16, QLatin1Char( '0' )) + ";} QPushButton[_rightClicked = true]{background-color:white;} ";
It seems a complicated way to build the string but BtnColorValue come from a color list (which is a QList) I have to cycle with
-
Thanks for your precious help, I still don't figure how to manage events with stylesheets as the docs are mostly about visual customization, but I'm sure this can be found somewhere.