说明:近期做项目遇到一个UI设计问题,就是背景显示,借此机会记录一下
需求:
1、qwt控件设置罗盘背景
2、qwt去除控件边框
3、保证qwt画轨迹不影响罗盘
思路:
1、qwt添加画布,在画布上重定义绘图事件(使用事件监视器)。 思路结果失败!!!
2、qwt添加画布,在画布上设置背景图片。 思路结果失败!!!
3、直接设置qwt背景,取消画布(画布会覆盖qwt背景)。 思路结果成功!!!
尝试1(思路1):在画布上重定义绘图事件
(1)事件处理器
//---------绘制导航罗盘---------// bool eventFilter(QObject *watched,QEvent *e);//绘图
bool Display_Navigator::eventFilter(QObject *watched, QEvent *e) { if (watched == ui->qwtPlot->canvas() ) { if (e->type() == QEvent::Paint)//QEvent::Paint) { paintOnWidget(ui->qwtPlot->canvas() ); qDebug()<<"eventFilter paint!"; return true; } } return QWidget::eventFilter(watched,e); //将事件传递给父类 }
(2)画图重绘
void Display_Navigator::paintOnWidget(QWidget *w) /* * 虚函数:指你希望重载的成员函数 *(1)repaint()函数或者update()函数被调用; *(2)被隐藏的部件现在被重新显示; */ { QPainter painter(this); QFont font; font.setPointSize(7);//字体大小设置为10 setFont(font); /*开启反走样*/ painter.setRenderHint(QPainter::Antialiasing,true); painter.setPen(Qt::white); painter.drawEllipse(QPointF(518,314),255,255);//画圆 //画刻度 QPen &pen = const_cast<QPen&>(painter.pen()); pen.setStyle(Qt::SolidLine); for(int i = 0 ;i <= 360;i+= 5) { if((i%5==0)&&(i%90!=0)) { QPointF ptStart = trans(i); QPointF ptEnd = trans(i,10); QPen pen; pen.setColor(QColor(255,255,0)); painter.setPen(pen); //旋转指定的角度 painter.rotate(i%5); painter.drawLine(ptStart, ptEnd); painter.save(); painter.restore(); } if((i%10==0)&&(i%90!=0)) { QPointF ptStart = trans(i); QPointF ptEnd = trans(i,20); QPen pen; pen.setColor(QColor(255,255,0)); painter.setPen(pen); painter.rotate(i%10); painter.drawLine(ptStart, ptEnd); painter.save(); painter.restore(); } if(i%90==0) { QPointF ptStart = trans(i); QPointF ptEnd = trans(i,20); QPen pen; pen.setColor(QColor(255,0,0)); painter.setPen(pen); painter.rotate(i%10); painter.drawLine(ptStart, ptEnd); painter.save(); painter.restore(); } } for(int i = 30 ;i <= 360;i+= 30) { QPen pen; pen.setColor(QColor(255,255,255)); painter.setPen(pen); QPointF pt1= trans2(i); painter.drawLine(QPointF(518,314), pt1); QPointF pt =trans(i); painter.save(); //偏移坐标原点到需要绘制刻度的位置 painter.translate(pt); //旋转指定的角度 painter.rotate(i); // 画刻度 painter.drawText(-30,-32,55,20,Qt::AlignCenter,QString::number(i)); painter.restore(); if(i == 90) { QPen pen; pen.setColor(QColor(255,255,255)); painter.setPen(pen); QPointF pt1= trans2(i); painter.drawLine(QPointF(518,314), pt1); QPointF pt =trans(i); painter.save(); //偏移坐标原点到需要绘制刻度的位置 painter.translate(pt); //旋转指定的角度 painter.rotate(i); pen.setColor(QColor(0,255,0)); painter.setPen(pen); QFont font; font.setPointSize(14); painter.setFont(font); painter.drawText(-20,-5,60,30,Qt::AlignCenter, QString::fromUtf8( "E" )); painter.restore(); } if(i == 180) { QPen pen; pen.setColor(QColor(255,255,255)); painter.setPen(pen); QPointF pt1= trans2(i); painter.drawLine(QPointF(518,314), pt1); QPointF pt =trans(i); painter.save(); //偏移坐标原点到需要绘制刻度的位置 painter.translate(pt); //旋转指定的角度 painter.rotate(i); pen.setColor(QColor(0,255,0)); painter.setPen(pen); QFont font; font.setPointSize(14); painter.setFont(font); painter.drawText(-20,-5,60,30,Qt::AlignCenter, QString::fromLatin1( "S" )); painter.restore(); } if(i == 270) { QPen pen; pen.setColor(QColor(255,255,255)); painter.setPen(pen); QPointF pt1= trans2(i); painter.drawLine(QPointF(518,314), pt1); QPointF pt =trans(i); painter.save(); //偏移坐标原点到需要绘制刻度的位置 painter.translate(pt); //旋转指定的角度 painter.rotate(i); pen.setColor(QColor(0,255,0)); painter.setPen(pen); QFont font; font.setPointSize(14); painter.setFont(font); painter.drawText(-20,-5,60,30,Qt::AlignCenter, QString::fromLatin1( "W" )); painter.restore(); } if(i == 360) { QPen pen; pen.setColor(QColor(255,255,255)); painter.setPen(pen); QPointF pt1= trans2(i); painter.drawLine(QPointF(518,314), pt1); QPointF pt =trans(i); //设置当前字体 painter.save(); //偏移坐标原点到需要绘制刻度的位置 painter.translate(pt); //旋转指定的角度 painter.rotate(i); pen.setColor(QColor(0,255,0)); painter.setPen(pen); QFont font; font.setPointSize(14); painter.setFont(font); painter.drawText(-20,-5,60,30,Qt::AlignCenter, QString::fromLatin1( "N")); painter.restore(); } } }
(3)获取角度对应的圆弧点
#define DegreeToArc(x) x*M_PI/180.0 /* 角度转弧度 */
QPointF Display_Navigator::trans(int angle) { QPointF ptResult(QPointF(518,314) ); //[角度转弧度] float rad = DegreeToArc(static_cast<float>(angle)); ptResult.setX(518 + (255) * qSin(static_cast<qreal>(rad))); ptResult.setY(314 - (255) * qCos(static_cast<qreal>(rad))); return ptResult; } QPointF Display_Navigator::trans(int angle,float len) { QPointF ptResult(QPointF(518,314) ); //[角度转弧度] float rad = DegreeToArc(static_cast<float>(angle)); ptResult.setX(518 + (255+len) * qSin(static_cast<qreal>(rad))); ptResult.setY(314 - (255+len) * qCos(static_cast<qreal>(rad))); return ptResult; } QPointF Display_Navigator::trans2(int angle) { QPointF ptResult(QPointF(518,314)); //[角度转弧度] float rad = DegreeToArc(static_cast<float>(angle)); ptResult.setX(518 +(255-30 )* qSin(static_cast<qreal>(rad))); ptResult.setY(314 -(255-30) * qCos(static_cast<qreal>(rad))); return ptResult; }
(3)安装事件
//----------绘图事件管理器----------// ui->qwtPlot->canvas()->installEventFilter(this);
(4)效果:
①没加绘图事件
②添加绘图事件
分析:可以在画布上添加绘图触发事件,但是会覆盖曲线,覆盖珊格线,不会显示曲线。在画布上设置背景失败!!!
尝试2(思路3):设置qwt背景
①获取控件qwt实际大小
void Display_Navigator::getQwtplotSize() { qwtplotSize = ui->qwtPlot->size(); }//只能在控件显示(show() )之后,获取实际的大小,不能在初始化就获取大小
②为qwt添加背景图片
//添加背景 QPixmap pixmap = QPixmap(":/image/Image/compass.png").scaled(qwtplotSize);//.scaled(ui->qwtPlot_2->size()); QPalette palette(ui->qwtPlot->palette()); palette.setBrush(QPalette::Background, QBrush(pixmap)); qDebug()<<"qwtplot.size="<<ui->qwtPlot->size(); ui->qwtPlot->setPalette(palette); ui->qwtPlot->setAutoFillBackground(true);//设置窗体自动填充背景
效果图:
导航图会有边框。
③去除qwt绘图控件的边框
ui->qwtPlot_2->setStyleSheet(QString::fromUtf8("border:none;"));//设置边框无
设置这句话必须设置窗体自动填充背景,不然背景图片加载不上。
最后成型效果图:
---恢复内容结束---