說明:近期做項目遇到一個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;"));//設置邊框無
設置這句話必須設置窗體自動填充背景,不然背景圖片加載不上。
最后成型效果圖:
---恢復內容結束---