社区新版论坛已上线,点击立即前往!使用 openKylin 账户授权登录,解锁更多体验!

openKylin论坛

 找回密码

在QWidget的外部进行绘制带有坐标轴的图像 [复制链接]



  1. =====================================Widget.h=====================================

  2. #ifndef WIDGET_H

  3. #define WIDGET_H


  4. #include <QWidget>


  5. namespace Ui {

  6.     class Widget;

  7. }


  8. class Widget : public QWidget {

  9.     Q_OBJECT

  10. public:

  11.     Widget(QWidget *parent = 0);

  12.     ~Widget();


  13. protected:

  14.     virtual void changeEvent(QEvent *e);

  15.     virtual bool eventFilter(QObject *watched, QEvent *e);

  16.     void paintOnWidget(QWidget *w);


  17. private:

  18.     Ui::Widget *ui;

  19. };


  20. #endif // WIDGET_H



  21. =====================================Widget.cpp=====================================

  22. #include "Widget.h"

  23. #include "ui_Widget.h"

  24. #include <QtGui/QPainter>


  25. Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) {

  26.     ui->setupUi(this);

  27.     ui->widget->installEventFilter(this);

  28. }


  29. Widget::~Widget() {

  30.     delete ui;

  31. }


  32. void Widget::changeEvent(QEvent *e) {

  33.     QWidget::changeEvent(e);

  34.     switch (e->type()) {

  35.     case QEvent::LanguageChange:

  36.         ui->retranslateUi(this);

  37.         break;

  38.     default:

  39.         break;

  40.     }

  41. }


  42. bool Widget::eventFilter(QObject *watched, QEvent *e) {

  43.     if (watched == ui->widget) {

  44.         if (e->type() == QEvent::Paint) {

  45.             paintOnWidget(ui->widget);

  46.             return true;

  47.         }

  48.     }


  49.     return QWidget::eventFilter(watched, e);

  50. }


  51. void Widget::paintOnWidget(QWidget *w) {

  52.     QPainter painter(w);


  53.     QFontMetrics metrics = painter.fontMetrics();

  54.     int textHeight = metrics.ascent() + metrics.descent();


  55.     int leftWidth = metrics.width(tr("9000")) + 5;

  56.     int rightWidth = metrics.width(tr("(日)"));

  57.     int width = w->size().width() - leftWidth - rightWidth;

  58.     int height = w->size().height() - 3 * textHeight;


  59.     // 绘制外框

  60.     painter.drawRect(0, 0, w->size().width() -1, w->size().height() - 1);

  61.     // 移动坐标系

  62.     //painter.translate(inset * 2, ui->yearWidget->size().height() - inset);

  63.     painter.translate(leftWidth, 1.75 * textHeight + height);


  64.     int totalCount = 9000; // 默认每年收入9000件衣服

  65.     int count = 10;        // 分成10成

  66.     float deltaX = width / 12.0f;         // x坐标上每分的宽度

  67.     float deltaY = (float)height / count; // y坐标上每分的宽度



  68.     // 画横坐标

  69.     painter.drawLine(0, 0, width, 0);

  70.     for (int i = 1; i <= 12; ++i) {

  71.         QString month = tr("%1月").arg(i);

  72.         int stringWidth = metrics.width(month);


  73.         // 绘制坐标刻度

  74.         painter.drawLine(deltaX * i, 0, deltaX * i, 4);


  75.         // 绘制坐标处的月

  76.         int monthX = deltaX * (i - 1) + ((deltaX - stringWidth) / 2);

  77.         painter.drawText(monthX, textHeight, month);

  78.     }


  79.     // 画纵坐标

  80.     painter.drawLine(0, 0, 0, -height);

  81.     painter.drawText(-metrics.width(tr("(件)")),

  82.                      -(deltaY * count + textHeight / 2 + metrics.descent()),

  83.                      tr("(件)"));

  84.     for (int i = 1; i <= count; ++i) {

  85.         QString value = QString("%1").arg(i * totalCount / count);

  86.         int stringWidth = metrics.width(value);


  87.         // 绘制坐标刻度

  88.         painter.drawLine(-4, -i * deltaY, 0, -i * deltaY);


  89.         // 绘制坐标值

  90.         //painter.drawText(-stringWidth - 4, -i * deltaY + stringHeight / 2, value);

  91.         painter.drawText(-stringWidth - 4, -(deltaY * i + textHeight / 2 - metrics.ascent()), value);

  92.     }
  93. }
复制代码


楼主
发表于 2014-7-8 14:18:03
回复

使用道具 举报

openKylin

GMT+8, 2024-7-3 00:01 , Processed in 0.023817 second(s), 18 queries , Gzip On.

Copyright ©2022 openKylin. All Rights Reserved .

ICP No. 15002470-12 Tianjin

快速回复 返回顶部 返回列表