主界面用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:umgsai@126.com");
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
本文出自 “优赛工作室” 博客,谢绝转载!