当前位置:网站首页>QT5.14 realizes simple user login system
QT5.14 realizes simple user login system
2022-08-06 06:31:00 【MStudioStudio】
使用linux sqlite3 Realize remote server login system
说明:
使用qt的network的TCP/IP 网络通信API
与 linux下简单的sqlite3 Database for data transfer,实现登录系统
实现原理为:
1.linux服务器:
If you use a cloud server, please see this description:The difference between using a cloud server is the connectionip不同而已,This code has been verified in Alibaba CloudUbuntu16.04 ECSVerification is possible under the server,So as to realize simple remote registration and login,If using cloud server,And add the corresponding port inbound and outbound rules in the security group policy,For detailed operation, please Baidu
**为实现TCP/IP数据传输,请参考如下cThe language-defined packets for data exchange and all header files used,Which is creating or opening a databasedb文件时,将会使用sql查询语句查询admin是否存在,Otherwise a user is inserted:admin, 密码为:123456,And use an auto-incrementing primary key,开始的位置为10000. **
#include <stdlib.h>
#include <stdio.h>
#include <sqlite3.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define portnumber 6666 //the defined port
typedef struct socket_head
{
int fun; //功能码 1 登陆 2 注册
}HEAD_T;
typedef struct socket_login
{
char username[32];
char userpwd[32];
}LOGIN_T;
typedef struct loginret //应答包
{
int flag;// 0 fail 1 success
char loginuser[32];
}LOGINRET_T;
The server main function is shown in the following code
int main(int argc, char *argv[])
{
sqlite3 *db;
char *errmsg=NULL; //用来存储错误信息字符串
char ret=0;
char **dbResult;
int nRow=0, nColumn=0; //nRow 查找出的总行数,nColumn 存储列
int rc;
int temp_flag=0;
char sql[128];
int sockfd,new_fd;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
int sin_size;
int nbytes;
char buffer[1024];
char Backdata[1024];
char *ptr;
HEAD_T reverse_head;
LOGIN_T reverse_login;
LOGINRET_T reverse_data;
ptr =(char*)malloc(sizeof(char));
memset(ptr,0,sizeof(char));
memset(sql,0,sizeof(char));
rc = sqlite3_open("linuxdb.db",&db); //打开数据库,如果不存在,创造数据库db
if(rc!=SQLITE_OK)
{
sqlite3_close(db);
fprintf(stderr,"can't open database:%s\n",sqlite3_errmsg(db));
exit(0);
return 0;
}
else
{
printf("creat db success\n");
}
ret=sqlite3_get_table(db,"create table if not exists user ( ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME VARCHAR(32) , PASSWORD VARCHAR(32) );",&dbResult,&nRow,&nColumn,&errmsg);
if(NULL!=errmsg)
{
printf("create fail -- user table\n");
sqlite3_free_table(dbResult);
errmsg=NULL;
return -1;
}
else
{
printf("creat user table success\n");
}
nRow=0;
nColumn=0;
errmsg=NULL;
ret=sqlite3_get_table(db,"select * from user where NAME = 'admin'; ",&dbResult,&nRow,&nColumn,&errmsg);
if(NULL!=errmsg)
{
sqlite3_free_table(dbResult);
errmsg=NULL;
}
printf("nRow=%d",nRow);
if(nRow==0)
{
nRow=0;
nColumn=0;
errmsg=NULL;
printf("admin is not exsit\n");
ret=sqlite3_get_table(db,"insert into user values(10000,'admin','123456');",&dbResult,&nRow,&nColumn,&errmsg);
if(NULL!=errmsg)
{
printf("insert admin error\n");
sqlite3_free_table(dbResult);
errmsg=NULL;
}
}
/* 服务器端开始建立sockfd描述符 */
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) // AF_INET:IPV4; SOCK_STREAM:TCP
{
fprintf(stderr,"Socket error:%s\n\a",strerror(errno));
exit(1);
}
//设置Socket属性:SO_REUSEADDR:允许在bindLocal addresses are reused during the process
int iSockopt = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
(const char *)&iSockopt, sizeof(int)) < 0 )
{
close(sockfd);
return -1;
}
/* 服务器端填充 sockaddr结构 */
bzero(&server_addr,sizeof(struct sockaddr_in)); // 初始化,置0
server_addr.sin_family=AF_INET; // Internet
server_addr.sin_addr.s_addr=INADDR_ANY; //INADDR_ANY Indicates that any can be receivedIP地址的数据,i.e. bound to allIP
//Used to bind to a fixedIP,inet_addrUsed to format numbersip转化为整形ip
server_addr.sin_port=htons(portnumber); // (将本机器上的short数据转化为网络上的short数据)端口号
/* 捆绑sockfd描述符到IP地址 */
if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)
{
fprintf(stderr,"Bind error:%s\n\a",strerror(errno));
exit(1);
}
/* 设置允许连接的最大客户端数 */
if(listen(sockfd,5)==-1)
{
fprintf(stderr,"Listen error:%s\n\a",strerror(errno));
exit(1);
}
while(1)
{
/* 服务器阻塞,直到客户程序建立连接 */
sin_size=sizeof(struct sockaddr_in);
if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==-1)
{
fprintf(stderr,"Accept error:%s\n\a",strerror(errno));
exit(1);
}
fprintf(stderr,"Server get connection from %s\n",inet_ntoa(client_addr.sin_addr)); // 将网络地址转换成.字符串
memset(buffer,0,sizeof(buffer));
memset(reverse_login.username,0,sizeof(reverse_login.username));
memset(reverse_login.userpwd,0,sizeof(reverse_login.userpwd));//给reverse_login进行清空操作
memset(Backdata,0,sizeof(Backdata));
memset(reverse_data.loginuser,0,sizeof(reverse_data.loginuser));
reverse_data.flag=0;
nbytes=0;
if((nbytes=read(new_fd,buffer,1024))==-1)
{
recv( new_fd, buffer, 1024, 0 );
fprintf(stderr,"Read Error:%s\n",strerror(errno));
exit(1);
}
buffer[ nbytes]='\0';
ptr=buffer;
printf("nbytes= %d buffer=%d\n",nbytes,sizeof(buffer));
printf("Server received %s\n",buffer); //这个通讯已经结束
memcpy(&reverse_head, ptr, sizeof(HEAD_T));
printf("head=%d\n ",reverse_head.fun);
switch(reverse_head.fun)
{
case 0:
{
printf("connect\n");
memcpy(Backdata,&reverse_head,sizeof(HEAD_T));
write(new_fd,Backdata,sizeof(Backdata));
break;
}
case 1:
{
printf("login\n");
memcpy(&reverse_login, ptr+ sizeof(HEAD_T), sizeof(LOGIN_T));
printf("name=%s pwd=%s\n ",reverse_login.username,reverse_login.userpwd);
nRow=0;
nColumn=0;
errmsg=NULL;
sprintf(sql,"select * from user where name='%s' and password='%s';",reverse_login.username,reverse_login.userpwd);
printf("%s\n",sql);
rc=sqlite3_get_table(db,sql,&dbResult,&nRow,&nColumn,&errmsg);
printf("nRow=%d nColumn=%d\n",nRow,nColumn);
if(rc==SQLITE_OK)
{
if(nRow==1)
{
printf("login success\n");
}
else if(nRow==0)
{
printf("no account\n");
}
else if(nRow>1)
{
printf("many account\n");
}
}
reverse_data.flag=nRow;
strcpy(reverse_data.loginuser,reverse_login.username);
memcpy(Backdata,&reverse_head,sizeof(HEAD_T));
memcpy(Backdata+sizeof(HEAD_T),&reverse_data,sizeof(LOGINRET_T));
write(new_fd,Backdata,sizeof(Backdata));
break;
}
case 2:
{
printf("register\n");
errmsg=NULL;
memcpy(&reverse_login, ptr+ sizeof(HEAD_T), sizeof(LOGIN_T));
printf("name=%s pwd=%s\n ",reverse_login.username,reverse_login.userpwd);
memset(sql,0,sizeof(sql));
sprintf(sql,"select * from user where name='%s';",reverse_login.username);
printf("%s\n",sql);
rc=sqlite3_get_table(db,sql,&dbResult,&nRow,&nColumn,&errmsg);
printf("nRow=%d nColumn=%d\n",nRow,nColumn);
if(rc==SQLITE_OK)
{
if(nRow>=1)
{
printf("error! account is exist\n");
temp_flag=1;
}
else if(nRow==0)
{
printf("search success!\n");
memset(sql,0,sizeof(sql));
sprintf(sql,"INSERT INTO user (NAME,PASSWORD) VALUES('%s','%s');",reverse_login.username,reverse_login.userpwd);
printf("%s\n",sql);
rc=sqlite3_get_table(db,sql,&dbResult,&nRow,&nColumn,&errmsg);
if(rc==SQLITE_OK)
{
printf("register success");
}
temp_flag=2;
}
else
{
printf("unknown error\n");
temp_flag=3;
}
}
reverse_data.flag=temp_flag;
strcpy(reverse_data.loginuser,reverse_login.username);
memcpy(Backdata,&reverse_head,sizeof(HEAD_T));
memcpy(Backdata+sizeof(HEAD_T),&reverse_data,sizeof(LOGINRET_T));
write(new_fd,Backdata,sizeof(Backdata));
temp_flag=0;
break;
}
}
ptr =NULL;
close(new_fd); /* 循环下一个 */
} /* 结束通讯 */
sqlite3_close(db);
close(sockfd);
exit(0);
}
2.qt5.14 The created login registration client:
.proThe following statement needs to be added to the fileTCP/IP
QT += network
主函数为
#include "widget.h"
#include "myconnect.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
myconnect w;
w.show();
return a.exec();
}
Use the simple singleton pattern,放在allwidgetpoint中
其中allwidgetpoint.h为
#ifndef ALLWIDGETPOINT_H
#define ALLWIDGETPOINT_H
class allwidgetpoint
{
public:
static QWidget *ptcp;
static QWidget *plogin;
static QWidget *pregister;
static QString ip;
static QString port;
};
#endif // ALLWIDGETPOINT_H
其中allwidgetpoint.cpp为,It mainly performs the initialization operation of the singleton
QWidget* allwidgetpoint::ptcp=NULL;
QWidget* allwidgetpoint::plogin=NULL;
QWidget* allwidgetpoint::pregister=NULL;
QString allwidgetpoint::ip="";
QString allwidgetpoint::port="";
在socket.hPut simply the definition of the packet format with the server
#ifndef SOCKET_H
#define SOCKET_H
typedef struct socket_head
{
int fun; //功能码 0连接检测 1 登陆 2 注册
}HEAD_T;
typedef struct socket_login
{
char username[32];
char userpwd[32];
}LOGIN_T;
typedef struct socket_register
{
char username[32];
char userpwd[32];
}REGISTER_T;
typedef struct loginret //应答包
{
int flag;// 0 fail 1 success
char loginuser[32];
}LOGINRET_T;
#endif // SOCKET_H
在connectThe effect achieved in 
在点击connectbutton and after receiving the data packet from the database
It will be shown as below
在connect.h中建立一个新的QWidgetfor port connection
class myconnect : public QWidget
{
Q_OBJECT
public:
myconnect(QWidget *parent = nullptr);
~myconnect();
char Date[128];
public slots:
void Button_connect_click();
void ReadBuffer();
private:
Mylogin *mylogin;
QLabel *Label_ip;
QLabel *Label_port;
QLineEdit *Edit_ip;
QLineEdit *Edit_port;
QTcpSocket *tcpclient;
QPushButton *Button_connect;
};
在connect.cpp中为
myconnect::myconnect(QWidget *parent)
{
allwidgetpoint::ptcp=this;
this->setFixedSize(500,300);
QDesktopWidget *deskdop = QApplication::desktop();
move((deskdop->width() - this->width())/2, (deskdop->height() - this->height())/2);
mylogin =new Mylogin();
tcpclient=new QTcpSocket();
this->Label_ip =new QLabel("Ip",this,0x00000000);
this->Label_ip->setGeometry(QRect(150,80,30,20));
this->Label_port =new QLabel("Port",this,0x00000000);
this->Label_port->setGeometry(QRect(150,110,30,20));
this->Edit_ip=new QLineEdit("192.168.1.109",this);
this->Edit_ip->setGeometry(QRect(190,80,150,20));
allwidgetpoint::ip="192.168.1.109";
this->Edit_port=new QLineEdit("6666",this);
this->Edit_port->setGeometry(QRect(190,110,150,20));
allwidgetpoint::port="6666";
this->Button_connect= new QPushButton("Connect",this);
this->Button_connect->setGeometry(QRect(230,170,50,20));
connect(Button_connect,SIGNAL(clicked(bool)),this,SLOT(Button_connect_click()));
connect(this->tcpclient,SIGNAL(readyRead()),this,SLOT(ReadBuffer()));
}
myconnect::~myconnect()
{
}
void myconnect::Button_connect_click()
{
allwidgetpoint::ip=this->Edit_ip->text();
allwidgetpoint::port=this->Edit_port->text();
qDebug()<<"ip="<<allwidgetpoint::ip<<"port="<<allwidgetpoint::port;
HEAD_T *connect_head = (HEAD_T*)malloc(sizeof(HEAD_T));
memset(connect_head,0,sizeof(HEAD_T));
connect_head->fun=0;
tcpclient->connectToHost(allwidgetpoint::ip,allwidgetpoint::port.toInt());
memcpy(Date,connect_head,sizeof(HEAD_T));
tcpclient->write(Date,sizeof(Date));
}
void myconnect::ReadBuffer()
{
HEAD_T head;
qDebug()<<"read connect";
QByteArray arry = tcpclient->readAll();
memcpy(&head,arry.data(),sizeof(HEAD_T));
qDebug()<<head.fun;
if(head.fun==0)
{
QMessageBox::information(NULL, "Tips", "已连接!");
qDebug()<<"ready OK";
this->hide();
allwidgetpoint::plogin->show();
}
}
Next is the login screen,Its effect is
在login.hThe login class is
class Mylogin: public QWidget
{
Q_OBJECT
public:
Mylogin(QWidget *parent = nullptr);
~Mylogin();
bool checklogin(QString name,QString password);
char Date[128];
public slots:
void Button_register_click();
void Button_login_click();
void ReadBuffer();
private:
QLabel *Label_name;
QLabel *Label_pwd;
QLineEdit *Edit_name;
QLineEdit *Edit_pwd;
myregister *login_register;
QTcpSocket *tcpclient;
QPushButton *Button_login;
QPushButton *Button_register;
QTimer* time;
// QSqlDatabase database;
};
login.cpp代码
Mylogin::Mylogin(QWidget *parent)
: QWidget(parent)
{
allwidgetpoint::plogin=this;
login_register=new myregister();
this->setFixedSize(500,300);
QDesktopWidget *deskdop = QApplication::desktop();
move((deskdop->width() - this->width())/2, (deskdop->height() - this->height())/2);
tcpclient=new QTcpSocket();
this->Label_name =new QLabel("帐号",this,0x00000000);
this->Label_name->setGeometry(QRect(150,80,30,20));
this->Label_pwd =new QLabel("密码",this,0x00000000);
this->Label_pwd->setGeometry(QRect(150,110,30,20));
this->Edit_name=new QLineEdit("",this);
this->Edit_name->setGeometry(QRect(190,80,150,20));
this->Edit_pwd=new QLineEdit("",this);
this->Edit_pwd->setGeometry(QRect(190,110,150,20));
this->Edit_pwd->setEchoMode(QLineEdit::Password);
this->Button_login= new QPushButton("登陆",this);
this->Button_login->setGeometry(QRect(170,170,50,20));
this->Button_register= new QPushButton("注册",this);
this->Button_register->setGeometry(QRect(280,170,50,20));
this->time = new QTimer;
connect(this->tcpclient,SIGNAL(readyRead()),this,SLOT(ReadBuffer()));
connect(((Button_register)),SIGNAL(clicked(bool)),this,SLOT(Button_register_click()));
connect(((Button_login)),SIGNAL(clicked(bool)),this,SLOT(Button_login_click()));
}
Mylogin::~Mylogin()
{
}
bool Mylogin::checklogin(QString name, QString password)
{
QSqlQuery SqlQuery;
QString login_check =QString("select * from user where NAME = '%1' and PASSWORD = '%2'").arg(name).arg(password);
if(!SqlQuery.exec(login_check))//==!QSqlQuery.exec(create_sql)
{
return false;
}
else
{
QString show_name ;
QString show_pwd ;
while(SqlQuery.next())
{
show_name = SqlQuery.value(1).toString();
show_pwd = SqlQuery.value(2).toString();
}
if(show_name==NULL || show_pwd==NULL)
return false;
}
return true;
}
void Mylogin::Button_register_click()
{
qDebug() <<"进入注册";
allwidgetpoint::pregister->show();
this->hide();
}
void Mylogin::Button_login_click()
{
QByteArray ba1 = Edit_name->text().toLatin1();
QByteArray ba2 = Edit_pwd->text().toLatin1();
HEAD_T *user_head = (HEAD_T*)malloc(sizeof(HEAD_T));
memset(user_head,0,sizeof(HEAD_T));
user_head->fun=1;
LOGIN_T *user = (LOGIN_T*)malloc(sizeof(LOGIN_T));
memset(user,0,sizeof(LOGIN_T));
strcpy(user->username,ba1.data());
strcpy(user->userpwd,ba2.data());
memcpy(Date,user_head,sizeof(HEAD_T));
memcpy(Date+sizeof(HEAD_T),user,sizeof(LOGIN_T));
tcpclient->connectToHost(allwidgetpoint::ip,allwidgetpoint::port.toInt());
tcpclient->write(Date,sizeof(Date));
}
void Mylogin::ReadBuffer()
{
HEAD_T head;
LOGINRET_T recevdata ;
qDebug()<<"in";
QByteArray arry = tcpclient->readAll();
memcpy(&head,arry.data(),sizeof(HEAD_T));
memcpy(&recevdata,arry.data()+sizeof(HEAD_T),sizeof(LOGINRET_T));
qDebug()<<head.fun<<recevdata.flag<<recevdata.loginuser;
if(recevdata.flag == 1)
//if((name_check,pwd_check))
{
this->Edit_name->clear();
this->Edit_pwd->clear();
QMessageBox::information(NULL, "Tips", "登陆成功");
}
else
{
this->Edit_pwd->clear();
QMessageBox::information(NULL, "Tips", "账户名/密码错误/账户不存在");
}
}
The registration system is shown in the figure below

register.h中为
class myregister:public QWidget
{
Q_OBJECT
public:
myregister(QWidget *parent = nullptr);
~myregister();
char Date[128];
public slots:
void back_login();
void btn_yes_click();
void ReadBuffer();
private:
QLabel *Label_name;
QLabel *Label_pwd;
QLabel *Label_confirm;
QLineEdit *Edit_name;
QLineEdit *Edit_pwd;
QLineEdit *Edit_confirm;
QPushButton *Button_yes;
QPushButton *Button_back;
QTcpSocket *tcpclient;
// QSqlDatabase database;
};
register.cpp中为
myregister::myregister(QWidget *parent)
: QWidget(parent)
{
allwidgetpoint::pregister=this;
tcpclient=new QTcpSocket();
this->setFixedSize(500,300);
QDesktopWidget *deskdop = QApplication::desktop();
move((deskdop->width() - this->width())/2, (deskdop->height() - this->height())/2);
this->Label_name =new QLabel("帐号",this,0x00000000);
this->Label_name->setGeometry(QRect(150,80,30,20));
this->Label_pwd =new QLabel("密码",this,0x00000000);
this->Label_pwd->setGeometry(QRect(150,110,30,20));
this->Label_confirm=new QLabel("密码确认",this,0x00000000);
this->Label_confirm->setGeometry(QRect(124,140,50,20));
this->Edit_name=new QLineEdit("",this);
this->Edit_name->setGeometry(QRect(190,80,150,20));
this->Edit_pwd=new QLineEdit("",this);
this->Edit_pwd->setGeometry(QRect(190,110,150,20));
this->Edit_pwd->setEchoMode(QLineEdit::Password);
this->Edit_confirm=new QLineEdit("",this);
this->Edit_confirm->setGeometry(QRect(190,140,150,20));
this->Edit_confirm->setEchoMode(QLineEdit::Password);
this->Button_yes= new QPushButton("确认",this);
this->Button_yes->setGeometry(QRect(170,170,50,20));
this->Button_back= new QPushButton("返回",this);
this->Button_back->setGeometry(QRect(280,170,50,20));
connect(this->tcpclient,SIGNAL(readyRead()),this,SLOT(ReadBuffer()));
connect(Button_back,SIGNAL(clicked(bool)),this,SLOT(back_login()));
connect(Button_yes,SIGNAL(clicked(bool)),this,SLOT(btn_yes_click()));
}
myregister::~myregister()
{
}
void myregister::back_login()
{
allwidgetpoint::plogin->show();
this->hide();
}
void myregister::btn_yes_click()
{
QString name_check=this->Edit_name->text();
QString pwd_check= this->Edit_pwd->text();
QString confirm_check= this->Edit_confirm->text();
if(pwd_check.compare(confirm_check)!=0)
{
name_check="";
pwd_check="";
confirm_check="";
QMessageBox::information(NULL, "Tips", "密码不一致,注册失败,请重试");
this->Edit_pwd->clear();
this->Edit_confirm->clear();
return ;
}
else
{
QByteArray ba1 = Edit_name->text().toLatin1();
QByteArray ba2 = Edit_pwd->text().toLatin1();
HEAD_T *register_head = (HEAD_T*)malloc(sizeof(HEAD_T));
memset(register_head,0,sizeof(HEAD_T));
register_head->fun=2;
REGISTER_T *myregister = (REGISTER_T*)malloc(sizeof(REGISTER_T));
memset(myregister,0,sizeof(REGISTER_T));
strcpy(myregister->username,ba1.data());
strcpy(myregister->userpwd,ba2.data());
memcpy(Date,register_head,sizeof(HEAD_T));
memcpy(Date+sizeof(HEAD_T),myregister,sizeof(REGISTER_T));
tcpclient->connectToHost(allwidgetpoint::ip,allwidgetpoint::port.toInt());
tcpclient->write(Date,sizeof(Date));
}
}
void myregister::ReadBuffer()
{
HEAD_T head;
LOGINRET_T recevdata ;
qDebug()<<"in";
QByteArray arry = tcpclient->readAll();
memcpy(&head,arry.data(),sizeof(HEAD_T));
memcpy(&recevdata,arry.data()+sizeof(HEAD_T),sizeof(LOGINRET_T));
qDebug()<<head.fun<<recevdata.flag<<recevdata.loginuser;
switch(recevdata.flag)
{
case 0://The server does not enter the judgment
{
QMessageBox::information(NULL, "Tips", "数据库错误 Code:0");
this->Edit_name->clear();
this->Edit_pwd->clear();
this->Edit_confirm->clear();
allwidgetpoint::plogin->show();
this->hide();
break;
}
case 1://The server side shows that the user exists
{
QMessageBox::information(NULL, "Tips", "Account name already exists");
this->Edit_name->clear();
this->Edit_pwd->clear();
this->Edit_confirm->clear();
break;
}
case 2://The server side shows that the registration is successful
{
QMessageBox::information(NULL, "Tips", "注册成功,即将返回");
this->Edit_name->clear();
this->Edit_pwd->clear();
this->Edit_confirm->clear();
allwidgetpoint::plogin->show();
this->hide();
break;
}
case 3://Server side shows unknown error
{
QMessageBox::information(NULL, "Tips", "数据库错误 Code:3");
this->Edit_name->clear();
this->Edit_pwd->clear();
this->Edit_confirm->clear();
allwidgetpoint::plogin->show();
this->hide();
break;
}
}
}
Some improvements can be made here,Such as do some restrictions on the input,如正则表达式 ip Username, etc. are restricted,
So everyone can improve by themselves,The above version is the primary version.
边栏推荐
猜你喜欢

Redis数据库(一)——Redis简介、部署及常用命令

NAACL 2022 | 字节和加州大学提出ConST模型,探讨对比学习如何助力语音翻译?

How to jailbreak the Kindle series 5.12.2.2 ~ 5.14.2 without disassembly?How to install third-party plugins

MacOS下 Qt6编译及链接MySQL

Ununtu20.04安装OSI及相关组件

PointNeXt: 通过改进的训练以及模型缩放策略重新探究PointNet++

Qt+YOLOv4实现目标检测

QT自定义安装包

Sprinig Boot + Redis 实现接口幂等性,写得太好了

C#和DL-EPI通信
随机推荐
Qt+YOLOv4实现目标检测
Talk预告 | 普渡大学王虓:如何利用合作对抗学习来提升自监督学习
How routers work
R语言处理时间序列数据
外连接,exists存在,(DML):用SQL录入数据,用SQL删除数据,用SQL更新数据
R_文字识别(OCR)
C64725铜合金带
十四、一起学习Lua 元表(Metatable)
动态规划之粉刷房子
AMPCOLOY940 美国进口高导热无铍铜合金
十、 一起学习Lua 数组
Distributed, Microservices, Cluster Concepts and Differences
动态规划之乘积最大子数组
(中)苹果有开源,但又怎样呢?
Convolutional Neural Network Notes 2
NAACL 2022 | 字节和加州大学提出ConST模型,探讨对比学习如何助力语音翻译?
7.23 ICML直播 | 浙江大学DCD实验室况琨团队:元学习去混杂、多智能体强化学习、因果推理
Sprinig Boot + Redis 实现接口幂等性,写得太好了
专业技术人员继续教育考试题
PCL1.12+VTK9.1+QT6编译部署