首页
统计
留言
投币
友链
关于
Search
1
抖音鸡汤(一)
15 阅读
2
扩展:268条PCB Layout设计规范!
7 阅读
3
新版Keilv5安装相关问题大全
7 阅读
4
Arduino库介绍——AccelStepper
6 阅读
5
Ubuntu系统——虚拟机ubuntu22.04没有网
3 阅读
基础
CPP语法
算法题
硬件设计
PCBLayout
电子设计
单片机
ESP32
STM32
STC51
Arduino
LuatOS
FreeRTOS
LVGL
Linux
QT
树莓派
T113S3
Linux系统
Linux应用开发
Linux驱动开发
IoT
MQTT
Lora
NB-IOT
米家
涂鸦
AI
OpenCV
项目
杂谈 | 日记
投资笔记
登录
Search
标签搜索
Arduino
ESP32
PCBLayout
鸡汤
ubuntu
步进电机
KEIL
CPP
QT
OTA
会焊工的程序猿
累计撰写
10
篇文章
累计收到
0
条评论
首页
栏目
基础
CPP语法
算法题
硬件设计
PCBLayout
电子设计
单片机
ESP32
STM32
STC51
Arduino
LuatOS
FreeRTOS
LVGL
Linux
QT
树莓派
T113S3
Linux系统
Linux应用开发
Linux驱动开发
IoT
MQTT
Lora
NB-IOT
米家
涂鸦
AI
OpenCV
项目
杂谈 | 日记
投资笔记
页面
统计
留言
投币
友链
关于
搜索到
4
篇与
的结果
2026-02-02
QT开发入门笔记——北京迅为
1 QT工程1.1qt基础qt的移植性非常的强。一套代码我们不用改太多,直接通用所有的平台。不久的将来,qt会被用到MCU上,学习QT还是非常有意义的。1.2做一个简单的qt界面如何创建一个QT工程?步骤一:步骤二:不要有中文路径步骤三:工程文件分析:点击forms,然后双击ui文件,就可以进入ui编辑器。ui编辑器面板介绍:做一个简单的QQ登录界面,我们用到组件放图片,放文本,放gif图的组件就是 qlabel 放账号和密码的对话框我们用的组件是 qlinedit 按钮我们使用的组件是 qpushbutton1.3关联信号和槽自动关联:在ui界面里,右键点击对应的控件->转到槽自动关联会给我们的工程添加以下内容:槽函数只能声明到private slots或者public slots 下面。(QT特有)手动关联:使用connect这个函数。connect(ui->logoBt,SIGNAL(clicked()),this,SLOT(logoBt_clicked_slots())); connect(A,SIGNAL(B),C,SLOT(D));//当对象A发出B信号时候,就会触发对象C的槽函数D1.4添加图片图标下载网址: iconfont-阿里巴巴矢量图标库1、添加图片:右键项目名->添加新文件->Qt->Qt Resource FileResourrces文件夹下右键.qrc文件->Open with->资源编辑器-添加前缀(一般默认根文件)->Crtl+S 保存文件->添加文件 注意:记得保存!!!2、引用图片右击想要的控件->改变样式表->添加资源->border-image。可以添加多张照片。1.5添加新的页面右键项目名->添加新文件->Qt->Qt 设计师类界面->设置类名26、28行,创建类的对象。问题:在这个类下随意创建一个对象就是我们在编辑的ui界面void MainWindow::on_loginBt_clicked() { qDebug() << "loginBt_clicked"; QString ssid = ui->ssidEdit->text(); QString pwd = ui->pswdEdit->text(); if(ssid == "yyx" && pwd == "123")//判断密码 { ctrl* ct = new ctrl; ct->setGeometry(this->geometry());//读取窗口的高宽数据进行设置 ct->show();//显示跳转的页面 } } void ctrl::on_backBt_clicked() { this->close();//这句话就可以关闭本文件对应的界面 }2 QT三驾马车qt下的串口编程,网络编程(TCP UDP),操作GPIO3 串口编程3.1自制串口调试助手3.1.1串口调试助手界面设计做一个串口调试助手需要用到的组件如下接受框:属性选择:发送框:UI设计界面如下:3.1.2串口调试助手程序设计由于版本比较高,会出现字体大小不合适的情况,需要在吗main.cpp里添加一段代码#include "widget.h" #include <QApplication> #include <iconv.h> int main(int argc, char* argv[]) { if(QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))//判断QT版本 { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); } QApplication a(argc, argv); Widget w; w.setWindowTitle("阿轩串口调试助手 V1.0.0");//界面程序名称 w.show(); return a.exec(); }需要在xxx.pro文件里上serialport库,QT += core gui serialport界面操作代码#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QSerialPort> #include <QString> namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget* parent = nullptr); ~Widget(); QSerialPort* serialPort = new QSerialPort(this); void serial_open_Bt_state();//串口打开时按钮盒选项的状态 void serial_close_Bt_state();//串口关闭时按钮盒选项的状态 private slots: void on_openBt_clicked(); void serialPortReadyRead_Slot(); void on_sendBt_clicked(); void on_clearBt_clicked(); void on_pushButton_1_clicked(); void on_pushButton_2_clicked(); void on_pushButton_3_clicked(); void on_pushButton_4_clicked(); void on_pushButton_5_clicked(); void on_pushButton_6_clicked(); void on_pushButton_7_clicked(); void on_pushButton_8_clicked(); void on_pushButton_9_clicked(); void on_pushButton_10_clicked(); void on_pushButton_11_clicked(); void on_pushButton_12_clicked(); void on_pushButton_13_clicked(); void on_pushButton_14_clicked(); void on_pushButton_15_clicked(); private: Ui::Widget* ui; }; #endif // WIDGET_H #include "widget.h" #include "ui_widget.h" #include <QSerialPortInfo> #include <QMessageBox> bool serial_state = false; Widget::Widget(QWidget* parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); QStringList serialNamePort; foreach (const QSerialPortInfo& info, QSerialPortInfo::availablePorts())//自动检测端口 { serialNamePort << info.portName(); } ui->serialCb->addItems(serialNamePort);//自动检测到的端口输出给串口选择框 connect(serialPort, SIGNAL(readyRead()), this, SLOT(serialPortReadyRead_Slot()));//检测串口收到的数据 serial_close_Bt_state();//启动时默认是未打开 } Widget::~Widget() { delete ui; } //串口打开之后一些按钮状态需要改变 void Widget::serial_open_Bt_state() { ui->sendBt->setEnabled(true); ui->pushButton_1->setEnabled(true); ui->pushButton_2->setEnabled(true); ui->pushButton_3->setEnabled(true); ui->pushButton_4->setEnabled(true); ui->pushButton_5->setEnabled(true); ui->pushButton_6->setEnabled(true); ui->pushButton_7->setEnabled(true); ui->pushButton_8->setEnabled(true); ui->pushButton_9->setEnabled(true); ui->pushButton_10->setEnabled(true); ui->pushButton_11->setEnabled(true); ui->pushButton_12->setEnabled(true); ui->pushButton_13->setEnabled(true); ui->pushButton_14->setEnabled(true); ui->pushButton_15->setEnabled(true); ui->serialCb->setEnabled(false); ui->baundrateCb->setEnabled(false); ui->dataCb->setEnabled(false); ui->checkCb->setEnabled(false); ui->stopCb->setEnabled(false); } //串口关闭后一些按钮状态也需要改变 void Widget::serial_close_Bt_state() { ui->sendBt->setEnabled(false); ui->pushButton_1->setEnabled(false); ui->pushButton_2->setEnabled(false); ui->pushButton_3->setEnabled(false); ui->pushButton_4->setEnabled(false); ui->pushButton_5->setEnabled(false); ui->pushButton_6->setEnabled(false); ui->pushButton_7->setEnabled(false); ui->pushButton_8->setEnabled(false); ui->pushButton_9->setEnabled(false); ui->pushButton_10->setEnabled(false); ui->pushButton_11->setEnabled(false); ui->pushButton_12->setEnabled(false); ui->pushButton_13->setEnabled(false); ui->pushButton_14->setEnabled(false); ui->pushButton_15->setEnabled(false); ui->serialCb->setEnabled(true); ui->baundrateCb->setEnabled(true); ui->dataCb->setEnabled(true); ui->checkCb->setEnabled(true); ui->stopCb->setEnabled(true); } //读取串口发来的信息并显示 void Widget::serialPortReadyRead_Slot() { QString buf; buf = QString(serialPort->readAll()); ui->recvEdit->appendPlainText(buf); } //串口开关按钮 void Widget::on_openBt_clicked() { if(serial_state == false) { QSerialPort::BaudRate baudRate;//波特率 QSerialPort::DataBits dataBits;//数据位 QSerialPort::StopBits stopBits;//停止位 QSerialPort::Parity checkBits;//校验位 //读取选择的波特率 if(ui->baundrateCb->currentText() == "1200") { baudRate = QSerialPort::Baud1200; } else if(ui->baundrateCb->currentText() == "2400") { baudRate = QSerialPort::Baud2400; } else if(ui->baundrateCb->currentText() == "4800") { baudRate = QSerialPort::Baud4800; } else if(ui->baundrateCb->currentText() == "9600") { baudRate = QSerialPort::Baud9600; } else if(ui->baundrateCb->currentText() == "19200") { baudRate = QSerialPort::Baud19200; } else if(ui->baundrateCb->currentText() == "38400") { baudRate = QSerialPort::Baud38400; } else if(ui->baundrateCb->currentText() == "57600") { baudRate = QSerialPort::Baud57600; } else if(ui->baundrateCb->currentText() == "115200") { baudRate = QSerialPort::Baud115200; } //读取选择的数据位 if(ui->dataCb->currentText() == "5") { dataBits = QSerialPort::Data5; } else if(ui->dataCb->currentText() == "6") { dataBits = QSerialPort::Data6; } else if(ui->dataCb->currentText() == "7") { dataBits = QSerialPort::Data7; } else if(ui->dataCb->currentText() == "8") { dataBits = QSerialPort::Data8; } //读取选择的停止位 if(ui->stopCb->currentText() == "1") { stopBits = QSerialPort::OneStop; } else if(ui->stopCb->currentText() == "1.5") { stopBits = QSerialPort::OneAndHalfStop; } else if(ui->stopCb->currentText() == "2") { stopBits = QSerialPort::TwoStop; } //读取选择的效验位 if(ui->checkCb->currentText() == "none") { checkBits = QSerialPort::NoParity; } serialPort->setPortName(ui->serialCb->currentText());//设置串口号 serialPort->setBaudRate(baudRate);//设置波特率 serialPort->setDataBits(dataBits);//设置数据位 serialPort->setStopBits(stopBits);//设置停止位 serialPort->setParity(checkBits);//设置校验位 //打开并判断是否打开成功 if(serialPort->open(QIODevice::ReadWrite) == true) { //QMessageBox::information(this, "提示", "成功"); // ui->labelstate->setText("串口已打开");//弹窗 serial_state = true; serial_open_Bt_state(); ui->openBt->setText("关闭串口"); } else { QMessageBox::information(this, "提示", "失败"); } } else { serialPort->close(); // ui->labelstate->setText("串口关闭");//弹窗 serial_state = false; serial_close_Bt_state(); ui->openBt->setText("打开串口"); } } void Widget::on_sendBt_clicked() { serialPort->write(ui->sendEdit->text().toLocal8Bit().data());//转为QByteString类型字符串,并且再转换成char*发送,防止乱码 serialPort->write("\r\n"); } void Widget::on_clearBt_clicked() { ui->recvEdit->clear(); } void Widget::on_pushButton_1_clicked() { serialPort->write(ui->lineEdit_1->text().toLocal8Bit().data()); } void Widget::on_pushButton_2_clicked() { serialPort->write(ui->lineEdit_2->text().toLocal8Bit().data()); } void Widget::on_pushButton_3_clicked() { serialPort->write(ui->lineEdit_3->text().toLocal8Bit().data()); } void Widget::on_pushButton_4_clicked() { serialPort->write(ui->lineEdit_4->text().toLocal8Bit().data()); } void Widget::on_pushButton_5_clicked() { serialPort->write(ui->lineEdit_5->text().toLocal8Bit().data()); } void Widget::on_pushButton_6_clicked() { serialPort->write(ui->lineEdit_6->text().toLocal8Bit().data()); } void Widget::on_pushButton_7_clicked() { serialPort->write(ui->lineEdit_7->text().toLocal8Bit().data()); } void Widget::on_pushButton_8_clicked() { serialPort->write(ui->lineEdit_8->text().toLocal8Bit().data()); } void Widget::on_pushButton_9_clicked() { serialPort->write(ui->lineEdit_9->text().toLocal8Bit().data()); } void Widget::on_pushButton_10_clicked() { serialPort->write(ui->lineEdit_10->text().toLocal8Bit().data()); } void Widget::on_pushButton_11_clicked() { serialPort->write(ui->lineEdit_11->text().toLocal8Bit().data()); } void Widget::on_pushButton_12_clicked() { serialPort->write(ui->lineEdit_12->text().toLocal8Bit().data()); } void Widget::on_pushButton_13_clicked() { serialPort->write(ui->lineEdit_13->text().toLocal8Bit().data()); } void Widget::on_pushButton_14_clicked() { serialPort->write(ui->lineEdit_14->text().toLocal8Bit().data()); } void Widget::on_pushButton_15_clicked() { serialPort->write(ui->lineEdit_15->text().toLocal8Bit().data()); } 4 软件打包成windows可执行文件QT如何打包生成独立可执行.exe文件_qt打包成可执行程序-CSDN博客4.1我们把工厂切换到release模式,然后编译release模式:基本没有调试信息。debug模式:有很多调试信息。4.2改一下图标先把图标加到工程所在文件夹。然后在pro文件里面添加RC_ICONS=serial_iocn.ico注意:图标的格式必须为.ico这个格式的,其他格式不行。4.3封包操作4.3.1将QT程序使用Release编译**4.3.2新建一个文件夹,将Release编译生成的exe文件复制到新建文件夹中先找到Release编译生成的exe文件夹位置,与项目创建的文件夹有关: 临时文件夹 --》 release --》 xx .exe文件 比如我的这个就是在D:\QtPro\build-Serial-Desktop_Qt_5_12_9_MinGW_64_bit-Release\release 把exe文件拷贝出来 随便在哪创建一个空的文件夹,然后将.exe文件拷贝进去 比如我在E盘新建了QTtest文件夹 4.3.3使用命令终端添加程序所需的依赖库在开始菜单中找到Qt命令终端(版本可能不一样打开对应版本就行),进入刚才新建的文件夹目录,使用 windeployqt 对生成的exe 文件进行打配置动态库文件: 一般来说,打开命令行终端后默认是在QT的安装路径下,这样需要先把路径切过去到exe文件的路径下再使用 windeployqt 命令 + .exe文件名操作或者直接windeployqt + .exe文件绝对路径 这样就成功了,可以双击exe文件测试是否可以正常打开。 到这一步其实可以选择把整个文件夹打个压缩包,然后就可以发送到其他PC端使用了,只需解压缩即可。 如果还觉得麻烦,想只用一个exe文件就能独立工作,那就接着往下操作。4.4合并打包程序(下面的步骤只适用于Windows系统下)4.4.1安装Enigma virtual box工具Enigma Virtual Box是软件虚拟化工具,它可以将多个文件封装到应用程序主文件,从而制作成为单执行文件的绿色软件。它支持所有类型的文件格式,虚拟化后的软件不释放任何临时文件到您的硬盘,文件模拟过程仅在内存运行。Enigma virtual box官方链接:https://enigmaprotector.com/cn/downloads.html 进入官网后找到红框部分点击下载即可,不需要注册账号: 下载后点击安装,安装过程一直next就行,注意勾选创建桌面快捷方式,默认是不创建的。 安装好后打开可以设置中文语言: 4.4.2打开安装好的Enigma Virtual Box,点击浏览,找到第三步的目录下的exe文件4.4.3点击增加,选择递归添加文件,选中demo文件夹点击确定4.4.4选择目标文件夹后点击确定4.4.5点击文件选项,选中压缩文件,点击确定4.4.6最后点击执行封包,等待结束即可。4.4.7最终生成的文件名和路径,找到该文件双击打开测试是否正常至此整个打包过程结束5 网络编程(TCP UDP)QT的网络编程:网络编程有TCP和UDP。5.1TCP协议TCP编程需要用到俩个类:QTcpServer和QTcpSocket查找帮助可知都需要添加network5.1.1服务器设计#include "widget.h" #include "ui_widget.h" // 构造函数,初始化Widget对象 Widget::Widget(QWidget* parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); // 设置UI tcpServer = new QTcpServer(this); // 创建一个新的QTcpServer对象 tcpSocket = new QTcpSocket(this); // 创建一个新的QTcpSocket对象 // 连接信号和槽,当有新的连接时调用newConnection_Slot槽函数 connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newConnection_Slot())); } // 槽函数,当有新的连接时调用 void Widget::newConnection_Slot() { tcpSocket = tcpServer->nextPendingConnection(); // 获取下一个挂起的连接 // 连接信号和槽,当有数据可读时调用readyRead_Slot槽函数 connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_Slot())); } // 槽函数,当有数据可读时调用 void Widget::readyRead_Slot() { // 将读取到的数据追加到recvTextEdit文本编辑器中 ui->recvTextEdit->appendPlainText(tcpSocket->readAll()); } // 析构函数,清理资源 Widget::~Widget() { delete ui; // 删除UI对象 } // 槽函数,当打开按钮被点击时调用 void Widget::on_openBt_clicked() { // 监听所有IP地址和端口,端口号从portEdit文本框中获取并转换为无符号整数 tcpServer->listen(QHostAddress::Any, ui->portEdit->text().toUInt()); } // 槽函数,当关闭按钮被点击时调用 void Widget::on_closeBt_clicked() { tcpServer->close(); // 关闭服务器 } // 槽函数,当发送按钮被点击时调用 void Widget::on_sendBt_clicked() { // 发送sendEdit文本框中的数据,数据转换为本地8位字节数组 // 发送前需要转换一下,转为QByteString类型字符串,并且再转换成char*发送,防止乱码 tcpSocket->write(ui->sendEdit->text().toLocal8Bit().data()); } 5.2.2客户端设计#include "widget.h" #include "ui_widget.h" // 构造函数,初始化Widget对象 Widget::Widget(QWidget* parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); // 设置UI tcpSocket = new QTcpSocket(this); // 创建一个新的QTcpSocket对象 } // 析构函数,清理资源 Widget::~Widget() { delete ui; // 删除UI对象 } // 槽函数,当连接成功时调用 void Widget::connected_Slot() { // 连接信号和槽,当有数据可读时调用readyRead_Slot槽函数 connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_Slot())); } // 槽函数,当有数据可读时调用 void Widget::readyRead_Slot() { // 将读取到的数据追加到recvTextEdit文本编辑器中 ui->recvTextEdit->appendPlainText(tcpSocket->readAll()); } // 槽函数,当打开按钮被点击时调用 void Widget::on_openBt_clicked() { // 连接到主机,IP地址和端口号分别从ipEdit和portEdit文本框中获取并转换 tcpSocket->connectToHost(ui->ipEdit->text(), ui->portEdit->text().toUInt()); // 连接信号和槽,当连接成功时调用connected_Slot槽函数 connect(tcpSocket, SIGNAL(connected()), this, SLOT(connected_Slot())); } // 槽函数,当关闭按钮被点击时调用 void Widget::on_closeBt_clicked() { tcpSocket->close(); // 关闭连接 } // 槽函数,当发送按钮被点击时调用 void Widget::on_sendBt_clicked() { // 发送sendEdit文本框中的数据,数据转换为本地8位字节数组 tcpSocket->write(ui->sendEdit->text().toLocal8Bit().data()); } 5.2UDP协议udp不分客户端和服务器,只需要使用一个类QUdpSocket#include "widget.h" #include "ui_widget.h" // 构造函数,初始化Widget对象 Widget::Widget(QWidget* parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); // 设置UI udpSocket = new QUdpSocket(this); // 创建一个新的QUdpSocket对象 // 设置按钮的初始状态 ui->openBt->setEnabled(true); ui->closBt->setEnabled(false); ui->sendBt->setEnabled(false); } // 析构函数,清理资源 Widget::~Widget() { delete ui; // 删除UI对象 } // 槽函数,当有数据可读时调用 void Widget::readyRead_Slot() { while (udpSocket->hasPendingDatagrams()) // 当有挂起的数据报时 { QByteArray array; array.resize(udpSocket->pendingDatagramSize()); // 调整数组大小以适应数据报 udpSocket->readDatagram(array.data(), array.size()); // 读取数据报 QString buf = array.data(); // 将数据转换为QString ui->recvEdit->appendPlainText(buf); // 将数据追加到recvEdit文本编辑器中 } } // 槽函数,当打开按钮被点击时调用 void Widget::on_openBt_clicked() { // 绑定本地端口,成功则启用相关按钮 if(udpSocket->bind(ui->localPort->text().toUInt()) == true) { ui->openBt->setEnabled(false); ui->closBt->setEnabled(true); ui->sendBt->setEnabled(true); } // 连接信号和槽,当有数据可读时调用readyRead_Slot槽函数 connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_Slot())); } // 槽函数,当关闭按钮被点击时调用 void Widget::on_closBt_clicked() { udpSocket->close(); // 关闭UDP连接 // 重置按钮的状态 ui->openBt->setEnabled(true); ui->closBt->setEnabled(false); ui->sendBt->setEnabled(false); } // 槽函数,当发送按钮被点击时调用 void Widget::on_sendBt_clicked() { QHostAddress address; address.setAddress(ui->aimIp->text()); // 设置目标IP地址 quint16 port = ui->aimPort->text().toUInt(); // 获取目标端口号 QString sendbuff = ui->sendEdit->text(); // 获取发送数据 // 发送数据报 udpSocket->writeDatagram(sendbuff.toLocal8Bit().data(), sendbuff.length(), address, port); } 6 时间编程qtime:qt的时间类qtimer:qt的定时类#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget* parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); connect( & timer, SIGNAL(timeout()), this, SLOT(timeout_Slot())); time.setHMS(0, 0, 0, 0); ui->showTime->setText(time.toString("hh:mm:ss:zzz")); } Widget::~Widget() { delete ui; } void Widget::timeout_Slot() { //qDebug() << "timeout_Slot"; time = time.addMSecs(30); ui->showTime->setText(time.toString("hh:mm:ss:zzz")); } void Widget::on_starBt_clicked() { //timer.setSingleShot(true);//只计时一次 timer.start(30); } void Widget::on_closBt_clicked() { timer.stop(); } void Widget::on_resetBt_clicked() { timer.stop(); time.setHMS(0, 0, 0, 0); ui->showTime->setText(time.toString("hh:mm:ss:zzz")); } static int i = 0; void Widget::on_bitBt_clicked() { QString temp; i = i + 1; temp.sprintf("%d--->", i); ui->bitTime->append(temp); ui->bitTime->append(time.toString("hh:mm:ss:zzz")); } void Widget::on_clearBt_clicked() { ui->bitTime->clear(); i = 0; }
2026年02月02日
1 阅读
0 评论
0 点赞
2026-01-30
Ubuntu系统——开启与配置SSH服务
安装与启动SSH服务安装OpenSSH ServerUbuntu默认可能未安装SSH服务端,使用以下命令安装:sudo apt update sudo apt install openssh-server启动SSH服务安装完成后,SSH服务通常会自动启动。可通过以下命令检查状态:sudo systemctl status ssh如果未运行,手动启动服务并设置开机自启:sudo systemctl start ssh sudo systemctl enable ssh防火墙配置如果系统启用了防火墙(ufw),需允许SSH端口(默认22):sudo ufw allow ssh # 或指定端口号:sudo ufw allow 22/tcp sudo ufw enable # 启用防火墙(如果未启用) sudo ufw status # 确认规则生效测试SSH连接ssh <username>@<ip-address>示例ssh user@192.168.1.100高级安全配置修改SSH配置文件(/etc/ssh/sshd_config)以增强安全性:sudo nano /etc/ssh/sshd_config常见配置选项:配置项说明示例值Port修改默认端口2222PermitRootLogin禁用root登录noPasswordAuthentication禁用密码登录no修改后重启服务生效:sudo systemctl restart ssh故障排查检查服务状态:sudo systemctl status ssh查看SSH日志:journalctl -u ssh确认端口监听:ss -tuln | grep 22 # 或替换为自定义端口
2026年01月30日
3 阅读
0 评论
0 点赞
2026-01-30
Code管理工具——Git
Git 常用命令仓库# 在当前目录新建一个Git代码库 $ git init # 新建一个目录,将其初始化为Git代码库 $ git init [project-name] # 下载一个项目和它的整个代码历史 $ git clone [url]配置# 显示当前的Git配置 $ git config --list # 编辑Git配置文件 $ git config -e [--global] # 设置提交代码时的用户信息 $ git config [--global] user.name "[name]" $ git config [--global] user.email "[email address]"增加/删除文件# 添加指定文件到暂存区 $ git add [file1] [file2] ... # 添加指定目录到暂存区,包括子目录 $ git add [dir] # 添加当前目录的所有文件到暂存区 $ git add . # 添加每个变化前,都会要求确认 # 对于同一个文件的多处变化,可以实现分次提交 $ git add -p # 删除工作区文件,并且将这次删除放入暂存区 $ git rm [file1] [file2] ... # 停止追踪指定文件,但该文件会保留在工作区 $ git rm --cached [file] # 改名文件,并且将这个改名放入暂存区 $ git mv [file-original] [file-renamed]代码提交# 提交暂存区到仓库区 $ git commit -m [message] # 提交暂存区的指定文件到仓库区 $ git commit [file1] [file2] ... -m [message] # 提交工作区自上次commit之后的变化,直接到仓库区 $ git commit -a # 提交时显示所有diff信息 $ git commit -v # 使用一次新的commit,替代上一次提交 # 如果代码没有任何新变化,则用来改写上一次commit的提交信息 $ git commit --amend -m [message] # 重做上一次commit,并包括指定文件的新变化 $ git commit --amend [file1] [file2] ...分支# 列出所有本地分支 $ git branch # 列出所有远程分支 $ git branch -r # 列出所有本地分支和远程分支 $ git branch -a # 新建一个分支,但依然停留在当前分支 $ git branch [branch-name] # 新建一个分支,并切换到该分支 $ git checkout -b [branch] # 新建一个分支,指向指定commit $ git branch [branch] [commit] # 新建一个分支,与指定的远程分支建立追踪关系 $ git branch --track [branch] [remote-branch] # 切换到指定分支,并更新工作区 $ git checkout [branch-name] # 切换到上一个分支 $ git checkout - # 建立追踪关系,在现有分支与指定的远程分支之间 $ git branch --set-upstream [branch] [remote-branch] # 合并指定分支到当前分支 $ git merge [branch] # 选择一个commit,合并进当前分支 $ git cherry-pick [commit] # 删除分支 $ git branch -d [branch-name] # 删除远程分支 $ git push origin --delete [branch-name] $ git branch -dr [remote/branch]标签# 列出所有tag $ git tag # 新建一个tag在当前commit $ git tag [tag] # 新建一个tag在指定commit $ git tag [tag] [commit] # 删除本地tag $ git tag -d [tag] # 删除远程tag $ git push origin :refs/tags/[tagName] # 查看tag信息 $ git show [tag] # 提交指定tag $ git push [remote] [tag] # 提交所有tag $ git push [remote] --tags # 新建一个分支,指向某个tag $ git checkout -b [branch] [tag]查看信息# 显示有变更的文件 $ git status # 显示当前分支的版本历史 $ git log # 显示commit历史,以及每次commit发生变更的文件 $ git log --stat # 搜索提交历史,根据关键词 $ git log -S [keyword] # 显示某个commit之后的所有变动,每个commit占据一行 $ git log [tag] HEAD --pretty=format:%s # 显示某个commit之后的所有变动,其"提交说明"必须符合搜索条件 $ git log [tag] HEAD --grep feature # 显示某个文件的版本历史,包括文件改名 $ git log --follow [file] $ git whatchanged [file] # 显示指定文件相关的每一次diff $ git log -p [file] # 显示过去5次提交 $ git log -5 --pretty --oneline # 显示所有提交过的用户,按提交次数排序 $ git shortlog -sn # 显示指定文件是什么人在什么时间修改过 $ git blame [file] # 显示暂存区和工作区的差异 $ git diff # 显示暂存区和上一个commit的差异 $ git diff --cached [file] # 显示工作区与当前分支最新commit之间的差异 $ git diff HEAD # 显示两次提交之间的差异 $ git diff [first-branch]...[second-branch] # 显示今天你写了多少行代码 $ git diff --shortstat "@{0 day ago}" # 显示某次提交的元数据和内容变化 $ git show [commit] # 显示某次提交发生变化的文件 $ git show --name-only [commit] # 显示某次提交时,某个文件的内容 $ git show [commit]:[filename] # 显示当前分支的最近几次提交 $ git reflog远程同步# 下载远程仓库的所有变动 $ git fetch [remote] # 显示所有远程仓库 $ git remote -v # 显示某个远程仓库的信息 $ git remote show [remote] # 增加一个新的远程仓库,并命名 $ git remote add [shortname] [url] # 取回远程仓库的变化,并与本地分支合并 $ git pull [remote] [branch] # 上传本地指定分支到远程仓库 $ git push [remote] [branch] # 强行推送当前分支到远程仓库,即使有冲突 $ git push [remote] --force # 推送所有分支到远程仓库 $ git push [remote] --all撤销# 恢复暂存区的指定文件到工作区 $ git checkout [file] # 恢复某个commit的指定文件到暂存区和工作区 $ git checkout [commit] [file] # 恢复暂存区的所有文件到工作区 $ git checkout . # 重置暂存区的指定文件,与上一次commit保持一致,但工作区不变 $ git reset [file] # 重置暂存区与工作区,与上一次commit保持一致 $ git reset --hard # 重置当前分支的指针为指定commit,同时重置暂存区,但工作区不变 $ git reset [commit] # 重置当前分支的HEAD为指定commit,同时重置暂存区和工作区,与指定commit一致 $ git reset --hard [commit] # 重置当前HEAD为指定commit,但保持暂存区和工作区不变 $ git reset --keep [commit] # 新建一个commit,用来撤销指定commit # 后者的所有变化都将被前者抵消,并且应用到当前分支 $ git revert [commit] 暂时将未提交的变化移除,稍后再移入 $ git stash $ git stash pop# 恢复暂存区的指定文件到工作区 $ git checkout [file] # 恢复某个commit的指定文件到暂存区和工作区 $ git checkout [commit] [file] # 恢复暂存区的所有文件到工作区 $ git checkout . # 重置暂存区的指定文件,与上一次commit保持一致,但工作区不变 $ git reset [file] # 重置暂存区与工作区,与上一次commit保持一致 $ git reset --hard # 重置当前分支的指针为指定commit,同时重置暂存区,但工作区不变 $ git reset [commit] # 重置当前分支的HEAD为指定commit,同时重置暂存区和工作区,与指定commit一致 $ git reset --hard [commit] # 重置当前HEAD为指定commit,但保持暂存区和工作区不变 $ git reset --keep [commit] # 新建一个commit,用来撤销指定commit # 后者的所有变化都将被前者抵消,并且应用到当前分支 $ git revert [commit] 暂时将未提交的变化移除,稍后再移入 $ git stash $ git stash pop其他# 生成一个可供发布的压缩包 $ git archive
2026年01月30日
3 阅读
0 评论
0 点赞
2026-01-20
Ubuntu系统——虚拟机ubuntu22.04没有网
一 概况今天登录虚拟ubuntu22.04发现不能上网,昨天还能上网,在此记录一下解决方案。二 原因分析个人怀疑是虚拟机不稳定导致网络启动失败查看网络状态[main] sudo cat /var/lib/NetworkManager/NetworkManager.state结果如下[main] NetworkingEnabled=false WirelessEnabled=true WWANEnabled=trueNetworkManager是一个服务,管理网络相关的,NetworkManager.state是网络状态,因为虚拟机不稳定,开机启动时候,启动网络不成功,所以记录了这个状态。三解决方案1.先停止网络管理服务2.删除网络状态文件3.重启网络服务sudo service NetworkManager stop sudo rm /var/lib/NetworkManager/NetworkManager.state sudo service NetworkManager start
2026年01月20日
3 阅读
0 评论
0 点赞