Qt开发学习笔记02

将窗口设为提示框

Qt::ToolTip

Qt 数据库连接池

#ifndef SQLITE_H
#define SQLITE_H

#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QQueue>
#include <QMutex>
#include <QDebug>
#include "../config.h"
#include "sqlInfo.h"

class SqLite {
public:
    static SqLite &instance() {
        // 使用单例模式保证只创建一个连接池对象
        static SqLite pool;
        return pool;
    }

    QSqlDatabase getConnection() {
        // 获取连接
        m_mutex.lock();
        if (m_connections.isEmpty()) {
            addConnections(10);
        }
        QSqlDatabase db;
        if (QSqlDatabase::contains("qt_sql_default_connection")) {
            db = QSqlDatabase::database("qt_sql_default_connection");
        } else {
            db = m_connections.dequeue();
        }
        m_mutex.unlock();

        // 如果连接断开,则重新连接
        if (!db.isOpen()) {
            db.open();
        }
        return db;
    }

    void releaseConnection(QSqlDatabase db) {
        // 释放连接
        m_mutex.lock();
        db.close();
        m_connections.enqueue(db);
        m_mutex.unlock();
    }

    static void init_table() {
        QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
        db.setDatabaseName(DB_PATH);
        if (!db.open()) {
            qDebug() << "Failed to open database:" << db.lastError().text();
        }
        QSqlQuery query(db);
        // 初始化数据库
        query.exec(CREATE_USER_TABLE);
        query.exec(CREATE_USER_INDEX);
        query.exec(CREATE_ROLE_TABLE);
        db.close();
    };

private:
    SqLite() {
        // 初始化连接池
        addConnections(30);
    }

    void addConnections(int count) {
        // 创建连接
        for (int i = 0; i < count; i++) {
            QSqlDatabase db;
            if (QSqlDatabase::contains("qt_sql_default_connection")) {
                db = QSqlDatabase::database("qt_sql_default_connection");
            } else {
                db = QSqlDatabase::addDatabase("QSQLITE");
            }
            db.setDatabaseName(DB_PATH);
            if (db.open()) {
                m_connections.enqueue(db);
            } else {
                qDebug() << "Failed to open database:" << db.lastError().text();
            }
        }
    }


private:
    QMutex m_mutex;
    QQueue<QSqlDatabase> m_connections;
};

#endif // SQLITE_H

Qt随机数

qDebug()<<QRandomGenerator::global()->bounded(10);		//生成一个0和10之间的整数
qDebug()<<QRandomGenerator::global()->bounded(10.123);	//生成一个0和10.123之间的浮点数
qDebug()<<QRandomGenerator::global()->bounded(10, 15);	//生成一个10和15之间的整数

Qt 监听鼠标点击事件

重写 mousePressEvent 方法

void SystemSet::mousePressEvent(QMouseEvent *event) {
    // 鼠标按下事件处理
    if (event->button() == Qt::LeftButton) {
        // 处理左键按下事件
        qDebug() << "editingFinished==LeftButton";
        ui->lockEdit->clearFocus();
    } else if (event->button() == Qt::RightButton) {
        // 处理右键按下事件
        ui->lockEdit->clearFocus();
        qDebug() << "editingFinished==RightButton" ;
    }
}

Qt关闭所有页面

QList<QWidget *> topLevelWidgets = QApplication::topLevelWidgets();
for (QWidget *widget : topLevelWidgets) {
  widget->close();
}

QT实现关机

要在Qt中实现关机功能,你需要使用操作系统提供的相关函数或命令来执行关机操作。由于不同操作系统之间的关机方式可能有所不同,下面我将为你提供针对不同操作系统的示例代码。

  • Windows系统

    #include <QProcess>
    
    void shutdownWindows()
    {
        QProcess::startDetached("shutdown -s -t 0");
    }
    
    

    也可使用下面方法

    system("shutdown -s -t 00");
    
  • macOS系统

    #include <QProcess>
    
    void shutdownMac()
    {
        QProcess::startDetached("sudo shutdown -h now");
    }
    
    

    请注意,macOS系统需要使用sudo权限来执行关机操作。

  • Linux系统

    #include <QProcess>
    
    void shutdownLinux()
    {
        QProcess::startDetached("sudo poweroff");
    }
    
    

    同样地,Linux系统也需要使用sudo权限来执行关机操作。

这些示例代码使用了Qt的QProcess类来启动外部进程执行关机命令。你可以根据自己的需求将其集成到你的Qt应用程序中的适当位置,并通过调用相应的函数来触发关机操作。

请注意,执行关机操作需要相应的权限,因此在某些情况下,用户可能需要提供管理员权限或确认密码才能成功执行关机命令。

Windows,关机,重启,注销,命令

使用函数system();
关机指令。(shutdown -s -t xx)
重启指令。(shutdown -r -t xx)
注销指令。(shutdown -l -t xx)

标准格式。(shutdown -s -t xx)
t xx是关机延时时间 /秒;xx可以是00,直接关机。
可能输入00后,windows提示n分钟后关机,但关机时间实际是设定的时间。

qt-5/stylesheet-reference中翻译过来的所有伪状态

有用的选择器类型

QTableView的基本属性

TableView 的基本使用

  • 添加数据

    QStandardItemModel* model = new QStandardItemModel(this);
    model->setHorizontalHeaderLabels(userHeader);//添加表头 userHeader={"序号", "用户名", "姓名", "手机号", "角色", "状态", "创建时间"}
    model->setRowCount(10); //列数
    ui->TableView->setModel(model);
    
     QStandardItem *pItem = new QStandardItem("正常");
     pItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);// 居中显示
     pItem->setData("1"); //例如,state=1 为正常 state=0 为禁用 页面显示为正常/禁用,则state的真实值可设置在这里
     model->setItem(0, 5, pItem);//将pItem设置在第0行5列
    
  • 获取QStandardItem中的data数据

    model->item(0, 5)->data().toInt();//toInt() 是数据转换,也可转为其他数据类型,根据设置的参数数据类型
    

Qt Qss的使用

参考文章:https://www.cnblogs.com/onefish51/p/9378290.html

Qt QscrollArea滚动条样式修改

QScrollBar:vertical {
    border: none;
    background: #F5F5F5;
    width: 10px;
    margin: 0px 0px 0px 0px;
}
QScrollBar::handle:vertical {
    background: #C0C0C0;
    min-height: 10px;
}
QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
    height: 0px;
}
QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
    background: none;
}

QString 删除最后一个字节

在C++中,可以使用QStringchop()函数来删除最后一个字节。这个函数会将字符串的长度减小一个字节,并且移除最后一个字符。

以下是一个示例代码:

QString str = "Hello World";
str.chop(1);

在上述代码中,我们定义了一个QString对象str,并赋值为"Hello World"。然后调用chop()函数,传入参数1,表示删除一个字节。执行完毕后,str的值将变为"Hello Worl",最后一个字节已被删除。

拖动窗口

在.h文件添加

protected:
    //拖拽窗口
    void mousePressEvent(QMouseEvent *event);

    void mouseMoveEvent(QMouseEvent *event);

    void mouseReleaseEvent(QMouseEvent *event);

private:
    bool m_bDrag;
    QPoint mouseStartPoint;
    QPoint windowTopLeftPoint;
    int _point;

在.cpp文件添加


void NumerKeypadDialog::mouseReleaseEvent(QMouseEvent *event) {
    if (event->button() == Qt::LeftButton) {
        m_bDrag = false;
    }
}

//拖拽操作
void NumerKeypadDialog::mousePressEvent(QMouseEvent *event) {
    if (event->button() == Qt::LeftButton) {
        m_bDrag = true;
        //获得鼠标的初始位置
        mouseStartPoint = event->globalPos();
        //mouseStartPoint = event->pos();
        //获得窗口的初始位置
        windowTopLeftPoint = this->frameGeometry().topLeft();
    }
}

void NumerKeypadDialog::mouseMoveEvent(QMouseEvent *event) {
    if (m_bDrag) {
        //获得鼠标移动的距离
        QPoint distance = event->globalPos() - mouseStartPoint;
        //改变窗口的位置
        this->move(windowTopLeftPoint + distance);
    }
}

Qt 弹窗页下的页面禁止操作

如果你想禁止在Qt弹窗页下的页面进行操作,可以采取以下方式:

  1. 设置模态对话框:使用setModal(true)方法将弹窗设置为模态对话框。这样,当弹窗打开时,用户无法在弹窗之外的页面上进行任何操作,直到关闭弹窗。
// 创建弹窗对象
QDialog dialog;

// 设置为模态对话框
dialog.setModal(true);

// 显示弹窗
dialog.exec();
  1. 拦截事件:通过重写页面的事件处理函数,阻止特定的事件传递给页面,从而禁止操作。例如,你可以重写QEvent::MouseButtonPress事件处理函数,使其在弹窗页下禁止鼠标按键的点击操作。
bool YourWidget::eventFilter(QObject *obj, QEvent *event)
{
    if (event->type() == QEvent::MouseButtonPress) {
        // 在这里判断是否处于弹窗页下,如果是则返回 true,表示拦截事件
        return true;
    }

    // 其他事件交给默认的处理方式
    return QObject::eventFilter(obj, event);
}
  1. 禁用控件:如果你只想禁止特定的控件操作,可以将这些控件设置为不可用状态。使用setEnabled(false)方法来禁用控件,并确保在弹窗关闭后恢复其可用状态。
// 禁用控件
QPushButton *button = new QPushButton("禁用按钮");
button->setEnabled(false);

// 恢复控件的可用状态
button->setEnabled(true);

通过以上方法,你可以在Qt弹窗页下禁止页面操作。根据你的具体需求,选择适合的方法即可。

QString 替换

在QString中进行替换可以使用replace()函数。该函数的语法如下:

QString& replace(const QString &before, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive)

其中,before表示要被替换的字符串,after表示替换后的字符串,cs表示是否区分大小写,默认为Qt::CaseSensitive(区分大小写)。

以下是一个示例代码:

QString str = "Hello World";
str.replace("World", "Universe");
// 替换后的字符串为 "Hello Universe"

如果有多个相同的子字符串需要替换,可以使用replace()函数的重载版本:

QString& replace(QChar before, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive)

以下是一个示例代码:

QString str = "Hello World";
str.replace('o', "X");
// 替换后的字符串为 "HellX WOrld"

请注意,replace()函数会修改原始的QString对象,而不是返回新的字符串。如果需要保留原始字符串并得到替换后的结果,可以使用QString的复制构造函数或者赋值运算符。

Qt 中程序睡眠

在 Qt 中,可以使用 QThread 类的静态函数 msleep()sleep() 来实现睡眠功能。

  1. 使用 msleep() 函数:
#include <iostream>
#include <QThread>

int main() {
    std::cout << "开始执行程序" << std::endl;

    // 休眠 2000 毫秒 (2秒)
    QThread::msleep(2000);

    std::cout << "休眠结束,继续执行程序" << std::endl;

    return 0;
}

上述代码中的 QThread::msleep(2000) 会使当前线程休眠 2000 毫秒(即2秒)。

  1. 使用 sleep() 函数:
#include <iostream>
#include <QThread>

int main() {
    std::cout << "开始执行程序" << std::endl;

    // 休眠 2 秒
    QThread::sleep(2);

    std::cout << "休眠结束,继续执行程序" << std::endl;

    return 0;
}

上述代码中的 QThread::sleep(2) 会使当前线程休眠 2 秒。

需要注意的是,以上两种方法都会阻塞当前线程的执行,所以一般不建议在 GUI 线程中使用。如果需要在 GUI 线程中进行延时操作,可以考虑使用 QTimer 类。

希望这个回答对你有帮助!如果还有其他问题,请随时提问。

QTcpSocket 不支持长连接

?:QTcpSocket 连接成功后自动断开,是不是不支持长连接

D: 是的,你的理解是正确的。QTcpSocket 在连接成功后不会自动保持长连接,它默认是一次性连接。当完成数据传输或发生错误时,QTcpSocket 会自动断开连接。

如果你想要实现长连接的效果,需要在合适的时机手动处理连接断开并重新连接的逻辑。可以通过监听 disconnected 信号来检测连接断开事件,并在该信号触发时重新调用 connectToHost() 方法进行重新连接。

以下是一个示例代码,展示了如何使用 QTcpSocket 手动实现长连接:

QTcpSocket* socket = new QTcpSocket(this);

// 处理连接断开事件
connect(socket, &QTcpSocket::disconnected, [=]() {
    qDebug() << "连接断开,正在尝试重新连接...";
    // 在连接断开时重新连接
    socket->connectToHost("192.168.1.1", 502);
});

// 连接到远程主机
socket->connectToHost("192.168.1.1", 502);

通过以上代码,当连接断开时,你可以在 disconnected 信号的槽函数中重新调用 connectToHost() 方法来实现重新连接的逻辑。

需要注意的是,在使用长连接时,应谨慎考虑网络负载和资源消耗,并根据实际需求进行适当的调整。此外,具体的操作系统和网络环境可能会对长连接的行为有所不同。因此,请确保根据你的需求和环境进行适当的设置和调试。

希望这可以解答你的问题。如果还有其他疑问,请随时提问。

QFrame 于 QWidget 的区别

QFrame 和 QWidget 都是 Qt 框架中的类,用于创建图形界面应用程序。它们之间有一些区别,如下所示:

  1. 功能: QWidget 是 Qt 的基本窗口类,它提供了一个空白的窗口,您可以在其中放置其他 UI 元素(例如按钮、文本框等)。QWidget 是 Qt 应用程序中所有窗口和控件的基类。而 QFrame 是 QWidget 的子类,它提供了一些额外的功能,如边框、背景、阴影等。您可以使用 QFrame 来创建具有特定样式和外观的小部件。

  2. 外观: QWidget 是一个非可见的容器,它本身没有定义任何外观特性。它只提供了基本的窗口功能,如事件处理和布局管理。而 QFrame 具有一些可见的外观特性,如边框和背景色。您可以使用 QFrame 的样式属性和方法来定制它的外观。

  3. 布局管理: QWidget 提供了布局管理器(如 QVBoxLayout、QHBoxLayout 等),用于管理内部控件的位置和大小。您可以将其他控件添加到 QWidget 中,并使用布局管理器来自动调整它们的位置和大小。QFrame 也继承了 QWidget 的布局管理功能,并且可以将其他控件添加到其中。

总的来说,QWidget 是一个基本的窗口类,而 QFrame 是 QWidget 的子类,提供了一些额外的外观特性。如果您需要一个简单的容器来放置其他控件,并且不需要特殊的外观效果,那么使用 QWidget 是合适的选择。如果您需要一个带有边框、背景等外观特性的小部件,那么可以选择使用 QFrame。

Qt 全屏/退出全屏

在 Qt 中,要退出全屏模式,可以使用 QWidgetshowNormal() 方法。该方法会将窗口恢复为正常大小,并显示在桌面上。

以下是退出全屏模式的示例代码:

QWidget* window = new QWidget();
// 将窗口设置为全屏
window->showFullScreen();

// 退出全屏模式
window->showNormal();

在上述代码中,我们首先将窗口设置为全屏显示,使用 showFullScreen() 方法。然后,通过调用 showNormal() 方法,窗口将退出全屏模式并恢复为正常大小。

请注意,showNormal() 方法会将窗口恢复到最初的大小和位置,因此如果在全屏模式之前窗口已被最大化或调整过大小,它将恢复到最初的状态。

TabWidget 根据QWidget 获取index

是的,在 QTabWidget 中可以根据 QWidget 获取其在 QTabWidget 中的索引(index)。您可以使用 QTabWidgetindexOf() 方法来实现这一功能。

以下是根据 QWidget 获取索引的示例代码:

QTabWidget* tabWidget = new QTabWidget();

// 创建几个 QWidget
QWidget* widget1 = new QWidget();
QWidget* widget2 = new QWidget();
QWidget* widget3 = new QWidget();

// 将这些 QWidget 添加到 QTabWidget 中的不同选项卡中
tabWidget->addTab(widget1, "Tab 1");
tabWidget->addTab(widget2, "Tab 2");
tabWidget->addTab(widget3, "Tab 3");

// 获取 widget2 在 QTabWidget 中的索引
int index = tabWidget->indexOf(widget2);

在上述代码中,我们首先创建了几个 QWidget,然后将它们添加到 QTabWidget 中的不同选项卡中。接下来,我们使用 indexOf() 方法来获取 widget2QTabWidget 中的索引,并将其存储在 index 变量中。

请注意,索引是从 0 开始的,表示 QTabWidget 中选项卡的顺序。如果 widget2 不存在于 QTabWidget 中,indexOf() 方法将返回 -1。

QTreeWidget 如何设置复选框

在项目中添加项目后默认是没有复选框的,需要在属性中设置,找到 chackState 属性,修改为 checked 后复选框后出现

如果一个父级项目下有多个子项目,选中一个子项目,父项目自动设置为半选(父项目与子项目联动),需要在父项目设置Tristate 属性

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

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

相关文章

翻译: 生成式人工智能的经济潜力 第一部分商业价值 The economic potential of generative AI

生成式人工智能即将引发下一波生产力的浪潮。我们首先看看业务价值可能会增加的地方&#xff0c;以及对劳动力的潜在影响。 1. 人工智能已经逐渐渗透到我们的生活中 人工智能已经逐渐渗透到我们的生活中&#xff0c;从为智能手机提供动力的技术到汽车上的自动驾驶功能&#x…

实现简易的多人聊天

服务端 import java.io.*; import java.net.*; import java.util.ArrayList; public class Server{public static ServerSocket server_socket;public static ArrayList<Socket> socketListnew ArrayList<Socket>(); public static void main(String []args){try{…

SpringBoot Maven打包插件spring-boot-maven-plugin无法解析离谱原因记录

目录 一、常见打包插件无法解析原因二、打包插件无法解析离谱原因三、总结 打包配置 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><…

基于深度学习路径规划RRT*-训练图像预处理

基于深度学习路径规划RRT*-训练图像预处理 图像预处理说明 在基于采样的RRT算法对机器人进行路径规划时&#xff0c;由于采样点的随机性&#xff0c;会增加路径的搜索时间的路径的非最优性&#xff0c;所以基于神经网络的优势&#xff0c;利用深度学习进行RRT的随机采样&…

M2芯片回顾

M芯片&#xff0c; 一竟到底&#xff1a; M1芯片的体积&#xff1a; M2 代表 M 系列芯片的第二代&#xff1a; 其进一步提升了芯片的性能和功率 &#xff0c;这也是 M 芯片目前的追求&#xff1a;最大化性能的同时&#xff0c;最大限度降低功耗。 UMA 统一内存架构被再一次提到…

【开源】基于Vue+SpringBoot的智慧家政系统

项目编号&#xff1a; S 063 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S063&#xff0c;文末获取源码。} 项目编号&#xff1a;S063&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询家政服…

三种基于路径跟踪的位相解包裹算法比较

目录 1. 枝切法(Branch Cut&#xff0c;简称 BC) 2 质量图导向的路径跟踪算法(Quality Guide&#xff0c;简称QG) 3 菱形算法(Rhombus Alogrithm&#xff0c;简称 RA) 1. 枝切法(Branch Cut&#xff0c;简称 BC) 美国的 JPL实验室的 Goldstein和 Zebker等人在1986年提出的枝…

Numpy 实现基尼指数算法的决策树

基尼系数实现决策树 基尼指数 Gini ⁡ ( D ) 1 − ∑ k 1 K ( ∣ C k ∣ ∣ D ∣ ) 2 \operatorname{Gini}(D)1-\sum_{k1}^{K}\left(\frac{\left|C_{k}\right|}{|D|}\right)^{2} Gini(D)1−k1∑K​(∣D∣∣Ck​∣​)2 特征 A A A条件下集合 D D D的基尼指数&#xff1a; Gi…

97基于matlab的改进的带记忆的模拟退火算法求解TSP问题

基于matlab的改进的带记忆的模拟退火算法求解TSP问题&#xff0c;采用多普勒型降温曲线描述迭代过程&#xff0c;在传统算法的基础上增加记忆功能&#xff0c;可测试中国31/64/144以及att48城市的数据&#xff0c;也可自行输入数据进行测试&#xff0c;测试结果基本达到当前最优…

Java - InetAddress#isReachable 方法解析

文章目录 前言代码资源 前言 在 Java 中&#xff0c;InetAddress 类提供一个方法来检查一个网络地址是否可达&#xff0c;其作用类似与在命令行执行 ping 命令&#xff0c; 这个方法就是 isReachable 方法。 代码 var baidu InetAddress.getByName("www.baidu.com&quo…

点评项目——短信登陆模块

2023.12.6 短信登陆如果基于session来实现&#xff0c;会存在session共享问题&#xff1a;多台Tomcat不能共享session存储空间&#xff0c;这会导致当请求切换到不同服务器时出现数据丢失的问题。 早期的解决办法是让session提供一个数据拷贝的功能&#xff0c;即让各个Tomcat的…

封装校验规则(以及复选框和整体校验)-----Vue3+ts项目

登录校验页面 <script setup lang"ts"> import { ref } from vue import { mobileRules, passwordRules } from /utils/rules const mobile ref() const password ref() </script><!-- 表单 --><van-form autocomplete"off">&l…

OpenEuler系统桌面终端设置字体

初始界面 终端的字体间距过大&#xff0c;阅读起来不方便。 调整终端字体 点击菜单&#xff0c;选择“配置文件首选项” 未命名 ---- 文本---- 勾选 自定义字体 ---- 选择 "DejaVu LGC Sans Mono"字体 你也可以根据自己的喜好&#xff0c;选择其他字体。 修改好了…

智慧园区可视化综合管理平台建设方案,智能化、数字化才是关键

园区作为城市的基本单元&#xff0c;是经济发展的重要载体。随着我国经济的快速发展&#xff0c;各类工业园区、办公园区等园区的规划建设也越来越多。伴随着互联网新兴技术的发展和应用&#xff0c;智慧园区已成为当今城市规划和社会发展的关注焦点&#xff0c;今天我们来介绍…

工具站推荐

自己搭了一个文本工具站 TextTool&#xff0c;包含了常用的文本功能。 我自己比较常用 行转列、列转行、下划线替换的功能。 欢迎各位大佬提意见和建议

学习Python的未来前景分析

文章目录 前言学python可以干什么如果具备Python编程&#xff0c;能用Python做什么&#xff1a;学Python语言能干什么1.常规软件开发2.科学计算3.自动化运维4.云计算 学python编程对未来的影响关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Py…

/proc/sys/net/ipv4/ 下网络参数的理解

/proc/sys/net/ipv4/下文件详细解释&#xff1a; /proc/sys/net/ipv4/下文件 /proc/sys/net/ipv4/ip_forward 该文件表示是否打开IP转发。 0&#xff0c;禁止 1&#xff0c;转发 基本用途&#xff1a;如VPN、路由产品的利用&#xff1b; 出于安全考虑&#xff0c;Linux系…

机器学习实验五:集成学习

系列文章目录 机器学习实验一&#xff1a;线性回归机器学习实验二&#xff1a;决策树模型机器学习实验三&#xff1a;支持向量机模型机器学习实验四&#xff1a;贝叶斯分类器机器学习实验五&#xff1a;集成学习机器学习实验六&#xff1a;聚类 文章目录 系列文章目录一、实验…

记一次Qt程序在win7上执行报错:0xc000007b排查步骤

前言 今天在运行别人发的一个Qt包的时候发现在我的虚拟机中运行不起&#xff0c;我的虚拟机系统是win7企业版不带sp1。在装vc2015运行库的时候也不能装。在网上搜寻资料说需要安装2919442等相关补丁。我下载相关补丁后运行提示不能安装。于是我又找到win7 企业版sp1的exe程序安…

Git多人协作(一)

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 前言 由于博主是一个人&#xff0c;所以博主为完成这篇文章&#xff0c;在Linux下克隆了一个仓库&#xff0c;在windows下克隆了一个仓库&#xff0c;以此来模拟多人协作开发。而实际开发中&#xff0c;每个人都有自己的git…