#ifndef CWIDGET_H
#define CWIDGET_H
#include <QWidget>
class QSize;
class QImage;
class CWidget : public QWidget
{
Q_OBJECT
Q_CLASSINFO("Author", "velconia")
Q_CLASSINFO("URL", "velconias@gmail.com")
Q_CLASSINFO("Unimplement", "InitPalette, InitLayout")
public:
CWidget(QWidget *parent = 0);
virtual ~CWidget();
// Handle palette
virtual void InitPalette() = 0;
// 改变palette的简便方法,效率并不高
// 如果有非常多的brush需要改变,那么最好
// 不要用这个方法
inline void changePalette(QPalette::ColorRole cr,
const QBrush& b)
{
QPalette p = this->palette();
p.setBrush(cr, b);
this->setPalette(p);
}
// Handle layout
virtual void InitLayout() = 0;
// Handle image
inline QImage* foregroundImage() const
{ return this->_foregroundImage; }
inline QImage* backgroundImage() const
{ return this->_backgroundImage; }
protected:
virtual void paintEvent(QPaintEvent *);
protected:
QImage* _foregroundImage;
QImage* _backgroundImage;
};
#endif // CWIDGET_H
#ifndef CWINDOW_H
#define CWINDOW_H
#include "cwidget.h"
#include "cbutton.h"
class CWindow : public CWidget
{
Q_OBJECT
public:
enum CWindowSize {
Small = 0,
Suitable,
Full
};
CWindow(CWidget *parent = 0);
virtual ~CWindow();
// 智能设置window大小
virtual void setWindowSize(CWindowSize);
inline CWindowSize windowSize() const
{ return this->_size; }
// 得到顶方感应区域大小
QRect getTopSensorArea()
{
return QRect(0, 0, width(), BTN_SPLITTER_HEIGHT * 2 + BTN_HEIGHT);
}
// 继承自CWidget
virtual void InitPalette();
virtual void InitLayout();
protected:
CWindowSize _size;
CButton* _mini_button;
CButton* _max_button;
CButton* _close_button;
virtual void mouseDoubleClickEvent(QMouseEvent *);
// 仍旧要做一些特殊的渲染,这些特殊要求如果要包含在style系统内部
// 那么将会带来非常巨额的类数量的增长,所以还是在cwindow内部实现了
virtual void paintEvent(QPaintEvent *);
protected slots:
// 根据当前状态改变window的大小
void changeSize()
{
if (this->isFullScreen())
this->showNormal();
else
this->showFullScreen();
}
private:
// 创建关闭按钮
inline CButton* CreateCloseBtn()
{
// Create button
CButton* b = new CButton(this, CONIA_RED, PORTABLE_RED, PORTABLE_RED);
b->InitLayout();
b->InitPalette();
// Configure button
b->move(BTN_SPLITTER_WIDTH,
BTN_SPLITTER_HEIGHT);
b->setFixedSize(BTN_WIDTH,
BTN_HEIGHT);
// Do connect
// 使用这个按钮映射close操作
QObject::connect(b, SIGNAL(clicked(QPoint)), this, SLOT(close()));
return b;
}
// 创建最大化按钮
inline CButton* CreateMaxBtn()
{
// Create button
CButton* b = new CButton(this);
b->InitLayout();
b->InitPalette();
// Configure button
b->move(BTN_SPLITTER_WIDTH * 2 + BTN_WIDTH,
BTN_SPLITTER_HEIGHT);
b->setFixedSize(BTN_WIDTH,
BTN_HEIGHT);
// Do connect
// 使用这个按钮映射最大化操作
QObject::connect(b, SIGNAL(clicked(QPoint)), this, SLOT(changeSize()));
return b;
}
// 创建最小化按钮
inline CButton* CreateMiniBtn()
{
// Create button
CButton* b = new CButton(this);
b->InitLayout();
b->InitPalette();
// Configure button
b->move(BTN_SPLITTER_WIDTH * 3 + BTN_WIDTH * 2,
BTN_SPLITTER_HEIGHT);
b->setFixedSize(BTN_WIDTH,
BTN_HEIGHT);
// Do connect
// 使用这个按钮映射最小化操作
QObject::connect(b, SIGNAL(clicked(QPoint)), this, SLOT(showMinimized()));
return b;
}
// 按钮的宽
static const int BTN_WIDTH = 10;
// 按钮的长
static const int BTN_HEIGHT = 10;
// 按钮之间间隔的长度
static const int BTN_SPLITTER_WIDTH = 5;
// 按钮与顶部的距离
static const int BTN_SPLITTER_HEIGHT = 5;
static const CWindowSize DEF_WND_SIZE = Suitable;
};
#endif // CWINDOW_H
#ifndef CSTYLEOPTION_H
#define CSTYLEOPTION_H
#include <QStyleOption>
class QImage;
class CWidget;
class CStyleOption : public QStyleOption
{
// 这不是一个QObject....
// Q_OBJECT
// Q_CLASSINFO("author", "velconia")
// Q_CLASSINFO("URL", "velconias@gmail.com")
public:
CStyleOption();
// Copy Control
CStyleOption(const CStyleOption&);
CStyleOption& operator=(const CStyleOption&);
virtual ~CStyleOption();
virtual void initFromConiaWidget(const CWidget*);
public:
// 尝试使用一个CAnimation去控制image的绘制
// 还可以提供对外的接口,控制CAnimation的实现
// 如SetCAnimation(CAnimation&)等
QImage* foregroundImage;
QImage* backgroundImage;
private:
inline void deleteResource()
{
delete(foregroundImage);
delete(backgroundImage);
foregroundImage = NULL;
backgroundImage = NULL;
}
};
#endif // CSTYLEOPTION_H
#ifndef CSTYLE_H
#define CSTYLE_H
#include <QCommonStyle>
class CStyleOption;
class CStyle : public QCommonStyle
{
Q_OBJECT
public:
explicit CStyle();
void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
QPainter *p, const QWidget *w) const;
protected:
virtual void drawAux(const CStyleOption *opt, QPainter *p) const;
virtual qreal roundedX() const
{ return DEF_ROUNDED_X; }
virtual qreal roundedY() const
{ return DEF_ROUNDED_Y; }
static const qreal DEF_ROUNDED_X = 5;
static const qreal DEF_ROUNDED_Y = 5;
};
#endif // CSTYLE_H
#ifndef CPAINTINGWINDOW_H
#define CPAINTINGWINDOW_H
#include "cwindow.h"
#include <QPainterPath>
class CPaintingWindow : public CWindow
{
public:
CPaintingWindow(CWidget* parent);
protected:
virtual void mousePressEvent(QMouseEvent *);
virtual void mouseMoveEvent(QMouseEvent *);
virtual void mouseReleaseEvent(QMouseEvent *);
virtual void paintEvent(QPaintEvent *);
protected:
QPoint curPos;
QPainterPath paintingPath;
};
#endif // CPAINTINGWINDOW_H
#ifndef CBUTTON_H
#define CBUTTON_H
#include "cwidget.h"
#include "cglobal.h"
class CButton : public CWidget
{
Q_OBJECT
Q_CLASSINFO("author", "velconia")
Q_CLASSINFO("URL", "velconias@gmail.com")
public:
// conia的每个button都有三种状态
enum ButtonState {
NoState = 0,
Pressed,
CursorIn
};
CButton(CWidget* parent = 0, QColor noStateColor = CONIA_GREEN,
QColor pressedColor = PORTABLE_GREEN,
QColor cursorInColor = PORTABLE_GREEN);
virtual ~CButton();
virtual void InitLayout();
virtual void InitPalette();
virtual QSize sizeHint() const
{ return QSize(DEF_WIDTH, DEF_HEIGHT); }
// 这个函数将会改变当前状态,并根据状态改变
// palette从而改变颜色,改变foregroundImage
// 从而改变button展示的图片
virtual void setState(ButtonState);
inline ButtonState state() const
{ return this->_state; }
// 这两个可以先留待下次实现
// virtual void setText(const QString&);
// QString& text() const
// { return this->_text; }
signals:
void pressed(QPoint);
void released(QPoint);
void clicked(QPoint);
void entered();
void left();
protected:
// 对鼠标监听事件的实现
virtual void mousePressEvent(QMouseEvent *);
virtual void mouseReleaseEvent(QMouseEvent *);
virtual void mouseMoveEvent(QMouseEvent *);
virtual void enterEvent(QEvent *);
virtual void leaveEvent(QEvent *);
protected:
ButtonState _state;
// 对应三种状态的image
QImage* _noStateImage;
QImage* _pressedImage;
QImage* _cursorInImage;
// 对应三种状态的color
QColor _noStateColor;
QColor _pressedColor;
QColor _cursorInColor;
private:
static const int DEF_WIDTH = 120;
static const int DEF_HEIGHT = 40;
};
#endif // CBUTTON_H
通过上面的一些类相互协作,我们最后能够实现一个Qt的画图软件~如下图: