双缓冲就是在绘制控件的时候,首先把要绘制的内容放到一个图片上,然后再将图片一次性画到控件上
首先我们在绘图区会有画各种图形,用鼠标来画的话,那么就会有鼠标点击事件,鼠标移动事件,重绘控件事件,绘制的时候有画笔,画笔的风格,宽度,颜色。。。
QColor( 250, 250, 200)会生成一个QColor对象作为QPalette构造参数
这个函数的作用是为当前窗口构建一个调色板,它的button颜色为QColor( 250, 250, 200),其他的颜色是基于这个颜色自动的计算,Wondow也是button颜色。
所有Qt窗口部件都拥有一个调色板并使用它绘制自己.通常,活动状态的窗口标题栏为蓝色的,而非活动(inactive)状态的窗口的标题栏显示为灰色的;活动状态的窗口和非活动状态的窗口都可以包含状态为不可用的窗口不见,一个不可用的窗口不见(包括该窗口不见包含的子窗口部件)显示为灰色的,用户是无法同它进行交互的.通过改变窗口不见的调色板的各个组中的颜色,能够改变窗口不见的显示颜色,比如改变背景色,文本颜色等. QPalete::Window,通常指窗口部件的背景色; QPalette:WindowText,通常指窗口不见的前景色; QPalette::Base,指文本输入窗口部件(比如QtextEdit,QLinedit等)的背景色. QPalette::Text,与QPalette::Base一块使用,指文本输入窗口部件的前景色; QPalette::Button,指按钮窗口部件的背景色; QPalette::ButtonText,指按钮窗口部件的前景色.
DrawWidget::DrawWidget(QWidget*parent):
QWidget(parent)
{//构造函数
setAutoFillBackground(true); //自动设定背景颜色
setPalette(QPalette(Qt::white)); //设置调色板的颜色为白色
pix=newQPixmap(size()); //这个pixmap对象用来接受准备绘制到空间的内容
pix->fill(Qt::white); //填充这个图片的背景是白色
setMinimumSize(600,400); //设置绘图区域窗体的最小大小
}
void DrawWidget::setStyle(int s)
{
style=s;
}
void DrawWidget::setWidth(int w) //设置线段宽
{
weight=w;
}
void DrawWidget::setColor(QColor c)
{
color=c;
}
//有了绘制地方,有了画笔,接下来就是如何绘制图画了
//这里我们是用鼠标绘画的,以鼠标第一次点击作为起始点,然后第二次点击作为结束点
void DrawWidget::mousePressEvent(QMouseEvent *e)
{
//记录第一次点击的鼠标的起始坐标
startPos = e->pos();
}
//然后拖拉鼠标,寻找到一个新的结束点,然后绘画到图片
void DrawWidget::mouseMoveEvent(QMouseEvent *e)
{
//首先得到绘画的工具
QPainter *painter = new QPainter;
//设置好画笔的风格
QPen pen;
pen.setStyle((Qt::PenStyle)style); //设置画笔的风格
pen.setWidth(weight); //设置画笔的宽度
pen.setColor(color); //设置画笔的颜色
painter->begin(pix); //首先在图片上画图
painter->setPen(pen); //把设置好的画笔给绘图工具
painter->drawLine(startPos, e->pos()); //画一条直线,重起点到结束
painter->end(); //结束绘画,和上面的begin对应,就是结束在图片上的绘画
startPos = e->pos(); //把这个结束的坐标做一个一个新的开始,这样就可以画多边形了
this->update(); //更新空间的画面,多次的update调用结果只调用一次paintEvent事件
}
//在调用paintEven之前,Qt会清除掉相应空间的内容,上面的update会调用paintEvent事件
void DrawWidget::paintEvent(QPaintEvent *)
{
QPainter painter(this); //得到当前控件绘制工具
painter.drawPixmap(QPoint(0, 0), *pix); //重0,0开始绘制这个图片
}
那么。我们就有必要重新设置绘图区的大小了。
//这样基本就完成了绘制的操作,但是如果绘画区域不够用了,我们会想把画布变大
void DrawWidget::resizeEvent(QResizeEvent *event)
{
if(height() > pix->height() || width() > pix->width()) //只要控件的区域比画布还要大,那么我们就改到一样大
{
QPixmap *newPix = new QPixmap(size()); //设置一个新的画布,大小和控件一样大
//同样先把背景设置为白色
newPix->fill(Qt::white);
//设置完了,赋值到原来的地方之前,我们先前的画不能消失,所以早替换新画布之前要保留前面的画
QPainter p(newPix); //在新画布上进行操作
p.drawPixmap(QPoint(0, 0), *pix); //把原来的画画上去
pix = newPix;
}
QWidget::resizeEvent(event); //完成其余默认的工作
}
//清空图画,只要一个新的什么都没有的画布替换就可以了
//这样基本就完成了绘制的操作,但是如果绘画区域不够用了,我们会想把画布变大
void DrawWidget::resizeEvent(QResizeEvent *event)
{
if(height() > pix->height() || width() > pix->width()) //只要控件的区域比画布还要大,那么我们就改到一样大
{
QPixmap *newPix = new QPixmap(size()); //设置一个新的画布,大小和控件一样大
//同样先把背景设置为白色
newPix->fill(Qt::white);
//设置完了,赋值到原来的地方之前,我们先前的画不能消失,所以早替换新画布之前要保留前面的画
QPainter p(newPix); //在新画布上进行操作
p.drawPixmap(QPoint(0, 0), *pix); //把原来的画画上去
pix = newPix;
}
QWidget::resizeEvent(event); //完成其余默认的工作
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{//初始化界面
drawWidget =new DrawWidget; //创建一个新的修改界面呢文件
//把这个设置为控件的中心窗体
this->setCentralWidget(drawWidget);
//创建一个工具栏
createToolBar(); //创建一个工具栏
//设置主窗体初始最小大小
setMinimumSize(600, 400);
ShowStyle(); //显示选择的风格,初始化风格,设置控件中的当前值作为选项
drawWidget->setWidth(widthSpinBox->value()); //初始化画笔宽度
drawWidget->setColor(Qt::black); //初始画笔为黑色
}
各个属性的实现和对于的信号与槽的相应
//创建工具栏的实现
void MainWindow::createToolBar()
{
//首先得到一个工具栏
QToolBar *toolBar = this->addToolBar("Tool");
//首先是设置风格
styleLabel = new QLabel(tr("line style")); //全都是线性的风格
styleComboBox = new QComboBox;
//各种风格,这个Qt的说明文档里面有,粘过来就好,这里强制转换为int类型,后面可以转换回来
styleComboBox->addItem(tr("SolidLine"),static_cast(Qt::SolidLine));
styleComboBox->addItem(tr("DashLine"),static_cast(Qt::DashLine));
styleComboBox->addItem(tr("DotLine"),static_cast(Qt::DotLine));
styleComboBox->addItem(tr("DashDotLine"),static_cast(Qt::DashDotLine));
styleComboBox->addItem(tr("DashDotDotLine"),static_cast(Qt::DashDotDotLine));
connect(styleComboBox, SIGNAL(activated(int)), this, SLOT(ShowStyle()));
//设置画笔线宽
widthLabel =new QLabel(tr("线宽:")); //创建线宽选择控件
widthSpinBox =new QSpinBox;
// connect(widthSpinBox,SIGNAL(valueChanged(int)),drawWidget,SLOT(setWidth(int)));
connect(widthSpinBox, SIGNAL(valueChanged(int)), drawWidget, SLOT(setWidth(int)));
colorBtn =new QToolButton; //创建颜色选择控件
QPixmap pixmap(20,20);
pixmap.fill(Qt::black);
colorBtn->setIcon(QIcon(pixmap));
connect(colorBtn,SIGNAL(clicked()),this,SLOT(ShowColor()));
clearBtn =new QToolButton(); //创建清除按钮
clearBtn->setText(tr("清除"));
connect(clearBtn,SIGNAL(clicked()),drawWidget,SLOT(clear()));
toolBar->addWidget(styleLabel);
toolBar->addWidget(styleComboBox);
toolBar->addWidget(widthLabel);
toolBar->addWidget(widthSpinBox);
toolBar->addWidget(colorBtn);
toolBar->addWidget(clearBtn);
}
//设置当前选择的风格
void MainWindow::ShowStyle()
{
drawWidget->setStyle(styleComboBox->itemData(styleComboBox->currentIndex(), Qt::UserRole).toInt());
}
//设置画笔颜色
void MainWindow::ShowColor()
{
//重颜色对话框中取得颜色
QColor color = QColorDialog::getColor(static_cast(Qt::black), this); //默认是黑色
//取得的颜色值赋值到绘画区,和按钮图片
if(color.isValid())
{
drawWidget->setColor(color); //设置画笔颜色
QPixmap p(20, 20);
p.fill(color);
colorBtn->setIcon(QIcon(p));
}
}
我先写在了word文档上面,然后直接复制粘贴,发现不能,然后小小的排版了一下,不知道效果怎么样,不管了,发了吧!