第一个Qt程序中的秘密

创建第一个程序

        首先我们打开Qt Creator

        打开文件->New Projects... 菜单,创建我们的第一个Qt项目

        选择 Qt Widgets Application,点击选择...按钮

        之后,输入项目名称QtLearning,并选择创建路径,

        在build system中选择qmake(默认选项),点击下一步

        除了qmake以外,还有CMake和Qbs选项,这三种方式都是Qt支持的编译方式,现阶段看,qmake是最主要的编译方式,其次是CMake,而Qbs已经逐渐被Qt放弃。虽然现在qmake依然是Qt所采用的的主要编译方式,但是现在CMake的采用率越来越高,CMake凭借强大的组织能力而越来越受到整个C++阵营的欢迎,现在已经成为了C++社区的主流编译方式。

        qmake 和CMake都是通过某种方法来构建MakeFile文件,然后交给其他编译工具进行编译。

        这一步需要把Generate form选项去掉,其他保持默认就可以。点击下一步,

        这个画面是设定多语言支持的,我们保持默认,点击下一步,

        这个是选择编译器,我们选择MinGW 64-bit作为我们的编译器,点击下一步

        补充知识:

        MinGW的全称是Minimalist GNU on Windows,它是是将经典的开源 C语言 编译器 GCC 移植到了 Windows 平台下,并且包含了 Win32API ,因此可以将源代码编译为可在 Windows 中运行的可执行程序。GCC编译器是Linux系统上的主流编译器,采用这个编译选项能够让我们编写的代码具有更好的兼容性。而MinGW除有GCC编译器外,还集成很多其他的工具,比如MSYS等。

        MSVC这个是微软的C++编译器,如果我们的程序或代码只是在Windows上运行的话,我们可以选择这个选项,从而可以更好的利用一下Windows的特性。

        这个是创建项目的最后一步,选择版本控制系统,我们不需要选择,点击完成。

        在经过一系列的构建步骤之后,我们就看到了已经构建好的源码

        我们看到向导已经帮我们创建了四个文件并且把他们放到了对应的目录中,

  1. QtLearning.pro
  2. maindwindow.h
  3. main.cpp
  4. maindwindow.cpp

        这其中main.cpp是程序的入口,在这个文件中有一个程序的入口函数main,而maindwindow.h和maindwindow.cpp是主窗口的对应代码,QtLearning.pro是工程文件。

工程文件中都有什么

        QtLearning.pro是整个项目的工程文件。任何一个 Qt 项目都至少包含一个 pro 文件,此文件负责存储与当前项目有关的配置信息,比如:

  1. 项目中用到了哪些模块?
  2. 项目中包含哪些源文件,哪些头文件,它们的存储路径是什么?
  3. 项目使用哪个图片作为应用程序的图标?
  4. 项目最终生成的可执行文件的名称是什么?

        一个项目中可能包含上百个源文件,Qt 编译这些源文件的方法是:先由 qmake 工具根据 pro 文件记录的配置信息生成相应的 MakeFile文件,然后执行 make 命令完成对整个项目的编译。也就是说,pro 文件存储的配置信息是用来告知编译器如何编译当前项目的,所以一个Qt项目要想完美运行,既要保证各个源文件中程序的正确性,还要保证 pro 文件中配置信息的合理性。

        实际开发中,Qt会自动修改工程文件的内容,但有时也需要我们手动修改,例如程序中用到某个第三方库时,就需要我们手动修改工程文件。所以我们需要了解工程文件的构成。

        下表列出了一些常用变量并描述了它们的内容。

配置项

含 义

QT

指定项目中用到的所有模块,默认值为 core 和 gui,中间用 += 符号连接。

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

如果 QT 版本大于 4(Qt5 或更高版本),则需要添加 widgets 模块,该模块包含所有控件类。

TARGET

指定程序成功运行后生成的可执行文件的名称,中间用 = 符号连接。

TEMPLATE

指定如何运行当前程序,默认值为 app,表示当前程序是一个应用程序,可以直接编译、运行。常用的值还有 lib,表示将当前程序编译成库文件。

DEFINES

在程序中新定义一个指定的宏,比如 DEFINES += xxx,如同在程序中添加了 #define xxx 语句。

SOURCES

指定项目中包含的所有 .cpp 源文件。

HEADERS

指定项目中包含的所有 .h 头文件。

FORMS

指定项目中包含的 ui 文件。

INCLUDEPATH

指定头文件的存储路径,例如:INCLUDEPATH += /opt/ros/include

CONFIG

经常对应的值有:

release:以 release 模式编译程序;

debug:以 debug 模式编译程序;

warn_on:编译器输出尽可能多的警告;

c++11:启动 C++11 标准支持。

例如 CONFIG += c++11。

        QT 用来指明当前项目中用到的所有模块,它的默认值是 core 和 gui,分别表示引入 Core 模块和 GUI 模块:

  1. Core 模块包含了 Qt GUI 界面开发的核心功能,其它所有模块都需要依赖于这个模块,它是所有 Qt GUI 项目必备的模块;
  2. GUI 模块提供了用于开发 GUI 应用程序的必要的一些类。

        需要注意的是,每个新创建的 Qt GUI 项目中,都默认包含 Core 模块和 GUI 模块,如果项目中用不到它们,可以使用QT -=删除。

        例如,删除项目中包含的 GUI 模块,只需在 pro 文件中添加一条配置信息:        

QT -= gui

        看了这些我们就能够读懂QtLearning.pro文件并进行修改了,修改后的文件如下,

QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
TARGET = MyFirstApp
TEMPLATE = app
SOURCES += \main.cpp \mainwindow.cpp
HEADERS += \mainwindow.h

        然后我们就可以编译程序了。

        当然也可以完全不修改工程文件,直接进行编译。这里进行简单的修改只是学习一下如何修改这个工程文件,在我们的程序需要其他第三方的库的时候后,我们就需要修改这个文件以利用相关的功能。

        经过编译之后,我们的第一个程序就可以运行起来了。

        由于我们没有添加任何东西,也没有对主窗口进行设定,所以我们看到的主窗口的标题栏是TARGET的名字,窗口大小可以调整,整个窗口都是空白的。

主窗口头文件中有什么

        接下来我们分析mainwindow,我们打开mainwindow.h文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();
};
#endif // MAINWINDOW_H

        这个文件非常简单,首先包含了QMainWindow的头文件,然后就是MainWindow类的定义,它是QMainWindow的子类,关于QMainWindow的内容会在后面说明,接下来有一个Q_OBJECT的宏,然后是构造函数和析构函数。

        这里需要注意的是Q_OBJECT宏,Q_OBJECT宏是Qt对象模型中的一个关键要素。它通常定义在继承自QObject的类的私有部分,为该类提供元对象(meta-object)系统所需的底层支持。Q_OBJECT宏是Qt框架的核心,用于启用如信号槽、动态属性、类型信息等Qt的核心功能。在使用Q_OBJECT宏时,需要注意其与QObject的继承关系,使用Q_OBJECT宏的类都必须直接或间接的继承自QObject类。Q_OBJECT宏的生命要紧跟在class语句的之下,其他语句之上,这样才能够保证元对象能够被正常编译。

元对象系统和元对象编译器

        那么什么是元对象系统呢。这里涉及到了两方面的知识:Qt 元对象系统元对象编译器。

        首先是元对象系统 (Meta-Object System),Qt元对象系统 (Meta-Object System)是Qt框架的基石,它为 QObject 类(以及其子类)提供了一些独特的功能。以下是元对象系统所提供的主要功能:

  1. 信号与槽机制:信号槽机制是 Qt 的核心特性之一,为组件之间的通信提供了一种安全且灵活的方法。这种机制使得组件可以在不必了解对方实现细节的情况下,实现解耦式的通信。
  2. 对象自省 (Introspection):元对象系统允许在运行时查询关于对象的信息,例如类名、属性、信号和槽等。这使得 Qt 能够实现更加灵活的动态行为和强大的工具集成。
  3. 动态属性:元对象系统支持在运行时为 QObject 添加和修改动态属性。这些属性的值可以在没有改变类定义的情况下被设置和读取。

        要使用 Qt 元对象系统,首先需要在类声明中添加 Q_OBJECT 宏。此外,该类需要继承自 QObject(直接或间接继承都可以)。Q_OBJECT 宏告诉 Qt 元对象编译器 (MOC) 为类生成所需的元对象代码,以支持信号槽机制、动态属性等特性。不包含 Q_OBJECT 宏的类将无法使用元对象系统提供的功能。

        其次是元对象编译器 (MOC),元对象编译器(Meta-Object Compiler,简称 MOC)是 Qt 框架中一个独特的工具,负责生成 QObject 子类的元信息。MOC 是一个预处理程序,它在 C++ 编译器处理源代码之前,扫描包含 Q_OBJECT 宏的 QObject 子类源文件,并输出额外的 C++ 代码。这些生成的代码用于实现信号槽机制、动态属性等元对象系统提供的功能。

        元对象编译器 (MOC) 的主要作用是:

  1. 提供信号槽的实现:元对象编译器为信号槽机制生成底层实现代码。当两个 QObject 子类通过信号和槽连接时,MOC 生成的代码能够将信号与槽关联起来并在需要时执行槽函数。
  2. 支持运行时类型信息:MOC 生成的代码包含对象的运行时类型信息。这些信息可以用于实现对象自省,例如查询对象的类名、属性、信号和槽等。
  3. 支持动态属性:元对象编译器生成的代码允许 QObject 子类在运行时添加、修改和访问动态属性。

        MOC 作为一个预处理工具,是 Qt 开发过程中不可或缺的一环。它允许开发者为 QObject 子类添加元数据,从而支持信号槽机制等功能。开发者需要确保 QObject 子类中包含 Q_OBJECT 宏,使得 MOC 能够正确地扫描并生成所需的元信息。

        这些知识在我们对Qt程序已经很熟悉之后,需要单独进行学习,才能够从更深层次去明白Qt的实现机制,现阶段我们只要知道我们添加这行代码的作用就可以了。

入口主函数中都有什么

        接下来我们分析一下main.cpp文件,我们看到这个文件中的代码非常简单

#include "mainwindow.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}

        首先它包含了mainwindow的头文件,然后包含了QApplication的定义。

        接下来就是整个程序的入口main函数,所有的Qt程序都只能有且只有一个main()函数。

        main函数的内部,首先创建了一个QApplication 对象,并将命令行参数传递给它,通常情况下,我们需要在main函数的开始就创建QApplication的对象,也就是在任何Qt 的窗口系统部件被使用之前创建QApplication对象,然后把命令行交给它处理,这是因为有一些命令行参数是需要QApplication来处理的,它处理之后会将对应的命令行参数从argv中删除,也就是argv和argc的值和内容会因此而减少。一个应用程序只应该定义一个 QApplication类的实例,我们在程序开始创建的QApplication的实例可以通过全局指针qApp进行访问,qApp指针可以后续程序中的任何地方进行访问,他给我们提供了大量有关程序全局的方法,比如取得所有窗口,取得剪贴板的内容等。

        QApplication类是Qt程序中非常重要的一个类,它负责管理GUI程序的控制流和主要设置,处理QWidget特有的初始化和收尾工作,提供各种事件、剪贴板、窗口、控件等的管理和控制。

        它的继承关系如下:

QApplication → QGuiApplication → QCoreApplication → QObject

        这几个类看起来都差不多,那么他们应该如何使用呢,

  1. 对于非GUI的程序,请使用QCoreApplication以避兔不必要地初始化图形用户界面所需的资源。
  2. 对于不基于QWidget的GUI的程序,使用QGuiApplication,因为它不依赖于QtWidgets库。
  3. 对于是基于QWidget的GUI应用程序,使用QApplication

        QApplication的主要职责范围是:

  1. 它利用用户的桌面设定来初始化应用程序。并且它会跟踪这些属性,以防用户全局更改桌面,例如通过某种控制面板。
  2. 它从底层窗口系统接收事件并通过使用sendEvent() 和postEvent()将事件发送到部件。
  3. 它解析常见的命令行参数并相应地设置其内部状态。
  4. 它定义应用程序的外观,并将该外观封装在对象中。
  5. 它提供用户可见的字符串的本地化。
  6. 它提供了一些特殊的方法,如clipboard()。
  7. 它知道应用程序的窗口。您可以使用widgetAt()询问哪个小部件位于某个位置,获取topLevelWidgets() 列表,关闭所有的窗口 closeAllWindows()等。
  8. 它管理应用程序的鼠标光标处理,请参阅 setOverrideCursor()。

        QApplication 对象可通过instance()函数访问,该函数返回与全局指针qApp等效的指针。

        在main()函数里,我们接着创建了一个MainWindow 对象,并调用它的show()方法将窗口显示出来。

        这个MainWindow是QMainWindow的一个子类,继承关系如下:

MainWindow → QMainWindow → QWidget → QObject and QPaintDevice

        主窗口(QMainWindow)也是一个非常重要的类,几乎所有的基于QWidget的GUI程序都会有一个或多个QMainWindow或者是它的子类的实例,以用来与用户进行交互。QMainWindow提供了用于构建应用程序用户界面的框架和主窗口的管理,并且它有自己的布局,我们可以在其中添加工具栏(QToolBar)、停靠部件(QDockWidget)、菜单栏(QMenuBar) 和状态栏(QStatusBar)。

        主窗口的布局有一个中心区域,可以被任何类型的部件占据。我们可以从下面的布局图像中看出他们的组成,我们在后面的程序中会对逐一的添加这些内容。QMainWindow除了支持单文档窗口(SDI),也支持多文档窗口(MDI),只需要使用一个特殊的QMdiArea作为中心部件就可以了,否则就使用普通的或者是自定义的部件作为中心部件。

        在main函数的最后,调用QApplication的exec()函数,并将该函数的返回值作为返回值。

        QApplication的exec()函数是QApplication类中一个非常重要的函数,这个函数使我们的程序进入事件循环并等待,直到exit()函数被调用,exec()函数的返回值就是在exit()函数中设置的(如果是通过quit()函数调用的exit(),那么返回值就是0。

        只有调用exec()函数才能开始消息循环处理。消息循环从系统接收各种事件,并将这些事件调度给对应的程序部件、窗口等。

        除了使用模态方法表示部件、窗口之外,在QApplication的exec()在被调用之前不能进行任何用户交互,因为模态部件也是调用自己的exec()来启动自己消息循环。

        这里Qt官方给了我们提了一个建议,如果要执行某些必要的处理,即使在没有挂起事件时也需要执行特殊处理的时候,让我们使用一个没有等待时间的QTimer来进行,从而保证该处理一定会被调用。当然也可以使用processEvents()来实现更高级的空闲处理方案。

        Qt框架建议我们将清理代码放在aboutToQuit()信号的处理函数中,而不是将其放在应用程序的main()函数的最后。因为在某些系统平台上,QApplication的exec()调用可能不会被返回就直接退出了程序,例如:在 Windows 平台上,当用户注销时,系统会在Qt关闭所有顶级窗口后终止进程。因此,不能保证应用程序在调用 QApplication的exec()之后有时间退出其事件循环并在函数结束时执行代码。

        到这里为止,我们通过向导创建的第一个Qt程序基本分析完成了,这里面其实给我们提供了大量的信息,我们在重新回顾一下:

  1. 工程文件(.pro),它的构成方法,组织方式以及一些常用的命令,正式同坐这些,才能够做成MakeFile文件,进行编译。
  2. Q_OBJECT宏,这个是在所有自定义Widget都要添加的东西,它给我们提供了信号槽、动态属性、类型信息等Qt的核心功能的实现。它的声明要保证紧跟在class语句的之下
  3. 元对象系统,这个是Qt的核心功能之一,它的主要提供了信号与槽机制、对象自省 (Introspection)、动态属性的支持等能力。
  4. 元对象编译器 (MOC),它是一个预处理工具,是 Qt 开发过程中不可或缺的一环,它在 C++ 编译器处理源代码之前,扫描包含 Q_OBJECT 宏的 QObject 子类源文件,并输出额外的 C++ 代码。这些生成的代码用于实现信号槽机制、动态属性、运行时类型信息等元对象系统提供的功能。
  5. QApplication类,这个类给我们提供大量的和操作系统相关的功能,从而避免我们直接和特定的操作系统打交道,这个类也给我们提供了消息循环,保证我们程序的运行。
  6. QMainWindow类,这是一个很重要的Qt类,它提供了用于构建应用程序用户界面的框架和主窗口的管理,它支持SDI和MDI不同模式。

        其实,这些信息其实对于我们理解一套框架是非常有用的,但是由于代码比较简单,我们常常会忽略这其中隐藏的重要信息,然后在以后编写代码的时候遇到对应的问题,却不知道从何处开始着手,比如说鼠标事件、键盘事件、MDI窗口如何创建等问题。

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

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

相关文章

ConnectWise ScreenConnect 身份验证绕过漏洞复现可RCE(CVE-2024-1709)

0x01 产品简介 ConnectWise ScreenConnect ,是一款自托管的远程桌面软件应用,该款软件允许用户自行托管,可以在自己的服务器、个人电脑、虚拟机或虚拟专用服务器上运行。 0x02 漏洞概述 ConnectWise ScreenConnect低于23.9.8 版本的产品中,SetupWizard.aspx接口处存在身…

[newstarctf2023] --RE wp

AndroGenshin: rc4加密表&#xff0c;base64换表&#xff1a; 脚本梭就行 python username b"genshinimpact" base64_table [125, 239, 101, 151, 77, 163, 163, 110, 58, 230, 186, 206, 84, 84, 189, 193, 30, 63, 104, 178, 130, 211,164, 94, 75, 16, 32, 33…

发布 rust 源码包 (crates.io)

rust 编程语言的包 (或者 库, library) 叫做 crate, 也就是软件中的一个组件. 一个完整的软件通常由多个 crate 组成, rust 编译器 (rustc) 一次编译一整个 crate, 不同的 crate 可以同时并行编译. rust 官方有一个集中发布开源包的网站 crates.io. 发布在这上面的 crate 可以…

vue3框架组件自动导入unplugin-vue-components

1.安装 npm i unplugin-vue-components -save-dev 2.配置 我这里用的是Vue CLI&#xff0c;所以要在vue.config.js文件中添加配置&#xff0c;官网中有写不同打包工具的配置写法 框架我使用的是Element Plus&#xff0c;使用前去官网查看自己的框架是否支持&#xff0c;主流…

LLM之RAG实战(二十七)| 如何评估RAG系统

有没有想过今天的一些应用程序是如何看起来几乎神奇地智能的&#xff1f;这种魔力很大一部分来自于一种叫做RAG和LLM的东西。把RAG&#xff08;Retrieval Augmented Generation&#xff09;想象成人工智能世界里聪明的书呆子&#xff0c;它会挖掘大量信息&#xff0c;准确地找到…

电脑黑屏什么都不显示怎么办 电脑开机黑屏不显示任何东西的4种解决办法

相信有很多网友都有经历电脑开机黑屏不显示任何东西&#xff0c;找了很多方法都没处理好&#xff0c;其实关于这个的问题&#xff0c;首先还是要了解清楚开机黑屏的原因&#xff0c;才能够对症下药&#xff0c;下面大家可以跟小编一起来看看怎么解决吧 电脑开机黑屏不显示任何…

【无刷电机学习】基础概念及原理介绍(持续更新中...)

目录&#xff08;2024.02.22版&#xff09; 1 定义 2 各种电机优势比较 2.1 有刷与无刷比较 2.2 交流与直流比较 2.3 内转子与外转子比较 2.4 低压BLDC的一些优点 3 基本原理 3.1 单相无刷电机 3.2 三相无刷电机 4 驱动方法 4.1 六步换相控制 4.1.1 基本原理 4…

突发!AI独角兽「竹间智能」被曝停工停产6个月

大家好我是二狗。 今天早上起来刷朋友圈&#xff0c;看到一张截图——AI创企竹间智能&#xff0c;宣称因为公司所处的经营环境艰难&#xff0c;部分部门和岗位将从即日起停工停产6个月。 图源&#xff1a;&#xff08;企服科学&#xff09; 下面是文字版&#xff1a; 由于公司…

Linux网络编程(三-UDP协议)

目录 一、UDP概述 二、UDP的首部格式 三、UDP缓冲区 四、基于UDP的应用层协议 五、常见问题 一、UDP概述 UDP(User Datagram Protocol&#xff0c;用户数据协议报)是传输层协议&#xff0c;提供不可靠服务&#xff0c;其特点包括&#xff1a; 无连接&#xff1a;知道对端…

CSP-202309-3-梯度求解

CSP-202309-3-梯度求解 作为一个算法小白&#xff0c;本人第一次接触大模拟的题&#xff0c;本题的算法参考自&#xff1a;【CSP】202309-3 梯度求解 解题思路 1.输入处理 getchar();&#xff1a;从标准输入读取一个字符。这里它的作用可能是用来“吃掉”&#xff08;消耗&a…

Kafka_04_Topic和日志

Kafka_04_Topic和日志 Topic/PartitionTopicPartition 日志存储存储格式日志清理删除压缩 Topic/Partition Topic/Partition: Kafka中消息管理的基础单位 Topic和Partition并不实际存在(仅逻辑上的概念) 如: Topic和Partition关系 // 每个日志文件可对应多个日志分段, 其还可…

缓存篇—缓存击穿

在很多场景下&#xff0c;我们的业务通常会有几个数据会被频繁地访问&#xff0c;比如秒杀活动&#xff0c;这类被频地访问的数据被称为热点数据。 如果缓存中的某个热点数据过期了&#xff0c;此时大量的请求访问了该热点数据&#xff0c;就无法从缓存中读取&#xff0c;直接…

《UE5_C++多人TPS完整教程》学习笔记22 ——《P23 记录加入的玩家(Couting Incoming Players)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P23 记录加入的玩家&#xff08;Couting Incoming Players&#xff09;》 的学习笔记&#xff0c;该系列教学视频为 Udemy 课程 《Unreal Engine 5 C Multiplayer Shooter》 的中文字幕翻译版&#xff0c;UP主&#xff…

如何使用Docker部署MongoDB并结合内网穿透实现远程访问本地数据库

文章目录 前言1. 安装Docker2. 使用Docker拉取MongoDB镜像3. 创建并启动MongoDB容器4. 本地连接测试5. 公网远程访问本地MongoDB容器5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定TCP地址远程访问 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 …

2024最佳住宅代理IP服务商有哪些?

跨境出海已成为了近几年的最热趋势&#xff0c;大批量的企业开始开拓海外市场&#xff0c;而海外电商领域则是最受欢迎的切入口。新兴的tiktok、Temu&#xff0c;老牌的Amazon、Ebay&#xff0c;热门的Etsy、Mecari等等都是蓝海一片。跨境入门并不难&#xff0c;前期的准备中不…

Spring Boot打war包部署到Tomcat,访问页面404 !!!

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 文章目录 Spring Boot打war包部署到Tomcat&#xff0c;访问页面404 &#xff01;&#xff01;&#xff01;解决办法&#xff1a;检查Tomcat版本和Jdk的对应关系&#xff0c;我的Tomcat是6.x&#x…

Sping基础篇----掌握Sping的控制反转/依赖注入的概念【实战案例总结】

作为一名对技术充满热情的学习者&#xff0c;我一直以来都深刻地体会到知识的广度和深度。在这个不断演变的数字时代&#xff0c;我远非专家&#xff0c;而是一位不断追求进步的旅行者。通过这篇博客&#xff0c;我想分享我在某个领域的学习经验&#xff0c;与大家共同探讨、共…

KVM虚拟机的克隆方式

话不多说&#xff0c;直接上操作 首先确定我们要克隆的模板机器&#xff0c;这样可以方便我们后续克隆许多机器 IP获取最好就是dhcp模式&#xff0c;这样克隆出来的机器就不需要自己再去改ip了 确定需要克隆的模板机以后&#xff0c;先关机再执行克隆操作 virsh shutdown ser…

【SiamFC】《Fully-Convolutional Siamese Networks for Object Tracking》

ECCV 2016 Workshops 文章目录 1 Background and Motivation2 Related Work3 Advantages / Contributions4 Method5 Experiments5.1 Datasets and Metrics5.2 The OTB-13 benchmark5.3 The VOT benchmarks5.4 Dataset size 6 Conclusion&#xff08;own&#xff09;/ Future wo…

Android系统启动流程

android的启动流程是从底层开始进行的&#xff0c;具体如下所示&#xff1a; Android是基于Linux内核的系统&#xff0c;Android的启动过程主要分为两个阶段&#xff0c;首先是Linux内核的启动&#xff0c;然后是Android框架的启动。 可以将Andorid系统的启动流程分为以下五个…