解决方案:
moc_iconeditor.cpp
/**************************************************************************** ** Meta object code from reading C++ file 'iconeditor.h' ** ** Created by: The Qt Meta Object Compiler version 67 (Qt 5.4.0) ** ** WARNING! All changes made in this file will be lost! *****************************************************************************/ #include "../../iconeditor.h" #include <QtCore/qbytearray.h> #include <QtCore/qmetatype.h> #if !defined(Q_MOC_OUTPUT_REVISION) #error "The header file 'iconeditor.h' doesn't include <QObject>." #elif Q_MOC_OUTPUT_REVISION != 67 #error "This file was generated using the moc from 5.4.0. It" #error "cannot be used with the include files from this version of Qt." #error "(The moc has changed too much.)" #endif QT_BEGIN_MOC_NAMESPACE struct qt_meta_stringdata_iconEditor_t { QByteArrayData data[5]; char stringdata[48]; }; #define QT_MOC_LITERAL(idx, ofs, len) \ Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \ qptrdiff(offsetof(qt_meta_stringdata_iconEditor_t, stringdata) + ofs \ - idx * sizeof(QByteArrayData)) \ ) static const qt_meta_stringdata_iconEditor_t qt_meta_stringdata_iconEditor = { { QT_MOC_LITERAL(0, 0, 10), // "iconEditor" QT_MOC_LITERAL(1, 11, 8), // "penColor" QT_MOC_LITERAL(2, 20, 9), // "iconImage" QT_MOC_LITERAL(3, 30, 10), // "zoomFactor" QT_MOC_LITERAL(4, 41, 6) // "size_t" }, "iconEditor\0penColor\0iconImage\0zoomFactor\0" "size_t" }; #undef QT_MOC_LITERAL static const uint qt_meta_data_iconEditor[] = { // content: 7, // revision 0, // classname 0, 0, // classinfo 0, 0, // methods 3, 14, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 0, // signalCount // properties: name, type, flags 1, QMetaType::QColor, 0x00095103, 2, QMetaType::QImage, 0x00095103, 3, 0x80000000 | 4, 0x0009510b, 0 // eod }; void iconEditor::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) { Q_UNUSED(_o); Q_UNUSED(_id); Q_UNUSED(_c); Q_UNUSED(_a); } const QMetaObject iconEditor::staticMetaObject = { { &QWidget::staticMetaObject, qt_meta_stringdata_iconEditor.data, qt_meta_data_iconEditor, qt_static_metacall, Q_NULLPTR, Q_NULLPTR } }; const QMetaObject *iconEditor::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject; } void *iconEditor::qt_metacast(const char *_clname) { if (!_clname) return Q_NULLPTR; if (!strcmp(_clname, qt_meta_stringdata_iconEditor.stringdata)) return static_cast<void*>(const_cast< iconEditor*>(this)); return QWidget::qt_metacast(_clname); } int iconEditor::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QWidget::qt_metacall(_c, _id, _a); if (_id < 0) return _id; #ifndef QT_NO_PROPERTIES if (_c == QMetaObject::ReadProperty) { void *_v = _a[0]; switch (_id) { case 0: *reinterpret_cast< QColor*>(_v) = penColor(); break; case 1: *reinterpret_cast< QImage*>(_v) = iconImage(); break; case 2: *reinterpret_cast< size_t*>(_v) = zoomFactor(); break; default: break; } _id -= 3; } else if (_c == QMetaObject::WriteProperty) { void *_v = _a[0]; switch (_id) { case 0: setPenColor(*reinterpret_cast< QColor*>(_v)); break; case 1: setIconImage(*reinterpret_cast< QImage*>(_v)); break; case 2: setZoomFactor(*reinterpret_cast< size_t*>(_v)); break; default: break; } _id -= 3; } else if (_c == QMetaObject::ResetProperty) { _id -= 3; } else if (_c == QMetaObject::QueryPropertyDesignable) { _id -= 3; } else if (_c == QMetaObject::QueryPropertyScriptable) { _id -= 3; } else if (_c == QMetaObject::QueryPropertyStored) { _id -= 3; } else if (_c == QMetaObject::QueryPropertyEditable) { _id -= 3; } else if (_c == QMetaObject::QueryPropertyUser) { _id -= 3; } else if (_c == QMetaObject::RegisterPropertyMetaType) { if (_id < 3) *reinterpret_cast<int*>(_a[0]) = -1; _id -= 3; } #endif // QT_NO_PROPERTIES return _id; } QT_END_MOC_NAMESPACE
/**************************************************************************** ** Resource object code ** ** Created by: The Resource Compiler for Qt version 5.4.0 ** ** WARNING! All changes made in this file will be lost! *****************************************************************************/ #ifdef QT_NAMESPACE # define QT_RCC_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name # define QT_RCC_MANGLE_NAMESPACE0(x) x # define QT_RCC_MANGLE_NAMESPACE1(a, b) a##_##b # define QT_RCC_MANGLE_NAMESPACE2(a, b) QT_RCC_MANGLE_NAMESPACE1(a,b) # define QT_RCC_MANGLE_NAMESPACE(name) QT_RCC_MANGLE_NAMESPACE2( \ QT_RCC_MANGLE_NAMESPACE0(name), QT_RCC_MANGLE_NAMESPACE0(QT_NAMESPACE)) #else # define QT_RCC_PREPEND_NAMESPACE(name) name # define QT_RCC_MANGLE_NAMESPACE(name) name #endif #ifdef QT_NAMESPACE namespace QT_NAMESPACE { #endif #ifdef QT_NAMESPACE } #endif int QT_RCC_MANGLE_NAMESPACE(qInitResources_iconeditor)(); int QT_RCC_MANGLE_NAMESPACE(qInitResources_iconeditor)() { return 1; } int QT_RCC_MANGLE_NAMESPACE(qCleanupResources_iconeditor)(); int QT_RCC_MANGLE_NAMESPACE(qCleanupResources_iconeditor)() { return 1; } namespace { struct initializer { initializer() { QT_RCC_MANGLE_NAMESPACE(qInitResources_iconeditor)(); } ~initializer() { QT_RCC_MANGLE_NAMESPACE(qCleanupResources_iconeditor)(); } } dummy; }
#ifndef ICONEDITOR_H #define ICONEDITOR_H #include <qwidget.h> #include <qimage.h> #include <qcolor.h> class iconEditor : public QWidget { Q_OBJECT Q_PROPERTY(QColor penColor READ penColor WRITE setPenColor) Q_PROPERTY(QImage iconImage READ iconImage WRITE setIconImage) Q_PROPERTY(size_t zoomFactor READ zoomFactor WRITE setZoomFactor) private: const static size_t DEFAULT_ZOOM = 0x00000008;//默认缩放 const static size_t DEFAULT_PIXEL = 0x00000010;//默认像素 const static size_t DEFAULT_FILL = 0x000000FF;//默认填充 const static size_t MIN_ZOOM = 0x00000003;//最小缩放 const static size_t MAX_ALPHA = 0x000000FF;//最大透明 public: iconEditor(QWidget* = NULL); ~iconEditor() = default; public: void setPenColor(const QColor&); const QColor penColor()const{ return m_color; } void setZoomFactor(const size_t); const size_t zoomFactor() const{ return m_zoom; } void setIconImage(const QImage&); const QImage iconImage()const { return m_image; } QSize sizeHint()const; protected: void mousePressEvent(QMouseEvent*); void mouseMoveEvent(QMouseEvent*); void paintEvent(QPaintEvent*); private: void setImagePixel(const QPoint&, bool); QRect pixelRect(int, int)const; private: size_t m_zoom; QColor m_color; QImage m_image; }; #endif // ICONEDITOR_H
#include "iconeditor.h" #include <qpainter.h> #include <qevent.h> iconEditor::iconEditor(QWidget *parent) : QWidget(parent), m_color(Qt::black), m_zoom(DEFAULT_ZOOM), m_image(QImage(DEFAULT_PIXEL,DEFAULT_PIXEL,QImage::Format_RGB32)){ //当改变大小时。窗口部件的内容并没有发生变化,而且内容仍旧保留从窗口部件的左上角开始的特性 //当重新定义窗口部件的大小是,通过使用这个信息就避免重新绘制已经显示的区域 setAttribute(Qt::WA_StaticContents); //设置尺寸策略 setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); //图像填充为透明 m_image.fill(qRgba(DEFAULT_FILL, DEFAULT_FILL, DEFAULT_FILL, MAX_ALPHA)); } QSize iconEditor::sizeHint()const{ //图像大小*缩小因子得合适大小 QSize size = m_zoom * m_image.size(); //当大于最小因子后 就要有网格,因此留出一像素 if (m_zoom > MIN_ZOOM) size += QSize(1, 1); //返回大小 return size; } void iconEditor::setPenColor(const QColor& newColor){ if (&m_color == &newColor) return; //设置画笔颜色 m_color = newColor; } void iconEditor::setIconImage(const QImage& newImage){ if (&m_image == &newImage) return;//如果相同就不进行设置 //转图片的格式 m_image = newImage.convertToFormat(QImage::Format_ARGB32); update();//重绘 updateGeometry();//自适应大小 } void iconEditor::setZoomFactor(const size_t newZoom){ if (m_zoom == newZoom) return;//如果相同就不进行设置 m_zoom = newZoom ? newZoom : 1;//防止缩小因子为0 因为可能做除数 update();//重绘 updateGeometry();//自适应大小 } void iconEditor::paintEvent(QPaintEvent* event){ QPainter painter(this); //画笔 //获得宽高 int width = m_image.width(); int height = m_image.height(); //如果大于最小的缩小因子,那么就要绘制网格 if (m_zoom > MIN_ZOOM){ //调色板获得窗口颜色 以设置画笔 painter.setPen(palette().foreground().color()); //竖线 for (int x = 0; x <= width; ++x) painter.drawLine(m_zoom * x, 0, m_zoom * x,m_zoom * height); //横线 for (int y = 0; y <= height; ++y) painter.drawLine(0, m_zoom * y, width * m_zoom, m_zoom * y); } for (int x = 0; x <= width; ++x){ for (int y = 0; y <= height; ++y){ QRect rect = pixelRect(x, y);//获得矩形 //对落在矩形内的面积进行绘制 if (!event->region().intersected(rect).isEmpty()){ //获得颜色 QColor color = QColor::fromRgba(m_image.pixel(x, y)); //如果并非完全不透明,就先绘制白色背景 if (color.alpha() < MAX_ALPHA) painter.fillRect(rect, Qt::white); //填充颜色 painter.fillRect(rect, color); } } } } inline QRect iconEditor::pixelRect(int x, int y)const{ //QRect(x,y,w,h) return m_zoom > MIN_ZOOM ? QRect(m_zoom * x + 1, m_zoom * y + 1, m_zoom - 1, m_zoom - 1) : QRect(m_zoom * x, m_zoom * y, m_zoom, m_zoom); } 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 x = pos.x() / m_zoom; int y = pos.y() / m_zoom; //获得矩形的x y //检测是否在图形中 if (!m_image.rect().contains(x, y)) return; //如果要设置颜色 颜色为当前画笔的颜色 if (opaque) m_image.setPixel(x, y, penColor().rgba()); else m_image.setPixel(x, y, qRgba(DEFAULT_FILL,DEFAULT_FILL,DEFAULT_FILL,MAX_ALPHA)); //否则清空 //更新点 update(pixelRect(x, y)); }
#include "iconeditor.h" #include <QtWidgets/QApplication> #include <qmainwindow.h> int main(int argc, char *argv[]) { QApplication a(argc, argv); QMainWindow* window = new QMainWindow(); iconEditor* editor = new iconEditor(window); window->setCentralWidget(editor); window->show(); return a.exec(); }