QGraphicsWidget custom control implementation button

Source: Internet
Author: User
Tags drawtext

The implementation of the button is similar to the implementation of the label function, but the button has three states: normal, hover, and pressed. You only need to implement the three States differently.


Three different buttons are also designed here. Only the icon is displayed, only the text is displayed, and both the text and the icon are displayed.


int main(int argc, char *argv[]){    QApplication app(argc, argv);    QGraphicsScene *scene = new QGraphicsScene;    QGraphicsView *view = new QGraphicsView(scene);    scene->setSceneRect(0, 0, 300, 300);                                                                                                                                                                                                      QPixmap normalPixmap("images/button_normal.png");    QPixmap hoverPixmap("images/button_hover.png");    QPixmap pressedPixmap("images/button_pressdown.png");    ShowButton *showbutton1 = new ShowButton(normalPixmap, hoverPixmap, pressedPixmap);        ......}

This is also based on QGraphicsWidget. Therefore, you must first create a scenario scene and then read three different images as the background image of the button in three different states.


The ShowButton here is the control we want to implement. The following shows the header file of the control.

Showbutton. h

#ifndef SHOWBUTTON_H#define SHOWBUTTON_H#include <QGraphicsWidget>class QGraphicsSceneMouseEvent;class QGraphicsSceneHoverEvent;class ShowButton: public QGraphicsWidget{    Q_OBJECTpublic:    enum State { NormalState, HoverState, PressedState };    enum Style { TextOnly, IconOnly, TextBesidesIcon, TextUnderIcon};public:    ShowButton(const QPixmap &, const QPixmap &, const QPixmap &);    void setText(const QString &, const QFont &, const QColor &);    void setIcon(const QPixmap& icon);    void setStyle(Style style);    QString getText();signals:    void clicked();protected:    void mousePressEvent(QGraphicsSceneMouseEvent *e);    void mouseReleaseEvent(QGraphicsSceneMouseEvent *e);    void hoverEnterEvent(QGraphicsSceneHoverEvent *e);    void hoverLeaveEvent(QGraphicsSceneHoverEvent *);protected:    virtual QRectF boundingRect();    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);private:    void setPixmap(State state);private:    int m_cnt;    bool m_isPressed;    bool m_iconOn;    bool m_textOn;    QPixmap m_pixmap;    QPixmap m_normalPixmap;    QPixmap m_hoverPixmap;    QPixmap m_pressedPixmap;    QPixmap m_icon;    QString m_text;    QSize m_size;    QFont m_font;    QColor m_color;    Style m_style;                                                                                                                                                       };#endif // SHOWBUTTON_H

SetPixmap (State state State) is private here because this function does not provide external interfaces, but is only used for setting the button background image internally.


The specific implementation of functions is as follows,

Showbutton. cpp

# Include <QPainter> # include <QGraphicsSceneMouseEvent> # include <QGraphicsSceneHoverEvent> # include "showbutton. h "# include" clickhandler. h "ShowButton: ShowButton (const QPixmap & normalPixmap, const QPixmap & hoverPixmap, const QPixmap & pressedPixmap): m_isPressed (false), m_iconOn (false), m_textOn (false) {m_cnt = 0; m_text = ""; m_icon = NULL; m_pixmap = normalPixmap; m_normalPixmap = normalPixmap; m_ho VerPixmap = hoverPixmap; m_pressedPixmap = pressedPixmap; setAcceptHoverEvents (true);} void ShowButton: setStyle (Style style) {if (style = m_style) {return;} m_style = style; if (IconOnly = style) {m_iconOn = true; m_textOn = false;} else if (TextOnly = style) {m_iconOn = false; m_textOn = true ;} else {m_iconOn = true; m_textOn = true ;}} void ShowButton: setText (const QString & string, Const QFont & font, const QColor & color) {m_text = string; m_textOn = true; m_font = font; m_color = color;} void ShowButton: setIcon (const QPixmap & icon) {m_icon = icon; m_iconOn = true;} void ShowButton: paint (QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) {Q_UNUSED (option); Q_UNUSED (widget ); const QRect & rect = boundingRect (). toRect (); setPreferredSize (rect. width (), Rect. height (); // draw the background painter of the button-> drawPixmap (rect, m_pixmap); if (m_iconOn &&! M_icon.isNull () {QRect iconRect (0, 0, m_icon.size (). width (), m_icon.size (). height (); painter-> drawPixmap (iconRect, m_icon);} else if (m_textOn &&! M_text.isEmpty () {QFontMetrics metrics (m_font); qreal width = metrics. width (m_text); qreal height = metrics. height (); QRect textRect (0, 0, width, height); painter-> drawText (textRect, Qt: AlignCenter, m_text );} // if (m_textOn & m_iconOn &&! M_icon.isNull ()&&! M_text.isEmpty () {// text beside the icon if (TextBesidesIcon = m_style) {QRect mixRect (0, 0, m_icon.size (). width (), rect. height (); painter-> drawPixmap (mixRect, m_icon); QRect textRect (m_icon.size (). width (), 0, rect. width ()-m_icon.size (). width (), rect. height (); painter-> drawText (textRect, Qt: AlignCenter, m_text);} // text under the icon if (TextUnderIcon = m_style) {QRect mixRect (0, 0, rect. width (), m_icon.size (). Height (); painter-> drawPixmap (mixRect, m_icon); QRect textRect (0, m_icon.size (). height (), rect. width (), rect. height ()-m_icon.size (). height (); painter-> drawText (textRect, Qt: AlignCenter, m_text) ;}} QRectF ShowButton: boundingRect () {m_size = m_pixmap.size (); qreal widthText; qreal heightText; QSize iconSize; qreal totalWidth; qreal totalHeight; // obtain the width and height of text information if (m_textOn) {QFontMetrics metric S (m_font); widthText = metrics. width (m_text); heightText = metrics. height (); // return QRectF (0, 0, widthText, heightText);} // obtain the width and height of the icon if (m_iconOn) {iconSize = m_icon.size ();} if (2 = m_style) {totalWidth = widthText + iconSize. width (); totalHeight = heightText> iconSize. height ()? HeightText: iconSize. height ();} else if (3 = m_style) {totalWidth = widthText> iconSize. width ()? WidthText: iconSize. width (); totalHeight = heightText + iconSize. height ();} else {totalWidth = widthText + iconSize. width (); totalHeight = heightText + iconSize. height ();} return QRectF (0, 0, totalWidth, totalHeight);} void ShowButton: setPixmap (State state) {switch (state) {case NormalState: m_pixmap = m_normalPixmap; break; case HoverState: m_pixmap = m_hoverPixmap; break; case PressedState: M_pixmap = m_pressedPixmap; break;} void ShowButton: mousePressEvent (QGraphicsSceneMouseEvent * e) {if (e-> button () = Qt: LeftButton) {m_isPressed = true; setPixmap (PressedState); update () ;}} void ShowButton: mouseReleaseEvent (QGraphicsSceneMouseEvent * e) {if (e-> button () = Qt: LeftButton) {if (m_isPressed) {m_cnt ++; m_isPressed = false; setPixmap (NormalState); update (); emit clicked (); }}} Void ShowButton: hoverEnterEvent (QGraphicsSceneHoverEvent *) {if (! M_isPressed) {setPixmap (HoverState); update () ;}} void ShowButton: hoverLeaveEvent (QGraphicsSceneHoverEvent *) {if (! M_isPressed) {setPixmap (NormalState); update () ;}} QString ShowButton: getText () {return m_text ;}

It should be noted that the ShowButton: mouseReleaseEvent function does not implement the response itself, but only sends a clicked () signal, and the response to the message, that is, the slot corresponding to the signal will be separately encapsulated in a class, which facilitates different message responses. The implementation of the class composed of the slots for processing message responses is as follows:

Clickhandler. h

#include <QUrl>class ClickHandler : public QObject{    Q_OBJECT;public:    ClickHandler(QObject* parent);private slots:    void on_linkOpen();    void on_messageBox();};

Clickhandler. cpp

#include <QDesktopServices>#include <QMessageBox>#include "showbutton.h"#include "clickhandler.h"void ClickHandler::on_linkOpen(){    ShowButton* button = qobject_cast<ShowButton*>(sender());    QString text = button->getText();    text = "www.hao123.com";    QDesktopServices::openUrl(text);}void ClickHandler::on_messageBox(){    ShowButton* button = qobject_cast<ShowButton*>(sender());    QString text = button->getText();    QMessageBox::about(NULL, "msg box", text);}ClickHandler::ClickHandler( QObject* parent ): QObject(parent){}

Pay attention to the ClickHandler: on_linkOpen () function. This function can automatically obtain the text information in the button, convert the text into a URL address, and then open it, in order to facilitate the absence of code on the false address of text information, interested readers can add the code themselves, and the source code of the program will be placed in the attachment. The preceding Implementation of custom control layout is also used. For more information, see the previous article.

Main. cpp

ShowButton *showbutton1 = new ShowButton(normalPixmap, hoverPixmap, pressedPixmap);    showbutton1->setStyle(ShowButton::IconOnly);    QPixmap icon = ("images/yyboy16.ico");    showbutton1->setIcon(icon);    showbutton1->setMaximumSize(icon.size());    ShowButton *showbutton2 = new ShowButton(normalPixmap, hoverPixmap, pressedPixmap);    showbutton2->setStyle(ShowButton::TextOnly);    QFont font("times", 20, QFont::Bold, true);    QColor color(255, 0, 0);    QString str("YY");    showbutton2->setText(str, font, color);    QFontMetrics metrics(font);    qreal wid = metrics.width(str);    qreal hei = metrics.height();     showbutton2->setMaximumSize(wid, hei);    ShowButton *showbutton3 = new ShowButton(normalPixmap, hoverPixmap, pressedPixmap);    showbutton3->setStyle(ShowButton::TextUnderIcon);    showbutton3->setText(str, font, color);    showbutton3->setIcon(icon);                   showbutton3->setMaximumSize(wid + icon.size().width(), hei + icon.size().height());                   ClickHandler *clickHandler = new ClickHandler(view);    QObject::connect(showbutton1, SIGNAL(clicked()), clickHandler, SLOT(on_linkOpen()));    QObject::connect(showbutton2, SIGNAL(clicked()), clickHandler, SLOT(on_messageBox()));    QGraphicsWidget *widget = new QGraphicsWidget;    QGraphicsLinearLayout *linearLayout = new QGraphicsLinearLayout(Qt::Vertical);    linearLayout->addItem(showbutton1);    linearLayout->addItem(showbutton2);    linearLayout->addItem(showbutton3);    widget->setLayout(linearLayout);    scene->addItem(widget);    view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);    view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);    view->resize(300, 300);    view->setWindowTitle(QObject::tr("My hao123 Button"));    view->show();    app.exec();}


This article from the "selling cute programmers" blog, please be sure to keep this source http://7677869.blog.51cto.com/7667869/1265278

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.