在绘制控件时,首先将要绘制的内容绘制在一张图片中,再将图片一次性绘制到控件上。
在Qt的早期版本中,为了用户界面更加清爽,经常用这个技术来消除闪烁。
自Qt5版本后,QWidget能够自动处理闪烁,因此我们不用再担心这个问题。
双缓冲机制的使用场合:
项目名称为“DrawWidget”,基类选择“QMainWindow”,类名默认即可,取消“创建界面”复选框,完成项目工程的建立。
在项目名上右击,选择“添加新文件 ...”,基类选择“QWidget”,类名为“DrawWidget”。
添加如下代码:(主要定义需要用到的函数和变量)
#ifndef DRAWWIDGET_H
#define DRAWWIDGET_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
class DrawWidget : public QWidget
{
Q_OBJECT
public:
explicit DrawWidget(QWidget *parent = 0);
void mousePressEvent(QMouseEvent *);
void mouseMoveEvent(QMouseEvent *);
void paintEvent(QPaintEvent *);
void resizeEvent(QResizeEvent *);
signals:
public slots:
void setStyle(int );
void setWidth(int );
void setColor(QColor );
void clear();
private:
QPixmap *pix;
QPoint startPos; //记录鼠标的当前位置
QPoint endPos;
int style;
int weight;
QColor color;
};
#endif // DRAWWIDGET_H
在构造函数中完成窗体参数及部分功能初始化工作。
代码如下:
#include "drawwidget.h"
DrawWidget::DrawWidget(QWidget *parent) : QWidget(parent)
{
setAutoFillBackground(true); //允许调整控件背景颜色
setPalette(QPalette(Qt::white));
pix = new QPixmap(size());
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();
startPos = e->pos();
update();
}
void DrawWidget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.drawPixmap(QPoint(0,0), *pix);
}
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::clear()
{
QPixmap *clearPix = new QPixmap(size());
clearPix->fill(Qt::white);
pix = clearPix;
update();
}
此文件主要用于申明创建工具栏的函数createToolBar( )和选择线型样式线型颜色的餐函数showStyle( )、showColor( ) 。以及定义需要用到的变量。
代码如下:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include
#include
#include
#include "drawwidget.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
void createToolBar();
public slots:
void showStyle();
void showColor();
private:
DrawWidget *drawWidget;
QLabel *styleLabel;
QComboBox *styleComboBox;
QLabel *widthLabel;
QSpinBox *widthSpinBox;
QToolButton *colorBtn;
QToolButton *clearBtn;
};
#endif // MAINWINDOW_H
添加如下代码:
#include "mainwindow.h"
#include
#include
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
drawWidget = new DrawWidget;
setCentralWidget(drawWidget);
createToolBar();
setMinimumSize(600, 400);
showStyle();
drawWidget->setWidth(widthSpinBox->value());
drawWidget->setColor(Qt::black);
}
MainWindow::~MainWindow()
{
}
void MainWindow::createToolBar()
{
QToolBar *toolBar = addToolBar("Tool");
styleLabel = new QLabel(tr("线型风格: ")); //线型风格
styleComboBox = new QComboBox;
styleComboBox->addItem(tr("SolodLine") , 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)));
colorBtn = new QToolButton; //设置按钮的格式
QPixmap pixmap(30,30);
pixmap.fill(Qt::red);
colorBtn->setIcon(QIcon(pixmap));
connect(colorBtn,SIGNAL(clicked(bool)),this,SLOT(showColor()));
clearBtn = new QToolButton;
clearBtn->setText(tr("清除"));
connect(clearBtn,SIGNAL(clicked(bool)),drawWidget,SLOT(clear()));
toolBar->addWidget(styleLabel);
toolBar->addWidget(styleComboBox);
toolBar->addWidget(widthLabel);
toolBar->addWidget(widthSpinBox);
toolBar->addWidget(colorBtn);
toolBar->addWidget(clearBtn);
toolBar->setMovable(false); //设置工具条不可拖动
}
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));
}
}
设置一下程序界面中出现的文字的字体和颜色
代码如下:
#include "mainwindow.h"
#include "drawwidget.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QFont font("楷体", 15);
a.setFont(font);
MainWindow w;
w.show();
return a.exec();
}
至此,整个程序的编码工作便完成了。
程序有一点小瑕疵,当鼠标的移动速度较慢时,线型就体现不出来,不管是DashLine还是DotLine,都显示为实线,我也请在讨论群里请教了一些朋友,结果越讨论越复杂,没有一个较好切简单的解决办法。
如果哪位看客有好的方法,可以留言哦。人多力量大嘛。O(∩_∩)O哈哈~
使用博客目录阅读博客,会让思路结构更加清晰哦。(仅支持电脑端)