QT图形视图系统 - 使用一个项目来学习QT的图形视图框架 - 终篇

简介: 接上一篇,我们需要继续完成以下的效果;先上个效果图:

QT图形视图系统 - 终篇

接上一篇,我们需要继续完成以下的效果;


先上个效果图:

image.gif

修改背景,使之整体适配

上一篇我们绘制了标尺,并且我们修改了放大缩小和对应的背景,整体看来,我们的滚动条会和背景不搭配,因此我们需要修改我们的背景,这里使用qss修改;并且我们把之前的背景也写到这个里面。


style1.qss

QGraphicsView
{
    background: #000000;
}
QScrollBar:horizontal {
    border: none;
    background: #000000;
    height: 15px;
}
QScrollBar::handle:horizontal {
    background: white;
    min-width: 20px;
}
QScrollBar::add-line:horizontal {
    border: none;
    background: #000000;
    width: 0px;
}
QScrollBar::sub-line:horizontal {
    border: none;
    background: #000000;
    width: 0px;
    subcontrol-position: left;
    subcontrol-origin: margin;
}
/*QScrollBar:left-arrow:horizontal, QScrollBar::right-arrow:horizontal {*/
/*    border: 2px solid grey;*/
/*    width: 3px;*/
/*    height: 3px;*/
/*    background: white;*/
/*}*/
QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {
    background: none;
}
QScrollBar:vertical {
    border: none;
    background: #000000;
    width: 15px;
    border-bottom: 1px solid red;
}
QScrollBar::handle:vertical {
    background: white;
    min-height: 20px;
}
QScrollBar::add-line:vertical {
    border: none;
    background: #000000;
    height: 0px;
    subcontrol-position: bottom;
    subcontrol-origin: margin;
}
QScrollBar::sub-line:vertical {
    border: none;
    background: #000000;
    height: 0px;
    subcontrol-position: top;
    subcontrol-origin: margin;
}
QScrollBar:up-arrow:vertical, QScrollBar::down-arrow:vertical {
    border: 2px solid grey;
    width: 3px;
    height: 3px;
    background: white;
}
QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
    background: none;
}

然后我们加载这个qss即可, 将之前设置qss的地方修改成读取这个文件

QFile file(":/resources/qss/style1.qss");
file.open(QIODevice::ReadOnly);
// 设置软件背景色
setStyleSheet(QString(file.readAll()));
file.close();

绘制对应刻度的线条

QGraphicsView有两个函数,一个是绘制背景色,一个是绘制前景色。我们的样条实际上绘制的是背景色,因此我们需要重写这两个函数;

void drawForeground(QPainter* painter, const QRectF& rect) override;
void drawBackground(QPainter* painter, const QRectF& rect) override;

去掉之前再scene中添加的文字,我们接下来开始绘制


背景没有什么好说的,直接绘制成黑色的就可以

void GraphicsView::drawBackground(QPainter *painter, const QRectF &rect)
{
    painter->fillRect(rect, Qt::black);
    // QGraphicsView::drawBackground(painter, rect);
}

接下来我们通过前景色来绘制刻度线

constexpr int32_t uScale = 100000;
constexpr double dScale = 1.0 / uScale;
static std::unordered_map<int, int> gridLinesX, gridLinesY;
void GraphicsView::drawForeground(QPainter *painter, const QRectF &rect)
{
    // fixme 这个地方需要修改成按照单位转换的
    double scale =  pow(10.0, ceil(log10(8.0 / h_ruler_->zoom())));
    double lineWidth {0};
    gridLinesX.clear(), gridLinesY.clear();
    const QColor color[4] {
            {255, 0, 0, 127}, // 0处使用红色绘制
            QColor(100, 100, 100, 50),  // Grid1
            QColor(100, 100, 100, 150), // Grid5
            QColor(100, 100, 100, 255), // Grid10
    };
    double y, x;
    draw(scale * 0.1, rect, x, y);
    draw(scale * 0.5, rect, x, y);
    draw(scale * 1.0, rect, x, y);
    gridLinesX[0] = 0;
    gridLinesY[0] = 0;
    static QVector<QLineF> lines[4];
    for (auto&& vec : lines)
        vec.clear();
    double tmp {};
    for (auto [x, colorIndex] : gridLinesX) {
        tmp = x * dScale;
        lines[colorIndex].push_back(QLineF(tmp, rect.top(), tmp, rect.bottom()));
    }
    for (auto [y, colorIndex] : gridLinesY) {
        tmp = y * dScale;
        lines[colorIndex].push_back(QLineF(rect.left(), tmp, rect.right(), tmp));
    }
    painter->save();
    painter->setRenderHint(QPainter::Antialiasing, false);
    int colorIndex {};
    for (auto&& vec : lines) {
        painter->setPen({color[colorIndex++], lineWidth});
        painter->drawLines(vec.data(), vec.size());
    }
    auto width { rect.width() };
    auto height { rect.height() };
    painter->setPen({Qt::yellow, 0.0});
    painter->drawLine(QLineF {point_.x() - width, point_.y(), point_.x() + width, point_.y()});
    painter->drawLine(QLineF {point_.x(), point_.y() - height, point_.x(), point_.y() + height});
    painter->restore();
}
void GraphicsView::draw(double sc, const QRectF& rect, double &x, double &y)
{
    if (sc >= 1.0) {
        int top = floor(rect.top());
        int left = floor(rect.left());
        y = top - top % int(sc);
        x = left - left % int(sc);
    } else {
        const double k = 1.0 / sc;
        int top = floor(rect.top()) * k;
        int left = floor(rect.left()) * k;
        y = (top - top % int(k)) / k;
        x = (left - left % int(k)) / k;
    }
    for (const auto end_ = rect.bottom(); y < end_; y += sc)
        ++gridLinesY[ceil(y * uScale)];
    for (const auto end_ = rect.right(); x < end_; x += sc)
        ++gridLinesX[ceil(x * uScale)];
}

这样我们便有了网格线


下面的函数是对ruler和鼠标移动时候的操作

void GraphicsView::updateRuler()
{
    updateSceneRect(QRectF()); //
    QPoint p = mapFromScene(QPointF());
    v_ruler_->setOrigin(p.y());
    h_ruler_->setOrigin(p.x());
    v_ruler_->setRulerZoom(qAbs(transform().m22() * 0.1));
    h_ruler_->setRulerZoom(qAbs(transform().m11() * 0.1));
    update();
}
void GraphicsView::mouseMoveEvent(QMouseEvent *event)
{
    QGraphicsView::mouseMoveEvent(event);
    v_ruler_->setCursorPos(event->pos());
    h_ruler_->setCursorPos(event->pos());
    point_ = mapToScene(event->pos());
    emit sig_mouseMove(event->pos());
    update();
}

我们之前对鼠标样式进行了修改,这个里面也不要忘记将View中的鼠标修改成十字

展示的是主要代码,并不是全部代码,如果需要全部代码请联系博主获取

目录
相关文章
|
2月前
|
算法 计算机视觉
基于qt的opencv实时图像处理框架FastCvLearn实战
本文介绍了一个基于Qt的OpenCV实时图像处理框架FastCvLearn,通过手撕代码的方式详细讲解了如何实现实时人脸马赛克等功能,并提供了结果展示和基础知识回顾。
104 7
基于qt的opencv实时图像处理框架FastCvLearn实战
|
2月前
|
文字识别 计算机视觉 开发者
基于QT的OCR和opencv融合框架FastOCRLearn实战
本文介绍了在Qt环境下结合OpenCV库构建OCR识别系统的实战方法,通过FastOCRLearn项目,读者可以学习Tesseract OCR的编译配置和在Windows平台下的实践步骤,文章提供了技术资源链接,帮助开发者理解并实现OCR技术。
127 9
基于QT的OCR和opencv融合框架FastOCRLearn实战
WK
|
8天前
|
开发框架 开发工具 C++
C++跨平台框架Qt
Qt是一个功能强大的C++跨平台应用程序开发框架,支持Windows、macOS、Linux、Android和iOS等操作系统。它提供了250多个C++类,涵盖GUI设计、数据库操作、网络编程等功能。Qt的核心特点是跨平台性、丰富的类库、信号与槽机制,以及良好的文档和社区支持。Qt Creator是其官方IDE,提供了一整套开发工具,方便创建、编译、调试和运行应用程序。Qt适用于桌面、嵌入式和移动应用开发。
WK
29 5
|
11天前
|
存储 文件存储 数据库
【QT项目】QT项目综合练习之简易计数器(QT6+文件存储)
【QT项目】QT项目综合练习之简易计数器(QT6+文件存储)
|
1月前
|
存储 Windows
(13) Qt事件系统(two)
文章详细介绍了Qt事件系统,包括事件分发、自定义事件、事件传播机制、事件过滤以及事件与信号的区别。
74 3
(13) Qt事件系统(two)
|
17天前
|
XML 数据可视化 C语言
001 Qt_从零开始创建项目
本文是Qt专栏的第一篇,介绍了如何创建一个Qt项目。
64 4
|
1月前
|
编解码 程序员
(12)Qt事件系统(one)
本文详细介绍了Qt事件系统,包括各种系统事件、鼠标事件、键盘事件、定时器等的处理方法和示例代码。
70 0
(12)Qt事件系统(one)
|
2月前
|
定位技术 Go 开发工具
dynamic-situational-awareness-qt学习记录
本文是作者yantuguiguziPGJ关于dynamic-situational-awareness-qt学习记录的分享,介绍了在Qt学习过程中发现的qml资源丰富的代码仓库,并提供了资源路径和相关的安装、配置步骤,涉及的内容有数字地球、GIS纹理等,同时提供了相关链接和git命令来克隆代码仓库和ArcGIS Runtime SDK for Qt的安装说明。
|
2月前
|
C语言 C++ Windows
QT多插件通信框架CTK编译记录
本文记录了编译QT多插件通信框架CTK的过程,包括编译结果截图、部署配置、Log4Qt编译配置、参考链接和拓展资料。文中提供了详细的编译步骤和配置文件示例,以及相关的资源链接。
QT多插件通信框架CTK编译记录
|
4月前
|
数据安全/隐私保护 C++ 计算机视觉
Qt(C++)开发一款图片防盗用水印制作小工具
文本水印是一种常用的防盗用手段,可以将文本信息嵌入到图片、视频等文件中,用于识别和证明文件的版权归属。在数字化和网络化的时代,大量的原创作品容易被不法分子盗用或侵犯版权,因此加入文本水印成为了保护原创作品和维护知识产权的必要手段。 通常情况下,文本水印可以包含版权声明、制作者姓名、日期、网址等信息,以帮助识别文件的来源和版权归属。同时,为了增强防盗用效果,文本水印通常会采用字体、颜色、角度等多种组合方式,使得水印难以被删除或篡改,有效地降低了盗用意愿和风险。 开发人员可以使用图像处理技术和编程语言实现文本水印的功能,例如使用Qt的QPainter类进行文本绘制操作,将文本信息嵌入到图片中,
180 1
Qt(C++)开发一款图片防盗用水印制作小工具

推荐镜像

更多