Results 1 to 19 of 19

Thread: Creating Custom Ellipse Button

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jan 2007
    Posts
    209
    Thanks
    34
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Creating Custom Ellipse Button

    I tried this code then did QEllipseButton b; b.setText("woot"); b.show(); in a simple window of Qt, and it will not show the area. I tried r3, and r1, update,setting a background... but it wont make me a button with a different size.

    Like I would like to make an egg shaped button that works just like a pushbutton, but has a nice background image on it.

    Qt Code:
    1. class QEllipseButton : public QPushButton {
    2. public:
    3. QEllipseButton(QWidget * parent = 0): QPushButton(parent){
    4. }
    5. protected:
    6. void paintEvent ( QPaintEvent * event ){
    7. QRegion r1(QRect(200, 50, 500, 400), // r1: elliptic region
    8. QRegion::Ellipse);
    9. QRegion r2(QRect(200, 70, 90, 30)); // r2: rectangular region
    10. QRegion r3 = r1.intersected(r2); // r3: intersection
    11.  
    12. QPainter painter(this);
    13. painter.setClipping(true);
    14. painter.setClipRegion(r1);
    15. //QBrush brush(QColor(255,0,0,255));
    16. //painter.setBackground(brush);
    17. //update();
    18. }
    19. };
    To copy to clipboard, switch view to plain text mode 

    thx for help.

  2. #2
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Creating Custom Ellipse Button

    Why don't you try QWidget::setMask( const QRegion& ).
    Using a painter to achieve this will probably not work, because the background of the widget is not (yet) transparent. You could first fill the widget rect with a transparent pixmap but it is better and easier to use QWidget::setMask.

    Regards

  3. #3
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Creating Custom Ellipse Button

    Oh, and even if you subclass QPushButton, overriding paintEvent will not keep the push button behavior. If you like, you could call QPushButton:aintEvent in the paint event of your class( at the beginning ). But this could mess up things even more...

    In my opinnion, the best solution is to subclass QAbstractButton and custom draw your button in all the states ( pressed, normal, hovered, disabled, etc...). This allows more freedom in defining the look of your widget.

    Regards

  4. #4
    Join Date
    Jan 2007
    Posts
    209
    Thanks
    34
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Creating Custom Ellipse Button

    Could you show any code examples of this?

  5. #5
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Creating Custom Ellipse Button

    Unfortunately I do not have any examples, nor the time to create one . But it should be pretty straightforwards.

    You define an enum in your QAbstractButton subclass.
    Qt Code:
    1. typedef enum States
    2. {
    3. eStateNormal,
    4. eStatePressed,
    5. eStateHovered,
    6. eStateDisabled
    7. } States;
    To copy to clipboard, switch view to plain text mode 
    Then , add a State member in your class.
    The state switching depends on the user actions.
    Initially you start with eStateNormal.
    In mousePressEvent, if the button is Qt::LeftButton, the state is eStatePressed.
    In mouseMoveEvent, if no btns are pressed, the state is eStateHovered.
    In mouseReleaseEvent, if the previous state was eStatePressed, then switch to eStateNormal.

    After this, everything happens in paintEvent:
    Qt Code:
    1. void MyBtn::paintEvent( QPaintEvent* )
    2. {
    3. switch( mButtonState )
    4. {
    5. case eStateNormal:
    6. //Paint in this state
    7. break;
    8. case eStatePressed:
    9. //Paint in this state
    10. break;
    11. case eStateHovered:
    12. //Paint in this state
    13. break;
    14. case eStateDisabled:
    15. //Paint in this state
    16. break;
    17. }
    18. }
    To copy to clipboard, switch view to plain text mode 

    Actually, you should make pixmaps for all the states ( either external or you build them here ). It will make drawing faster.

    Regards

  6. #6
    Join Date
    Jan 2007
    Posts
    209
    Thanks
    34
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Creating Custom Ellipse Button

    Yeah I don't think this is working:
    Qt Code:
    1. class QEllipseButton : public QAbstractButton {
    2. public:
    3. typedef enum States
    4. {
    5. eStateNormal,
    6. eStatePressed,
    7. eStateHovered,
    8. eStateDisabled
    9. } States;
    10. States m_ButtonState;
    11. QEllipseButton(QWidget * parent = 0): QAbstractButton(parent){
    12. m_ButtonState = eStateNormal;
    13. }
    14. protected:
    15. void mousePressEvent(QMouseEvent *event){
    16. if (event->button() == Qt::LeftButton) {
    17. m_ButtonState = eStatePressed;
    18. }
    19. }
    20. void mouseMoveEvent(QMouseEvent *event){
    21. if(event->buttons() & Qt::LeftButton) {
    22. m_ButtonState = eStateHovered;
    23. }
    24. }
    25. void mouseReleaseEvent(QMouseEvent *event){
    26. if(event->buttons() && m_ButtonState == eStatePressed){
    27. m_ButtonState = eStateNormal;
    28. }
    29. }
    30. void paintEvent ( QPaintEvent * event ){
    31. QRegion r1(QRect(200, 50, 500, 400), // r1: elliptic region
    32. QRegion::Ellipse);
    33. QRegion r2(QRect(200, 70, 90, 30)); // r2: rectangular region
    34. QRegion r3 = r1.intersected(r2); // r3: intersection
    35.  
    36. QPainter painter(this);
    37. QPixmap qpx;
    38. switch( m_ButtonState ){
    39. case eStateNormal:
    40. qpx.load(QString("JoinNormal.jpg"));
    41. break;
    42. case eStatePressed:
    43. qpx.load(QString("JoinPressed.jpg"));
    44. break;
    45. case eStateHovered:
    46. qpx.load(QString("JoinHover.jpg"));
    47. break;
    48. case eStateDisabled:
    49. qpx.load(QString("JoinNormal.jpg"));
    50. break;
    51. }
    52. QRectF target(10.0, 20.0, 80.0, 60.0);
    53. QRectF source(0.0, 0.0, 70.0, 40.0);
    54. painter.drawPixmap(target, qpx, source);
    55. painter.setClipping(true);
    56. painter.setClipRegion(r1);
    57. //QBrush brush(QColor(255,0,0,255));
    58. //painter.setBackground(brush);
    59. //update();
    60. }
    61. };
    To copy to clipboard, switch view to plain text mode 


    class QEllipseButton : public QAbstractButton {
    public:
    typedef enum States
    {
    eStateNormal,
    eStatePressed,
    eStateHovered,
    eStateDisabled
    } States;
    States m_ButtonState;
    QEllipseButton(QWidget * parent = 0): QAbstractButton(parent){
    m_ButtonState = eStateNormal;
    }
    protected:
    void mousePressEvent(QMouseEvent *event){
    if (event->button() == Qt::LeftButton) {
    m_ButtonState = eStatePressed;
    }
    }
    void mouseMoveEvent(QMouseEvent *event){
    if(event->buttons() & Qt::LeftButton) {
    m_ButtonState = eStateHovered;
    }
    }
    void mouseReleaseEvent(QMouseEvent *event){
    if(event->buttons() && m_ButtonState == eStatePressed){
    m_ButtonState = eStateNormal;
    }
    }
    void paintEvent ( QPaintEvent * event ){
    QRegion r1(QRect(200, 50, 500, 400), // r1: elliptic region
    QRegion::Ellipse);
    QRegion r2(QRect(200, 70, 90, 30)); // r2: rectangular region
    QRegion r3 = r1.intersected(r2); // r3: intersection

    QPainter painter(this);
    QPixmap qpx;
    switch( m_ButtonState ){
    case eStateNormal:
    qpx.load(QString("JoinNormal.jpg"));
    break;
    case eStatePressed:
    qpx.load(QString("JoinPressed.jpg"));
    break;
    case eStateHovered:
    qpx.load(QString("JoinHover.jpg"));
    break;
    case eStateDisabled:
    qpx.load(QString("JoinNormal.jpg"));
    break;
    }
    QRectF target(10.0, 20.0, 80.0, 60.0);
    QRectF source(0.0, 0.0, 70.0, 40.0);
    painter.drawPixmap(target, qpx, source);
    painter.setClipping(true);
    painter.setClipRegion(r1);
    //QBrush brush(QColor(255,0,0,255));
    //painter.setBackground(brush);
    //update();
    }
    };


    I posted twice, so you can copy one, since someone not so smart decided to use number lines with Geshi knowing that no one can COPY the code because of damn number lines.

  7. #7
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 163 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Creating Custom Ellipse Button

    You have to trigger repainting after updating your state (call update()).
    Just setting your internal state variable will not cause your button to repaint itself in this state.

    HTH
    Christoph

  8. #8
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Creating Custom Ellipse Button

    Yes.
    I forgot that, but you must call an update() to schedule a paintEvent each time you switch the states.

    Other than this, the code looks good.

    Regards

  9. #9
    Join Date
    Jan 2007
    Posts
    209
    Thanks
    34
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Creating Custom Ellipse Button

    No the code still does not work:

    #include <QtGui>
    #include "flowlayout.h"
    class QEllipseButton : public QAbstractButton {
    public:
    typedef enum States
    {
    eStateNormal,
    eStatePressed,
    eStateHovered,
    eStateDisabled
    } States;
    States m_ButtonState;
    QEllipseButton(QWidget * parent = 0): QAbstractButton(parent){
    m_ButtonState = eStateNormal;
    }
    protected:
    void mousePressEvent(QMouseEvent *event){
    if (event->button() == Qt::LeftButton) {
    m_ButtonState = eStatePressed;
    update();
    }
    }
    void mouseMoveEvent(QMouseEvent *event){
    if(event->buttons() & Qt::LeftButton) {
    m_ButtonState = eStateHovered;
    update();
    }
    }
    void mouseReleaseEvent(QMouseEvent *event){
    if(event->buttons() && m_ButtonState == eStatePressed){
    m_ButtonState = eStateNormal;
    update();
    }
    }
    void paintEvent ( QPaintEvent * event ){
    QRegion r1(QRect(200, 50, 500, 400), // r1: elliptic region
    QRegion::Ellipse);
    QRegion r2(QRect(200, 70, 90, 30)); // r2: rectangular region
    QRegion r3 = r1.intersected(r2); // r3: intersection

    QPainter painter(this);
    QPixmap qpx;
    switch( m_ButtonState ){
    case eStateNormal:
    qpx.load(QString("Normal.jpg"));
    break;
    case eStatePressed:
    qpx.load(QString("Pressed.jpg"));
    break;
    case eStateHovered:
    qpx.load(QString("Hover.jpg"));
    break;
    case eStateDisabled:
    qpx.load(QString("Normal.jpg"));
    break;
    }
    QRectF target(100.0, 100.0, 100.0, 100.0);
    QRectF source(100.0, 100.0, 100.0, 100.0);
    painter.drawPixmap(target, qpx, source);
    painter.setClipping(true);
    painter.setClipRegion(r1);
    //QBrush brush(QColor(255,0,0,255));
    //painter.setBackground(brush);
    //update();
    }
    };

    ----------------- hOW i run it: -------
    QEllipseButton b;
    b.setText("hoot");
    b.show();

  10. #10
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Creating Custom Ellipse Button

    Qt Code:
    1. QRectF target(100.0, 100.0, 100.0, 100.0);
    2. QRectF source(100.0, 100.0, 100.0, 100.0);
    To copy to clipboard, switch view to plain text mode 
    Is the problem, by any chance, that you don't see any pixmap?
    Try drawing everything relative to (0,0), not (100, 100).
    Also, overwrite QAbstractButton::sizeHint() and return your size hint( which probably is the size of one of the pixmaps ).

    Regards

  11. #11
    Join Date
    Jan 2007
    Posts
    209
    Thanks
    34
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Creating Custom Ellipse Button

    I used 0, and I finally saw the picture. However, the clip stuff never works. Also putting everything inside a QHBoxLayout and settingLayout with a widget, makes it dissappear.

    Also Hover absolutely does not work.

Similar Threads

  1. Connect Button to a custom slot
    By Majestade in forum Qt Programming
    Replies: 2
    Last Post: 28th March 2007, 17:17
  2. custom maximize button---
    By Naveen in forum Qt Programming
    Replies: 1
    Last Post: 24th February 2006, 13:11

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.