子类化QWidget IconEditor实现<二>

接上一章

 现在我们系统的来分析下IconEditor,下面是iconEditor.h文件的内容:

#ifndef ICONEDITOR_H
#define ICONEDITOR_H
 
#include <QWidget>
#include <QColor>
#include <QImage>
 
 
 
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:
    iconeditor(QWidget *parent = 0);
 
    void setPenColor(const QColor  &newColor);
    QColor penColor() const {return curColor;}
    void setIconImage(const QImage &newImage);
    QImage iconImage() const {return image;}
    void setZoomFactor(int newZoom);
    int zoomFactor() const {return zoom;}
    QSize sizeHint() const;
 
    ~iconeditor();
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;
};
 
#endif // ICONEDITOR_H
 

iconeditor继承QWidget类,如果用到槽函数那么Q_OBJECT是必须的。

这里使用Q_PROPERTY()宏声明了三个自定义属性:penColor、iconImage、zoomFactor,每一个属性都有一个数据类型,一个“读”函数和一个可选的“写”函数,关于Q_PROPERTY的原型如下所示,其中:type name 和READ getFunction是必须的。

 Q_PROPERTY(type name
            READ getFunction
            [WRITE setFunction]
            [RESET resetFunction]
            [NOTIFY notifySignal]
            [DESIGNABLE bool]
            [SCRIPTABLE bool]
            [STORED bool]
            [USER bool]
            [CONSTANT]
            [FINAL])
接下来我们看看这几个属性的内容,这里penColor、iconImage、zoomFactor 使用了内联函数

void iconeditor::setPenColor(const QColor &newColor)
{
        curColor  = newColor;
}
 函数setPenColor()会设置笔画的当前颜色、这个颜色将会用于此后新绘制的像素中。 

void iconeditor::setIconImage(const QImage &newImage)
{
    if(newImage != image) {
        image = newImage.convertToFormat(QImage::Format_ARGB32);
        update();
        updateGeometry();
    }
}
 setIconImage()设置需要编辑的图像,如果图像不是正在编辑的图像,则通过convertToFormat()转换成待缓冲的32位的图像,存储在ARGB值中。update()会使用新的图像强制重绘这个窗口部件,updateGeometry()通知这个窗口部件的布局已经发生了改变,于是、该布局会自适应新的布局。 

void iconeditor::setZoomFactor(int newZoom)
{
    if(zoom < 1)
        newZoom = 1;
    if(newZoom != zoom) {
        zoom = newZoom;
        update();
        updateGeometry();
    }
}
用于设置缩放因子,由于在 setImagePixel()中zoom作为被除数,所以应该纠正任何小于1的值。

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().intersect(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::setImagePixel(const QPoint &pos, bool opaque)
{
    int i = pos.x() / zoom;
    int j = pos.y() / zoom;
    if(image.rect().contains(i, j)) {
        if(opaque) {
            image.setPixel(i, j, penColor().rgba());
        } else {
            image.setPixel(i, j, qRgba(0, 0, 0, 0));
        }
        update(pixelRect(i, j));
    }
}
 
QRect iconeditor::pixelRect(int i, int j) const
{
    if(zoom > 3) {
        return QRect(zoom * i + 1, zoom  * j + 1, zoom - 1, zoom - 1);
    } else {
        return QRect(zoom * i, zoom * j, zoom, zoom);
    }
}
 

在这里又要使用到我们前面章节 提到过的QT资源机制的使用了,我们加入这个mouse.png的图片后,在main.cpp中

    iconeditor *IconEdit = new iconeditor;
    IconEdit->setIconImage(QImage(":/image/mouse.png"));
    IconEdit->show();
调用下前面实现的setIconImage就可以看到如下效果了:






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值