Qt day2
目录
1.多态,虚函数,纯虚函数
1.多态性(Polymorphism):
2.虚函数(Virtual Function):
3.纯虚函数(Pure Virtual Function):
将引用作为函数参数有以下几个特点
1.传递引用可以避免拷贝:
2.可以修改原始对象:
3.引用参数需要传递有效对象:
4.可以避免拷贝构造函数的调用:
5.对原始对象的修改在函数外可见:
结构和联合之间的主要区别:
1.内存布局:
2.成员访问:
3.占用空间:
4.用途:
练习一个界面加跳转到另一个界面
界面1 .h文件
界面2 .h文件
页面2 form.cpp 文件
页面1 widget.cpp 文件
main.cpp 文件
结果为:
一、加载资源文件
1> 将所需的资源文件夹放入工程项目所在路径下
2> 在工程文件中,右键添加新文件
3> 选择Qt --》资源文件
4> 添加前缀
5> 添加文件
6> 点下锤子即可
二、信号与槽机制(非常重要)
2.1 信号与槽的介绍
2.2 信号与槽的连接
2.3 发射自定义信号
2.4 信号与槽的案例
2.5 信号函数与槽函数的总结
2.6 使用信号与槽完成两个界面的跳转
1.多态,虚函数,纯虚函数
多态性(Polymorphism),虚函数(Virtual Function),以及纯虚函数(Pure Virtual Function)都是面向对象编程中的重要概念,用于实现对象之间的灵活性和可扩展性。
1.多态性(Polymorphism):
多态性指的是同一个接口可以被不同的对象以不同的方式实现。这使得不同的类可以共享相同的接口,但可以根据其具体实现在运行时表现出不同的行为。多态性有两种类型:编译时多态性(静态多态性)和运行时多态性(动态多态性)。在C++中,运行时多态性是通过虚函数实现的。
2.虚函数(Virtual Function):
虚函数是在基类中声明为虚拟的,并在派生类中进行重写(覆盖)的函数。通过使用虚函数,可以在运行时根据对象的实际类型来调用相应的函数。使用虚函数,可以实现运行时多态性,使得通过基类指针或引用调用函数时,能够调用到派生类的实现。
class Shape {
public:virtual void draw() {// 基类虚函数}
};class Circle : public Shape {
public:void draw() override {// 派生类覆盖基类虚函数}
};
3.纯虚函数(Pure Virtual Function):
纯虚函数是在基类中声明为虚拟的,但没有在基类中给出实现的函数。它的目的是要求派生类提供实现,否则派生类也会成为抽象类。一个包含纯虚函数的类被称为抽象基类(Abstract Base Class)。
class AbstractShape {
public:virtual void draw() = 0; // 纯虚函数
};class ConcreteCircle : public AbstractShape {
public:void draw() override {// 派生类必须提供纯虚函数的实现}
};
总之,多态性通过虚函数和纯虚函数的概念实现,使得面向对象的程序能够更加灵活地适应不同的场景和需求,同时提高了代码的可扩展性和可维护性。
将引用作为函数参数有以下几个特点
1.传递引用可以避免拷贝:
与传递对象本身相比,传递引用作为函数参数可以避免在函数调用过程中进行对象的拷贝操作,从而提高性能和效率,特别是对于大对象或类对象来说。
2.可以修改原始对象:
通过传递引用,函数可以直接修改传递的对象,因为引用是原对象的别名。这使得函数能够对对象进行原地修改,而不需要返回修改后的对象。
3.引用参数需要传递有效对象:
传递引用参数时,需要确保传递的是有效的对象,因为引用不能指向空值(nullptr)。如果传递了无效的对象引用,可能会导致未定义的行为。
4.可以避免拷贝构造函数的调用:
当传递对象的副本时,会调用拷贝构造函数来创建一个新的对象,但传递引用参数时不会触发拷贝构造函数的调用。
5.对原始对象的修改在函数外可见:
由于传递的是原始对象的引用,对对象的修改会在函数外部可见,不像传值参数那样只是在函数内部有效。以下是一个使用引用作为函数参数的示例:
#include <iostream>void modifyValue(int &x) {x = x * 2;
}int main() {int num = 5;std::cout << "Original value: " << num << std::endl;modifyValue(num);std::cout << "Modified value: " << num << std::endl;return 0;
}
在这个示例中,modifyValue 函数接受一个整数引用作为参数,直接修改传递的整数值。在 main 函数中,调用 modifyValue 后,原始的 num 值被修改,这种修改在函数外部可见。
结构和联合之间的主要区别:
1.内存布局:
结构(struct):结构中的每个成员都在内存中占据独立的空间,成员之间不会共享内存。这意味着结构的大小至少是其所有成员大小之和。
联合(union):联合中的所有成员共享同一块内存,联合的大小取决于最大成员的大小。只有联合中的一个成员可以被有效地存储。
2.成员访问:
结构(struct):可以同时访问结构中的多个成员,每个成员都有自己的地址。
联合(union):只能访问联合中当前活动的成员,因为它们共享相同的内存空间。
3.占用空间:
结构(struct):占用的内存空间取决于所有成员的大小之和,每个成员都有自己的内存空间。
联合(union):占用的内存空间取决于最大成员的大小,不同成员共享同一块内存。
4.用途:
结构(struct):用于存储一组不同类型的数据,每个成员都有自己的含义。
联合(union):用于在同一块内存中存储不同类型的数据,但只会使用其中一个成员。下面是一个简单的示例,说明结构和联合之间的区别:
#include <iostream>struct MyStruct {int a;double b;
};union MyUnion {int x;double y;
};int main() {MyStruct s;MyUnion u;std::cout << "Size of struct: " << sizeof(s) << std::endl; // Output: Size of struct: 12std::cout << "Size of union: " << sizeof(u) << std::endl; // Output: Size of union: 8s.a = 5;s.b = 3.14;u.x = 10;u.y = 2.71;std::cout << "Struct members: " << s.a << ", " << s.b << std::endl; // Output: Struct members: 5, 3.14std::cout << "Union members: " << u.x << ", " << u.y << std::endl; // Output: Union members: 2, 2.71return 0;
}
需要根据具体的需求来选择使用结构还是联合。如果需要在同一块内存中存储不同类型的数据,而且每次只会使用其中一个成员,那么联合可能更合适。如果需要同时存储多个成员,每个成员都有自己的含义,那么结构更适合。
练习一个界面加跳转到另一个界面
界面1 .h文件
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QPushButton>
#include <QDebug>
#include <QIcon>
#include <QLabel>
#include <QPixmap>
#include <QLineEdit>
class Widget : public QWidget
{Q_OBJECT //信号与槽的元对象
signals://自定义信号函数void jump();//void btn_1_clicked();public slots://自定义的槽函数void btn_1_clicked();void btn_2_clicked();//void on_jump_slot();
public:Widget(QWidget *parent = nullptr);~Widget();private:QLabel *lab2;QLabel *lab3;QLabel *lab1;QLineEdit *edit1;QLineEdit *edit2;QPushButton *btn1;QPushButton *btn2;
};
#endif // WIDGET_H
界面2 .h文件
#ifndef FORM_H
#define FORM_H#include <QWidget>namespace Ui {
class Form;
}class Form : public QWidget
{Q_OBJECTpublic:explicit Form(QWidget *parent = nullptr);~Form();public slots:void jump_slot();private:Ui::Form *ui;
};#endif // FORM_H
页面2 form.cpp 文件
#include "form.h"
#include "ui_form.h"Form::Form(QWidget *parent) :QWidget(parent),ui(new Ui::Form)
{ui->setupUi(this);
}Form::~Form()
{delete ui;
}void Form::jump_slot()
{this->show();
}
页面1 widget.cpp 文件
#include "widget.h"
#include "form.h"
Widget::Widget(QWidget *parent): QWidget(parent)
{this->setFixedSize(900, 800); //设置固定尺寸//3、窗口标题this->setWindowTitle("My First Window");//4、设置窗口的iconthis->setWindowIcon(QIcon(":/new/prefix1/icon/wodepeizhenshi.png"));//5、设置背景色,一般使用样式表完成this->setStyleSheet("background-color:rgb(226,227,228);");//标签lab1 = new QLabel(this);lab1->setGeometry(0, 0, 900, 458);lab1->setPixmap(QPixmap(":/new/prefix1/icon/logo1.png"));lab1->setScaledContents(true);lab2 = new QLabel(this);lab2->setGeometry(270, 500, 40, 40);lab2->setPixmap(QPixmap(":/new/prefix1/icon/userName.jpg"));lab2->setScaledContents(true);lab3 = new QLabel(this);lab3->setGeometry(270, 580, 40, 40);lab3->setPixmap(QPixmap(":/new/prefix1/icon/passwd.jpg"));lab3->setScaledContents(true);//行编辑器//1、构造一个行编辑器,构造时给定父组件edit1= new QLineEdit(this);edit2 = new QLineEdit(this);edit1->setPlaceholderText("QQ/手机/邮箱"); //设置编辑器的占位文本edit2->setPlaceholderText("密码");edit1->resize(200,40); //设置尺寸edit2->resize(200,40);edit1->move(350,500); //移动位置edit2->move(350,580);edit2->setEchoMode(QLineEdit::Password); //设置回显模式//按钮组件btn1 = new QPushButton("登录", this);btn2 = new QPushButton("取消", this);btn1->resize(110,60);btn1->move(320,650);btn2->resize(110,60);btn2->move(450,650);btn1->setIcon(QIcon(":/new/prefix1/icon/login.png"));btn2->setIcon(QIcon(":/new/prefix1/icon/cancel.png"));//使用qt5版本连接connect(btn1,&QPushButton::clicked,this,&Widget::btn_1_clicked);//使用qt4版本连接connect(btn2,SIGNAL(pressed()),this,SLOT(close()));
}Widget::~Widget()
{
}
void Widget::btn_1_clicked()
{if(edit1->text() == "admin" && edit2->text() == "123456"){qDebug() << "登录成功";emit jump();this->close();}else{qDebug() << "登录失败";edit1->clear();edit2->clear();}
}void Widget::btn_2_clicked()
{this->close();
}
main.cpp 文件
#include "widget.h"
#include "form.h"
#include <QApplication>
int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();Form m;QObject::connect(&w,&Widget::jump ,&m,&Form::jump_slot);return a.exec();
}
结果为:
一、加载资源文件
1> 将所需的资源文件夹放入工程项目所在路径下
2> 在工程文件中,右键添加新文件
3> 选择Qt --》资源文件
4> 添加前缀
5> 添加文件
6> 点下锤子即可
二、信号与槽机制(非常重要)
2.1 信号与槽的介绍
1> 功能:实现多个组件之间的互相通信,是QT引以为傲的核心机制
2> 信号:就是信号函数,定义在类体的signals权限下,是一个不完整的函数,只有声明没有定义
3> 槽:就是槽函数,定义在类体的slots权限下,是一个完整的函数,既有声明,也有定义,也可以当做普通函数被使用
4> 无论是信号函数还是槽函数,返回值一般都是void类型,参数可以自定义,参数的目的就是为了传递信息的
5> 包含信号与槽定义的类
class Widget : public QWidget
{Q_OBJECT //信号与槽的元对象signals:void my_signal(); //自定义信号函数public slots:void my_slot(); //自定义的槽函数public:Widget(QWidget *parent = nullptr);~Widget();private:Ui::Widget *ui;
};
2.2 信号与槽的连接
1> 在ui界面下的信号与槽的编辑处进行连接,该连接方式只能发射系统提供的信号,并使用系统提供的槽函数接受
2> 在ui界面的组件上,右键转到槽,选择信号,槽函数逻辑自己书写
3> qt4版本的连接函数,该版本的连接是不友好的连接
[static] QMetaObject::Connection //返回值是一个连接,并且该函数是一个静态成员函数QObject::connect( //函数名const QObject *sender, //信号的发射者,是组件的指针const char *signal, //要发射的信号是一个C语言风格的字符串,将信号函数传递进来时,需要使用SIGNAL宏进行转换const QObject *receiver, //信号的接受者,是组件的指针onst char *method) //处理信号的槽函数,是C风格字符串,将槽函数传递进来时,需要使用SLOT宏进行转换
注意:信号函数必须是信号的发射者所在的类中有的信号函数,而槽函数也必须是信号的接受者中有的槽函数
举个例子:QLabel *label = new QLabel;QScrollBar *scrollBar = new QScrollBar;QObject::connect(scrollBar, SIGNAL(valueChanged(int)),label, SLOT(setNum(int)));
4> qt5版本的连接函数
[static] QMetaObject::Connection //返回值是一个连接,并且该函数是一个静态成员函数QObject::connect( //函数名const QObject *sender, //信号的发射者,是组件的指针PointerToMemberFunction signal, //信号函数的函数指针变量,直接填写函数名即可const QObject *receiver, //信号的接受者,是组件的指针PointerToMemberFunction method) //槽函数的函数指针变量,直接填写函数名即可举个例子:QLabel *label = new QLabel;QLineEdit *lineEdit = new QLineEdit;QObject::connect(lineEdit, &QLineEdit::textChanged,label, &QLabel::setText);
5> 信号连接外部函数或lambda表达式
[static] QMetaObject::Connection //返回值是一个连接,并且该函数是一个静态成员函数QObject::connect( //函数名const QObject *sender, //信号的发射者,是组件的指针PointerToMemberFunction signal, //信号函数的函数指针变量,直接填写函数名即可Functor functor) //处理信号的功能函数,可以是全局函数,也可以是lambda表达式举个例子:void someFunction();QPushButton *button = new QPushButton;QObject::connect(button, &QPushButton::clicked, someFunction);Lambda 表达式作为槽函数:QByteArray page = ...;QTcpSocket *socket = new QTcpSocket;socket->connectToHost("qt-project.org", 80);QObject::connect(socket, &QTcpSocket::connected, [=] () {socket->write("GET " + page + "\r\n");});
6> 断开信号与槽的连接
只需将上面的连接函数前加dis即可,参数都不变
//断开按钮对应的槽函数
void Widget::on_btn6_clicked()
{disconnect(btn3, SIGNAL(pressed()), ui->btn1, SLOT(hide()));disconnect(ui->btn4, &QPushButton::clicked, this, &Widget::my_slot);}
2.3 发射自定义信号
1> 在自定义类体内的signals权限下,定义自定义的信号函数,返回值为void,可以有参数也可以没有参数
2> 在程序所需处,使用关键字emit发射自定义的信号:emit 信号名(实参列表);
3> 将自定义的信号与槽函数进行连接
4> 当自定义的信号发射后,槽函数会立即响应
2.4 信号与槽的案例
1> 配置文件
2> 头文件
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include<QDebug>
#include<QPushButton>
#include<QTextToSpeech> //文本转语音的头文件QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECT //信号与槽的元对象signals:void my_signal(); //自定义信号函数public slots:void my_slot(); //自定义的槽函数public:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_btn2_clicked();void on_btn6_clicked();private:Ui::Widget *ui;//自定义一个按钮QPushButton *btn3;//定义一个播报员指针QTextToSpeech *speecher;};
#endif // WIDGET_H
3> 源文件
#include "widget.h"
#include "ui_widget.h"void fun()
{qDebug()<<"我是过路的";
}Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//给播报员实例化空间speecher = new QTextToSpeech(this);//给btn3实例化空间this->btn3 = new QPushButton("按钮3", this);this->btn3->move(ui->btn2->x(), ui->btn2->y()+50);this->btn3->resize(ui->btn2->size());//使用qt4版本的连接,将按钮3发射的pressed信号与按钮1的槽函数进行连接connect(btn3, SIGNAL(pressed()), ui->btn1, SLOT(hide()));//参数1:信号的发射者,按钮3的指针//参数2:要发射的信号,是在按钮所在类中拥有的信号函数,需要使用SIGNAL宏函数进行转换//参数3:信号的接受者,ui界面上的按钮1指针//参数4:处理信号的槽函数,是信号接收者所在类中拥有的槽函数//注意:该链接方式是不友好的链接,原因是 即使宏函数中写错,编译器不报错,但是没有现象//使用qt5版本的链接,将ui界面上的btn4按钮发射的clicked信号,与当前界面的自定义的槽函数连接connect(ui->btn4, &QPushButton::clicked, this, &Widget::my_slot);//将ui界面上的按钮5,发射的clicked信号,连接到全局函数中connect(ui->btn5, &QPushButton::clicked, fun);//将ui界面上的按钮5发射的clicked信号连接到lambda表达式中connect(ui->btn5, &QPushButton::clicked, [&](){// qDebug()<<"我是路人乙";speecher->say("我是路人乙");});//将当前界面的my_signal信号连接到自定义的槽函数中connect(this, &Widget::my_signal, [&](){speecher->say("已经成功断开按钮3和按钮4的连接");});}Widget::~Widget()
{delete ui;
}//自定义槽函数的实现
void Widget::my_slot()
{static int num = 0;if(num%2){ui->btn2->setEnabled(false);}else{ui->btn2->setEnabled(true);}num++;
}//该函数就是按钮2的clicked信号对应的槽函数
void Widget::on_btn2_clicked()
{static int num = 0;if(num % 3 == 0){ui->btn2->setStyleSheet("background-color:red;");}else if(num % 3 == 1){ui->btn2->setStyleSheet("background-color:yellow;");}else{ui->btn2->setStyleSheet("background-color:green;");}num++;
}//断开按钮对应的槽函数
void Widget::on_btn6_clicked()
{disconnect(btn3, SIGNAL(pressed()), ui->btn1, SLOT(hide()));disconnect(ui->btn4, &QPushButton::clicked, this, &Widget::my_slot);//发射自定义的信号emit my_signal();}
4> ui界面
3> 选择Qt --》资源文件
4> 添加前缀
2.5 信号函数与槽函数的总结
1> 一个信号可以连接到多个槽函数中,当信号被发射后,与之连接的所有槽函数都会被执行
2> 一个槽函数,可以连接多个信号函数,但凡其中一个信号被发射,那么该槽函数就会被执行
3> 一个信号函数,也可以连接到另一个信号函数上,表明当前一个信号发射时,后一个信号跟着被发射
4> 信号函数与槽函数参数个数总结
1、信号函数和槽函数进行链接时,一般要求信号函数和槽函数的参数保持一致connect(信号发送者, SIGNAL(signalFun()),信号接收者, SLOT(slotFun())); //Okconnect(信号发送者, SIGNAL(signalFun(int)),信号接收者, SLOT(slotFun(int))); //Okconnect(信号发送者, SIGNAL(signalFun(int, char)),信号接收者, SLOT(slotFun(int, char))); //Okconnect(信号发送者, SIGNAL(signalFun(char, int)),信号接收者, SLOT(slotFun(int, char))); //Falseconnect(信号发送者, SIGNAL(signalFun(int)),信号接收者, SLOT(slotFun(char))); //False2、当信号函数的参数大于槽函数的参数时connect(信号发送者, SIGNAL(signalFun(int, char)),信号接收者, SLOT(slotFun())); //Okconnect(信号发送者, SIGNAL(signalFun(int, char)),信号接收者, SLOT(slotFun(int))); //Okconnect(信号发送者, SIGNAL(signalFun(int, char)),信号接收者, SLOT(slotFun(char))); //False3、当信号函数的参数小于槽函数的参数时connect(信号发送者, SIGNAL(signalFun(int)),信号接收者, SLOT(slotFun(int, char))); //Falseconnect(信号发送者, SIGNAL(signalFun(int)),信号接收者, SLOT(slotFun(int, char=0))); //Ok
5> 案例
ui界面
头文件
#include <QWidget>
#include<QDebug>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();signals:void my_signal(); //自定义信号函数void my_signal_1(QString msg); //自定义带参数的信号函数public slots:void btn1_slot1(); //声明函数void btn1_slot2(); //声明函数void my_signal_1_slot(QString m = "lallalallalaal");private slots:void on_btn3_clicked();private:Ui::Widget *ui;
};
#endif // WIDGET_H
源文件
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//1、一个信号可以连接多个槽函数,当信号发射时,所有与之连接的槽函数全部都执行connect(ui->btn1, &QPushButton::clicked, this, &Widget::btn1_slot1);connect(ui->btn1, &QPushButton::clicked, this, &Widget::btn1_slot2);//2、一个槽函数可以连接多个信号connect(ui->btn2, &QPushButton::clicked, this, &Widget::btn1_slot1);//3、信号函数连接信号函数,表明发射第一个信号后,第二个信号跟着发射connect(ui->btn2, &QPushButton::clicked, this, &Widget::my_signal);connect(this, &Widget::my_signal, [](){qDebug()<<"德玛西亚";});//4、连接my_signal_1信号到自定义的槽函数中connect(this, SIGNAL(my_signal()), this, SLOT(my_signal_1_slot()));}Widget::~Widget()
{delete ui;
}//槽函数1的定义
void Widget::btn1_slot1()
{qDebug()<<"Good good study";
}
//槽函数2的定义
void Widget::btn1_slot2()
{qDebug()<<"day day up";
}//按钮3发射的信号对应的槽函数
void Widget::on_btn3_clicked()
{qDebug()<<"我现在想发射一个my_signal_1信号";//emit my_signal_1("hello world");emit my_signal();
}
//定义处理my_signal_1的槽函数
void Widget::my_signal_1_slot(QString m)
{qDebug()<<"我是处理my_signal_1信号的槽函数:"<<m;
}
2.6 使用信号与槽完成两个界面的跳转
1> 创建两个界面文件
在编辑器的项目处,邮件,add new
2> 创建一个新的界面
3> 两个界面的头文件
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();signals:void jump(); //自定义跳转函数private slots:void on_jumpBtn_clicked();private:Ui::Widget *ui;
};
#endif // WIDGET_H/***********************************第二个界面的头文件*******************/
#ifndef SECOND_H
#define SECOND_H#include <QWidget>namespace Ui {
class Second;
}class Second : public QWidget
{Q_OBJECTpublic:explicit Second(QWidget *parent = nullptr);~Second();public slots:void jump_slot(); //定义有关处理跳转信号的槽函数private:Ui::Second *ui;
};#endif // SECOND_H
4> 源文件
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//信号函数也可以连接信号函数//connect(ui->jumpBtn, &QPushButton::clicked, this, &Widget::jump);
}Widget::~Widget()
{delete ui;
}跳转按钮对应的槽 函数
void Widget::on_jumpBtn_clicked()
{//发射跳转信号emit jump();//关闭当前 界面this->hide();
}/*************************************第二个文件的源文件****************/
#include "second.h"
#include "ui_second.h"Second::Second(QWidget *parent) :QWidget(parent),ui(new Ui::Second)
{ui->setupUi(this);
}Second::~Second()
{delete ui;
}//处理跳转信号函数对应的槽函数
void Second::jump_slot()
{this->show(); //将当前界面进行展示
}
相关文章:

Qt day2
目录 1.多态,虚函数,纯虚函数 1.多态性(Polymorphism): 2.虚函数(Virtual Function): 3.纯虚函数(Pure Virtual Function): 将引用作为函数参…...

JavaScript - 好玩的打字动画
效果预览: 🚀HTML版本 <!DOCTYPE html> <html> <head><title>打字动画示例</title><style>.typewriter {color: #000;overflow: hidden; /* 隐藏溢出的文本 */white-space: nowrap; /* 不换行 */border-right: .…...

rpm打包
文章目录 rpm打包 1. rpm打包步骤0)准备工作:安装打包工具rpm-build和rpmdevtools(1)在线安装(2)离线安装 1)创建初始化目录2)准备打包内容3)编写打包脚本 spec文件4&…...

匠心新品:大彩科技超薄7寸WIFI线控器发布,热泵、温控器、智能家电首选!
一、产品介绍 此次发布一款7寸高清全新外壳产品,让HMI人机界面家族再添一新成员。该产品相比其他外壳有以下5个大改动: 1 表面玻璃盖板使用2.5D立体结构; 2 液晶盖板采用一体黑设计,且液晶屏与触摸板是全贴合结构; …...

华为云云服务器评测|使用云耀云服务器L实例部署Portainer工具
华为云云服务器评测|使用云耀云服务器L实例部署Portainer工具 一、云耀云服务器L实例介绍1.1 云耀云服务器L实例简介1.2 云耀云服务器L实例特点1.3 云耀云服务器L实例使用场景 二、本次实践介绍2.1 本次实践简介2.2 Portainer简介 三、购买云耀云服务器L实例3.1 登录…...
C++并发编程:构建线程安全队列(第一部分:粗粒度锁)
C并发编程:构建线程安全队列(第一部分:粗粒度锁) 引言 在多线程编程中,线程之间的数据共享和通信是一个非常重要的问题。在这篇博客中,我们将讨论如何用C实现一个基础但非常实用的线程安全队列。这个队列…...
C++设计模式-更新中
单例模式 这个类实现了单例模式。单例模式是一种设计模式,旨在确保一个类只有一个实例,并提供一个全局访问点来获取该实例。 在 ConnectionManager 类中,它通过以下方式实现了单例模式: 构造函数 ConnectionManager() 被声明为…...

Hydra工具的使用
目录 Hydra初识 Hydra使用 hydra破解mysql 前言 不固定用户名密码爆破 hydra破解ssh 以用户名为密码登录 hydra破解rdp 将爆破密码的结果输出到文件中 Hydra初识 前言: hydra是一款开源的暴力破解工具,支持多种服务破解原理:使用户…...

Pytorch学习:卷积神经网络—nn.Conv2d、nn.MaxPool2d、nn.ReLU、nn.Linear和nn.Dropout
文章目录 1. torch.nn.Conv2d2. torch.nn.MaxPool2d3. torch.nn.ReLU4. torch.nn.Linear5. torch.nn.Dropout 卷积神经网络详解:csdn链接 其中包括对卷积操作中卷积核的计算、填充、步幅以及最大值池化的操作。 1. torch.nn.Conv2d 对由多个输入平面组成的输入信号…...

水果库存系统(SSM+Thymeleaf版)
不为失败找理由,只为成功找方法。所有的不甘,因为还心存梦想,所以在你放弃之前,好好拼一把,只怕心老,不怕路长。 文章目录 一、前言二、系统架构与需求分析1、技术栈1.1 后端1.2 前端 2、需求分析 三、设计…...

如何在VueJS应用程序中设置Toast通知
通知是开发者提升应用程序互动性和改善用户体验的强大工具。通过利用通知,开发者可以在用户与应用程序互动的同时,有效地向用户传达重要事件。 通知在应用程序中起着至关重要的作用,可以及时通知用户有关各种操作和事件的信息。它们可以用于通…...

css让元素保持等比例宽高
使用新属性 aspect-ratio: 16/9; 代码示例 <style>div {width: 60%;/* 等比例宽高 */aspect-ratio: 16/9;background-color: red;margin: auto;}</style> </head><body><div></div> </body>示例 aspect-ratio兼容性...

骨传导和入耳式哪个危害大一点?入耳式和骨传导哪种好?
骨传导和入耳式这两种耳机虽然都存在一定的危害,但是入耳式耳机对人体的危害要更大一点。 入耳式耳机直接塞进耳朵这种佩戴方式,会阻塞外部声音的进入,长时间使用可能会导致耳道感染,还可能对听力造成损伤,而骨传导耳…...

介绍OpenCV
OpenCV是一个开源计算机视觉库,可用于各种任务,如物体识别、人脸识别、运动跟踪、图像处理和视频处理等。它最初由英特尔公司开发,目前由跨学科开发人员社区维护和支持。OpenCV可以在多个平台上运行,包括Windows、Linux、Android和…...

Android中的view绘制流程,简单理解
简单理解 Android中的View类代表用户界面中基本的构建块。一个View在屏幕中占据一个矩形区域、并且负责绘制和事件处理。View是所有widgets的基础类,widgets是我们通常用于创建和用户交互的组件,比如按钮、文本输入框等等。子类ViewGroup是所有布局&…...

商城开发:店铺管理系统应具备哪些功能?
电子商务的迅猛发展,越来越多的企业选择在线商城作为业务拓展的重要渠道。而要实现一个成功的在线商城,一个强大而高效的店铺管理系统是不可或缺的。店铺管理系统作为商城的核心管理工具,应具备一系列功能,以提供卓越的用户体验和…...

小白学go基础04-命名惯例对标识符进行命名
计算机科学中只有两件难事:缓存失效和命名。 命名是编程语言的要求,但是好的命名却是为了提高程序的可读性和可维护性。好的命名是什么样子的呢?Go语言的贡献者和布道师Dave Cheney给出了一个说法:“一个好笑话,如果你…...

使用iCloud和Shortcuts实现跨设备同步与自动化数据采集
在如今的数字时代,跨设备同步和自动化数据采集对于提高工作效率和便利性至关重要。苹果的iCloud和Shortcuts App为我们提供了强大的工具,可以实现跨设备同步和自动化数据采集的功能。本文将详细介绍如何利用iCloud和Shortcuts App实现这些功能࿰…...
Spring框架-基于STOMP使用Websocket
文章目录 前言一、范例演示1.注解方式2.XML方式二、可能出现错误错误: WebSocket代理中断错误: 缺少EventExecutor类错误: 缺少Publisher类错误: 缺少Scheduler类错误: WebSocket调用失败总结前言 Spring框架提供了多种WebSock消息机制,不仅包含了模拟SockJS,还提供了基…...

kafka-- 安装kafka manager及简单使用
一 、安装kafka manager 管控台: # 安装kafka manager 管控台: ## 上传 cd /usr/local/software ## 解压 unzip kafka-manager-2.0.0.2.zip -d /usr/local/ cd /usr/local/kafka-manager-2.0.0.2/conf vim /usr/local/kafka-manager-2.0.0.2/conf/appl…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...