Results 1 to 4 of 4

Thread: Creating flat QPushButton in Linux, without button sinking when clicked

  1. #1
    Join Date
    Aug 2014
    Posts
    11
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Creating flat QPushButton in Linux, without button sinking when clicked

    Hi,

    I am having some issue in coding in QT for Linux.
    The scenario is that I have to create some pushbuttons, but I don't want QT native pushbutton, and I have images for both Pressed and Normal states of the button.

    I am using QIcon, QStylesheet and QPaintEvent overriding to display the image.

    Here is the code structure

    header file:
    Qt Code:
    1. class NewButton:public QPushButton
    2. {
    3. private:
    4. QString normalImage;
    5. QString pressedImage;
    6. public:
    7. NewButton() : QPushButton() {}
    8. NewButton(QWidget *w) : QPushButton(w) {}
    9. void setNormalImage(QString nImg)
    10. {
    11. normalImage=nImg;
    12. }
    13. void setPressedImage(QString pImg)
    14. {
    15. pressedImage=pImg;
    16. }
    17. void paintEvent(QPaintEvent *event)
    18. {
    19. QPixmap pmapUp(normalImage);
    20. pmapUp.setMask(pmapUp.createMaskFromColor(QColor(255,0,255)));
    21. QPixmap pmapDown(pressedImage);
    22. pmapDown.setMask(pmapDown.createMaskFromColor(QColor(255,0,255)));
    23.  
    24. QIcon icon;
    25. if (this->isDown())
    26. {
    27. icon.addPixmap(pmapDown, QIcon::Normal, QIcon::On);
    28. icon.addPixmap(pmapDown, QIcon::Normal, QIcon::Off);
    29. }
    30. else
    31. {
    32. icon.addPixmap(pmapUp, QIcon::Normal, QIcon::On);
    33. icon.addPixmap(pmapUp, QIcon::Normal, QIcon::Off);
    34. }
    35. this->setIcon(icon);
    36. QPushButton::paintEvent(event)
    37. }
    38. };
    39.  
    40. class MainWindow:public QMainWindow
    41. {
    42. public:
    43. explicit MainWindow(QWidget *parent = 0);
    44. ~MainWindow();
    45. private:
    46. NewButton *pb;
    47. }
    To copy to clipboard, switch view to plain text mode 

    cpp file

    Qt Code:
    1. MainWindow::MainWindow(QWidget *parent) :
    2. QMainWindow(parent)
    3. {
    4. setGeometry(10,10,800,600);
    5. centralWidget = new QWidget(this);
    6. centralWidget->setObjectName(QStringLiteral("centralWidget"));
    7. centralWidget->setGeometry(0,0,780,580);
    8. pb=new NewButton(centralWidget);
    9. pb->setGeometry(20,20,116,68);
    10. pb->setFlat(true);
    11. pb->setIconSize(QSize(116,68));
    12. pb->setStyleSheet("QPushButton{border:0px; outline: none;}");
    13. pb->show();
    14. }
    To copy to clipboard, switch view to plain text mode 


    This code is working fine in Windows, i.e. the button doesn't get shifted (sunken) when clicked. But in Linux the button is moving/shifting/sinking when clicked.
    i found that out by passing same image for normal and pressed image.
    In case of Windows, nothing happens when the button is clicked, but in Linux case, click is seen by sunken/risen images.

    I want the Windows type behavior, since the pressed image is also passed by me which is already sunken. So basically in Linux case, it gets sunken twice (once by the image, and other by QT native)

    I have tried some QProxyStyle

    Qt Code:
    1. class MyProxyStyle : public QProxyStyle
    2. {
    3. public:
    4. MyProxyStyle(QStyle *style = 0) : QProxyStyle(style) { }
    5. int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) {
    6. cout<<"pixelMetric enter"<<endl;
    7. int ret = 0;
    8. switch (metric) {
    9. case QStyle::PM_ButtonShiftHorizontal:
    10. case QStyle::PM_ButtonShiftVertical:
    11. ret = 0;//QProxyStyle::pixelMetric(metric, option, widget)+20;
    12. break;
    13. default:
    14. ret = QProxyStyle::pixelMetric(metric, option, widget);
    15. break;
    16. }
    17. return ret;
    18. }
    19. };
    To copy to clipboard, switch view to plain text mode 

    And in cpp file, I tried

    Qt Code:
    1. pb->setStyle(new MyProxyStyle(pb->style()));
    To copy to clipboard, switch view to plain text mode 
    But this is having no effect. Also the "cout" under pixelMetric is not getting executed. So maybe the style is not getting set to this PushButton.

    Can anyone please help me. I am completely stuck on this.
    I am using Qt 5.3.1 (also tried on Qt 5.2.1)

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Creating flat QPushButton in Linux, without button sinking when clicked

    I guess the main problem is calling QPushButton:aintEvent().

    Do you need this to be a QPushButton subclass? It looks like this would be more a case when to derive from QAbstractButton.

    Cheers,
    _

  3. The following user says thank you to anda_skoa for this useful post:

    ashtray4241 (10th October 2014)

  4. #3
    Join Date
    Aug 2014
    Posts
    11
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Creating flat QPushButton in Linux, without button sinking when clicked

    Thanks for your reply. I haven't tried with QAbstractButton. And I think apart from SetFlat(), I don't need any functionality specific to QPushButton, so I guess QAbstractButton can be tried.
    Btw, after several hits and trials, I have found a solution, although I am not sure how elegant that is.

    So basically, instead of calling "QPushButton:aintEvent(event)" in overridden paintEvent, I am using "drawControl" directly from this function. And here, instead of checking is button is down/checked to set "option.state" to QStyle::State_Sunken/QStyle::State_Raised (as done in QPushButton paintEvent), I am directly setting it to QStyle::State_Raised without any checks. This way the button is never sinks.
    So until I find something more elegant than this, I will consider the issue to be fixed.

  5. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Creating flat QPushButton in Linux, without button sinking when clicked

    That sounds like a suitable solution as well.

    The initial implementation just did too much my calling the base class paintEvent() as a whole, doing what it would have done but leaving out things it should no longer do is a viable approach.

    Cheers,
    _

Similar Threads

  1. QPushbutton, background-color but flat ?
    By gab74 in forum Qt Programming
    Replies: 4
    Last Post: 15th December 2011, 10:15
  2. how i want flat Drop-down Button for ComboBox ?
    By pavanbarot in forum Qt Programming
    Replies: 2
    Last Post: 7th September 2010, 06:50
  3. make a flat QPushButton
    By harmodrew in forum Newbie
    Replies: 2
    Last Post: 6th August 2010, 16:46
  4. How to show QPushButton as flat when it is checked
    By santosh.kumar in forum Qt Programming
    Replies: 1
    Last Post: 3rd August 2010, 10:07
  5. QPushbutton Flat property and icon appearance.
    By darpan in forum Qt Programming
    Replies: 1
    Last Post: 4th November 2006, 08:30

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.