完成大作业后的总结(一点关于使用qt的总结)

前言(废话)

byd,CSDN上消失了一个月,现在终于回归了

中间跑去做大作业了(虽然中间水了两周),还有一堆破事,转专业,竞赛啥的

嘛,这是最后的成果:

外排序部分很快就写完了,后面的画图和gui设计搞了我好久(毕竟第一次接触)

大作业的要求:

1.对股票数据进行排序 (必须使用外排序,用于排序的内存大小限制为32MB,此限制的检查,需要通过资源管理器展现。)

嘛,简单,我是参考了这篇文章:

【外排序】外排序算法(磁盘排序、磁带排序) 外存设备结构分析 败者树多路归并 最佳归并树白话讲解-CSDN博客

在知道是归并排序之后就开干了,其中对文件进行归并的时候用上了STL的priority_queue,后面老师又介绍了最小堆,这两个都可以,先不论效率咋样,直接使用现成的priority_queue是更加方便的

2.创建索引,加快数据访问

索引的创建直接使用文件输入输出把索引放在一个文件里面就行了,这个可以在外排序的过程中进行。

为了加快索引的访问,我是创建了一个索引类来读取文件里面的索引来将索引放在内存的

可以看看我的索引类的声明:

struct index{
    char code[codeL];
    int YM;
    index(){}
    index(char * tmp, int YM):YM(YM){memcpy(code, tmp, codeL);}
    bool operator<(const index tmp)const;
    bool operator!=(const index tmp)const;
    bool operator==(const index tmp)const;
};//为索引类使用的结构

class Index{
private:
    bool is_build;
    std::map<index, long> m;
public:
    Index(){is_build = false;}
    void build(void);
    long get_index(const index &tmp){return m[tmp];}
    long get_next_index(const index &tmp);
    bool is_index_existed(const index &tmp);
    QStringList get_all_code(void);//给出所有的股票代码
    QStringList get_all_code(const int YM);//根据年月给出对应的股票代码
    QStringList get_all_month(void);//给出所有的年月
    QStringList get_all_month(const char str[codeL]);//根据股票代码给出对应的年月
};//索引类

其中map是STL的map,即映射

3.对股票价格进行可视化

来了,最难的部分

为什么我说最难?因为这玩意我根本不了解,byd,老师不教你,网络上的描述不清不楚,我当时还以为是要扔到主函数来使用。还有那个qcustomplot,byd对qt版本还有要求(刚开始没看到),给qt换版本都遇到一堆问题,nnd qtcreator6.0以上的版本用using namespace std;还会出bug,看着那一个又一个的error,感觉都要寄了

不过最后是成功克服

先说说qcustomplot的部署吧:

Qt Plotting Widget QCustomPlot - Setting Up

这是官网,最新版本的qcustomplot要求qt版本不高于6.4(现在最新的基本都是6.7,6.8),里面也有教程,简单说就是把qcustomplot.cpp和.h下下来,扔到工程文件夹,让.pro添加这两个现有文件就行了,其中qt6.0以上的还要改.pro文件里面的一行,以及提升widget类(具体看里面教程)

(qcustomplot是用来画图的)

然后是qt版本的改变:

希望被虐的可以网络上找镜像下载5.15以下的离线安装包,然后用qt手动添加(太痛苦了)

当然这边有比较简单的办法:

先Win+R,然后输入cmd后回车

定位到你放qt的文件夹(这是我的文件夹,其中框出来的文件是要改qt版本的文件):

方法:Windows下cmd快速到达指定文件位置(三种方法总结)_cmd怎么转到指定文件夹-CSDN博客

(注意不是用资源管理器打开,要不然下载很慢)

然后输入:

.\MaintenanceTool.exe --mirror https://mirrors.ustc.edu.cn/qtproject

就可以镜像下载,速度更快

接下来

第二张图点完archive之后记得点筛选

第三张图选自己想要的版本就行了,相应版本的不要都选了,只要如图所示的MinGW就行了(我大作业只要这个就是了)

接下来就可以在qtcreator的构建界面添加构建的qt版本了(可以在新建工程的时候选)

接下来是qt的ui设计的使用

先构建带有ui的项目

构建的时候选自己想要的qt版本就行了

双击该文件就可以进行ui编辑

写组件的槽函数

(以上图片来自助教的ppt)

想要使用qt的ui设计,就需要了解一下信号和槽:

【Qt 学习笔记】详解Qt中的信号和槽_从信号与槽开始学qt-CSDN博客

简单来说就是信号触发的时候,执行槽函数

还需要了解一下qt ui设计的控件,就是ui设计左边那一栏:

【Qt教程】2.1 - Qt5 UI设计器、常用控件_打开qt5 设计器-CSDN博客

提前说一下,主函数main是不需要改的,qt已经给你弄好了,主要改变的是mainwindow(或者你把mainwindow改成的其他名称,以下我都称为mainwindow)

这一次的大作业我只用到了widget,lineedit,pushbutton这几个控件,相应的操作可以上网找,其中给用户输入候选项可以了解一下qt的completer,获取文件路径可以了解一下qt的getfilename函数

想要用哪个控件,就把它拖到中间,然后为它调整大小,位置,设计槽函数

比如我给一个pushbutton控件命名为“选择文件”,然后我向上图所示的一样,转到槽函数,然后选择clicked()信号,qt就会自动转到mainwindow.cpp,给你写好槽函数的框架,你填充函数内容就行了

对于一些控件的使用,比如lineedit,我想获取用户输入的内容,但是信号是在pushbutton的clicked()那里,我们可以通过在函数中用ui->lineedit(或者你给他取的名字)来使用这个控件,获取输入的内容就是:

QString str = ui->lineedit->text();

说实话,我觉得这是比较坑的一部分,因为对ui的定义文件并没有显示在工程中,当时我都不知道该怎么用(或者说我太菜了)

关于绘制k线图

助教已经给出示例代码了:

    ui->custom_plot->clearItems();
    ui->custom_plot->clearGraphs();
    ui->custom_plot->clearPlottables();
    ui->custom_plot->plotLayout()->clear();
    ui->custom_plot->replot();
    QCPAxisRect *cs_axis_rect = new QCPAxisRect(ui->custom_plot), *vol_axis_rect = new QCPAxisRect(ui->custom_plot);
    ui->custom_plot->plotLayout()->addElement(0, 0, cs_axis_rect);
    ui->custom_plot->plotLayout()->addElement(1, 0, vol_axis_rect);
    vol_axis_rect->setMaximumSize(QSize(QWIDGETSIZE_MAX, 100));
    for(QCPAxis *axis : cs_axis_rect->axes()) {
        axis->setLayer("axes");
        axis->grid()->setLayer("grid");
    }
    for(QCPAxis *axis : vol_axis_rect->axes()) {
        axis->setLayer("axes");
        axis->grid()->setLayer("grid");
    }

    QCPFinancial *candle_stick = new QCPFinancial(cs_axis_rect->axis(QCPAxis::atBottom), cs_axis_rect->axis(QCPAxis::atLeft));
    QCPBars *volume_pos = new QCPBars(vol_axis_rect->axis(QCPAxis::atBottom), vol_axis_rect->axis(QCPAxis::atLeft));
    QCPBars *volume_neg = new QCPBars(vol_axis_rect->axis(QCPAxis::atBottom), vol_axis_rect->axis(QCPAxis::atLeft));
    QCPDataContainer<QCPFinancialData> QCP_financial_data;
    QSharedPointer<QCPAxisTickerText> text_ticker(new QCPAxisTickerText);

    // 替换为你读取到的数据
    QDateTime currentDateTime = QDateTime::currentDateTime();
    qint64 seed = currentDateTime.toMSecsSinceEpoch();
    QRandomGenerator generator(seed);
    for (int i=1; i<=31; i++) {
        QCPFinancialData data;
        data.key = i;
        data.open = generator.generateDouble()*10;
        data.close = generator.generateDouble()*10;
        data.high = std::max(data.open, data.close) + generator.generateDouble();
        data.low = std::min(data.open, data.close) - generator.generateDouble();
        qDebug() << data.open << data.close << data.high << data.low;
        QCP_financial_data.add(data);

        (i % 2 ? volume_neg : volume_pos)->addData(data.key, generator.generateDouble()*10);
        text_ticker->addTick(data.key, QString::fromStdString(std::to_string(i)));
    }

    candle_stick->setName("日K");
    candle_stick->setChartStyle(QCPFinancial::csCandlestick);
    candle_stick->setBrushPositive(QColor("#EC0000"));
    candle_stick->setBrushNegative(QColor("#00DA3C"));
    candle_stick->setPenPositive(QColor("#8A0000"));
    candle_stick->setPenNegative(QColor("#008F28"));
    candle_stick->data()->set(QCP_financial_data);
    volume_pos->setPen(Qt::NoPen);
    volume_pos->setBrush(QColor("#EC0000"));
    volume_neg->setPen(Qt::NoPen);
    volume_neg->setBrush(QColor("#00DA3C"));

    connect(cs_axis_rect->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), vol_axis_rect->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
    connect(vol_axis_rect->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), cs_axis_rect->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));

    vol_axis_rect->axis(QCPAxis::atBottom)->setTicker(text_ticker);
    vol_axis_rect->axis(QCPAxis::atBottom)->setTickLabelRotation(15);
    cs_axis_rect->axis(QCPAxis::atBottom)->setBasePen(Qt::NoPen);
    cs_axis_rect->axis(QCPAxis::atBottom)->setTickLabels(false);
    cs_axis_rect->axis(QCPAxis::atBottom)->setTicks(false);

    ui->custom_plot->rescaleAxes();
    cs_axis_rect->axis(QCPAxis::atBottom)->setRange(0, 32);

    QCPMarginGroup *group = new QCPMarginGroup(ui->custom_plot);
    ui->custom_plot->axisRect()->setMarginGroup(QCP::msLeft|QCP::msRight, group);
    cs_axis_rect->setMarginGroup(QCP::msLeft|QCP::msRight, group);
    vol_axis_rect->setMarginGroup(QCP::msLeft|QCP::msRight, group);

    ui->custom_plot->replot();

(这玩意是放在槽函数里面的,别搞错了,需要改数据的地方也已经标示出来了)

其中ui->custom_plot中的custom_plot是被提升的widget类(你部署qcustomplot的时候搞的)的名字,可以自己改掉

4.相关系数计算与热力图展示

助教的示例代码:

    ui->custom_plot->clearItems();
    ui->custom_plot->clearGraphs();
    ui->custom_plot->clearPlottables();
    ui->custom_plot->plotLayout()->clear();
    ui->custom_plot->replot();

    QCPAxisRect *axis_rect = new QCPAxisRect(ui->custom_plot);
    ui->custom_plot->plotLayout()->addElement(0, 0, axis_rect);
    QCPColorMap *color_map = new QCPColorMap(axis_rect->axis(QCPAxis::atBottom), axis_rect->axis(QCPAxis::atLeft));
    QSharedPointer<QCPAxisTickerText> text_ticker(new QCPAxisTickerText);

    int k = 10;
    color_map->data()->setSize(k, k);
    color_map->data()->setRange(QCPRange(0, k-1), QCPRange(0, k-1));

    QDateTime currentDateTime = QDateTime::currentDateTime();
    qint64 seed = currentDateTime.toMSecsSinceEpoch();
    QRandomGenerator generator(seed);
    for (int i=0; i<k; i++) {
        for (int j=0; j<k; j++) {
            double correlation = generator.generateDouble() * 2 - 1;
            color_map->data()->setCell(i, j, correlation);
            QCPItemText *textLabel = new QCPItemText(ui->custom_plot);
            if (correlation > 0) textLabel->setColor(Qt::white);
            else textLabel->setColor(Qt::black);
            textLabel->setPositionAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
            textLabel->position->setAxes(axis_rect->axis(QCPAxis::atBottom), axis_rect->axis(QCPAxis::atLeft));
            textLabel->position->setAxisRect(axis_rect);
            textLabel->setClipToAxisRect(true);
            textLabel->position->setCoords(i, j); // 设置位置
            textLabel->setText(QString::number(correlation)); // 显示数值
        }
        text_ticker->addTick(i, QString::fromStdString(std::to_string(i)));
    }

    axis_rect->axis(QCPAxis::atLeft)->setTicker(text_ticker);
    axis_rect->axis(QCPAxis::atBottom)->setTicker(text_ticker);
    axis_rect->axis(QCPAxis::atBottom)->setTickLabelRotation(15);
    axis_rect->axis(QCPAxis::atLeft)->setTickLength(0);
    axis_rect->axis(QCPAxis::atBottom)->setTickLength(0);
    axis_rect->axis(QCPAxis::atLeft)->grid()->setPen(Qt::NoPen);
    axis_rect->axis(QCPAxis::atBottom)->grid()->setPen(Qt::NoPen);
    axis_rect->axis(QCPAxis::atLeft)->grid()->setZeroLinePen(Qt::NoPen);
    axis_rect->axis(QCPAxis::atBottom)->grid()->setZeroLinePen(Qt::NoPen);
    axis_rect->axis(QCPAxis::atLeft)->setRange(-0.5, k-0.5);
    axis_rect->axis(QCPAxis::atBottom)->setRange(-0.5, k-0.5);

    QCPColorScale *color_scale = new QCPColorScale(ui->custom_plot);
    ui->custom_plot->plotLayout()->addElement(0, 1, color_scale);
    color_scale->setType(QCPAxis::atRight);
    color_scale->setDataRange(QCPRange(-1.0, 1.0));
    color_map->setColorScale(color_scale);
    QCPColorGradient gradient;
    gradient.setColorStopAt(0.0, QColor("#ffffd0"));
    gradient.setColorStopAt(0.5, QColor("#3eb6c5"));
    gradient.setColorStopAt(1.0, QColor("#042060"));
    color_map->setGradient(gradient);
    color_map->setInterpolate(false);
    ui->custom_plot->replot();

(实际上助教有对数值设置的有改进,在微信群里)

补充(2024/6/3):

助教改进的代码:

double correlation = code1.second.calc_correlation(code2.second);
if (!std::isnan(correlation)) {
    color_map->data()->setCell(i, j, correlation);
    QCPItemText *textLabel = new QCPItemText(ui->custom_plot);
    if (correlation > 0) textLabel->setColor(Qt::white);
    else textLabel->setColor(Qt::black);
    textLabel->setPositionAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    textLabel->position->setAxes(axis_rect->axis(QCPAxis::atBottom), axis_rect->axis(QCPAxis::atLeft));
    textLabel->position->setAxisRect(axis_rect);
    textLabel->setClipToAxisRect(true);
    textLabel->position->setCoords(i, j); // 设置位置
    textLabel->setText(QString::number(correlation)); // 显示数值
}
else color_map->data()->setAlpha(i, j, 0);

(把第二个for循环的内容换成这个)

5.预测价格变动并展示

助教的示例代码:

ui->custom_plot->clearItems();
    ui->custom_plot->clearGraphs();
    ui->custom_plot->clearPlottables();
    ui->custom_plot->plotLayout()->clear();
    ui->custom_plot->replot();
    QCPAxisRect *last_axis_rect = new QCPAxisRect(ui->custom_plot), *next_axis_rect = new QCPAxisRect(ui->custom_plot);
    ui->custom_plot->plotLayout()->addElement(0, 0, last_axis_rect);
    ui->custom_plot->plotLayout()->addElement(0, 1, next_axis_rect);
    QCPGraph *last_line_plot = new QCPGraph(last_axis_rect->axis(QCPAxis::atBottom), last_axis_rect->axis(QCPAxis::atLeft));
    QCPGraph *next_target_line_plot = new QCPGraph(next_axis_rect->axis(QCPAxis::atBottom), next_axis_rect->axis(QCPAxis::atLeft));
    QCPGraph *next_predict_line_plot = new QCPGraph(next_axis_rect->axis(QCPAxis::atBottom), next_axis_rect->axis(QCPAxis::atLeft));
    last_line_plot->setPen(QPen(Qt::red));
    next_target_line_plot->setPen(QPen(Qt::red));
    next_predict_line_plot->setPen(QPen(Qt::green));

    QDateTime currentDateTime = QDateTime::currentDateTime();
    qint64 seed = currentDateTime.toMSecsSinceEpoch();
    QRandomGenerator generator(seed);
    for (int i=1; i<=31; i++) {
        last_line_plot->addData(i, generator.generateDouble()*10);
        next_target_line_plot->addData(i, generator.generateDouble()*10);
        next_predict_line_plot->addData(i, generator.generateDouble()*10);
    }

    for(QCPAxis *axis : last_axis_rect->axes()) {
        axis->setLayer("axes");
        axis->grid()->setLayer("grid");
    }
    for(QCPAxis *axis : next_axis_rect->axes()) {
        axis->setLayer("axes");
        axis->grid()->setLayer("grid");
    }
    ui->custom_plot->rescaleAxes();
    last_axis_rect->axis(QCPAxis::atBottom)->setRange(0, 32);
    next_axis_rect->axis(QCPAxis::atBottom)->setRange(0, 32);

    ui->custom_plot->replot();

其中,last_line_plot是当月实际,next_target_line_plot是下月实际,next_predict_line_plot是下月预测

一些牢骚(废话)

因为我不发朋友圈也不发QQ动态,有什么事我就顺便扔CSDN上,发发牢骚

害,转到信息学院被拒绝了,byd,没想到我拿出三个竞赛奖项也不能打动他们的心,虽然说蓝桥杯A组省三是很菜的啦,但是CSP认证370分可以排到全国前10%哦,可恶啊,校内举办的那什么微观博易杯我也是以第三名拿下了二等奖(可恶为什么一等奖不是三个人,悲),虽然说不能吊打信院的所有学生吧,至少能吊打大多数吧。可恶啊。到时候高瓴人工智能院也拒绝我,我可是要到处乱说“贵校的理科不仅不行,看人也不是很准”这种话的

不过转专业都失败了我还是要自学计算机就是了,计算机本来就是靠自学的,主要是我不想学任何文科相关的专业啦

转专业失败了就是农发的狗了,到时候到处乱蹭课

  • 35
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值