Qt小程序(六)-IconEditor

目录

前言

虽然在Qt中可以不使用窗口编程,但是不使用窗口编程,Qt又有什么意义呢!本部分意图实现一个自定义窗口部件!学习,分享,感谢!

paintEvent重写

paintEvent(QPaintEvent* )函数是QWidget类中的虚函数,用于ui的绘制,会在多种情况下被其他函数自动调用,比如update()。一般使用时都会从QWidget类中继承void paintEvent(QPaintEvent *);函数。
因为只是需要使用绘图函数,所以update()自动调用paintEvent(QPaintEvent *)对我来说就足够了。

QPainter类

详细参考这位大神的博客:一去丶二三里,这里引用其中一部分。

QPainter用于执行绘图操作,其提供的API在GUI或QImage、QOpenGLPaintDevice、QWidget和QPaintDevice显示图形(线、形状、渐变等)、文本和图像。
绘图系统由QPainter完成具体的绘制操作,QPainter类提供大量高度优化的函数来完成GUI编程所需要的大部分绘制工作。它可以绘制一切想要的图形,从最简单的一条直线到其他任何复杂的图形,例如:点、线、矩形、饼状图、多边形、贝塞尔弧线等。此外,QPainter也支持一些高级特性,例如反走样、像素融合、渐变填充和矢量路径等,QPainter也执行线性变换,例如平移、旋转、缩放。

代码

这个程序的功能是读入一张图片,通过设置放大倍数,可以把图片在原始的尺寸上放大,相当于把像素点放大,如果放大系数大于3,就画出对应像素点的小方块。然后通过鼠标事件可以设置每一个放大的像素点的颜色。
- main.cpp

#include "iconeditor.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    IconEditor w;

    w.setWindowTitle(QObject::tr("Icon Editor"));
    // this function will call update()
    w.setIconImage(QImage(":/images/mouse.png"));
    w.setPenColor(Qt::yellow);    // 设置画笔颜色
    w.show();

    return a.exec();
}
  • iconeditor.cpp
#include "iconeditor.h"
#include <QPaintEvent>

IconEditor::IconEditor(QWidget *parent)
    : QWidget(parent)
{
    setAttribute(Qt::WA_StaticContents);    // update ignore existed
    setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
    curColor = Qt::black;
    zoom = 8;
    image = QImage(16, 16, QImage::Format_ARGB32);
    image.fill(qRgba(0, 0, 0, 0));
}

IconEditor::~IconEditor()
{

}

void IconEditor::setPenColor(const QColor &newColor)
{
    curColor = newColor;
}

void IconEditor::setZoomFactor(int newZoom)
{
    if(newZoom < 1)
        newZoom = 1;
    if(newZoom != zoom)
    {
        zoom = newZoom;
        update();
        updateGeometry();
    }

}

QSize IconEditor::sizeHint() const
{
    QSize size = zoom * image.size();
    if(zoom >= 3)
        size += QSize(1, 1);
    return size;
}

void IconEditor::paintEvent(QPaintEvent* event)
{
    // define QPainter Object, use QPainter to draw
    QPainter painter(this);

    if(zoom >= 3)
    {
        // every QWidget have a plaette
        // setPen is to set painter Brush color
        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);
            }
        }
    }
}

// this function is set the Rect fill pixel
// 因为线占据了一些坐标点的像素,所以设置的像素区域就要除掉线所占的像素区域
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+1, zoom*j+1, zoom, zoom);
    }
}

void IconEditor::setIconImage(const QImage &newImage)
{
    if(newImage != image)
    {
        image = newImage.convertToFormat(QImage::Format_ARGB32);
        update();       // this function will call paintEvent automatically
        updateGeometry();
    }
}

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);
    }
}

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));    // update the pixel mouse clicked
}

  • iconeditor.h
#ifndef ICONEDITOR_H
#define ICONEDITOR_H

#include <QWidget>
#include <QImage>
#include <QColor>
#include <QPainter>

class IconEditor : public QWidget
{
    Q_OBJECT

public:
    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 *);    // reload
private:
    QImage image;
    QColor curColor;
    int zoom;
    QRect pixelRect(int i, int j) const;
    void setImagePixel(const QPoint &pos, bool opaque);
};

#endif // ICONEDITOR_H

总结

这个程序实现了图标编辑器,可以按系数放大图片,然后设置放大的后的图标的小方格的颜色。总体来说,这个程序包含放大显示、显示图标、鼠标操作三个部分。其实Qt对各种操作分的很清晰,理解起来也很简单。
注意:这些程序都是我从视频中学习来的,代码不是我写的,只是代码的搬运工。
学习!分享!感谢!

上一篇: QPainter学习(一)——绘制函数记录
下一篇: Qt编程错误集锦
simonXi-tech
博客等级 码龄10年 398粉丝 52原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值