主界面用MainWindow,其他的都用Dialog。在MainWindow的构造函数中连接数据库,在MainWdow的析构函数中关闭数据库的连接。
QT连接Access代码片段如下
bool createConnection(){ QSqlDatabase db; db = QSqlDatabase::addDatabase("QODBC"); db.setDatabaseName("DRIVER={Microsoft Access Driver (*.mdb)};FIL={MS Access};DBQ=HouseManager.mdb;UID=;PWD="); if(!db.open()) { QMessageBox::critical(0,QObject::tr("Database Error"),db.lastError().text()); return false; } return true; }
用户登录部分代码片段如下
void Dialog_Login::slotUserLogin(){ QString username = ui->username->text();//从界面取到用户输入的值 QString password = ui->password->text(); QSqlQuery query; QString sql = "select * from h_user where username = :username and password = :password"; query.prepare(sql); query.bindValue(":username", username); query.bindValue(":password", password); if(query.exec()){ if(query.next()){ QString group = query.value("group").toString(); if(group == "user"){//user登录之后发出user登录信号,在MainWindow中接收该信号 emit signalUserLogin(); this->close(); }else if(group == "superuser"){ emit signalSuperUserLogin();//superuser登录之后发出superuser登录信号,在MainWindow中接收该信号 this->close(); }else{ QMessageBox::information(this, "提示", "登陆失败,缺少用户组信息", QMessageBox::Ok); } }else{ //登录失败,请检查用户名或密码 qDebug() << "Login failed,please check your username and password"; QMessageBox::information(this, "提示", "登陆失败,请检查用户名或密码", QMessageBox::Ok); // emit signalSuperUserLogin();//此句仅在测试阶段使用,免除登录麻烦 // this->close(); } }else{ //执行查询请求错误 qDebug() << "Erros occured when query executed"; QMessageBox::information(this, "提示", "登陆失败,请检查用户名或密码", QMessageBox::Ok); } }
MainWindow构造函数如下
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); this->setFixedSize(1000, 620); dialog_Login = new Dialog_Login(this);//初始化登录UI connect(dialog_Login, SIGNAL(signalUserLogin()), this, SLOT(slotUserLogin())); connect(dialog_Login, SIGNAL(signalSuperUserLogin()), this, SLOT(slotSuperUserLogin())); dialog_Login->show();//接收到登录成功的信号之后才显示MainWindow的主界面 }
slotSuperUserLogin槽函数如下
void MainWindow::slotSuperUserLogin(){//superuser登录之后的槽函数 initAction();//初始化Action initSuperUserMenu();//初始化菜单 creatTrayIcon();//创建系统托盘 this->show();//显示MainWindow主界面 }
由于user和superuser的菜单中大部分菜单项都是相同的,所以可以共用。
void MainWindow::initAction(){//初始化菜单栏里面的Action。很多Action可以共用 exitAction = new QAction(QIcon(tr(":/images/images/quit_128X128.png")), tr("退出"), this); exitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_W)); exitAction->setStatusTip(tr("退出系统"));//退出代码QApplication::exit(0); connect(exitAction, SIGNAL(triggered()), this, SLOT(slotExitAction())); userAction = new QAction(QIcon(tr(":/images/images/systemUser_84X84.png")), tr("系统用户"), this); connect(userAction, SIGNAL(triggered()), this, SLOT(slotUserAction())); customerAction = new QAction(QIcon(tr("")), tr("客户数据"), this); connect(customerAction, SIGNAL(triggered()), this, SLOT(slotCustomerAction())); aboutAction = new QAction(QIcon(tr(":/images/images/about_256X256.png")), tr("关于"), this); aboutAction->setStatusTip(tr("关于")); connect(aboutAction, SIGNAL(triggered()), this, SLOT(slotAboutAction())); }
初始化菜单项Action之后就可以构建菜单
void MainWindow::initSuperUserMenu(){//初始化superuser登录之后的菜单 menu = this->menuBar()->addMenu(tr("文件")); menu->addAction(exitAction); sysData = this->menuBar()->addMenu(tr("系统数据")); sysData->addAction(userAction);//用户数据 sysData->addAction(customerAction);//客户数据 helpMenu = this->menuBar()->addMenu(tr("帮助")); helpMenu->addAction(aboutAction); }
创建系统托盘
void MainWindow::creatTrayIcon(){ restoreWindowAction = new QAction("还原",this); restoreWindowAction->setIcon(QIcon(tr(":/images/images/maxmize_256X256.png"))); this->connect(restoreWindowAction,SIGNAL(triggered()),this,SLOT(showNormal())); hideWindowAction = new QAction("隐藏", this); hideWindowAction->setIcon(QIcon(tr(":/images/images/minimize_256X256.png"))); this->connect(hideWindowAction, SIGNAL(triggered()), this, SLOT(hide())); trayMenu = new QMenu((QWidget*)QApplication::desktop()); trayMenu->addAction(restoreWindowAction); trayMenu->addAction(hideWindowAction); trayMenu->addSeparator(); trayMenu->addAction(exitAction); if (!QSystemTrayIcon::isSystemTrayAvailable()) //判断系统是否支持系统托盘图标 { return; } trayIcon = new QSystemTrayIcon(this); trayIcon->setIcon(QIcon(":/images/images/HouseManager_128X128.ico")); //设置图标图片 setWindowIcon(QIcon(":/images/images/HouseManager_128X128.ico")); //把图片设置到窗口上 trayIcon->setToolTip("房屋管理系统 V1.0"); //托盘时,鼠标放上去的提示信息 trayIcon->showMessage("房屋管理系统","单击右键打开菜单~",QSystemTrayIcon::Information,10000); trayIcon->setContextMenu(trayMenu); //设置托盘上下文菜单 trayIcon->show(); this->connect(trayIcon,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this,SLOT(iconActivated(QSystemTrayIcon::ActivationReason))); }
关闭事件
void MainWindow::closeEvent(QCloseEvent *event){ if (trayIcon->isVisible()) { trayIcon->showMessage("房屋管理系统","单击右键打开菜单~",QSystemTrayIcon::Information,5000); this->hide(); //最小化 event->ignore(); } else{ event->accept(); } }
托盘图标点击事件
void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason) { switch(reason) { case QSystemTrayIcon::Trigger: qDebug() << "单击左键"; //单击左键 case QSystemTrayIcon::DoubleClick: //双击左键 qDebug() << "双击左键"; if(this->isHidden()){ showNormal(); this->activateWindow();//激活当前窗口 }else{ this->hide(); } break; case QSystemTrayIcon::MiddleClick: //单击滚轮 trayIcon->showMessage("房屋管理系统","单击右键打开菜单~",QSystemTrayIcon::Information,10000); break; default: break; } }
关于菜单项槽函数
void MainWindow::slotAboutAction(){//关于 QMessageBox message(QMessageBox::NoIcon, "关于", "公寓出租管理系统\nAll rights reserved!!!\nV1.0\n2014.06.29\n作者E-mail:[email protected]"); message.setIconPixmap(QPixmap(":/images/images/HouseManager_256X256.ico")); message.exec(); }
系统用户菜单项实现
void MainWindow::slotUserAction(){ dialog_users = new Dialog_users(this); dialog_users->setModal(true); dialog_users->exec();//这种方式弹出来的Dialog挡住后面的MainWindow }
下面展示Dialog_users的实现
Dialog_users的主界面显示系统用户列表,暂未实现翻页功能。Dialog_users构造函数
Dialog_users::Dialog_users(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog_users) { ui->setupUi(this); this->setWindowTitle("用户管理"); this->setFixedSize(800, 500); ui->label_add_user->installEventFilter(this); ui->label_delete_user->installEventFilter(this); ui->label_edit_user->installEventFilter(this); QSqlQuery query; query.prepare("select * from h_user"); QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); model = new QStandardItemModel(); model->setColumnCount(4); model->setHeaderData(0,Qt::Horizontal,QString::fromLocal8Bit("用户名")); model->setHeaderData(1,Qt::Horizontal,QString::fromLocal8Bit("密码")); model->setHeaderData(2,Qt::Horizontal,QString::fromLocal8Bit("用户组")); model->setHeaderData(3,Qt::Horizontal,QString::fromLocal8Bit("备注")); ui->tableView->setModel(model); ui->tableView->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);//不可编辑 ui->tableView->setColumnWidth(0,101); ui->tableView->setColumnWidth(1,102); ui->tableView->setColumnWidth(2,102); ui->tableView->setColumnWidth(3,300); ui->tableView->setSelectionBehavior(QTableView::SelectRows); int i = 0; if(query.exec()){ while(query.next()){ model->setItem(i,0,new QStandardItem(query.value("username").toString())); //设置字符颜色 model->item(i,0)->setForeground(QBrush(QColor(255, 0, 0))); //设置字符位置 model->item(i,0)->setTextAlignment(Qt::AlignCenter); model->setItem(i,1,new QStandardItem(query.value("password").toString())); model->setItem(i,2,new QStandardItem(query.value("group").toString())); model->setItem(i,3,new QStandardItem(query.value("note").toString())); i++; } }else{ qDebug() << "执行SQL语句发生错误"; } }
执行效果
Dialog_users::eventFilter的实现,三个label分别对应右上角的三个图标
bool Dialog_users::eventFilter(QObject *obj, QEvent *event){ if (obj == ui->label_add_user) { if (event->type() == QEvent::MouseButtonPress){ slotAddUser(); qDebug() << "add"; } }else if(obj == ui->label_delete_user){ if (event->type() == QEvent::MouseButtonPress){ qDebug() << "delete user label clicked"; if(ui->tableView->selectionModel()->selectedIndexes().empty()){ QMessageBox::information(this, "提示", "请先选中要删除的行", QMessageBox::Ok); return false; } QMessageBox mess(QMessageBox::Question, "删除提示", "确定删除选中的用户吗?" , NULL); QPushButton *okButton = mess.addButton(tr("确定"), QMessageBox::AcceptRole); QPushButton *cancelButton = mess.addButton(tr("取消"),QMessageBox::RejectRole); mess.exec(); if ((QPushButton*)mess.clickedButton() == okButton) { slotDeleteUsers(); } } }else if(obj == ui->label_edit_user){ if (event->type() == QEvent::MouseButtonPress){ slotEditUser(); // qDebug() << "edit"; } } else{ return Dialog_users::eventFilter(obj, event); } }
slotAddUser槽函数的实现
void Dialog_users::slotAddUser(){ dialog_useradd = new Dialog_useradd(this); dialog_useradd->setModal(true); this->connect(dialog_useradd, SIGNAL(signalUserAdded(QString)), this, SLOT(slotUserAdded(QString)));//添加成功之后发出信号,接收信号的槽函数把添加的数据显示在tabelView里面 dialog_useradd->exec(); }
slotUserAdded槽函数的实现
void Dialog_users::slotUserAdded(QString username){ QString sql = "select * from h_user where username = :username";//将添加的用户名作为参数传过来 QSqlQuery query; query.prepare(sql); query.bindValue(":username", username); if(query.exec()){ if(query.next()){ // qDebug() << model->rowCount(); int i = model->rowCount(); model->setItem(i,0,new QStandardItem(query.value("username").toString())); //设置字符颜色 model->item(i,0)->setForeground(QBrush(QColor(255, 0, 0))); //设置字符位置 model->item(i,0)->setTextAlignment(Qt::AlignCenter); model->setItem(i,1,new QStandardItem(query.value("password").toString())); model->setItem(i,2,new QStandardItem(query.value("group").toString())); model->setItem(i,3,new QStandardItem(query.value("note").toString())); } } }
slotEditUser槽函数的实现
void Dialog_users::slotEditUser(){ qDebug() << ui->tableView->currentIndex().row(); qDebug() << model->item(ui->tableView->currentIndex().row(), 0)->text(); dialog_useredit = new Dialog_useredit(this); dialog_useredit->setUsername(model->item(ui->tableView->currentIndex().row(), 0)->text());//将要修改的用户名作为参数传过去 dialog_useredit->setValue();//将要修改的用户的信息填写到界面中 dialog_useredit->setModal(true); this->connect(dialog_useredit, SIGNAL(signalUserEdited(QString)), this, SLOT(slotUserEdited(QString)));//修改完用户的信息之后要把更新之后的数据在tabelView中显示出来 dialog_useredit->exec(); }
slotUserEdited槽函数的实现
void Dialog_users::slotUserEdited(QString username){//修改完用户信息之后刷新用户列表 qDebug() << "signal recieved"; QString sql = "select * from h_user where username = :username"; QSqlQuery query; query.prepare(sql); query.bindValue(":username", username); if(query.exec()){ if(query.next()){ int i = ui->tableView->currentIndex().row(); model->setItem(i,0,new QStandardItem(query.value("username").toString())); //以下两句加上时,首次进入用户列表界面,编辑第一个用户,提交时会发生异常,暂未找到原因 //原因:ui->tableView->currentIndex().row()第一次输出时0,后面输出变成了-1,暂未找到原因 model->item(i,0)->setForeground(QBrush(QColor(255, 0, 0))); model->item(i,0)->setTextAlignment(Qt::AlignCenter); // qDebug() << ui->tableView->currentIndex().row(); model->setItem(i,1,new QStandardItem(query.value("password").toString())); // qDebug() << query.value("group").toString(); // qDebug() << ui->tableView->currentIndex().row(); model->setItem(i,2,new QStandardItem(query.value("group").toString())); // qDebug() << ui->tableView->currentIndex().row(); model->setItem(i,3,new QStandardItem(query.value("note").toString())); // qDebug() << ui->tableView->currentIndex().row(); } } }
slotDeleteUsers槽函数的实现。删除用户时可能一次删除多个用户,这段代码我没仔细研究,经过测试没什么问题。
void Dialog_users::slotDeleteUsers(){ QItemSelectionModel *selections = ui->tableView->selectionModel(); QModelIndexList selected = selections->selectedIndexes();//得到选中的列 QMap<int, int> rowMap; foreach (QModelIndex index, selected) { rowMap.insert(index.row(), 0); } int rowToDel; QMapIterator<int, int> rowMapIterator(rowMap); rowMapIterator.toBack(); while (rowMapIterator.hasPrevious()) { rowMapIterator.previous(); rowToDel = rowMapIterator.key();//当前待删除的行 qDebug() << "rowToDel:" << rowToDel; QSqlQuery query; QString username = model->item(rowToDel, 0)->text();//当前行的第0列是username qDebug() << username; QString sql = "delete from h_user where username = :username"; query.prepare(sql); query.bindValue(":username", username); if(query.exec()){ qDebug() << "删除成功!!!"; model->removeRow(rowToDel); }else{ qDebug() << "删除失败,username=" << username; QMessageBox::information(this, "提示", "*** 删除失败 ***", QMessageBox::Ok); } } }
添加、修改Dialog的实现
void Dialog_useradd::slotAddUser(){ QString username = ui->username->text();//取得用户输入的值 QString password = ui->password->text(); QString group = ui->group->currentText(); QString note = ui->note->toPlainText(); if(username.length() < 5){ QMessageBox::information(this, "提示", "用户名不能小于5位", QMessageBox::Ok); }else if(password.length() < 5){ QMessageBox::information(this, "提示", "密码不能小于5位", QMessageBox::Ok); }else{ QSqlQuery query; QString sql = "select * from h_user where username = :username"; query.prepare(sql); query.bindValue(":username", username); if(query.exec()){ if(query.next()){ qDebug() << "user already exists"; QMessageBox::information(this, "提示", "该用户名已经存在!", QMessageBox::Ok); }else{ sql="insert into [h_user] ([username], [password], [group], [note]) values (:username, :password, :group, :note)"; query.prepare(sql); query.bindValue(":username", username); query.bindValue(":password", password); query.bindValue(":group", group); query.bindValue(":note", note); if(query.exec()){ QMessageBox::information(this, "提示", "添加成功", QMessageBox::Ok); emit signalUserAdded(username);//发出添加用户成功信号,父窗口收到信号后刷新 //qDebug() << "发出信号"; this->close(); }else{ QMessageBox::information(this, "提示", "添加失败", QMessageBox::Ok); } } } } }
void Dialog_useredit::setValue(){ QString sql = "select * from h_user where username = :username"; QSqlQuery query; query.prepare(sql); query.bindValue(":username", username); if(query.exec()){ if(query.next()){//将待修改的用户信息填写到UI中 ui->username->setText(query.value("username").toString()); ui->password->setText(query.value("password").toString()); ui->group->setCurrentText(query.value("group").toString()); ui->note->setText(query.value("note").toString()); } } }
void Dialog_useredit::slotEditUserAction(){ QString username = ui->username->text(); QString password = ui->password->text(); if(password.length()<5){ QMessageBox::information(this, "提示", "密码不能小于5位", QMessageBox::Ok); }else{ QString group = ui->group->currentText(); QString note = ui->note->toPlainText(); QString sql = "update h_user set [password] = :password, [group] = :group, [note] = :note where username = :username"; QSqlQuery query; query.prepare(sql); query.bindValue(":password", password); query.bindValue(":group", group); query.bindValue(":note", note); query.bindValue(":username", this->username); if(query.exec()){ qDebug() << "update information successfully!!!"; qDebug() << "signal emited!!!1"; emit signalUserEdited(this->username);//父窗口中接收该信号 qDebug() << "signal emited!!!2"; this->close(); } } }
补充,eventFilter实现中,可以将要进行的操作直接写在if中,不用写槽函数。dialo_customer中是这样实现的
bool Dialog_customers::eventFilter(QObject *obj, QEvent *event){ if(obj == ui->label_view){ // qDebug() << "label_view"; if(event->type() == QEvent::MouseButtonPress){ if(ui->tableView->selectionModel()->selectedIndexes().empty()){ QMessageBox::information(this, "提示", "请先选中要查看的行", QMessageBox::Ok); return false; } dialog_customersview = new Dialog_customersview(this); dialog_customersview->setModal(true); dialog_customersview->setCustomername(model->item(ui->tableView->currentIndex().row(), 0)->text()); dialog_customersview->setValue(); dialog_customersview->exec(); } }else if(obj == ui->label_add){ if(event->type() == QEvent::MouseButtonPress){ dialog_customeradd = new Dialog_customeradd(this); this->connect(dialog_customeradd, SIGNAL(signalCustomerAdded(QString)), this, SLOT(slotCustomerAdded(QString))); dialog_customeradd->setModal(true); dialog_customeradd->exec(); } }else if(obj == ui->label_delete){ if(event->type() == QEvent::MouseButtonPress){ if(ui->tableView->selectionModel()->selectedIndexes().empty()){ QMessageBox::information(this, "提示", "请先选中要删除的行", QMessageBox::Ok); return false; } QMessageBox mess(QMessageBox::Question, "删除提示", "确定删除选中的客户吗?" , NULL); QPushButton *okButton = mess.addButton(tr("确定"), QMessageBox::AcceptRole); QPushButton *cancelButton = mess.addButton(tr("取消"),QMessageBox::RejectRole); mess.exec(); if ((QPushButton*)mess.clickedButton() == okButton) { QItemSelectionModel *selections = ui->tableView->selectionModel(); QModelIndexList selected = selections->selectedIndexes(); // qDebug() << selected.empty(); QMap<int, int> rowMap; foreach (QModelIndex index, selected) { rowMap.insert(index.row(), 0); // qDebug() << index.row(); } int rowToDel; QMapIterator<int, int> rowMapIterator(rowMap); rowMapIterator.toBack(); while (rowMapIterator.hasPrevious()) { rowMapIterator.previous(); rowToDel = rowMapIterator.key(); // qDebug() << "rowToDel:" << rowToDel; QSqlQuery query; QString customername = model->item(rowToDel, 0)->text(); // qDebug() << customername; QString sql = "delete from h_customer where customername = :customername"; query.prepare(sql); query.bindValue(":customername", customername); if(query.exec()){ qDebug() << "deleted successfully!!!"; model->removeRow(rowToDel); }else{ qDebug() << "delete failed,customername=" << customername; QMessageBox::information(this, "提示", "*** 删除失败 ***", QMessageBox::Ok); } } } } }else if(obj == ui->label_edit){ if(event->type() == QEvent::MouseButtonPress){ if(ui->tableView->selectionModel()->selectedIndexes().empty()){ QMessageBox::information(this, "提示", "请先选中要修改的行", QMessageBox::Ok); return false; } // qDebug() << "edit"; dialog_customeredit = new Dialog_customeredit(this); this->connect(dialog_customeredit, SIGNAL(signalCustomerEditted(QString)), this, SLOT(slotCustomerEditted(QString))); dialog_customeredit->setCustomername(model->item(ui->tableView->currentIndex().row(), 0)->text()); dialog_customeredit->setValue(); dialog_customeredit->setModal(true); dialog_customeredit->exec(); } } }
待完成的功能:翻页,文件上传下载
源码下载http://yunpan.cn/Q7yyar2rkHPuV 访问密码 6b7b
本文出自 “优赛工作室” 博客,谢绝转载!