C++实现图书管理系统(Qt C++ GUI界面版)

前瞻
本项目基于【C++】图书管理系统(完整版)

图书管理系统功能概览:

  1. 登录,注册
  2. 学生,老师借书,查看自己当前借书情况,还书。
  3. 管理员增加书,查看当前借阅情况,查看当前所有借阅人,图书信息。

效果概览:
登录:输入用户名和密码,选择对应角色(管理员、学生、老师),点击登录,对应信息存储在txt文件中,程序会自动校验是否输入的用户名和密码存在并对应
在这里插入图片描述
在这里插入图片描述

注册:当用户点击注册时,将跳转到注册页面,程序会将用户信息存入txt文件中,注册成功后,会自动跳转到登录界面,用户也可以通过点击登录按钮跳转回登录界面
在这里插入图片描述
用户界面(学生或老师):当用户登录成功后,进入操作界面,包括功能如下:
借书:
在这里插入图片描述
查看自己借阅情况
在这里插入图片描述
还书:
在这里插入图片描述
管理员界面: 包括功能如下:
增加书:
在这里插入图片描述
查看当前借阅情况:
在这里插入图片描述
查看所有图书:
在这里插入图片描述
查看借阅人详细信息:
在这里插入图片描述
目前该系统大致功能如上。

代码概览:

各个模块主要负责功能
主要用于数据处理、存储部分,类似后端
 CBook.h  用于对书抽象,并实现了>>的重载,便于文件读入,读出
 CUser.h  工具人,作为老师,学生的父类
 CStudent.h  对学生进行的抽象
 CTeacher.h 对老师进行的抽象
 CAdministrator.h 对管理的抽象
 CManagementBooks.h  用户所有的相关操作的中间执行者,有设计模式中代理的思想
 QtLibrarySystem.cpp  界面的的实现与系统入口
 主要用于数据暂时,处理用户输入,类似前端
 RegistrationPage.h 注册界面实现类
 UserPage.h用户界面实现类
 LoginPage.h登录界面实现类
 AdminPage.h管理员界面实现类

说明:获取方式见文章最后,点击查看,还有就是文件读入建议大家都直接放在相应项目里面,不然就写绝对路径。有问题欢迎大家在评论区提问,喜欢就点个赞咯!


全部代码与讲解:

CUser.cpp

#include "CUser.h"
#include<iostream>
#include<fstream>
using namespace std;




CUser::CUser()
{
    m_name = "陈1";
}

void CUser::setId(string id)
{
    m_id = id;
}

void CUser::setName(string name)
{
    m_name = name;
}

void CUser::setGender(string gender)
{
    m_gender = gender;
}



void CUser::setDepartment(string department)
{
    m_department = department;
}

void CUser::setPhone(string phone)
{
    m_phone = phone;
}




CUser::~CUser()
{
}

string CUser::returnBook(CManagementBooks& mb,string bookName)
{
    int all = mb.checkBorrowedBook(m_id);
    if (all == 0)
    {
        return  "您暂未借书,无需归还";
    }
    else
    {
        if (mb.checkTrueBorrow(m_id, bookName))
        {
            mb.Return(m_id, bookName);
            return "";
        }
        else
        {
            return "您并未借阅此书";
        }
    }
    return "";
}

string CUser::getId()
{
    return m_id;
}

string CUser::getName()
{
    return m_name;
}

string CUser::getGender()
{
    return m_gender;
}


string CUser::getDepartment()
{
    return m_department;
}

string CUser::getPhone()
{
    return m_phone;
}

std::ostream& operator<<(std::ostream& os, const CUser* user)
{
    os << endl << user->m_id << " " << user->m_name << " " << user->m_gender << " " << user->m_department << " " << user->m_phone;
    return os;
}

std::istream& operator>>(std::istream& is, CUser* user)
{
    is >> user->m_id >> user->m_name >> user->m_gender >> user->m_department >> user->m_phone;
    return is;
}

CTeacher.cpp

#include "CTeacher.h"
#include<fstream>

CTeacher::CTeacher()
{
    m_name = "刘一";
}

string CTeacher::borrowBookFromLibrary(CManagementBooks& mb, string name)
{

    int all = mb.checkBorrowedBook(m_id);
    if (all < 5)
    {
        if (mb.borrow(name))
        {
            ofstream writeFile("borrowedBook.txt", ios::app);
            mb.setMapValue(m_id, name);
            writeFile << endl << m_id << " " << name;
            writeFile.close();
        }
    }
    else
    {
        return "您已经超过了最大可借阅数";
    }
    return "";
}
void CTeacher::showInfo()
{
    cout << "姓名:" << m_name << " " << "学号:" << m_id << " " << "性别:" << m_gender << " " << "院系:" << m_department << " " << "联系方式:" << m_phone << endl;
}




CStudent.cpp

#include "CStudent.h"
#include<fstream>
using  namespace std;


CStudent::CStudent()
{
    m_class = "软件";
}

void CStudent::showInfo()
{
    cout << "姓名:" << m_name << " " << "学号:" << m_id << " " << "性别:" << m_gender << " " << "院系:" << m_department << " " << "班级:" << m_class << " " << "联系方式:" << m_phone << endl;
}

string CStudent::borrowBookFromLibrary(CManagementBooks& mb, string name)
{
    int all = mb.checkBorrowedBook(m_id);
    if (all < 3)
    {
        if (mb.borrow(name))
        {
            ofstream writeFile("borrowedBook.txt", ios::app);
            mb.setMapValue(m_id, name);
            writeFile << endl << m_id << " " << name;
            writeFile.close();
        }
        else
        {
            return "此书数量不足或暂无此书";
        }
    }
    else
    {
        return "您已经超过了最大可借阅数";
    }
    return "";

}



void CStudent::setClass(string Class)
{
    m_class = Class;
}



string CStudent::getClass()
{
    return m_class;
}


CManagementBooks.cpp

#include "CManagementBooks.h"
#include<algorithm>
using namespace std;
static bool cmp(CBook book1, CBook book2)
{
	return book1.getNum() > book2.getNum();
}
void CManagementBooks::showCurrentAllBook()
{
	sort(m_books.begin(), m_books.end(), cmp);
	for (int i = 0; i < m_allBookNum; i++)
	{
		cout << "书名:" << m_books[i].getName() << " " << "剩余数量" << m_books[i].getNum() << endl;
	}
}

CManagementBooks::CManagementBooks()
{
	m_allBookNum = 0;
}

void CManagementBooks::addBook(CBook book)
{
	int flag = 0;
	for (int i = 0; i < m_allBookNum; i++)
	{
		if (m_books[i].getName() == book.getName())
		{
			flag = 1;
			m_books[i].setNum(m_books[i].getNum() + book.getNum());
			ofstream writeFile("library.txt", ios::out);
			for (int i = 0; i < m_allBookNum; i++)
			{
				writeFile << m_books[i];
			}
			writeFile.close();
			break;
		}
	}
	if (!flag)
	{
		ofstream writeFile("library.txt", ios::app);
		m_books.push_back(book);
		m_allBookNum++;
		writeFile << book;
		writeFile.close();
	}
}



int CManagementBooks::getAllBookNum()
{
	return m_allBookNum;
}

void CManagementBooks::showAllBooksInfo()
{
	sort(m_books.begin(), m_books.end(), cmp);
	for (int i = 0; i < m_allBookNum; i++)
	{
		m_books[i].showInfo();
	}
}

bool CManagementBooks::borrow(string name)
{

	for (int i = 0; i < m_allBookNum; i++)
	{
		if (m_books[i].getName() == name)
		{
			if (m_books[i].getNum() >= 1)
			{
				m_books[i].setNum(m_books[i].getNum() - 1);
				ofstream writeFile("library.txt");
				for (int i = 0; i < m_allBookNum; i++)
				{
					writeFile << m_books[i];
				}
				writeFile.close();
				return true;
			}
			else
			{
				return false;
			}
		}

	}
	return false;
}

void CManagementBooks::Return(string id, string bookName)
{
	CBook book;
	book.setName(bookName);
	addBook(book);
	ofstream writeFile("borrowedBook.txt", ios::out);
	for (auto iter = m_outBookMap.begin(); iter != m_outBookMap.end(); ++iter)
	{
		if (iter->first == id && iter->second == bookName)
		{
			m_outBookMap.erase(iter);
			break;
		}
	}
	for (auto map : m_outBookMap)
	{
		writeFile << endl << map.first << " " << map.second;
	}
	writeFile.close();
}

void CManagementBooks::initOutBook()
{
	ifstream readFile("borrowedBook.txt");
	if (!readFile.is_open())
	{
		cout << "查看全体借书情况数据读取出错" << endl;
	}
	else
	{
		while (!readFile.eof())
		{
			string studentId, bookName;
			readFile >> studentId >> bookName;
			m_outBookMap.insert(pair<string, string>(studentId, bookName));
		}
	}
	readFile.close();

}

void CManagementBooks::checekOutBook()
{
	for (auto map : m_outBookMap)
	{
		cout << "借阅人学工号:" << map.first << " " << "借阅书名:" << map.second << endl;
	}
}

void CManagementBooks::initBooks()
{
	ifstream readFile;
	readFile.open("library.txt");
	if (!readFile.is_open())
	{
		cout << "图书数据读取错误" << endl;
		readFile.close();
		return;
	}
	while (!readFile.eof())
	{

		CBook book;
		readFile >> book;
		m_allBookNum++;
		m_books.push_back(book);
	}
	readFile.close();
}

int CManagementBooks::checkBorrowedBook(string userId)
{

	int flag = 0;
	for (auto map : m_outBookMap)
	{
		if (userId == map.first)
		{
			if (!flag)
			{
				cout << "您已经借的全部图书如下:" << endl;
				flag++;
			}
			else
			{
				flag++;
			}
			cout << map.second << " ";
		}
	}
	if (!flag)
	{
		cout << "您目前没有借书" << endl;
	}
	cout << "共:" << flag << "本";
	cout << endl;
	return flag;
}

vector<userInfo> CManagementBooks::viewBorrowerDetails()
{
	ifstream readFile("teacher.txt");
	ifstream readFile1("student.txt");
	vector<userInfo>users;
	if (!readFile1.is_open() || !readFile.is_open())
	{
		cout << "用户数据读取错误" << endl;
	}
	while (!readFile1.eof())
	{
		string act1, name, department, gender,phone;
		readFile1 >> act1 >> name >> gender >> department>> phone;
		if(act1!="" && name != "")
		users.push_back({ act1,name ,gender ,department,"学生",phone});
	}
	while (!readFile.eof())
	{
		string act1, name, department, gender, phone;
		readFile >> act1 >> name >> gender >> department;
		if (act1 != "" && name != "")
		users.push_back({ act1,name ,gender ,department,"老师",phone });

	}
	readFile.close();
	readFile1.close();
	return users;
}

bool CManagementBooks::checkTrueBorrow(string id, string bookName)
{

	for (auto map : m_outBookMap)
	{
		if (map.first == id && map.second == bookName)
		{
			return true;
		}
	}
	return false;
}

void CManagementBooks::setMapValue(string userId, string bookName)
{
	m_outBookMap.insert(pair<string, string>(userId, bookName));
}

vector<CBook> CManagementBooks::getAllBook()
{
	return m_books;
}

unordered_multimap<string, string> CManagementBooks::getOutBookMap()
{
	return m_outBookMap;
}





CBook.cpp

#include "CBook.h"
#include <iostream>
#include<fstream>
using namespace std;


CBook::CBook()
{
	string b = "";
	string randStr = "0123456789X";
	for (int i = 0; i <= 12; i++)
	{
		if (i == 1 || i == 5 || i == 11)
		{
			b += '-';
		}
		else
		{
			if (i == 12)
			{
				b += randStr[rand() % 11];
			}
			else
			{
				b += randStr[rand() % 10];
			}
		}
	}
	m_num = 1;
	m_name = "等待戈多";
	m_author = "xx元";
	m_isbn = b;
	m_page = rand();
	m_pressInfo = "xx出版社";
	m_price = rand();
}

void CBook::setNum(int num)
{
	m_num = num;
}

int CBook::getNum()
{
	return m_num;
}


void CBook::setName(string name)
{
	m_name = name;
}

string CBook::getName()
{
	return m_name;
}

void CBook::setIsbn(string isbn)
{
	m_isbn = isbn;
}

string CBook::getIsbn()
{
	return m_isbn;
}

void CBook::setPressInfo(string perssInfo)
{
	m_pressInfo = perssInfo;
}

string CBook::getPressInfo()
{
	return m_pressInfo;
}

void CBook::setPrice(double price)
{
	m_price = price;
}

double CBook::getPrice()
{
	return m_price;
}

void CBook::setPage(int page)
{
	m_page = page;

}

int CBook::getPage()
{
	return m_page;
}

void CBook::setAuthor(string author)
{
	m_author = author;
}

string CBook::getAuthor()
{
	return m_author;
}


void CBook::checkIsnb()
{
	int sum = 0;
	for (int i = 0, j = 1; i < m_isbn.size(); i++) {
		if (m_isbn[i] != '-' && i != 12) {
			sum += (m_isbn[i] - '0') * j;
			j++;
		}

	}
	sum %= 11;
	char c = 'X';
	if (sum < 10) c = sum + '0';
	if (m_isbn[12] == c) puts("This book isbn are Right!");
	else puts("This book isbn are wrong!");
}



bool CBook::isBorrowed()
{
	if (m_num >= 1)
	{
		m_num--;
		return true;
	}
	return false;
}

void CBook::showInfo()
{
	cout << "作者:" << m_author << " " << "isbn号码:" << m_isbn << " " << "书本名称:" << m_name << " "
		<< "总页数:" << m_page << " " << "出版社:" << m_pressInfo << " " << "价格:" << m_price
		<< " " << "剩余本数:" << m_num << endl;
}

std::ostream& operator <<(std::ostream& os, const CBook& book)
{
	os << endl << book.m_name << " " << book.m_isbn << " " << book.m_pressInfo << " " << book.m_price << " " << book.m_page << " " << book.m_author << " " << book.m_num;
	return os;
}

std::istream& operator>>(std::istream& is, CBook& book)
{
	is >> book.m_name >> book.m_isbn >> book.m_pressInfo >> book.m_price >> book.m_page >> book.m_author >> book.m_num;
	return is;
}

}

userPage.cpp

#include "UserPage.h"
#include <QMessageBox>
#include <QFont>

UserPage::UserPage(QWidget* parent) : QWidget(parent)
{
    // 创建主布局
    QVBoxLayout* mainLayout = new QVBoxLayout(this);
    setWidgetFont(this);

    // 创建选项卡部件
    tabWidget = new QTabWidget(this);

    // 借书选项卡
   
    // 创建显示当前图书列表的QTableWidget
    QTableWidget* currentBooksList = new QTableWidget(borrowTab);
    currentBooksList->setObjectName("currentBooksList");
    setWidgetFont(currentBooksList);
    // 创建标签用于说明图书列表
    QLabel* currentBooksLabel = createStyledLabel("当前图书列表:");
    borrowLayout->addWidget(currentBooksLabel);
    borrowLayout->addWidget(currentBooksList);
    // 添加书名输入标签和输入框
    QLabel* bookNameLabel = createStyledLabel("输入要借的书名:");
    borrowLayout->addWidget(bookNameLabel);
    borrowLayout->addWidget(bookNameEdit);
    borrowLayout->addWidget(borrowButton);
    tabWidget->addTab(borrowTab, "借书");

    // 查看借书情况选项卡
    

    // 还书选项卡
    

    mainLayout->addWidget(tabWidget);
    // 设置编码
    codec = QTextCodec::codecForName("GBK");

    // 连接借书按钮点击事件
    connect(borrowButton, &QPushButton::clicked, this, &UserPage::onBorrowButtonClicked);
    // 连接还书按钮点击事件
    connect(returnButton, &QPushButton::clicked, this, &UserPage::onReturnButtonClicked);
    connect(tabWidget, &QTabWidget::currentChanged, [this](int index) {
        if (index == tabWidget->indexOf(borrowedBooksTab)) {
            onViewBorrowedBooksClicked();
        }
        else if (index == tabWidget->indexOf(returnTab)) {
            onShowBorrowedBooksForReturnClicked();
        }
        else if (index == tabWidget->indexOf(borrowTab)) {
            onBorrowTabClicked();
        }
        });
    mb.initBooks();
    mb.initOutBook();
    initCurrentBookList();
}

void UserPage::onBorrowButtonClicked()
{
    QString bookName = bookNameEdit->text();
    if (bookName.isEmpty())
    {
        QMessageBox::warning(this,"借书提示","请输入要借的书名");
        return;
    }
    std::string allow = user->borrowBookFromLibrary(mb, codec->fromUnicode(bookName).toStdString());
    if (allow != "")
    {
        QMessageBox::critical(this, "借书失败", codec->toUnicode(allow.c_str()));
        return;
    }
    // 尝试获取当前图书列表部件
    QTableWidget* currentBooksList = this->findChild<QTableWidget*>("currentBooksList");
    if (currentBooksList)
    {
        QList<QTableWidgetItem*> foundItems = currentBooksList->findItems(bookName, Qt::MatchExactly);
        if (!foundItems.isEmpty())
        {
            QTableWidgetItem* itemToModify = foundItems.first();
            int row = currentBooksList->row(itemToModify);

            // 获取当前可借数量并减1
            QTableWidgetItem* numItem = currentBooksList->item(row, 6);
            int currentNum = numItem->text().toInt();
            if (currentNum > 0)
            {
                currentNum--;
                numItem->text() = QString::number(currentNum);
                QMessageBox::information(this, "借书成功", "已成功借阅 " + bookName);
                // 重新加载图书数据
                onBorrowTabClicked();
            }
        }
    }
}

void UserPage::onReturnButtonClicked()
{
    QList<QTableWidgetItem*> selectedItems = returnableBooksList->selectedItems();
    if (selectedItems.isEmpty())
    {
        QMessageBox::warning(this, "还书提示", "请选择要归还的书籍");
        return;
    }

    // 使用QSet来避免重复添加书籍ID
    QSet<QString> addedBookIds;
    QList<QString> bookIds;
    for (QTableWidgetItem* item : selectedItems)
    {
        // 获取该项所在行的索引
        int row = returnableBooksList->row(item);
        // 获取该行第二列的表格项(索引为1)
        QTableWidgetItem* secondColumnItem = returnableBooksList->item(row, 1);
        if (secondColumnItem)
        {
            QString bookId = secondColumnItem->text();
            if (!addedBookIds.contains(bookId))
            {
                bookIds.append(bookId);
                addedBookIds.insert(bookId);
            }
        }
    }

    // 执行还书操作,假设user有还书相关函数,mb是管理书籍相关数据的对象
    std::string result;
    for (const QString& bookId : bookIds)
    {
        // 这里调用还书函数,根据实际情况可能需要调整参数传递方式
        result = user->returnBook(mb, codec->fromUnicode(bookId).toStdString());
        if (result != "")
        {
            break;
        }
    }
    if (result == "")
    {
        // 还书成功,更新界面显示
        QMessageBox::information(this, "还书成功", "已成功归还所选书籍");

        // 重新加载当前用户借阅的书籍列表,以更新界面显示
        onShowBorrowedBooksForReturnClicked();
    }
    else
    {
        QMessageBox::warning(this, "还书失败", codec->toUnicode(result.c_str()));
    }
}

QLabel* UserPage::createStyledLabel(const QString& text)
{
    QLabel* label = new QLabel(text);
    setWidgetFont(label);
    return label;
}

void UserPage::setWidgetFont(QWidget* widget)
{
    QFont font;
    font.setFamily("宋体");
    font.setPointSize(16);
    widget->setFont(font);
}

void UserPage::initCurrentBookList()
{
    // 清空之前的显示内容
   
    QTableWidget* currentBooksList = this->findChild<QTableWidget*>("currentBooksList");
    currentBooksList->setEditTriggers(QAbstractItemView::NoEditTriggers);
    if (currentBooksList)
    {
        // 设置表格列数和表头
        currentBooksList->setColumnCount(7);
        QStringList headers;
        headers << "作者" << "isbn号码" << "书本名称" << "总页数" << "出版社" << "价格" << "剩余本数";
        currentBooksList->setHorizontalHeaderLabels(headers);

        // 设置表格字体大小
        QFont tableFont;
        tableFont.setPointSize(10); // 设置字体大小为12,你可以根据需要调整这个值
        currentBooksList->setFont(tableFont);

        // 设置表头字体大小
        QHeaderView* headerView = currentBooksList->horizontalHeader();
        QFont headerFont;
        headerFont.setPointSize(10); // 设置字体大小为12,你可以根据需要调整这个值
        headerView->setFont(headerFont);

        // 添加书籍信息
        for (auto& book : mb.getAllBook())
        {
            int row = currentBooksList->rowCount();
            currentBooksList->insertRow(row);
            QTableWidgetItem* authorItem = new QTableWidgetItem(codec->toUnicode(book.getAuthor().c_str()));
            QTableWidgetItem* isbnItem = new QTableWidgetItem(codec->toUnicode(book.getIsbn().c_str()));
            QTableWidgetItem* nameItem = new QTableWidgetItem(codec->toUnicode(book.getName().c_str()));
            QTableWidgetItem* pressInfoItem = new QTableWidgetItem(codec->toUnicode(book.getPressInfo().c_str()));
            QTableWidgetItem* pagesItem = new QTableWidgetItem((QString::number(book.getPage())));
            QTableWidgetItem* priceItem = new QTableWidgetItem((QString::number(book.getPrice())));
            QTableWidgetItem* numItem = new QTableWidgetItem(QString::number(book.getNum()));

            currentBooksList->setItem(row, 0, authorItem);
            currentBooksList->setItem(row, 1, isbnItem);
            currentBooksList->setItem(row, 2, nameItem);
            currentBooksList->setItem(row, 3, pagesItem);
            currentBooksList->setItem(row, 4, pressInfoItem);
            currentBooksList->setItem(row, 5, priceItem);
            currentBooksList->setItem(row, 6, numItem);
        }
    }

    // 设置列宽,这里的宽度值可以根据实际情况调整
    currentBooksList->setColumnWidth(0, 150);
    currentBooksList->setColumnWidth(1, 150);
    currentBooksList->setColumnWidth(2, 200);
    currentBooksList->setColumnWidth(3, 100);
    currentBooksList->setColumnWidth(4, 200);
    currentBooksList->setColumnWidth(5, 100);
    currentBooksList->setColumnWidth(6, 100);
}

void UserPage::onUserUpdated(CUser* user)
{
    this->user = user;
}

void UserPage::onViewBorrowedBooksClicked()
{
    // 清空之前的显示内容
    borrowedBooksList->clearContents();
    borrowedBooksList->setRowCount(0);

    // 设置表格列数和表头
    borrowedBooksList->setColumnCount(2);
    borrowedBooksList->setEditTriggers(QAbstractItemView::NoEditTriggers);
    QStringList headers;
    headers << "借阅者账号" << "借阅图书";
    borrowedBooksList->setHorizontalHeaderLabels(headers);

    // 获取当前用户的借书信息列表
    std::unordered_multimap<string, string> borrowedBooks = mb.getOutBookMap();

    // 添加借书信息到表格中
    for (const auto& book : borrowedBooks) {
        if (book.first != user->getId()) continue;
        int row = borrowedBooksList->rowCount();
        borrowedBooksList->insertRow(row);

        QTableWidgetItem* bookNameItem = new QTableWidgetItem(codec->toUnicode(book.first.c_str()));
        QTableWidgetItem* authorItem = new QTableWidgetItem(codec->toUnicode(book.second.c_str()));

        borrowedBooksList->setItem(row, 0, bookNameItem);
        borrowedBooksList->setItem(row, 1, authorItem);
    }
    borrowedBooksList->setColumnWidth(0, 500);
    borrowedBooksList->setColumnWidth(1, 500);
}

void UserPage::onShowBorrowedBooksForReturnClicked()
{

    // 设置选择模式为单选整行
    returnableBooksList->setSelectionBehavior(QAbstractItemView::SelectRows);
    returnableBooksList->setSelectionMode(QAbstractItemView::SingleSelection);
}
void UserPage::onBorrowTabClicked()
{
    // 清空之前的显示内容
  
}

loginPage.cpp

#include "LoginPage.h"

LoginPage::LoginPage(QWidget* parent) : QWidget(parent)
{
    // 创建用户名输入框
    usernameEdit = new QLineEdit(this);
    
    // 创建密码输入框,并设置为密码模式
    passwordEdit = new QLineEdit(this);
    setWidgetFontAndSize(passwordEdit);
    setInputBoxHeight(passwordEdit, 35); // 设置用户名输入框高度

    // 创建角色选择下拉框
    roleLoginComboBox = new QComboBox(this);
    roleLoginComboBox->addItems({ "学生", "老师", "管理员" });
    setWidgetFont(roleLoginComboBox);

    // 创建登录按钮
    loginButton = new QPushButton("登录", this);
    setWidgetFont(loginButton);

    // 创建注册按钮
    registerButton = new QPushButton("注册", this);
    setWidgetFont(registerButton);

    // 设置布局
    QVBoxLayout* mainLayout = new QVBoxLayout(this);

    QHBoxLayout* usernameLayout = new QHBoxLayout();
    usernameLayout->addWidget(createStyledLabel("用户名:"));
    usernameLayout->addWidget(usernameEdit);
    mainLayout->addLayout(usernameLayout);

    QHBoxLayout* passwordLayout = new QHBoxLayout();
    passwordLayout->addWidget(createStyledLabel("密码:"));
    passwordLayout->addWidget(passwordEdit);
    mainLayout->addLayout(passwordLayout);
    QHBoxLayout* roleLoginLayout = new QHBoxLayout();
    roleLoginLayout->addWidget(createStyledLabel("角色:"));
    roleLoginLayout->addWidget(roleLoginComboBox);
    mainLayout->addLayout(roleLoginLayout);
    QHBoxLayout* buttonLayout = new QHBoxLayout();
    buttonLayout->addWidget(loginButton);
    buttonLayout->addWidget(registerButton);
    mainLayout->addLayout(buttonLayout);

    // 连接按钮点击事件到相应的槽函数
    connect(loginButton, &QPushButton::clicked, this, &LoginPage::onLoginButtonClicked);
    connect(registerButton, &QPushButton::clicked, this, &LoginPage::onRegisterButtonClicked);
}

void LoginPage::onLoginButtonClicked()
{
    QString account = usernameEdit->text();
    QString password = passwordEdit->text();
    QString role = roleLoginComboBox->currentText();
    CUser* user = nullptr;
    CAdministrator admin;
    if (account.isEmpty() || password.isEmpty())
    {
        QMessageBox::critical(this, "错误", "用户名或密码不能为空!");
        return;
    }
    std::ifstream readFile;
    std::ifstream readFile1;
    if (role == "老师")
    {
        readFile.open("teacherLogin.txt");
        readFile1.open("teacher.txt");
        user = new CTeacher();
    }
    else if(role == "学生")
    {
        readFile1.open("student.txt");
        readFile.open("studentLogin.txt");
        user = new CStudent();
    }
    else
    {
        readFile1.open("admin.txt");
        readFile.open("adminLogin.txt");
        int flag = 0;
        while (!readFile.eof())
        {
            std::string act;
            readFile >> act;
            if (act == account.toStdString())
            {
                std::string pwd;
                readFile >> pwd;
                if (pwd == password.toStdString())
                {
                    QMessageBox::about(this, "登录成功", "登录成功!");
                    flag = 1;
                    while (!readFile1.eof())
                    {

                        readFile1 >> admin;

                        if (admin.getId() == act)
                        {
                            emit adminUpdated(admin);
                            break;
                        }
                    }
                    break;
                }
            }

        }
        if (!flag)
        {
            QMessageBox::critical(this, "错误", "用户名或密码错误!");
            return;
        }
        emit adminLoginSuccess();
        readFile.close();
        readFile1.close();
        return;
    }
    int flag = 0;
    while (!readFile.eof())
    {
        std::string act;
        readFile >> act;
        if (act == account.toStdString())
        {
            std::string pwd;
            readFile >> pwd;
            if (pwd == password.toStdString())
            {
                QMessageBox::about(this, "登录成功", "登录成功!");
                flag = 1;
                while (!readFile1.eof())
                {
              
                    readFile1 >> user;

                    if (user != nullptr && user->getId() == act)
                    {
                        emit userUpdated(user);
                        break;
                    }
                }
                break;
            }
        }

    }
    if (!flag)
    {
        QMessageBox::critical(this, "错误", "用户名或密码错误!");
        return;
    }
    emit loginSuccess();
    readFile.close();
    readFile1.close();
}

void LoginPage::onRegisterButtonClicked()
{
    emit registerButtonClicked();
}

// 设置输入框宽度的函数
void LoginPage::setInputBoxWidth(QWidget* widget, int width)
{
    widget->setFixedWidth(width);
}

// 创建带有指定样式的标签函数
QLabel* LoginPage::createStyledLabel(const QString& text)
{
    QLabel* label = new QLabel(text);
    setWidgetFont(label);
    return label;
}

// 设置输入框字体和大小的函数
void LoginPage::setWidgetFontAndSize(QWidget* widget)
{
    QFont font;
    font.setFamily("宋体");
    font.setPointSize(16);
    widget->setFont(font);
}
void LoginPage::setInputBoxHeight(QWidget* widget, int height)
{
    widget->setFixedHeight(height);
}

// 设置按钮字体的函数
void LoginPage::setWidgetFont(QWidget* widget)
{
    QFont font;
    font.setFamily("宋体");
    font.setPointSize(16);
    widget->setFont(font);
}

register.cpp

#include "RegistrationPage.h"
#include <QFont>

RegistrationPage::RegistrationPage(QWidget* parent) : QWidget(parent)
{
    // 创建用户名输入框
    usernameEdit = new QTextEdit(this);
    setWidgetFontAndSize(usernameEdit);
    setInputBoxHeight(usernameEdit, 35); // 设置用户名输入框高度

    // 创建姓名输入框
    nameEdit = new QTextEdit(this);
    setWidgetFontAndSize(nameEdit);
    setInputBoxHeight(nameEdit, 35); // 设置姓名输入框高度

    // 创建部门输入框
    departmentEdit = new QTextEdit(this);
    setWidgetFontAndSize(departmentEdit);
    setInputBoxHeight(departmentEdit, 35); // 设置部门输入框高度

    // 创建电话输入框
    phoneEdit = new QTextEdit(this);
    setWidgetFontAndSize(phoneEdit);
    setInputBoxHeight(phoneEdit, 35); // 设置电话输入框高度

    // 创建密码输入框,并设置为密码模式
    passwordEdit = new QTextEdit(this);
    setWidgetFontAndSize(passwordEdit);
    setInputBoxHeight(passwordEdit, 35); // 设置密码输入框高度

    // 创建性别选择下拉框
    genderComboBox = new QComboBox(this);
    genderComboBox->addItems({ "男", "女" });
    setWidgetFont(genderComboBox);

    // 创建角色选择下拉框
    roleLoginComboBox = new QComboBox(this);
    roleLoginComboBox->addItems({ "学生", "老师", "管理员" });
    setWidgetFont(roleLoginComboBox);

    // 创建注册按钮
    registerButton = new QPushButton("注册", this);
    setWidgetFont(registerButton);

    // 创建登录按钮
    loginButton = new QPushButton("登录", this);
    setWidgetFont(loginButton);


    
    // 连接注册按钮的点击事件到槽函数
    connect(registerButton, &QPushButton::clicked, this, &RegistrationPage::onRegisterButtonClicked);
    connect(loginButton, &QPushButton::clicked, this, &RegistrationPage::onLoginButtonClicked); // 连接登录按钮点击事件
}

void RegistrationPage::onRegisterButtonClicked()
{
    QString act = usernameEdit->toPlainText();
    QString name = nameEdit->toPlainText();
    QString department = departmentEdit->toPlainText();
    QString phone = phoneEdit->toPlainText();
    QString pwd = passwordEdit->toPlainText();
    QString gender = genderComboBox->currentText();
    QString role = roleLoginComboBox->currentText();

    if (act == "" || name == "" || department == "" || phone == "")
    {
        QMessageBox::critical(this, "错误", "请将信息补充完整!");
        return;
    }

    if (role == "管理员")
    {
        QMessageBox::critical(this, "错误", "管理员无法注册!");
        return;
    }

    std::ofstream writeFile;
    std::ofstream writeFile1;

    if (role == "老师")
    {
        writeFile1.open("teacher.txt", std::ios::app);
        writeFile.open("teacherLogin.txt", std::ios::app);
    }
    else
    {
        writeFile1.open("student.txt", std::ios::app);
        writeFile.open("studentLogin.txt", std::ios::app);
    }

    writeFile << std::endl << act.toStdString() << " " << pwd.toStdString();
    writeFile1 << std::endl << act.toStdString() << " " << name.toStdString() << " " << gender.toStdString() << " " << department.toStdString() << " " << phone.toStdString();

    writeFile.close();
    writeFile1.close();

    QMessageBox::about(this, "注册成功", "快去登录系统吧");

    // 发射注册成功信号
    emit registrationSuccess();
}

void RegistrationPage::onLoginButtonClicked()
{
    
}

// 设置控件字体和字号的函数
void RegistrationPage::setWidgetFont(QWidget* widget)
{
    QFont font;
    font.setFamily("宋体");
    font.setPointSize(16);
    widget->setFont(font);
}

// 设置输入框宽度的函数
void RegistrationPage::setInputBoxWidth(QWidget* widget, int width)
{
    widget->setFixedWidth(width);
}

// 创建带有指定样式的标签函数
QLabel* RegistrationPage::createStyledLabel(const QString& text)
{
    QLabel* label = new QLabel(text);
    setWidgetFont(label);
    return label;
}

// 设置输入框字体和大小的函数
void RegistrationPage::setWidgetFontAndSize(QWidget* widget)
{
    QFont font;
    font.setFamily("宋体");
    font.setPointSize(16);
    widget->setFont(font);
}

void RegistrationPage::setInputBoxHeight(QWidget* widget, int height)
{
    widget->setFixedHeight(height);
}

CAdministrator.cpp

cout<<需要完整源码,只需10<<endl;
cout<<源码+讲解,只需25元 需要请加位心:ch18384322303,备注:图书管理系统GUI源码<<endl;
cout<<讲解包括:<<endl;
cout<<项目讲解视频(如何运行,环境安装,代码思路等)、qt安装流程、qt安装包<<endl;
cout<<本项目问题答疑(不限次数)<<endl;

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

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

相关文章

【LeetCode: 560. 和为 K 的子数组 + 前缀和 + 哈希表】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

微信小程序实现登录注册

文章目录 1. 官方文档教程2. 注册实现3. 登录实现4. 关于作者其它项目视频教程介绍 1. 官方文档教程 https://developers.weixin.qq.com/miniprogram/dev/framework/路由跳转的几种方式&#xff1a; https://developers.weixin.qq.com/miniprogram/dev/api/route/wx.switchTab…

嵌入式系统 (2.嵌入式硬件系统基础)

2.嵌入式硬件系统基础 2.1嵌入式硬件系统的组成 嵌入式硬件系统以嵌入式微处理器为核心&#xff0c;主要由嵌入式微处理器、总线、存储器、输入/输出接口和设备组成。 嵌入式微处理器 嵌入式微处理器采用冯诺依曼结构或哈佛结构&#xff1a;前者指令和数据共享同一存储空间…

多模态大模型初探索:通过ollama部署多模态大模型

文章目录 前言模型下载 前言 今天和同事聊天&#xff0c;聊到多模态大模型&#xff0c;感觉可以作为2025年的一个新的探索方向。希望和大家一起学习&#xff0c;一起进步。 今天也是尝试了我能想到的最基本最快速地本地部署多模态大模型的方式&#xff0c;那便是使用ollama。…

【超详细】React SSR 服务端渲染实战

前言 这篇文章和大家一起来聊一聊 React SSR&#xff0c;本文更偏向于实战。你可以从中学到&#xff1a; 从 0 到 1 搭建 React SSR 服务端渲染需要注意什么 react 18 的流式渲染如何使用 文章如有误&#xff0c;欢迎指出&#xff0c;大家一起学习交流&#xff5e;。 &…

js策略模式

定义一组算法&#xff0c;将每个算法封装成一个独立的类&#xff0c;并使它们可以互相替换。策略模式使得算法的变化不会影响到使用算法的客户。 const priceProcessor {pre(originPrice) {if (originPrice > 100) {return originPrice - 20;}return originPrice * 0.9;}…

Python中的可变对象与不可变对象;Python中的六大标准数据类型哪些属于可变对象,哪些属于不可变对象

Python中的可变对象与不可变对象&#xff1b;Python中的六大标准数据类型哪些属于可变对象&#xff0c;哪些属于不可变对象 Python中的可变对象与不可变对象一、Python的六大标准数据类型1. 数字类型 (Number)2. 字符串 (String)3. 列表 (List)4. 元组 (Tuple)5. 集合 (Set)6. …

js状态模式

允许一个对象在其内部状态改变时改变它的行为。 状态模式将对象的状态封装成独立的类&#xff0c;并使它们可以互相转换 // 定义状态接口class State {constructor() {if (this.constructor State) {throw new Error(不能实例化抽象类);}}// 定义状态方法handle(context) {th…

基于64QAM的载波同步和定时同步性能仿真,包括Costas环和gardner环

目录 1.算法仿真效果 2.算法涉及理论知识概要 3.MATLAB核心程序 4.完整算法代码文件获得 1.算法仿真效果 matlab2022a仿真结果如下&#xff08;完整代码运行后无水印&#xff09;&#xff1a; 仿真操作步骤可参考程序配套的操作视频。 2.算法涉及理论知识概要 载波同步是…

【Web安全】SQL 注入攻击技巧详解:布尔盲注(Boolean-Based Blind SQL Injection)

【Web安全】SQL 注入攻击技巧详解&#xff1a;布尔盲注&#xff08;Boolean-Based Blind SQL Injection&#xff09; 引言 布尔盲注&#xff08;Boolean-Based Blind SQL Injection&#xff09;是一种在无法直接从数据库获取数据的情况下&#xff0c;通过观察数据库响应的布尔…

太速科技-418-基于AD9361 +ZYNQ7020 的软件无线电 SDR 套件

基于AD9361 ZYNQ7020 的软件无线电 SDR 套件 一、板卡信息 ● ZYNQ芯片采用XC7Z020&#xff0c;逻辑容量更大&#xff0c;支持更大的逻辑设计&#xff1b; ● 内存采用两片512M DDR3&#xff0c;共1GByte&#xff0c;更大容量。 ● 支持千兆网口&#xff0c;支持ZEDFMCO…

SpringBoot日常:集成Kafka

文章目录 1、pom.xml文件2、application.yml3、生产者配置类4、消费者配置类5、消息订阅6、生产者发送消息7、测试发送消息 本章内容主要介绍如何在springboot项目对kafka进行整合&#xff0c;最终能达到的效果就是能够在项目中通过配置相关的kafka配置&#xff0c;就能进行消息…

分布式IO模块:激光切割机产线高效控制的创新引擎

在智能制造的浪潮中&#xff0c;激光切割技术以其高精度、高效率的特点&#xff0c;成为了现代工业生产中不可或缺的一部分。特别是在汽车制造、航空航天、电子设备及精密零部件加工等领域&#xff0c;激光切割机以其无与伦比的切割精度和灵活性&#xff0c;引领着制造业的转型…

RK3562编译Android13 ROOT固件教程,触觉智能开发板演示

本文介绍编译Android13 ROOT权限固件的方法&#xff0c;触觉智能RK3562开发板演示&#xff0c;搭载4核A53处理器&#xff0c;主频高达2.0GHz&#xff1b;内置独立1Tops算力NPU&#xff0c;可应用于物联网网关、平板电脑、智能家居、教育电子、工业显示与控制等行业。 关闭seli…

wireshark抓包工具新手使用教程

wireshark抓包工具新手入门使用教程 一、Wireshark软件安装二、Wireshark 抓包示范三、Wireshakr抓包界面四、Wireshark过滤器设置五、wireshark过滤器表达式的规则六、Wireshark抓包分析TCP三次握手七、Wireshark分析常用列标签格式 Wireshark是一款开源的网络协议分析工具&am…

如何用Python编程实现自动整理XML发票文件

传统手工整理发票耗时费力且易出错&#xff0c;而 XML 格式发票因其结构化、标准化的特点&#xff0c;为实现发票的自动化整理与保存提供了可能。本文将详细探讨用python来编程实现对 XML 格式的发票进行自动整理。 一、XML 格式发票的特点 结构化数据&#xff1a;XML 格式发票…

【网络安全 | 漏洞挖掘】HubSpot 全账户接管(万字详析)

未经许可,不得转载。 今天我们将分享一个关于在 Bugcrowd 平台的 HubSpot 公共漏洞赏金计划中实现全账户接管的故事。 文章目录 正文SQL 注入主机头污染(Host Header Poisoning)负载均衡器主机头覆盖(Load Balancer Host Header Override)Referer Header 测试ORIGIN Heade…

2025_0105_生活记录

3号去内蒙看了流星雨。还记得上次看流星的时间是2018年&#xff0c;也是冬天&#xff0c;大家在雁栖湖校区的操场上仰望星空。那个时候幸运的看到了一颗流星&#xff0c;便迅速地在心里许愿。这次看到了三颗流星&#xff0c;我也许了愿&#xff0c;希望实现。 24年走过了十多个…

(四)ROS通信编程——服务通信

前言 学完了话题通信其实操作流程基本都已经很熟悉了&#xff0c;因此服务通讯的学习就会流畅许多。 服务通信也是ROS中一种极其常用的通信模式&#xff0c;服务通信是基于请求响应模式的&#xff0c;是一种应答机制。也即: 一个节点A向另一个节点B发送请求&#xff0c;B接收…

《繁星路》V1.8.3(Build16632266)官方中文学习版

《繁星路》官方中文版https://pan.xunlei.com/s/VODae2_2Z3QyMF02I5y321uHA1?pwdqgsh# 作为一款星际模拟游戏&#xff0c;完美融合了硬科幻元素与基地建设玩法&#xff0c;体验改造行星的恢弘与壮阔。化身人工意识AMI&#xff0c;遵照基本指示推进火星改造的各项工作&#xf…