说明:近期做项目遇到一个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;"));//设置边框无
设置这句话必须设置窗体自动填充背景,不然背景图片加载不上。
最后成型效果图:

---恢复内容结束---