Qt学习之自定义窗口部件

自定义Qt窗口部件

实现一个十六进制的SpinBox,一般SpinBox只支持十进制整数,但是可以子类化方法实现该功能
需重新实现以下虚函数
virtual QString	textFromValue ( int value ) const
virtual int	valueFromText ( const QString & text ) const
例如:(摘抄自QtAssitant)
 int IconSizeSpinBox::valueFromText(const QString &text) const
 {
     QRegExp regExp(tr("(\\d+)(\\s*[xx]\\s*\\d+)?"));

     if (regExp.exactMatch(text)) {
         return regExp.cap(1).toInt();
     } else {
         return 0;
     }
 }

 QString IconSizeSpinBox::textFromValue(int value) const
 {
     return tr("%1 x %1").arg(value);
 }
自己实现hexspinBox的代码
#ifndef HEXSPINBOX_H
#define HEXSPINBOX_H

#include <QSpinBox>


class QRegExpValidator;
class hexspinBox : public QSpinBox
{
    Q_OBJECT
    
public:
    explicit hexspinBox(QWidget *parent = 0);
    ~hexspinBox();
    
protected:
    //重写基类函数
    QValidator::State validate(QString &input, int &pos) const;
    int valueFromText(const QString &text) const;
    QString textFromValue(int val) const;
private:
    QRegExpValidator *validator;

};

#endif // HEXSPINBOX_H
//实现代码
#include "hexspinbox.h"
#include <QSpinBox>

hexspinBox::hexspinBox(QWidget *parent) :
    QSpinBox(parent)
{
   setRange(0, 255);
   validator = new QRegExpValidator(QRegExp("[0-9A-Fa-F]{0, 8}"), this);
}

QValidator::State hexspinBox::validate(QString &input, int &pos) const{
    return validator->validate(input, pos);
}

QString hexspinBox::textFromValue(int val) const{
    return QString::number(val, 16).toUpper();
}

int hexspinBox::valueFromText(const QString &text) const{
    bool ok;
    return text.toInt(&ok, 16);
}

子类化QWidget

当手里没有任何一个Qt窗口部件能够满足任何任务需求时,我们可以创建自己想要的窗口部件。要实现这一点,只需通过子类化QWidget,并且通过重新实现一些用来绘制窗口部件和相应鼠标点击的事件处理器即可
比如继承QWidget类
例如,创建一个可以改变区域颜色的简单图形界面程序
先让主类继承QWidget,在重写需要自己实现的虚函数,如下面的 mousePressEvent , mouseMoveEvent, paintEvent
class IconEditor : public QWidget
{
    Q_OBJECT
    //声明类的属性
    Q_PROPERTY(QColor penColor READ  penColor WRITE setPenColor)
    Q_PROPERTY(QImage iconImage READ  iconImage WRITE setIconImage)
    Q_PROPERTY(int zoomFactor READ  zoomFactor WRITE setZoomFactor)    

public:
    explicit IconEditor(QWidget *parent = 0);
    ~IconEditor();
    
    void setPenColor(const QColor &newColor);
    QColor penColor() const { return curColor; }
    void setZoomFactor(int newZoom);
    int zoomFactor() const { return zoom; }
    void setIconImage(const QImage &newImage);
    QImage iconImage() const { return image; }
    QSize sizeHint() const;
    
protected:
    void mousePressEvent(QMouseEvent *);
    void mouseMoveEvent(QMouseEvent *);
    void paintEvent(QPaintEvent *);
    
private:
    void setImagePixel(const QPoint &pos, bool opaque);
    QRect pixelRect(int i, int j) const;
    
    QColor curColor;
    QImage image;
    int zoom;
};

再依次实现类中的函数,与MFC中自绘控件是一回事。以下是cpp中部分代码
void IconEditor::paintEvent(QPaintEvent *event){
    QPainter painter(this);
    
    if(zoom>=3){
        painter.setPen(palette().foreground().color());
        for(int i=0; i<=image.width(); i++){
            painter.drawLine(zoom*i, 0,
                             zoom*i, zoom*image.height());
            for(int j=0; j<=image.height(); j++){
                painter.drawLine(0, zoom*j,
                                 zoom*image.width(), zoom*j);
            }
            for(int i=0; i<image.width(); i++){
                for(int j=0; j<image.height(); j++){
                    QRect rect = pixelRect(i, j);
                    if(!event->region().intersected(rect).isEmpty()){
                        QColor color = QColor::fromRgba(image.pixel(i, j));
                        if(color.alpha()<255)
                            painter.fillRect(rect, Qt::white);
                        painter.fillRect(rect, color);
                    }
                }
            }
        }
    }
}
void IconEditor::mousePressEvent(QMouseEvent *event){
    if(event->button() == Qt::LeftButton){
        setImagePixel(event->pos(), true);
    } else if(event->button()==Qt::RightButton){
        setImagePixel(event->pos(), false);
    }
}

void IconEditor::mouseMoveEvent(QMouseEvent *event){
    if(event->buttons() & Qt::LeftButton){
        setImagePixel(event->pos(), true);
    } else if(event->buttons() & Qt::RightButton){
        setImagePixel(event->pos(), false);
    }
}




程序运行截图:

 

posted @ 2013-08-07 19:25  pangbangb  阅读(492)  评论(0编辑  收藏  举报