一直想做一个细讲qt的项目,上班摸鱼顺便写写csdn,缓解一下上班焦虑的心情,当然希望大家多多关注,毕竟写文章都是手打,浪费了很多时间。
最喜欢这种上班带薪摸鱼偷偷写代码的感觉。
1、UI设计
qt大家都知道分为qml,以及qtwidget,qml要比qt好看很多,但是大家都知道,一般的登录界面好看的都是贴图,图片好看,那么界面就好看。
为啥不是中文呢,是因为版本不一致吧,我开始用的6版本,现在换成5版本进行编译,出现的乱码问题没有办法解决,只能用英文。
但是程序是可以正常运行的。
2、代码部分
我们都知道数据库一般放在远程的服务器上,现在常用的数据库有redis非关系型数据库,方便存储json的数据格式的数据,而mysql数据库则是存放有关系的数据,最常用于表格。
在我认识了数据库一段时间之后,数据库的通信其实是对网络的封装,一个程序想要和另外一个程序进行通信,就需要通过协议传输二进制流,而相互识别的方式就是ip,也就是连接数据库为什么需要ip以及端口。
而交换数据的方式,使用的数据库命令。
2.1 连接数据库
void sql::init()
{
m_db = QSqlDatabase::addDatabase("QMYSQL");
m_db.setHostName("127.0.0.1");
m_db.setUserName("root");
m_db.setPassword("你的数据库密码");
m_db.setDatabaseName("demo");//建立数据库
if(m_db.open() == true)
{
qDebug()<<" mysql connect success";
QSqlQuery query;
query.exec("CREATE TABLE IF NOT EXISTS users ("
"users_id INT NOT NULL,"
"id VARCHAR(7) NOT NULL,"
"username VARCHAR(50) NOT NULL,"
"password VARCHAR(50) NOT NULL,"
"is_admin BOOL NOT NULL DEFAULT 0,"
"PRIMARY KEY (users_id))");
query.exec("CREATE TABLE IF NOT EXISTS student ("
"student_id INT NOT NULL,"
"id VARCHAR(7) NOT NULL,"
"username VARCHAR(20),"
"enrollment_time DATE,"
"gender VARCHAR(10),"
"age INT,"
"ethnic VARCHAR(20),"
"PRIMARY KEY (student_id))");
query.exec("CREATE TABLE IF NOT EXISTS score ("
"student_id INT NOT NULL,"
"id VARCHAR(7) NOT NULL,"
"username VARCHAR(50) NOT NULL,"
"course VARCHAR(20) NOT NULL,"
"course_time DATE,"
"PRIMARY KEY (student_id, course))");
}
else if (m_db.open() == false)
{
qDebug()<<"no dataabse drivers found";
return;
}
}
在这里我们连接了数据库并创建了三张表。
2.2 登录界面
在登录界面widget中,你可以直接在设计器中拖动,也可以直接写代码,我展示的这种方式是直接写代码。
// 创建背景图片标签
QLabel *backgroundLabel = new QLabel(this);
backgroundLabel ->setFixedSize(350, 600);
QPixmap backgroundPixmap(":\\pic\\background2.jpg");//相对路径
backgroundLabel->setPixmap(backgroundPixmap.scaled(size()));
m_useridLabel = new QLabel(this); //用户名标签
m_useridLabel->setObjectName("m_useridLabel");
m_useridLabel->setText("users:");
m_passwordLabel = new QLabel(this); //密码标签
m_passwordLabel->setObjectName("m_passwordLabel");
m_passwordLabel->setText("password:");
m_useridLineEdit = new QLineEdit(); //用户名
m_passwordLineEdit = new QLineEdit(); //密码
m_passwordLineEdit->setEchoMode(QLineEdit::Password); //设置密文
m_loginButton = new QPushButton("login");
QHBoxLayout *useridLayout = new QHBoxLayout();//水平布局
useridLayout->addWidget(m_useridLabel);
useridLayout->addWidget(m_useridLineEdit);
QHBoxLayout *passwordLayout = new QHBoxLayout();//水平布局
passwordLayout->addWidget(m_passwordLabel);
passwordLayout->addWidget(m_passwordLineEdit);
QVBoxLayout *loginLayout = new QVBoxLayout(); //垂直布局
loginLayout->addLayout(useridLayout); //将用户名水平布局添加到垂直布局中
loginLayout->addLayout(passwordLayout); //将密码的水平布局添加到垂直布局中
loginLayout->addWidget(m_loginButton); //将登录添加到垂直布局中
setLayout(loginLayout);
// useridLayout->setSpacing(20); // 设置间隔距离为 20px
setWindowTitle(tr("Login"));
2.3 实现登录验证的逻辑
登录界面有个按钮,点击按钮实现登录,同时与数据库中的用户名和密码作比对。
使用qt的信号与槽,则可以实现登录逻辑。
connect(m_loginButton, SIGNAL(clicked()), this, SLOT(LoginButtonClicked()));
槽函数的实现。
你需要new一个第二个界面,用于跳转,然后从lineedit获取用户输入的用户名和密码,然后判断这个用户名以及密码是不是与数据库中的用户名以及密码保持一致,如果一致则登录成功,如果不一致则登录失败。
void Widget::LoginButtonClicked()
{
nextwidget= new wight1(); // 创建第二个界面
QString userid = m_useridLineEdit->text();
QString password = m_passwordLineEdit->text();
QSqlQuery query;
query.prepare("SELECT * FROM users WHERE id = :userid AND password = :password");//查询表中的用户名和密码
query.bindValue(":userid", userid);//将用户名与表中进行绑定
query.bindValue(":password", password); //将密码与表中进行绑定
query.exec();
if (query.next()) {
is_admin = query.value(4).toBool();
if (is_admin) {
QMessageBox::information(this, tr("Login"), tr("管理员用户登录成功."));
if (nextwidget->Item1 != nullptr) {
nextwidget->Item1->setHidden(false);//显示第三个节点
// 遍历Item3的所有子节点,并设置它们为显示状态
// QList<QTreeWidgetItem*> children =nextwidget-> Item3->takeChildren();
/*for (auto child : children) {
nextwidget->Item3.child->setHidden(false);
}*/
}
} else {
QMessageBox::information(this, tr("Login"), tr("普通用户登录成功."));
if (nextwidget->Item1!= nullptr) {
nextwidget->Item1->setHidden(true);//影藏第三个子节点
// 遍历Item3的所有子节点,并设置它们为隐藏状态
/* QList<QTreeWidgetItem*> children =nextwidget-> Item3->takeChildren();
for (auto child : children) {
child->setHidden(true);
}
}*/
QPushButton *button2 =nextwidget->findChild<QPushButton*>("pushButton_7");
if (button2 != nullptr) {
// button1 ->setText("New Text"); // 修改按钮的文本
//button1 ->setEnabled(false); // 禁用按钮
button2->hide();
}
}
}
nextwidget ->show(); // 显示第二个界面
this->hide(); // 隐藏当前界面
}
else {
QMessageBox::warning(this, tr("Login"), tr("用户名和密码错误."));
}
}