信号槽【QT】

文章目录

  • 对象树
  • 字符集
  • 信号槽
  • QT坐标系
  • 信号与槽
    • connect
    • 自定义槽
    • 自定义信号
    • disconnect

对象树

#ifndef MYLABEL_H
#define MYLABEL_H

#include<QLabel>
class MyLabel : public QLabel
{
public:
    // 构造函数使用带 QWidget* 版本的.
    // 确保对象能够加到对象树上
    MyLabel(QWidget * parent);
    ~MyLabel()  ;
};

#endif // MYLABEL_H

上述代码,在 Qt 中不会产生内存泄露。

label 对象会在合适的时候被析构释放~~(虽然没有手动写 delete,确实能释放)

之所以能够把对象释放掉,主要是因为把这个对象是挂到了对象树上。

在这里插入图片描述

使用对象树,把这些内容组织起来,最主要的目的,就是为了能够在合适的时机 (窗口关闭/销毁)

把这些对象统一进行释放.

如果对象树的某个对象提前销毁,此时就会导致对应的控件就在界面上不存在了

 #include "mylabel.h"
#include<iostream>
#include<QDebug>
MyLabel::MyLabel(QWidget * parent)
    :QLabel(parent)
{

}

MyLabel::~MyLabel()
{
    //打印日志
    //会出现乱码
    //std::cout << "MyLabel 被销毁!" << std::endl;

    //QDebug 是 Qt 中的类。又不会直接使用这个类。这个宏,封装了 QDebug 对象。
    //直接使用 qDebug() 可以当做 cout来使用
    qDebug() << "MyLabel 被销毁!";
}

在这里插入图片描述

析构函数是执行了,虽然没有手动 delete,但是由于把 MyLabel 挂到了对象树上。此时窗口被销毁的时候,就会自动销毁对象树中的所有对象。MyLabel 的析构是执行了

解决乱码方案:
Qt 中提供了一个 qDebug() 工具,可以完成打印日志的过程。很好的处理字符编码

QDebug 是 Qt 中的类。又不会直接使用这个类。这个宏,封装了 QDebug 对象。
直接使用 qDebug() 这个东西就可以当做 cout 来使用。

使用 qDebug,打印的调试日志,是可以统一进行关闭的,qDebug 可以通过编译开关,来实现一键式关闭

字符集

出现乱码, 就是编码方式不匹配( 不局限于 C++)

如果字符串本身是 utf8 编码的,但是终端(控制台)是按照 gbk 的方式来解析显示的(拿着 utf8 这里的数值,去查询 gbk 的码表),就会出现乱码

用记事本方式来打开文件,将文件另存为,并查看文件字符集

在这里插入图片描述

显示的是 UTF-8,说明这个文件就是 UTF-8 编码

显示的是 ANSI,说明这个文件就是 GBK 编码

信号槽

Qt 中的 connect 是 QObject 这个类提供的静态函数。这个函数的作用就是 “连接信号和槽”

在 Qt Designer 中创建一个控件时,此时就会给这个控件分配一个 objectName 属性。这个属性的值,要求是在界面中得是唯一的(不能重复)

QPushButton :

qmake 在预处理 .ui 文件的时候,就会根据这里的 objectName 生成对应的 C++ 代码。C++ 代码中该 QPushButton 对象的变量名字就是这里的 objectName。这个变量就是 ui 属性中的成员变量。

widget.cpp文件中通过connect连接信号与槽函数

在这里插入图片描述

通过图形化界面的方式,实现的按钮版 hello world

此时按钮对象,不需要new , new 对象的操作已经是被 Qt 自动生成了
而且这个按钮对象,已经作为 ui 对象里的一个成员变量了。
也无需作为 Widget 的成员

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
        connect(ui->myButton ,&QPushButton::clicked ,this , &Widget::handleClick );
}

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

void Widget::handleClick()
{
    //获取文本是hello World
   if(ui->myButton->text()  == QString("hello World"))
   {
       // 当按钮被点击之后,就把按钮中的文本,进行切换
       ui->myButton->setText("hello qt");
   }
   //获取文本不是hello World
   else
   {
       // 当按钮被点击之后,就把按钮中的文本,进行切换
       ui->myButton->setText("hello World");
   }
}

widget.cpp

纯代码方式实现Hello World

纯代码版本:

myButton按钮对象是new 的
为了保证其他函数中能够访问到这个变量,就需要把myButton按钮对象设定为 Widget 类的成员变量

#include "widget.h"
#include "ui_widget.h"
#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    myButton = new QPushButton(this) ;
       myButton->setText("hello world") ;
       //将信号与槽函数关联
         connect(ui->pushButton ,&QPushButton::clicked ,this , &Widget::handleClick );
}

Widget::~Widget()
{
    delete ui;
}
//槽函数
 void Widget::handleClick ()
 {
     //检查myButton按钮的当前文本 是否为"hello world"
     if(myButton->text() == QString("hello world"))
     {
         myButton->setText("hellp qt") ;
     }
        else
     {
          myButton->setText("hellp world") ; 
     }

 }

QT坐标系

在这里插入图片描述

坐标系的原点 (0, 0) 就是屏幕的左上角 / 窗口的左上角

给 Qt 的某个控件,设置位置,就需要指定坐标。对于这个控件来说,坐标系原点就是相对于父窗口/控件的。

例如:

QPushButton 的父元素/父控件/父窗口 是 QWidget

在这里插入图片描述

QWidget 没有父元素 (NULL),就相当于父元素就是整个显示器桌面了~~

在这里插入图片描述

信号与槽

Qt 中,谈到信号,也是涉及到三个要素

信号源:由哪个控件发出的信号。

信号的类型:用户进行不同的操作,就可能触发不同的信号。

例如:点击按钮,触发点击信号。在输入框中移动光标,触发移动光标的信号。勾选一个复选框,选择一个下拉框,都会触发出不同的信号。

信号的处理方式:槽(slot),就是函数

Qt 中可以使用 connect 这样的函数,把一个信号和一个槽关联起来。后续只要信号触发了,Qt 就会自动的执行槽函数

槽函数,本质上也是一种"回调函数" (callback)

一定是先把信号的处理方式准备好,再触发信号

Qt 中,一定是先关联号信号和槽,然后再触发这个信号,顺序不能颠倒,否则信号就不知道如何处理了

connect

connect,这个函数和 Linux 中TCP的socket 中建立连接的函数,没有任何关系,只是名字恰巧一样了。

connect是 QObject 提供的静态的成员函数。

在这里插入图片描述

connect(const QObject *sender,
        const char *signal,
        const QObject *receiver,
        const char *method,
        Qt::ConnectionType type = Qt::AutoConnection);

sender : 当前信号是哪个控件发出来的

signal : 信号的类型

receiver : 哪个对象(控件)负责处理

method: 这个对象如何处理 (要处理信号的对象提供的成员函数)

type : 很少使用,暂时不考虑

例如:

#include "widget.h"
#include "ui_widget.h"
#include<QPushButton>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
   QPushButton * button      = new QPushButton(this) ;
   button->setText("关闭") ;
   button->move(200,300);

   //close是QWidget内置的槽函数. Widget继承自QWidget,也就继承了QWidget的槽函数.
   //close:关闭当前的窗口/控件
   connect(button ,&QPushButton::clicked , this , &Widget::close) ;
}
Widget::~Widget()
{
    delete ui;
}

自定义槽

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QPushButton>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //设置按钮
    //点击按钮就修改窗口标题
        QPushButton * button = new QPushButton (this) ;  //this,挂到对象树上
        button->setText("按钮");
        button->move(100,100); //移动坐标
        connect(button , &QPushButton::clicked , this , &Widget::handleClicked) ;


}

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

void Widget::handleClicked()
{
    //点击按钮就修改窗口标题
    setWindowTitle("按钮已经按下");

}

自定义槽函数 ,用ui界面

在Qt 中,除了通过connect来连接信号槽之外,还可以通过函数名字的方式来自动连接

在这里插入图片描述

在这里插入图片描述

选择clicked() ,就会在widget.cpp 生成on_pushButton_clicked 函数的定义

在这里插入图片描述

在这里插入图片描述

​ 当函数名符合上述规则之后,Qt就能自动的把信号和槽给建立上联系

自定义信号

Qt 的信号,本质上也就是一个“函数”

Qt 5 以及更高版本中,槽函数和普通的成员函数之间,基本没有差别

但是信号,则是一类非常特殊的函数。

程序员只要写出函数声明,并且告诉 Qt,这是一个“信号”即可。

这个函数的定义,是 Qt 在编译过程中自动生成的。(自动生成的过程,程序员无法干预)

作为信号函数,这个函数的返回值,必须是void ,有没有参数都可以, 甚至也可以支持重载

signals : 是 Qt 自己扩展出来的关键字

qmake 的时候,调用一些代码的分析/生成工具,

扫描到类中包含signals 这个关键字的时候.此时,就会自动的把下面的函数声明认为是信号,并且给这些信号函数自动的生成函数定义

widget.h:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
 //自定义信号   
signals:
    void  mysignal() ;
  //自定义槽函数
public slots: //qt5以上 ,public slots可以省略
    void handleMySignal() ; 
    
private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

如何才能触发出自定义的信号呢?

Qt 内置的信号,不需要手动通过代码来触发

用户在 GUI,进行某些操作,就会自动触发对应信号。(发射信号的代码已经内置到 Qt 框架中了)

例:

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
	 //将自定义信号与槽函数绑定
    connect (this, &Widget::mysignal , this, &Widget::handleMySignal) ;

}

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

void Widget::handleMySignal()
{
    setWindowTitle("处理自定义信号");
}


void Widget::on_pushButton_clicked()
{
   
    //发送信号的操作,也可以在任意合适的代码中.不一定非得在构造函数里
    //此时就是点击按钮的时候,发送自定义信号了
    emit mysignal();// 发出自定义的信号
    //emit可以省略
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
 //自定义信号
signals:
    void  mysignal() ;
  //自定义槽函数
public slots:
    void handleMySignal() ;
 //槽函数
private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

信号和槽也可以带参数
当信号带有参数的时候,槽的参数必须和信号的参数一致~~
此时发射信号的时候,就可以给信号函数传递实参。与之对应的这个参数就会被传递到对应的槽函数中。

这里的参数类型必须要一致
个数可以不一致,但是 信号的参数的个数必须要比槽的参数个数要更多。

个数可以不一致,但是 信号的参数的个数必须要比槽的参数个数要更多 ,原因:

一个槽函数,有可能会绑定多个信号,如果我们严格要求参数个数一致,就意味着信号绑定到槽的要求就变高了。换而言之,当下这样的规则,就允许信号和槽之间的绑定更灵活了。更多的信号可以绑定到这个槽函数上了

例如:

参数类型必须要一致 ,个数一致

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
     //将自定义信号与槽函数绑定
    connect (this, &Widget::mysignal , this, &Widget::handleMySignal) ;

}

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

void Widget::handleMySignal(const QString & text )
{
    setWindowTitle(text);
}


void Widget::on_pushButton_clicked()
{

    //发送信号的操作,也可以在任意合适的代码中.不一定非得在构造函数里
    //此时就是点击按钮的时候,发送自定义信号了
    emit mysignal("把标题设置为标题1");// 发出自定义的信号
}

void Widget::on_pushButton_2_clicked()
{
     emit mysignal("把标题设置为标题2");// 发出自定义的信号
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
 //自定义信号
signals:
    void  mysignal(const QString &  text) ;
  //自定义槽函数
public slots:
    void handleMySignal(const QString & text) ;
 //槽函数
private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

参数类型必须要一致 ,信号的参数的个数必须要比槽的参数个数要更多

例如:

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
     //将自定义信号与槽函数绑定
    connect (this, &Widget::mysignal , this, &Widget::handleMySignal) ;

}

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

void Widget::handleMySignal(const QString & text)
{
    setWindowTitle(text);
}


void Widget::on_pushButton_clicked()
{

    //发送信号的操作,也可以在任意合适的代码中.不一定非得在构造函数里
    //此时就是点击按钮的时候,发送自定义信号了
    emit mysignal("把标题设置为标题1","");// 发出自定义的信号
}

void Widget::on_pushButton_2_clicked()
{
     emit mysignal("把标题设置为标题2","");// 发出自定义的信号
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
 //自定义信号
signals:
    void  mysignal(const QString &  text,const QString & text2) ;
  //自定义槽函数
public slots:
    void handleMySignal(const QString & text) ;
 //槽函数
private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

Q_OBJECT:

Qt硬性规定:Qt中如果要让某个类能够使用信号槽(可以在类中定义信号和槽函数)

必须要在类最开始的地方,写下 Q_OBJECT 宏。

一个信号,可以 connect到多个槽函数上

一个槽函数,也可以被多个信号 connect

例如:

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
signals:
    //自定义信号
    void mySignal1() ;
     void mySignal2() ;
      void mySignal3()  ;
public slots:
      //自定义槽函数
      void mySlot1();
       void mySlot2();
        void mySlot3();
    
private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    
    //信号与槽函数 ,形成多对多的关系
    connect(this, &Widget::mySignal1, this, &Widget::mySlot1);
    connect(this, &Widget::mySignal1, this, &Widget::mySlot2);
    connect(this, &Widget::mySignal2, this, &Widget::mySlot1);
    connect(this, &Widget::mySignal2, this, &Widget::mySlot3);
}

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

void Widget::mySlot1()
{
    qDebug() << "mySlots1" ; 
}
void Widget::mySlot2()
{
    qDebug() << "mySlots2" ; 
}
void Widget::mySlot3()
{
    qDebug() << "mySlots3" ; 
}

disconnect

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
public slots :
    void  handClick() ;
public slots :
    void handClicked2();
private slots:
    void on_pushButton_2_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QPushButton>
#include<QDebug>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //将信号与槽函数关联
    connect(ui->pushButton  ,& QPushButton::clicked, this , &Widget::handClick) ;
}


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

void Widget::handClick()
{
    setWindowTitle("修改窗口的标题");
    qDebug() <<"handClick";
}

void Widget::handClicked2()
{
    setWindowTitle("修改窗口的标题2");
      qDebug() <<"handClicked2";
}
void Widget::on_pushButton_2_clicked()
{
    //1、先断开pushButton 的信号槽
    disconnect(ui->pushButton ,&QPushButton::clicked, this, &Widget::handClick );
    //2、重新绑定信号槽
      connect(ui->pushButton ,&QPushButton::clicked, this , &Widget::handClicked2) ;
}

定义槽函数使用lambda

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QPushButton>
#include<QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //设置一个按钮,并将按钮移动位置
               QPushButton * button= new QPushButton(this) ;
               button->setText("按钮" ) ;
               button->move(200,200) ;

              //关联信号与槽函数
               //lambda就是槽函数
               connect(button ,&QPushButton::clicked , this ,[button,this](){
                   qDebug()<<"lambda被执行了";
                      button->move(500,500) ;
                      this->move(500,500);
               } );


}

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


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

3.zabbix中文设置

1、zabbix中文设置 2、中文乱码的原因 zabbix使用DejaVuSan.ttf字体&#xff0c;不支持中文&#xff0c;导致中文出现乱码。解决方法很简单&#xff0c;把我们电脑里面字体文件传到zabbix服务器上。 3、解决zabbix乱码方法 3.1、从Window服务器找到相应的字休复制到zabbix S…

电脑连接不上手机热点 找不到到服务器的ip地址

手机热点连接不上 找不到到服务器的ip地址 emmm希望不会有人不会吧 解决方法&#xff1a; 1.点击右上角图标进入设置 2.点击更改所有wifi网络的DNS设置 3.查看自己的IP分配和DNS分配是不是DHCP自动分配&#xff0c;不是的话就不对了&#xff0c;需要点击编辑手动改一下 4.改完…

计算机网络之王道考研读书笔记-2

第 2 章 物理层 2.1 通信基础 2.1.1 基本概念 1.数据、信号与码元 通信的目的是传输信息。数据是指传送信息的实体。信号则是数据的电气或电磁表现&#xff0c;是数据在传输过程中的存在形式。码元是数字通信中数字信号的计量单位&#xff0c;这个时长内的信号称为 k 进制码…

MySQL数据库04|内置函数、存储过程、视图、事务、索引

目录 十三、MySQL常用内置函数 1、字符串函数 1️⃣拼接字符串&#xff1a;concat(str1,str2,…) 2️⃣包含字符个数&#xff1a;length(str) 3️⃣截取字符串&#xff1a;left(str,len)、right(str,len)、substring(str,pos,len) 4️⃣去除空格&#xff1a;ltrim(str)、r…

【Unity3D】实现可视化链式结构数据(节点数据)

关键词&#xff1a;UnityEditor、可视化节点编辑、Unity编辑器自定义窗口工具 使用Newtonsoft.Json、UnityEditor相关接口实现 主要代码&#xff1a; Handles.DrawBezier(起点&#xff0c;终点&#xff0c;起点切线向量&#xff0c;终点切线向量&#xff0c;颜色&#xff0c;n…

Group FLUX - Beta Sprint Essay2

文章目录 I. SCRUMAchievements from yesterday’s stand-up meeting to the present Commit recordFrontend-CommitsBackend-Commits PM ReportBurnup mapRunning image of our current program I. SCRUM Achievements from yesterday’s stand-up meeting to the present Zh…

硬盘清洁器 -一个功能出色的的文件与使用纪录清理工具,不仅可以将磁盘中不必要的暂存盘一次扫除,供大家学习研究参考

【核心功能】 1.硬件性能检测。 2.清理日常垃圾信息。 3.永久性删除文件。不可恢复擦除可用空间。 4.系统恢复和还原。 5.磁盘管理。 6.重复文件删除。坏链清除&#xff0c;删除非必要文件。 7.恢复删除文件。含电子照片、PDF、视频等。 8.批量重命名。 下载&#xff1a;https:…

[Linux] 进程信号概念 | 信号产生

&#x1fa90;&#x1fa90;&#x1fa90;欢迎来到程序员餐厅&#x1f4ab;&#x1f4ab;&#x1f4ab; 主厨&#xff1a;邪王真眼 主厨的主页&#xff1a;Chef‘s blog 所属专栏&#xff1a;青果大战linux 总有光环在陨落&#xff0c;总有新星在闪烁 为什么我的课设这么难…

流程引擎Activiti性能优化方案

流程引擎Activiti性能优化方案 Activiti工作流引擎架构概述 Activiti工作流引擎架构大致分为6层。从上到下依次为工作流引擎层、部署层、业务接口层、命令拦截层、命令层和行为层。 基于关系型数据库层面优化 MySQL建表语句优化 Activiti在MySQL中创建默认字符集为utf8&…

51c视觉~合集36

我自己的原文哦~ https://blog.51cto.com/whaosoft/12275223 #无监督盲超分算法MLMC 即插即用的解决方案 本文介绍了一种新的无监督盲超分辨率算法MLMC&#xff0c;该算法结合了元学习和马尔可夫链蒙特卡罗核估计&#xff0c;无需监督预训练或参数先验&#xff0c;即可实现…

Firecrawl教程①:自动化抓取与数据转化,赋能AI应用

Firecrawl教程①:自动化抓取与数据转化,赋能AI应用 前言一、功能特点1. 支持 LLM 可处理的数据格式2. 全面抓取网站3. 强大的操作支持4. 灵活的定制选项5. 支持多种编程语言 SDK二、如何开始使用 Firecrawl第一步:获取 API 密钥第二步:官网在线工具使用第三步:安装 Firecr…

关于目标检测YOLO 各版本区别v1-v11/X/R/P

概述 YOLO&#xff08;You Only Look Once&#xff0c;你只看一次&#xff09;是一系列开创性的实时目标检测模型&#xff0c;它们彻底改变了计算机视觉领域。由Joseph Redmon开发&#xff0c;后续版本由不同研究人员迭代&#xff0c;YOLO模型以其在图像中检测对象的高速度和准…

SpringBoot3整合FastJSON2如何配置configureMessageConverters

在 Spring Boot 3 中整合 FastJSON 2 主要涉及到以下几个步骤&#xff0c;包括添加依赖、配置 FastJSON 作为 JSON 处理器等。下面是详细的步骤&#xff1a; 1. 添加依赖 首先&#xff0c;你需要在你的 pom.xml 文件中添加 FastJSON 2 的依赖。以下是 Maven 依赖的示例&#…

java全栈day19--Web后端实战(java操作数据库3)

一、MyBatis 1.1介绍 前提引入&#xff1a; controller(控制层)作用&#xff1a;接受请求&#xff0c;响应数据 service(业务层)作用&#xff1a;负责具体的逻辑处理 dao(持久层)作用&#xff1a;数据访问层 一般的访问流程&#xff1a;浏览器发起请求过来&#xff0c;先…

社区版 IDEA 开发webapp 配置tomcat

1.安装tomcat 2.构建webapp项目结构 3.配置tomcat 安装smart tomcat插件 完成后settings会多一个选项tomcat server&#xff0c;然后我们把本地的tomcat配置过去。 4.为项目配置tomcat 配置项目路径&#xff0c;端口号。Context path 配置/ 表示直接用localhost就能访问 5.添加…

重新定义页签!Choerodon UI Tabs让管理更高效

01 引言 Tabs 组件通过提供平级区域&#xff0c;将大块内容进行有效的收纳和展现&#xff0c;从而保持界面整洁。但在企业应用的快速发展中&#xff0c;这样传统的页签组件已无法满足我们对界面布局和个性化展示的追求。Choerodon UI Tabs 组件通过支持多级分组、个性化配置、…

Qt编译MySQL数据库驱动

目录 Qt编译MySQL数据库驱动 测试程序 Qt编译MySQL数据库驱动 &#xff08;1&#xff09;先找到MySQL安装路径以及Qt安装路径 C:\Program Files\MySQL\MySQL Server 8.0 D:\qt\5.12.12 &#xff08;2&#xff09;在D:\qt\5.12.12\Src\qtbase\src\plugins\sqldrivers\mysql下…

vulnhub靶场【DriftingBlues】之9 final

前言 靶机&#xff1a;DriftingBlues-6&#xff0c;IP地址192.168.1.66 攻击&#xff1a;kali&#xff0c;IP地址192.168.1.16 都采用虚拟机&#xff0c;网卡为桥接模式 主机发现 使用arp-scan -l或netdiscover -r 192.168.1.1/24 信息收集 使用nmap扫描端口 网站探测 访…

智慧公交指挥中枢,数据可视化 BI 驾驶舱

随着智慧城市的蓬勃发展&#xff0c;公共交通作为城市运营的核心枢纽&#xff0c;正朝着智能化和数据驱动的方向演进。通过整合 CAN 总线技术(Controller Area Network&#xff0c;控制器局域网总线)、车载智能终端、大数据分析及处理等尖端技术&#xff0c;构建的公交“大脑”…

页面无滚动条,里面div各自有滚动条

一、双滚动条左右布局 实现效果 实现代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Doc…