从去年到现在一直在断断续续学习Qt,这是第一次写博客,感觉学到的东西很少,希望以后能多学、多练、多写吧!(还有部分功能没有实现,等实现了再来补全。)
首先使用了一个窗口布局来实现这三个功能,包括如何使用分割窗口和如何使用堆栈窗体。
实现效果图如下:
/*插入三个页面*/
mainwindow=new MainWindow();
drawwidget=new DrawWidget();
mainwindow2=new MainWindow2();
stack->addWidget(mainwindow);
stack->addWidget(drawwidget);
stack->addWidget(mainwindow2);
/*创建两个按钮*/
AmendBtn=new QPushButton(tr("修改"));
CloseBtn=new QPushButton(tr("关闭"));
QHBoxLayout *BtnLayout=new QHBoxLayout;
BtnLayout->addStretch(1);
BtnLayout->addWidget(AmendBtn);
BtnLayout->addWidget(CloseBtn);
/*进行整体布局*/
QVBoxLayout *RightLayout=new QVBoxLayout(this); RightLayout->setMargin(10); RightLayout->setSpacing(6); RightLayout->addWidget(stack); RightLayout->addLayout(BtnLayout);
之后再实现其它三个子窗口:
一、图形的绘制
1 绘图区实现
#include "paintarea.h" #include <Qpainter>PaintArea::PaintArea(QWidget *parent) : QWidget(parent) { setPalette(QPalette(Qt::white)); setAutoFillBackground(true); setMaximumSize(400,400); }//对窗体背景色的设置void PaintArea::setShape(Shape s)//形状 { shape=s; update(); }void PaintArea::setPen(QPen p)//画笔 { pen=p; update(); }void PaintArea::setBrush(QBrush b)//画刷 { brush=b; update(); }void PaintArea::setFillRule(Qt::FillRule rule)//设置填充模式 { fillRule=rule; update(); } void PaintArea::paintEvent(QPaintEvent *) { QPainter p(this); p.setPen(pen); p.setBrush(brush); QRect rect(50,100,300,200);//设定方形区域,为画长方形、圆角方形、椭圆等做准备。 static const QPoint points[4]= { QPoint(150,100), QPoint(300,150), QPoint(350,250), QPoint(100,300) };//创建一个QPint的数组,包含四个点,为画多边形、多边线及点做准备。 int startAngle =30*16;//起始角(弧形的起始点与圆心之间的连线与水平方向的夹角); int spanAngle =120*16;//跨度角(弧形起点、终点分别与圆心连线之间的夹角);QPainterPath path;//新建QPainterPath对象为画路径做准备 path.addRect(150,150,100,100); path.moveTo(100,100); path.cubicTo(300,100,200,200,300,300); path.cubicTo(100,300,200,200,100,100); path.setFillRule(fillRule); switch (shape) { case Line: p.drawLine(rect.topLeft(),rect.bottomRight());break; case Rectangle: p.drawRect(rect);break; case RoundRect: p.drawRoundRect(rect);break; case Ellipse: p.drawEllipse(rect);break; case Polygon: p.drawPolygon(points,4);break; case Polyline: p.drawPolyline(points,4);break; case Point: p.drawPoints(points,4);break; case Arc: p.drawArc(rect,startAngle,spanAngle);break; case Path: p.drawPath(path);break; case Text: p.drawText(rect,Qt::AlignCenter,tr("Hello Qt!"));break; case Pixmap: p.drawPixmap(150,150,QPixmap("butterfly.png"));break; default: break; } }2 主窗口的实现在里面实现了拓展对话框的功能:void MainWindow::createBaseInfo()MainWindow::MainWindow(QWidget *parent) : QWidget(parent) { paintArea=new PaintArea;createBaseInfo(); createDetailInfo(); QVBoxLayout *rightlayout=new QVBoxLayout(this); //layout->addWidget(paintArea); rightlayout->addWidget(baseWidget); rightlayout->addWidget(detailWidget); rightlayout->setSizeConstraint(QLayout::SetFixedSize);//设置窗体的大小固定,不能利用拖拽改变大小,//否则当再次单击“详细”按钮时,对话框不能恢复到初始状态。 rightlayout->setSpacing(10); QHBoxLayout *mainLayout=new QHBoxLayout;//布局 mainLayout->addWidget(paintArea); mainLayout->addLayout(rightlayout); mainLayout->setStretchFactor(paintArea,1); mainLayout->setStretchFactor(rightlayout,0);createBaseInfo()函数完成部分信息窗体部分的构建,具体代码如下:{
//paintArea=new PaintArea;//QHBoxLayout *LeftLayout=new QHBoxLayout;//LeftLayout->addWidget(paintArea);baseWidget=new QWidget;QLabel *shapeLabel=new QLabel(tr("形状:"));QComboBox *shapeComboBox=new QComboBox;shapeComboBox->addItem(tr("Line"),PaintArea::Line);shapeComboBox->addItem(tr("Rectangle"),PaintArea::Rectangle);shapeComboBox->addItem(tr("RoundedRect"),PaintArea::RoundRect);shapeComboBox->addItem(tr("Ellipse"),PaintArea::Ellipse);shapeComboBox->addItem(tr("Polyline"),PaintArea::Polyline);shapeComboBox->addItem(tr("Points"),PaintArea::Point);shapeComboBox->addItem(tr("Arc"),PaintArea::Arc);shapeComboBox->addItem(tr("Path"),PaintArea::Path);shapeComboBox->addItem(tr("Text"),PaintArea::Text);shapeComboBox->addItem(tr("Pixmap"),PaintArea::Pixmap);connect(shapeComboBox,SIGNAL(activated(int)),this,SLOT(ShowShape(int)));QGridLayout *LeftLayout=new QGridLayout;LeftLayout->addWidget(shapeLabel,0,0);LeftLayout->addWidget(shapeComboBox,0,1);QPushButton *DetailBtn=new QPushButton(tr("详情"));QDialogButtonBox *btnBox=new QDialogButtonBox(Qt::Vertical);btnBox->addButton(DetailBtn,QDialogButtonBox::ActionRole);QHBoxLayout *mainLayout=new QHBoxLayout(baseWidget);//mainLayout->addWidget(paintArea);// mainLayout->addLayout(LeftLayout);mainLayout->addLayout(LeftLayout);//mainLayout->setStretchFactor(paintArea,1);//mainLayout->setStretchFactor(RightLayout,0);mainLayout->addWidget(btnBox);//connect(DetailBtn,SIGNAL(clicked()),this,SLOT(showDetailInfo()));//ShowShape(shapeComboBox->currentIndex());}
createDetailInfo()函数实现其他信息窗体部分detailWidget的构建,并在函数的最后调用hide()隐藏此部分窗体,实现代码如下:
void MainWindow::createDetailInfo()
{
detailWidget=new QWidget;QLabel *penColorLabel=new QLabel(tr("画笔颜色"));QFrame *penColorFrame=new QFrame;penColorFrame->setFrameStyle(QFrame::Panel|QFrame::Sunken);penColorFrame->setAutoFillBackground(true);penColorFrame->setPalette(QPalette(Qt::blue));QPushButton *penColorBtn=new QPushButton(tr("更改"));connect(penColorBtn,SIGNAL(clicked()),this,SLOT(ShowPenColor()));QLabel *penWidthLabel=new QLabel(tr("画笔线宽:"));QSpinBox *penWidthSpinBox=new QSpinBox;penWidthSpinBox->setRange(0,20);connect(penWidthSpinBox,SIGNAL(valueChanged(int)),this,SLOT(ShowPenWidth(int)));QLabel *penStyleLabel=new QLabel(tr("画笔风格:"));QComboBox *penStyleComboBox =new QComboBox;penStyleComboBox->addItem(tr("SolidLine"),static_cast<int>(Qt::SolidLine));penStyleComboBox->addItem(tr("DashLine"),static_cast<int>(Qt::DashLine));penStyleComboBox->addItem(tr("DotLine"),static_cast<int>(Qt::DotLine));penStyleComboBox->addItem(tr("DashDotLine"),static_cast<int>(Qt::DashDotLine));penStyleComboBox->addItem(tr("DashDotDotLine"),static_cast<int>(Qt::DashDotDotLine));penStyleComboBox->addItem(tr("CustomDashLine"),static_cast<int>(Qt::CustomDashLine));connect(penStyleComboBox,SIGNAL(activated(int)),this,SLOT (ShowPenStyle(int)));QLabel *penCapLabel =new QLabel(tr("画笔顶帽:"));QComboBox *penCapComboBox =new QComboBox;penCapComboBox->addItem(tr("SquareCap"),Qt::SquareCap);penCapComboBox->addItem(tr("FlatCap"),Qt::FlatCap);penCapComboBox->addItem(tr("RoundCap"),Qt::RoundCap);connect(penCapComboBox,SIGNAL(activated(int)),this,SLOT(ShowPenCap (int)));QLabel *penJoinLabel =new QLabel(tr("画笔连接点:"));QComboBox *penJoinComboBox =new QComboBox;penJoinComboBox->addItem(tr("BevelJoin"),Qt::BevelJoin);penJoinComboBox->addItem(tr("MiterJoin"),Qt::MiterJoin);penJoinComboBox->addItem(tr("RoundJoin"),Qt::RoundJoin);connect(penJoinComboBox,SIGNAL(activated(int)),this,SLOT(ShowPenJoin (int)));QLabel *fillRuleLabel =new QLabel(tr("填充模式:"));QComboBox *fillRuleComboBox =new QComboBox;fillRuleComboBox->addItem(tr("Odd Even"),Qt::OddEvenFill);fillRuleComboBox->addItem(tr("Winding"),Qt::WindingFill);connect(fillRuleComboBox,SIGNAL(activated(int)),this,SLOT (ShowFillRule()));QLabel *spreadLabel =new QLabel(tr("铺展效果:"));QComboBox *spreadComboBox =new QComboBox;spreadComboBox->addItem(tr("PadSpread"),QGradient::PadSpread);spreadComboBox->addItem(tr("RepeatSpread"),QGradient::RepeatSpread);spreadComboBox->addItem(tr("ReflectSpread"),QGradient:: ReflectSpread);connect(spreadComboBox,SIGNAL(activated(int)),this,SLOT (ShowSpreadStyle()));QLabel *brushColorLabel =new QLabel(tr("画刷颜色:"));QFrame *brushColorFrame =new QFrame;brushColorFrame->setFrameStyle(QFrame::Panel|QFrame::Sunken);brushColorFrame->setAutoFillBackground(true);brushColorFrame->setPalette(QPalette(Qt::green));QPushButton *brushColorBtn =new QPushButton(tr("更改"));connect(brushColorBtn,SIGNAL(clicked()),this,SLOT (ShowBrushColor()));QLabel *brushStyleLabel =new QLabel(tr("画刷风格:"));QComboBox *brushStyleComboBox =new QComboBox;brushStyleComboBox->addItem(tr("SolidPattern"),static_cast<int>(Qt::SolidPattern));brushStyleComboBox->addItem(tr("Dense1Pattern"),static_cast<int>(Qt::Dense1Pattern));brushStyleComboBox->addItem(tr("Dense2Pattern"),static_cast<int>(Qt::Dense2Pattern));brushStyleComboBox->addItem(tr("Dense3Pattern"),static_cast<int>(Qt::Dense3Pattern));brushStyleComboBox->addItem(tr("Dense4Pattern"),static_cast<int>(Qt::Dense4Pattern));brushStyleComboBox->addItem(tr("Dense5Pattern"),static_cast<int>(Qt::Dense5Pattern));brushStyleComboBox->addItem(tr("Dense6Pattern"),static_cast<int>(Qt::Dense6Pattern));brushStyleComboBox->addItem(tr("Dense7Pattern"),static_cast<int>(Qt::Dense7Pattern));brushStyleComboBox->addItem(tr("HorPattern"),static_cast<int>(Qt::HorPattern));brushStyleComboBox->addItem(tr("VerPattern"),static_cast<int>(Qt::VerPattern));brushStyleComboBox->addItem(tr("CrossPattern"),static_cast<int>(Qt::CrossPattern));brushStyleComboBox->addItem(tr("BDiagPattern"),static_cast<int>(Qt::BDiagPattern));brushStyleComboBox->addItem(tr("FDiagPattern"),static_cast<int>(Qt::FDiagPattern));brushStyleComboBox->addItem(tr("DiagCrossPattern"),static_cast<int>(Qt:: DiagCrossPattern));brushStyleComboBox->addItem(tr("LinearGradientPattern"),static_cast<int>(Qt:: LinearGradientPattern));brushStyleComboBox->addItem(tr("ConicalGradientPattern"),static_cast<int>(Qt:: ConicalGradientPattern));brushStyleComboBox->addItem(tr("RadialGradientPattern"),static_cast<int>(Qt:: RadialGradientPattern));brushStyleComboBox->addItem(tr("TexturePattern"),static_cast<int>(Qt::TexturePattern));connect(brushStyleComboBox,SIGNAL(activated(int)),this,SLOT (ShowBrush(int)));QGridLayout *mainLayout=new QGridLayout(detailWidget);mainLayout->addWidget(penColorLabel,0,0);mainLayout->addWidget(penColorFrame,0,1);mainLayout->addWidget(penColorBtn,0,2);mainLayout->addWidget(penWidthLabel,1,0);mainLayout->addWidget(penWidthSpinBox,1,1);mainLayout->addWidget(penStyleLabel,2,0);mainLayout->addWidget(penStyleComboBox,2,1);mainLayout->addWidget(penCapLabel,3,0);mainLayout->addWidget(penCapComboBox,3,1);mainLayout->addWidget(penJoinLabel,4,0);mainLayout->addWidget(penJoinComboBox,4,1);mainLayout->addWidget(fillRuleLabel,5,0);mainLayout->addWidget(fillRuleComboBox,5,1);mainLayout->addWidget(spreadLabel,6,0);mainLayout->addWidget(spreadComboBox,6,1);mainLayout->addWidget(brushColorLabel,7,0);mainLayout->addWidget(brushColorFrame,7,1);mainLayout->addWidget(brushColorBtn,7,2);mainLayout->addWidget(brushStyleLabel,8,0);mainLayout->addWidget(brushStyleComboBox,8,1);
//QHBoxLayout *mainLayout =new QHBoxLayout(this);//mainLayout->addLayout(rightLayout);//mainLayout->setStretchFactor(paintArea,1);// mainLayout->setStretchFactor(rightLayout,0);//ShowShape(shapeComboBox->currentIndex());detailWidget->hide();}
showDetailInfo()函数完成窗体拓展切换工作,其具体代码如下:
void
MainWindow
::showDetailInfo
()
{
if(detailWidget->isHidden())
detailWidget->show();
else detailWidget->hide();
}
在主窗体实现过程中还有其它一些槽函数的调用,这里就不具体写出了。
二、双缓冲机制
1 绘图区实现
#include
"drawwidget9.h"
#include <QtGui>
#include <QPen>
DrawWidget9::DrawWidget9(QWidget *parent) : QWidget(parent)
{
setAutoFillBackground(true);//对窗体背景色的设置
setPalette(QPalette(Qt::white));
pix=new QPixmap(size());此QPixmap对象用来准备随时接收绘制的内容
pix->fill(Qt::white);
setMinimumSize(600,400);
}
void DrawWidget9::setStyle(int s)//线型风格
{
style=s;
}
void DrawWidget9::setWidth(int w)//线宽
{
weight=w;
}
void DrawWidget9::setColor(QColor c)//画笔颜色
{
color=c;
}
void DrawWidget9::mousePressEvent(QMouseEvent *e)//按下事件mousePressEvent(),鼠标按下时,记录当前的鼠标位置值startPos。
{
startPos=e->pos();
}
void DrawWidget9::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 DrawWidget9::paintEvent(QPaintEvent *)//完成绘图区的更新工作
{
QPainter painter(this);
painter.drawPixmap(QPoint(0,0),*pix);
}
void DrawWidget9::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 DrawWidget9::clear()//完成绘图区的清除工作
{
QPixmap *clearPix =new QPixmap(size());
clearPix->fill(Qt::white);
pix = clearPix;
update();
}
2 主函数drawwidget的实现
DrawWidget::DrawWidget(QWidget *parent) : QMainWindow(parent){ drawWidget9 =new DrawWidget9; //新建一个DrawWidget对象 setCentralWidget(drawWidget9); //新建的DrawWidget对象作为主窗口的中央窗体
createToolBar(); //实现一个工具栏
setMinimumSize(600,400); //设置主窗口的最小尺寸
ShowStyle(); //初始化线型,设置控件中的当前值作为初始值 drawWidget9->setWidth(widthSpinBox->value()); //初始化线宽 drawWidget9->setColor(Qt::black); //初始化颜色 }
// DrawWidget::~DrawWidget()
//createToolBar()函数完成工具栏的创建: void DrawWidget::createToolBar() { QToolBar *toolBar = addToolBar("Tool"); //为主窗口新建一个工具栏对象
styleLabel =new QLabel(tr("线型风格:")); //创建线型选择控件 styleComboBox =new QComboBox; styleComboBox->addItem(tr("SolidLine"),static_cast<int>(Qt::SolidLine)); styleComboBox->addItem(tr("DashLine"),static_cast<int>(Qt::DashLine)); styleComboBox->addItem(tr("DotLine"),static_cast<int>(Qt::DotLine)); styleComboBox->addItem(tr("DashDotLine"),static_cast<int>(Qt::DashDotLine)); styleComboBox->addItem(tr("DashDotDotLine"),static_cast<int>(Qt::DashDotDotLine)); connect(styleComboBox,SIGNAL(activated(int)),this,SLOT(ShowStyle())); //关联相应的槽函数
widthLabel =new QLabel(tr("线宽:")); //创建线宽选择控件 widthSpinBox =new QSpinBox; connect(widthSpinBox,SIGNAL(valueChanged(int)),drawWidget9,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()),drawWidget9,SLOT(clear()));
toolBar->addWidget(styleLabel); toolBar->addWidget(styleComboBox); toolBar->addWidget(widthLabel); toolBar->addWidget(widthSpinBox); toolBar->addWidget(colorBtn); toolBar->addWidget(clearBtn); }
void DrawWidget::ShowStyle() //改变线型参数的槽函数ShowStyle() { drawWidget9->setStyle(styleComboBox->itemData( styleComboBox->currentIndex(),Qt::UserRole).toInt()); } void DrawWidget::ShowColor() //设置画笔颜色的槽函数ShowColor() { QColor color = QColorDialog::getColor(static_cast<int>(Qt::black),this); //使用标准颜色对话框QColorDialog获得一个颜色值 if(color.isValid()) { drawWidget9->setColor(color); QPixmap p(20,20); p.fill(color); colorBtn->setIcon(QIcon(p)); } }
三、显示SVG格式图片
通过利用QSvgWidget类和QSvgRenDer类实现一个SVG图片浏览器,显示以“.svg”结尾的文件以介绍SVG格式图片显示的方法:
1 显示图片功能
//获得本窗体对象
SVGWidget
::SVGWidget
(
QWidget
*parent
)
:QSvgWidget(parent)
{
render=renderer();
}
//以下是鼠标滚轮的响应事件,使SVG图片能够通过鼠标滚轮的滚动进行缩放,具体的代码如下:
void SVGWidget::wheelEvent(QWheelEvent *e){
const double diff=0.1;QSize size =render->defaultSize();int width =size.width();int height =size.height();if(e->delta()>0){width =int(this->width()+this->width()*diff);height =int(this->height()+this->height()*diff);}else{width =int(this->width()-this->width()*diff);height =int(this->height()-this->height()*diff);}resize(width,height);}
2 图片在放大到超过主窗口的大小时,能够通过拖拽滚动条的方式进行查看
#include
"svgtest.h"
SVGTest::SVGTest(QWidget *parent)
:QScrollArea(parent)
{
svgWidget =new SVGWidget;
setWidget(svgWidget);
}
void SVGTest::setFile(QString fileName)//文件进行了选择或修改时,调用setFile()函数设置新的文件
{
svgWidget->load(fileName);//将新的SVG文件加载到svgWidget中进行显示
QSvgRenderer *render =svgWidget->renderer();
svgWidget->resize(render->defaultSize());
}
void SVGTest::mousePressEvent(QMouseEvent *event)
{
mousePressPos =event->pos();
scrollBarValuesOnMousePress.rx()=horizontalScrollBar()->value();
scrollBarValuesOnMousePress.ry()=verticalScrollBar()->value();
event->accept();
}
void SVGTest::mouseMoveEvent(QMouseEvent *event)
{
horizontalScrollBar()->setValue(scrollBarValuesOnMousePress.x()-event->pos().x()+mousePressPos.x()); //对水平滑动条的新位置进行设置
verticalScrollBar()->setValue(scrollBarValuesOnMousePress.y()-event->pos().y()+mousePressPos.y()); //对垂直滑动条的新位置进行设置
horizontalScrollBar()->update();
verticalScrollBar()->update();
event->accept();
}
3 创建一个SvgWindow对象作为主窗口的中央窗体
MainWindow2
::MainWindow2
(
QWidget
*parent
)
: QMainWindow(parent)
{
setWindowTitle(tr("SVG Viewer"));
createMenu();
svgTest=new SVGTest;
setCentralWidget(svgTest);
}
void MainWindow2::createMenu()//创建菜单栏
{
QMenu *fileMenu=menuBar()->addMenu(tr("文件"));
QAction *openAct=new QAction(tr("打开"),this);
connect(openAct,SIGNAL(triggered()),this,SLOT(slotOpenFile()));
fileMenu->addAction(openAct);
}
void MainWindow2::slotOpenFile()
{
QString name=QFileDialog::getOpenFileName(this,
"打开","/","svg files(*.svg)");
svgTest->setFile(name);
}
这篇博客写的有点差,好多东西都不会,自己也没有那么耐心细致的去弄,觉得特别的惭愧。。。最近要忙别的事了,不知道什么时候能把它改改,或者开始写下一篇呢?好希望自己能在这条路上越走越远。