<Qt> 初识Qt

news2024/12/23 23:32:20

目录

一、项目文件解析

widget.h

main.cpp

widget.cpp

widget.ui

.pro文件

二、QT 实现Hello World程序

(一)按钮控件

1. 纯代码

2. 图形化

(二)标签控件

1. 纯代码

2. 图形化

三、内存泄漏问题

四、qdebug()的使用

五、Qt 中的对象树

六、使用其他方式创建一个 Hello World 程序(编辑框和按钮方式)

(一)编辑框

1. 图形化

2. 纯代码

(二)按钮

1. 图形化

2. 纯代码

七、关于 Qt 中的命名规范 / 快捷键 / 查询文档

八、Qt 窗口坐标系


一、项目文件解析

创建一个新qt项目后,会生成几个默认对应的文件

widget.h

注意:这里的文件名在创建时默认为widget.h,我这里只是重命名了这个文件名

  • 在QT中如果某个类想要使用信号与槽signal slot的机制,那么必须引入Q_OBJECT这个宏,并且要将这个宏写在这个类的前面,这时候QT编译器就允许这个类自定义信号和槽函数;
  • Ui::Widget *ui这个指针是在 namespace Ui 里的 Widget 类里面定义的,并且这个ui 指针实际上是指向可视化设计的界面的,后面要访问这个可视化界面上的控件都是通过这个指针去访问的。

main.cpp

使用QT创建一个任意一个工程过后,main.cpp文件中都会自动生成以下代码:

  1. Qt系统提供的标准类名声明头⽂件没有 .h 后缀。
  2. Qt⼀个类对应⼀个头⽂件,类名就是头⽂件名。
  3. QApplication 为应⽤程序类;QApplication a;(a为应⽤程序对象,有且仅有⼀个。)
    3.1 QApplication管理图形⽤⼾界⾯应⽤程序的控制流和主要设置。
    3.2 QApplication是Qt的整个后台管理的命脉。它包含主事件循环,在其中来⾃窗⼝系统和其它资源的所有事件处理和调度。它也处理应⽤程序的初始化和结束,并且提供对话管理。
    3.3 对于任何⼀个使⽤Qt的图形⽤⼾界⾯应⽤程序,都正好存在⼀个QApplication对象,⽽不论这个应⽤程序在同⼀时间内是不是有0、1、2或更多个窗⼝。
  4. Widget w:实例化窗口对象。
  5. w.show():显示窗口对象,与之对应的 w.close() 隐藏窗口对象。
  6. a.exec():程序进⼊消息循环,等待对⽤⼾输⼊进⾏响应。这⾥main()把控制权转交给Qt,Qt完成事件处理⼯作,当应⽤程序退出的时候exec()的值就会返回。在 exec()中,Qt 接受并处理⽤⼾和系统的事件并且把它们传递给适当的窗⼝部件。

widget.cpp

注意:这里的文件名在创建时默认为widget.cpp,我这里只是重命名了这个文件名

widget.ui

widget.ui 是窗体界⾯定义⽂件,是⼀个XML⽂件,定义了窗⼝上的所有组件的属性设置、布局,及其信号与槽函数的关联等。⽤UI设计器可视化设计的界⾯都由Qt⾃动解析,并以XML⽂件的形式保存下来。在设计界⾯时,只需在UI设计器⾥进⾏可视化设计即可,⽽不⽤管widget.ui⽂件是怎么⽣成的。

.pro文件

⼯程新建好之后,在⼯程⽬录列表中有⼀个后缀为".pro"的⽂件,".pro"⽂件就是⼯程⽂件(project)
,它是 qmake ⾃动⽣成的⽤于⽣产 makefile 的配置⽂件。如图所示:

双击进⼊该⽂件,该⽂件的核⼼内容如下:

  • QT +=coregui:Qt 包含的模块
  • greaterThan(QT_MAJOR_VERSION, 4): QT+=widgets:⼤于Qt4版本才包含widget模块
  • TARGET=QtFirst:应⽤程序名⽣成的 .exe 程序名称
  • TEMPLATE=app:模板类型,应⽤程序模板
  • SOURCES+=main.cpp\ :源⽂件
  • widget.cpp:源⽂件
  • HEADERS+=widget.h:头⽂件

“.pro” ⽂件的写法如下:

  1. 注释:从"#"开始,到这⼀⾏结束。
  2. QT += coregui:Qt包含的模块 Qt5包含的模块如下图所⽰:

  3. greaterThan(QT_MAJOR_VERSION,4):QT+=widgets 这条语句的含义是,如果QT_MAJOR_VERSION ⼤于4也就是当前使⽤的Qt5及更⾼版本)需要增加widgets 模块。如果项⽬仅需⽀持Qt5,也可以直接添加"QT+=widgets"⼀句。不过为了保持代码兼容,最好还是按照QtCreator⽣成的语句编写。
  4. 指定⽣成的应⽤程序名:TARGET=QtDemo
  5. TEMPLATE=app:模板。告诉qmake为这个应⽤程序⽣成哪种makefile。下⾯是可供选择的模板:
    5.1 app:建⽴⼀个应⽤程序的makefile。这是默认值,所以如果模板没有被指定,这个将被使⽤。
    5.2 lib:建⽴⼀个库的makefile。
    5.3 vcapp:建⽴⼀个应⽤程序的VisualStudio项⽬⽂件。
    5.4 vclib: 建⽴⼀个库的VisualStudio项⽬⽂件。
    5.5 subdirs:这是⼀个特殊的模板,它可以创建⼀个能够进⼊特定⽬录的makefile并且为它调⽤make的makefile。
  6. ⼯程中包含的源⽂件:SOURCES+=main.cpp/widget.cpp
  7. ⼯程中包含的头⽂件:HEADERS+=widget.h
  8. ⼯程中包含的资源⽂件:RESOURCES+=painter.qrc
  9. ⼯程中包含的"ui"设计⽂件:FORMS+=widget.ui
  10. 配置信息:CONFIG+=c++11(使⽤c++11的特性) CONFIG⽤来告诉qmake关于应⽤程序的配置信息。

二、QT 实现Hello World程序

利用 Qt 创建一个Hello World 程序有两种方式。分别是图形化的方式和纯代码的方式。

(一)按钮控件

1. 纯代码

#include "mywidget.h"
#include "ui_mywidget.h"
#include <QPushButton> // 添加按钮对应的头文件

MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MyWidget)
{
    ui->setupUi(this);

    // 在这里编写我们的代码

    // 创建一个按钮控件
    QPushButton *pushButton = new QPushButton;

    // 在这个按钮写一个Hello World
    pushButton->setText("Hello World!");

    // 将这个按钮控件添加在窗口上
    pushButton->setParent(this);
}

MyWidget::~MyWidget()
{
    delete ui;
}

效果图:

2. 图形化

将按钮控件拖至屏幕上,双击控件,输入 Hello World。效果图如下:

(二)标签控件

1. 纯代码

#include "mywidget.h"
#include "ui_mywidget.h"
#include <QLabel> // 引入标签控件的头文件
#include <QFont>  // 引入字体头文件

MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MyWidget)
{
    ui->setupUi(this);

    // 创建一个标签控件
    QLabel *label = new QLabel;

    // 在这个标签写上Hello World
    label->setText("Hello World");

    // 创建一个字体对象
    // 将标签上的文字的字体设置成指定格式
    QFont font("黑体", 64);
    label->setFont(font);

    // 将标签这个控件放在窗口上
    // 并将这个控件移动到像素坐标为(150, 150)的地方
    label->move(150, 150);
    label->setParent(this);
}

MyWidget::~MyWidget()
{
    delete ui;
}

效果图如下: 

2. 图形化

效果图如下:

三、内存泄漏问题

在这段代码中,在 new 了一个对象之后,却没有 delete ,会不会造成内存泄漏?
答案是在 Qt 中不会造成内存泄漏。此处通过 new 的方式创建对象,就是为了把该对象的生命周期交给 Qt 的对象树统一管理。代码中的 label 对象会在合适的时机被析构释放,这个合适的时机是指在窗口关闭的时候。

四、qdebug()的使用

qDebug() 的使用效果和 std::cout << std::endl 的效果一样,但是比后者好。
原因是 qDebug() 会自动处理编码方式,在 Qt 中如果用 cout 打印文字日志,可能会出现乱码,因为编码不同。

如在析构函数中加入打印语句:

Widget::~Widget()
{
    std::cout << "析构函数\n";
    delete ui;
}

运行后,然后关闭窗口,自动调用析构函数,查看应用程序输出,会看到乱码: 

所以通常采用 qDebug() 的方式去打印日志:

#include <QDebug> // 包含这个头文件

Widget::~Widget()
{
    qDebug() << "析构函数";
    delete ui;
}

qDebug() 还有一个优点就是可以统一打开和关闭,就能方便程序员调试。
.pro 文件加入这条代码即可:

DEFINES += QT_NO_DEBUG_OUTPUT

需要 清除 然后重新构建才有效

五、Qt 中的对象树

在Qt中创建很多对象的时候会提供一个parent对象指针,这个parent到底是干什么的呢?

QObject是以对象树的形式组织起来的。

  • 当创建一个QObject对象时,会看到QObject的构造函数接收⼀个QObject指针作为参数,这个参数就是parent,即父对象指针。
  • 在创建QObject对象时,可以提供⼀个其父对象,创建的这个QObject对象会自动添加到其父对象的children()列表。
  • 当父对象析构的时候,这个列表中的所有对象也会被析构。(注意:这里的父对象并不是继承意义上的父类)。

这种机制在GUI程序设计中相当有用。如,一个按钮有一个QShortcut(快捷键)对象作为其子对象。当删除按钮的时候,这个快捷键理应被删除。这是合理的。

QWidget是能够在屏幕上显示的一切组件的父类

  • QWidget继承自QObject,因此也继承了这种对象树关系。一个孩子自动地成为父组件的⼀个子组件。因此,它会显示在父组件的坐标系统中,被父组件的边界剪裁。如:当用户关闭⼀个对话框的时候,应用程序将其删除,我们希望属于这个对话框的按钮、图标等应该⼀起被删除。因为这些都是对话框的子组件
  • 我们也可以自己删除子对象,它们会自动从其父对象列表中删除。如:当删除了一个工具栏时,其所在的主窗口会自动将该工具栏从其子对象列表中删除,并且自动调整屏幕显示。

对象树机制一定程度上解决了内存问题。

  • 当一个QObject对象在堆上创建的时候,Qt会同时为其创建一个对象树。不过对象树中对象的顺序是没有定义的,即销毁这些对象的顺序也是未定义的
  • 任何对象树中的QObject对象delete时,若这个对象有parent,则自动将其从parent的children()列表中删除;若有孩子,则自动delete每一个孩子。Qt保证没有QObject会被delete两次,这是由析构顺序决定的。

若QObject在栈上创建,Qt保持同样的行为。正常情况下也不会发生什么问题:

{
    QWidget window;
    QPushButton quit("Quit", &window);
}

作为父组件的window和作为子组件的quit都是QObject的子类。这段代码是正确的,quit的析构函数不会被调用两次,因为标准C++要求,局部对象的析构顺序应该按照其创建顺序的相反过程。因此,这段代码在超出作用域时,会先调用quit的析构函数,将其从父对象window的子对象列表中删除,然后才会再调用window的析构函数。

{
    QPushButton quit("Quit");
    QWidget window;
    quit.setParent(&window);
}

上述代码的析构顺序就有了问题。在上面的代码中,作为父对象的window会先被析构,因为它是最后一个创建的对象。在析构过程中,它会调用子对象列表中每一个对象的析构函数,即quit此时就被析构了。然后代码继续执行,在window析构之后,quit也会被析构,因为quit也是⼀个局部变量,在超出作用域的时候当然也需要析构。但是,这时候已经是第⼆次调用quit的析构函数了,C++不允许调用两次析构函数,因此,程序崩溃了:

自定义MyPushButton类观察释放过程

mypushbutton.h

#ifndef MYPUSHBUTTON_H
#define MYPUSHBUTTON_H
 
#include <QPushButton>
#include <QDebug>
 
class MyPushButton : public QPushButton
{
    Q_OBJECT
public:
    explicit MyPushButton(QWidget *parent = nullptr);
    ~MyPushButton();//添加MyPushButton类的析构函数
 
signals:
 
};
 
#endif // MYPUSHBUTTON_H

 mypushbutton.cpp

#include "mypushbutton.h"
 
MyPushButton::MyPushButton(QWidget *parent) : QPushButton(parent)
{
    qDebug() << "我的按钮的构造函数被调用";
}
 
MyPushButton::~MyPushButton()
{
    qDebug() << "我的按钮的析构函数被调用";
}

widget.h

#include "widget.h"
#include "ui_widget.h"
#include "mypushbutton.h"
 
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    MyPushButton* button = new MyPushButton(this);
    //传入this,将其设置到对象树中,当窗口关闭时就会自动调用其析构函数
    button->setText("我的按钮");
}
 
Widget::~Widget()
{
    qDebug() << "Widget的析构函数被调用";
    delete ui;
}

运行结果如下:

对象树确保的是先释放子节点的内存,后释放父节点的内存。而析构函数的调用顺序则不⼀定遵守上述要求,因此看到子节点的析构执行顺序反而在父节点析构顺序之后。

注意:调用析构函数和释放内存并非是同一件事情。

总结:

Qt的对象树机制虽然在⼀定程度上解决了内存问题,但是也引入了⼀些值得注意的事情。这些细节在今后的开发过程中很可能时不时跳出来烦扰一下,所以最好从开始就养成良好习惯。

注意:在Qt中,尽量在构造的时候就指定parent对象,并且大胆在堆上创建

六、使用其他方式创建一个 Hello World 程序(编辑框和按钮方式)

除了上面使用 label 标签的形式,还可以采用编辑框按钮的方式。同样分为图形化界面方式和纯代码方式完成。

(一)编辑框

1. 图形化

如下图所示,编辑框分为单行编辑框和多行编辑框,这里选择单行编辑框即可。拖动到编辑界面,然后输入文字:

运行查看效果。编辑框的内容运行后可以自己修改: 

2. 纯代码

纯代码方式和之前介绍过的大同小异。首先需要创建一个 QLineEdit 对象,然后设置文字:

效果图如下: 

(二)按钮

1. 图形化

在 ui 界面找到 Push Button 然后拖动到图形化编辑界面输入文字:

运行查看效果,可以点击这个按钮:

这个按钮是可以点击的,但是点击了没有反应。如果想要点击了有反应,需要用到信号和槽机制,后面会讲。这里先简单说一下,本质就是给按钮的点击操作,关联一个处理函数,当用户点击的时候,就会执行这个处理函数。

这里需要用到 connect 函数:

  • 第一个参数需要访问到 ui 文件中创建的控件,表示哪个控件发出的信号,在 Qt Designer 中创建一个控件的时候,此时就会给这个控件分配一个 objectName 属性,这个属性的值,要求在界面中是唯一的。qmake 在预处理.ui文件的时候,就会根据这里的 objectname 生成对应的C++代码。这个值可以在ui界面手动修改:

  • 第二个参数表示发出了个什么信号,这里 clicked 表示点击,当用户点击按钮时就会发出该信号。
  • 第三个参数表示谁来处理该信号,将第二个参数的信号能够关联到对应的槽函数上,在此之前需要确认关联到哪个对象的槽函数,填写 this ,关联到 widget 对象的槽函数。
  • 第四个参数传一个具体的处理函数,这个函数需要我们自己去写处理方式。我们的处理方式是:点击一次按钮,文本在 Hello World!和Hello Qt! 之间来回切换。代码如下:
void Widget::handClick()
{
    if(ui->pushButton->text() == QString("Hello World!"))
    {
        ui->pushButton->setText("Hello Qt!");
    }
    else
    {
        ui->pushButton->setText("Hello World!");
    }
}

记得先在头文件声明该函数

声明以后,快速生成函数定义快捷键:alt + 回车 会自动在 .cpp 文件帮我们处理好一些代码 

运行效果如下:

 点击一次按钮:

文本内容改变了,再点击一次 

点击一次按钮就会在两个文本内容之间来回切换,成功实现我们想要的功能。 

2. 纯代码

纯代码方式实现,首先需要new 一个 button 对象,为了能让其他成员函数能够访问该变量,需要将该对象定义为成员变量:

具体代码如下,功能如上面所述:

运行查看效果:

点击后: 

再次点击: 

实际开发以纯代码为主还是图形化界面为主?

这两者都很重要,难分主次。

  • 如果当前程序界面,界面内容是比较固定的,此时就会以图形化界面的方式来构造界面。
  • 如果当前界面,经常要动态变化,此时就会以代码的方式来构造界面。
  • 这两种方式,哪种方便就用哪种,而且这两种方式可以配合使用。

七、关于 Qt 中的命名规范 / 快捷键 / 查询文档

命名规范

  • 类名:首字母大写,单词和单词之间首字母大写,也就是大驼峰命名法。如:QPushButton
  • 函数名:首字母小写,单词和单词之间首字母大写,也就是小驼峰命名法。如:setText

快捷键

  • 注释:ctrl+ /
  • 运行:ctrl+ R
  • 编译:cttrl+ B
  • 字体缩放:ctrl +鼠标滑轮
  • 查找:ctrl + F
  • 整行移动:ctrl+shift+ ↑/↓
  • 帮助文档:F1
  • 自动对齐:ctrl+ i;
  • 同名之间的.h和.cpp的切换:F4
  • 生成函数声明的对应定义:alt + enter

使用帮助文档
打开文档一共有三种方法

  • 光标放到要查询的类名/方法名上,直接按F1
  • Qt Creator左侧边栏中直接用鼠标单击"帮助"按钮。
  • 找到Qt Creator的安装路径,在"bin"文件夹下找到assistant.exe,双击打开。

八、Qt 窗口坐标系

坐标体系:以左上角为原点(0,0),X向右增加,Y向下增加

对于嵌套窗口,其坐标是相对于父窗口来说的:

比如图中 QPushButton 的父窗口就是 QWidget,原点就是QWidget 左上角。QWidget没有父元素,相当于父元素就是整个显示器,原点就是显示器左上角。

上面我们提到过,以纯代码的方式创建一个这样一个程序,按钮会默认在左上角,也就是原点(0,0)处,这里的位置是可以通过设置改变的:

#include <QPushButton>
 
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
 
    QPushButton* button = new QPushButton(this);
    button->setText("按钮"); // 如果不设置,默认位置就是父窗口的(0,0)坐标
    button->move(200, 300);
}

如果想要给控件设置位置就要使用 move() 方法: 

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
 
    QPushButton* button = new QPushButton(this);
    button->setText("按钮"); // 如果不设置,默认位置就是父窗口的(0,0)坐标
    button->move(200, 300);
}

 这里move的第一个参数就是X坐标,第二个参数就是Y坐标,而参数的单位就是像素,显示器本身就是一大堆可以发光的亮点:

电脑屏幕设置中的分辨率:在水平方向上有1920个像素,垂直方向上有1080个像素,显示器像素越大,画面越好。

把这个按钮相对于原点水平移动200像素,垂直移动300像素,效果如下:

还可以设置窗口弹出时的位置,设置为弹出为显示器的原点处:

查看效果,在窗口弹出后位置在显示器左上角: 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1937165.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL(事务、索引)MyBatis

目录 事务 概述 四大特性&#xff08;ACID&#xff09; 索引 结构 语法 MyBatis 数据库连接池 lombok 基本操作--增删改查 根据主键删除 新增 更新 查询&#xff08;根据ID查询&#xff09; 查询&#xff08;条件查询&#xff09; XML映射文件 动态SQL 动态条…

Web安全:未验证的重定向和转发.

Web安全&#xff1a;未验证的重定向和转发. 未验证的重定向和转发漏洞是一种常见的Web安全漏洞&#xff0c;它允许攻击者将用户重定向到一个恶意的URL&#xff0c;而不是预期的安全URL。这种漏洞通常发生在应用程序处理重定向和转发请求时&#xff0c;未能对目标URL进行适当的…

RDMA 高性能架构基本原理与设计方案

在进行本文的学习学习之前&#xff0c;我们先对RDMA是什么做一个简单的科普与认识&#xff1a;一文带你了解什么是RDMA-CSDN博客 目录&#xff1a; 目录&#xff1a; 一、RDMA和传统网络方案的比较 1.1 传统网络方案&#xff1a; 1.1.1 缺点一&#xff1a;以太网卡&#xff0…

单机、集群、分布式服务器比较:

1. 单机服务器的瓶颈&#xff1a; 单机服务器&#xff1a;一台服务器独立运行一个工程所需的全部的业务模块 受限于服务器硬件资源&#xff0c;所承受用户并发量受限&#xff0c;32位linux操作系统最大并发量为两万任一模块的变动和修改&#xff0c;都会导致整个项目代码重新编…

移动端如何离线使用GPT

在移动端离线使用GPT&#xff0c;只需要一个app&#xff1a;H2O AI Personal GPT 是H2OAI上架的一款app&#xff0c;可离线使用&#xff0c;注重数据隐私&#xff0c;所有数据都只存储在本地。对H2OAI感兴趣的伙伴&#xff0c;可移步&#xff1a;https://h2o.ai 该app支持的模…

华为od 100问 持续分享6-入职体检

我是一名软件开发培训机构老师&#xff0c;我的学生已经有上百人通过了华为OD机试&#xff0c;学生们每次考完试&#xff0c;会把题目拿出来一起交流分享。 重要&#xff1a;2024年5月份开始&#xff0c;考的都是OD统一考试&#xff08;D卷&#xff09;&#xff0c;题库已经整…

如何学习Kafka:糙快猛的大数据之路(快速入门到实践)

在大数据开发的世界里,Kafka 无疑是一个不可或缺的重要角色。作为一个分布式流处理平台,它以其高吞吐量、可靠性和可扩展性而闻名。 目录 糙快猛学习法则Kafka 是什么?我的 Kafka 学习故事第一步: 快速上手第二步: 生产和消费消息第三步: 编写简单的生产者和消费者程序 深入Ka…

达梦数据库 DISQL连接数据库与执行SQL、脚本的方法

DISQL连接数据库与执行SQL、脚本的方法 1.DISQL介绍2.DISQL连接数据库的方法2.1 本地连接2.2 远程连接2.3 CONN连接 3.执行SQL、脚本的方法3.1 通过DISQL登录后在字符界面3.2 启动DISQL时运行脚本3.3 进入DISQL后&#xff0c;通过start命令运行脚本3.4 使用EDIT命令编辑脚本 1.…

(02)Unity使用在线AI大模型(调用Python)

目录 一、概要 二、改造Python代码 三、制作Unity场景 一、概要 查看本文需完成&#xff08;01&#xff09;Unity使用在线AI大模型&#xff08;使用百度千帆服务&#xff09;的阅读和实操&#xff0c;本文档接入指南的基础上使用Unity C#调用百度千帆大模型&#xff0c;需要…

【开发踩坑】使用PageHelper工具正常sql后面多无关语句

背景 SQL日志打印出现了脏东西&#xff1a; 本来结束的 where muc.code ?;后面凭空多出了一个 LIMIT语句 ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your …

【Spark On Hive】—— 基于电商数据分析的项目实战

文章目录 Spark On Hive 详解一、项目配置1. 创建工程2. 配置文件3. 工程目录 二、代码实现2.1 Class SparkFactory2.2 Object SparkFactory Spark On Hive 详解 本文基于Spark重构基于Hive的电商数据分析的项目需求&#xff0c;在重构的同时对Spark On Hive的全流程进行详细的…

Unity点击生成节点连线

Unity点击生成节点连线 效果 2.主要代码 Test_Line 控制类 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems;public class Test_Line : MonoBehaviour {public GameObject qiu_prefab;public List<Game…

基于 CNN(二维卷积Conv2D)+LSTM 实现股票多变量时间序列预测(PyTorch版)

前言 系列专栏:【深度学习&#xff1a;算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域&#xff0c;讨论了各种复杂的深度神经网络思想&#xff0c;如卷积神经网络、循环神经网络、生成对…

android13读取cpu频率,并调整频率

总纲 android13 rom 开发总纲说明 目录 1.前言 2.频率类型 3.获取cpu可以调节的频率 4.获取当前频率 5.设置频率 6.最后我们写个脚本,来实现,可以通过参数获取所有cpu的频率,以及设置最大最小频率 6.1 获取cpu频率 6.2 设置最大cpu频率 6.3 设置最小 7.彩蛋 1.前…

敏捷开发笔记(第12章节)--接口隔离原则(ISP)

目录 1&#xff1a;PDF上传链接 12.1&#xff1a;接口污染 12.2&#xff1a;分离客户就是分离接口 12.3&#xff1a;接口隔离原则&#xff08;ISP&#xff09; 12.4&#xff1a;类接口与对象接口 12.4.1&#xff1a;使用委托分离接口 12.4.2&#xff1a;使用多重继承分离接口 …

基于JAVA+SpringBoot+Vue+uniApp的校园日常作品商品分享小程序

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、SpringCloud、Layui、Echarts图表、Nodejs、爬…

为什么精酿人士选择FENDI CLUB啤酒

FENDI CLUB啤酒作为云仓酒庄平台的精酿啤酒自有品牌&#xff0c;平台提供以技术咨询与服务为核心的全产业链精酿产品解决方案&#xff0c;帮助啤酒代理商提高产品质量&#xff0c;树立优质品牌&#xff0c;推广精酿文化&#xff0c;促进精酿发展&#xff0c;力争成为中国本土品…

Leetcode3208. 交替组 II

Every day a Leetcode 题目来源&#xff1a;3208. 交替组 II 解法1&#xff1a;环形数组 把数组复制一份拼接起来&#xff0c;和 3101 题一样&#xff0c;遍历数组的同时&#xff0c;维护以 i 为右端点的交替子数组的长度 cnt。 如果 i ≥ n 且 cnt ≥ k&#xff0c;那么 i…

基于springboot+vue+uniapp的开放实验室预约管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

算法第九天:leetcode59.螺旋矩阵II

给你一个正整数 n &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;[[1,2,3],[8,9,4],[7,6,5]]示例 2&#xff1a; 输入&#xff1a;n 1 输出&am…