zoukankan      html  css  js  c++  java
  • 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);
        }
    }




    程序运行截图:

  • 相关阅读:
    grep 和vim用法
    【python】初识函数
    【python】 文件相关操作
    【python】基础数据类型相关知识点补充和深浅拷贝
    【python】is和==的区别以及encode()和decode()
    python中的字典以及相关操作
    python列表元祖以及range
    python基本数据类型
    python基础逻辑运算
    了解Python与安装Python解释器
  • 原文地址:https://www.cnblogs.com/pangblog/p/3244011.html
Copyright © 2011-2022 走看看