关于学生管理系统的总结

9 篇文章 1 订阅
4 篇文章 0 订阅
1-如何将窗体的标题栏状态栏工具栏去掉
   this->setWindowFlags(Qt::FramelessWindowHint | windowFlags());

或者

this->setWindowFlags(Qt::FramelessWindowHint);

这种窗体将无法被拖动。

解决办法

1-头文件添加两个事件,

void mouseMoveEvent(QMouseEvent *event);  //鼠标移动
 void mousePressEvent(QMouseEvent *ev);    //鼠标单击

void Login::mouseMoveEvent(QMouseEvent *event)
{
    //只允许左键拖动   持续的动作
    if(event->buttons()&Qt::LeftButton)  //buttons处理的是长事件,button处理的是短暂的事件
    {
        //窗口跟随鼠标移动
        //窗口的新位置=鼠标当前位置-差值
        move(event->globalPos()-m_pt);

    }
}

void Login::mousePressEvent(QMouseEvent *ev)
{
    // 如果鼠标左键按下  单击
    if(ev->button()&Qt::LeftButton)
    {
        //求差值=鼠标当前位置-窗口左上角点
        m_pt=ev->globalPos()-this->geometry().topLeft();  //geometry()是矩形窗口,topLeft()是左上角的信息。
    }
}

2-添加三个事件

#include <QMouseEvent>
protected:
    void mousePressEvent(QMouseEvent *e);
    void mouseMoveEvent(QMouseEvent *e);
    void mouseReleaseEvent(QMouseEvent *e);
    private:
    QPoint last;
//可以在构造函数中初始一下last变量用其成员函数setX,setY就是了
//接下来就是对三个鼠标事件的重写
void login::mousePressEvent(QMouseEvent *e)
{
    last = e->globalPos();
}
void login::mouseMoveEvent(QMouseEvent *e)
{
    int dx = e->globalX() - last.x();
    int dy = e->globalY() - last.y();
    last = e->globalPos();
    move(x()+dx, y()+dy);
}
void login::mouseReleaseEvent(QMouseEvent *e)
{
    int dx = e->globalX() - last.x();
    int dy = e->globalY() - last.y();
    move(x()+dx, y()+dy);
}
2-如何给背景添加图片,要求图片不会拉伸。自动缩放
 // 设置背景图片
    setAutoFillBackground(true);    // 这句要加上, 否则可能显示不出背景图.
    QPalette palette = this->palette();
//  QResource::registerResource(":/res/index.jpg");//这个是图片的存放位置
    palette.setBrush(QPalette::Window,
     QBrush(QPixmap(":/res/index.jpg").scaled(    // 缩放背景图.
     this->size(),
                                                                  Qt::IgnoreAspectRatio,
                                                                  Qt::SmoothTransformation)));    // 使用平滑的缩放方式
    this->setPalette(palette);

3-如何给控件设置样式
  QString str4=QString("QPushButton{font: 12pt Agency FB;font: 12pt 华文彩云; background-color: rgb(127, 140, 141);}"
                       "QPushButton:hover{font: 12pt Agency FB;font: 12pt 华文彩云; background-color: rgb(255, 170, 0);}");
 ui->Login_2->setStyleSheet(str4);

注意:之前在ui 界面设置的样式,会被我们使用qss的样式覆盖掉. 设置hover属性时,之前的属性应该用qss写在和hover属性同一个字符串中,而且若想保留部分的旧有样式,那旧有样式也要在hover重写

(这样能避免被qss覆盖旧有属性)

给lineEdit 设置样式时.字体样式要单独设置.(搞不清楚)

    QString str3=QString(""
                         "QLineEdit:hover{ font: 14pt 微软雅黑;  }"
                         "QLineEdit:hover{ font: 14pt 微软雅黑;  background-color: #34495e; color:white;}");
    ui->admin_searchbox->setStyleSheet(str3);
    ui->admin_searchbox->setFont( QFont("微软雅黑" ,14 ));//不加上这个没法设置文字属性

4-Qt怎么连接数据库

当连接类型是sqllite时

头文件包含

  #include< QSqlDatabase>
  private:
  QSqlDatabase m_db;

.cpp文件

//这是sqllite的操作语句

    //不存在相关驱动就加载
    if (QSqlDatabase::drivers().isEmpty())
        QMessageBox::information(nullptr, tr("No database drivers found"),
                                 tr("This demo requires at least one Qt database driver. "
                                    "Please check the documentation how to build the "
                                    "Qt SQL plugins."));


    m_db = QSqlDatabase::addDatabase("QSQLITE");//这里的m_db是我在头文件创建的数据库对象
#if 0//应用程序的输出目录,以后发布时,把数据库db文件放同级目录就行
    auto str= QCoreApplication::applicationDirPath()+="data.db";
    qDebug()<<str;
    
#endif

    m_db.setDatabaseName("C:\\Users\\X-SHELL-GOOGLE\\Desktop\\Data\\data.db");
//这个是数据库的存放位置
    if (!m_db.open())

        QMessageBox::warning(nullptr, tr("Unable to open database"), tr("An error occurred while "));


};
若选择的为mysql

#if 1

    QSqlDatabase db=QSqlDatabase::addDatabase("QMYSQL");
    //数据库连接所需要设置的信息
    db.setHostName("127.0.0.1");//
    db.setDatabaseName("stu_sys");//数据库名字
    db.setUserName("root");//数据库用户名
    db.setPassword("root");//数据库密码
    db.setPort(3306);//数据库端口号
   //连接数据库
    bool ok=db.open();
    if(ok)
    {
        qDebug()<<"success";
    }
    else {
        qDebug()<<"fail!";
    }





#endif


注意:

但注意,mysql数据库是非文件型数据库。也就是你没法找到他的数据库文件进行向sqllite 那样直接用数据库文件的相对路径直接使用数据库(后面有)

请问,qt连接MySQL数据库用的setdatabaseName怎么使用mysql数据库名字的相对路径( 找不到mysql数据库文件相对的路径 )


mysql只需要知道 数据库名称,用户名,密码,就行,不需要知道库文件在哪。mysql是一个服务,它隔离了文件与用户请求。
即使是你访问本机,也只能用localhost 或127.0.0.1通过网络接口,它只有网络接口

那别的电脑要使用怎么办
我这个数据库不在他电脑上
mysql数据库怎么迁移到另一台电脑

导出成sql文件,另一台电脑导入


本地使用的话不装数据库,就换成sqllite了


若采用云数据库(mysql为例)

你将得到以下

申请成功
数据库名称:stu_sys
数据库用户:rootroot
数据库密码:b7775733c7d1b39d
数据库地址:mysql.sqlpub.com:3306
注册邮箱:2278135632@qq.com

打开这个mysql数据库的方式(控制台为例)

mysql  -h 主机IP -u 用户名 -p密码 

在qt中连接这个数据库的代码(这里的主机ip可以是域名,域名会解析为ip)

#if 0

    QSqlDatabase db=QSqlDatabase::addDatabase("QMYSQL");
    //数据库连接所需要设置的信息
    db.setHostName("mysql.sqlpub.com");//填申请到的域名,自动解析ip
    db.setDatabaseName("stu_sys");//数据库名字
    db.setUserName("rootroot");//数据库用户名
    db.setPassword("b7775733c7d1b39d");//数据库密码
    db.setPort(3306);//数据库端口号
   //连接数据库
    bool ok=db.open();
    if(ok)
    {
        qDebug()<<"success";
    }
    else {
        qDebug()<<"fail!";
    }



#endif

5-在Qt中如何使用数据库的sql语句

以增加操作为例子

bool stuSql::addStu(stuInfo &info)//函数之前在stusql.h中定义
{
    QSqlQuery sql(m_db);//执行sqllite语句前必须使用此句//m_db是在连接数据库时候就创建的数据库对象
    //注意字符串字段加引号
    QString strSql=QString ("insert into student values(null,'%1',%2,%3,%4,%5,'%6','%7')")
            .arg(info.name).
            arg(info.age).
            arg(info.grade).arg(info.m_Class).arg(info.studentid).arg(info.phone).arg(info.wechat);
   
    //QString的参数可以用%数字代替.  这里有一个null,表明这里是一个主键,他的维护由数据库负责.
    sql.exec(strSql);//  在这里可以使用auto ret =sql.exec(strSql); 通过返回值来判断sql语句是否使用成功,如果成功就会返回true.
    
    
    return 0;
}
判断数据库的语句是否执行成功

以删除的函数为例

头文件包含

#include<QError>
bool stuSql::delUser(int& id)
{
    QSqlQuery sql(m_db);//执行sqllite语句前必须使用此句
    sql.exec(QString("delete from username where id='%1' ").arg(id));
    //    return sql.next();
    QSqlError e=sql.lastError();
    if(e.isValid())
    {
        qDebug()<<"343行 stusql delUser "<<e;
    }
    return 0;
}

当对数据库的成员执行select*from table等选择操作时,应该使用这样的while结构

QList<UserInfo> stuSql::getAllUser()
{
    QList<UserInfo> L;
    
    
    UserInfo m_Info;//这里的UserInfo是一个结构体类型
    
    
    QSqlQuery sql(m_db);//执行sqllite语句前必须使用此句
    sql.exec("select * from usename");
    
    while (sql.next()) {
        
        m_Info.username= sql.value(0).toString();
        m_Info.password  = sql.value(1).toString();
        m_Info.aut= sql.value(2).toString();
        L.push_back(m_Info);
    }
    
    return L;
};
quint32 stuSql::getStuCnt()
{
    QSqlQuery sql(m_db);//执行sqllite语句前必须使用此句
    sql.exec("select count(id) from student");  //sql.exec("select * from student");
    
    quint32 uicnt=0;
    while (sql.next()) {
        uicnt= sql.value(0).toUInt();//打印人数
 
    }
    //    qDebug()<<uicnt;打印总人数
    
    return uicnt;
}

bool stuSql::isExist(QString strUser)  //只是检索用户
{
    QSqlQuery sql(m_db);//执行sqllite语句前必须使用此句
    sql.exec(QString("select*from username where username='%1' ").arg(strUser));
    return sql.next();
    
    /*
如果无法检索到该记录,则结果将放在最后一条记录之后,并返回 false。如果成功检索到记录,则返回 true。\
     */
    
}

关于 sql.next() 解释

next()方法的作用:指针指向下一条记录,有记录(有值)返回true并把记录内容存入到对应的对象中,也就是obj.next()的obj中。如果没有返回false。

2.next()方法的应用:一般和ResultSet对象和while循环一起使用,去迭代结果集,并在循环中调用getXXX(intfieldIndex)/getXXX(String columnName)方法获取字段值。

过程:ResultSet对象具有指向其当前数据行的指针。开始,指针被置于第一行。

.next()方法将指针移动到下一行,然后while循环迭代遍历ResultSet对象。

while (obj.next()) {undefined

              }

光标移动到下一行数据,有值(数据)返回true并迭代遍历,没有值,说明表中的行数已经走完,所以返回false退出循环。 
6-给label增加点击事件.(默认Qlabel是不提供点击事件的)

头文件增加

  bool eventFilter(QObject *obj,QEvent *event);//声名使用过滤器 //myLabel加上点击效果

.cpp文件

  ui->myLabel->installEventFilter(this); //给控件安装事件过滤器
  
bool dlgAdmin::eventFilter(QObject *obj, QEvent *event)
{
    //判断对象是否为myButton   
    if(obj == ui->myLabel-)
    {
        //判断事件类型是否为鼠标事件
        if(event->type() == QEvent::MouseButtonPress)
        {
            //转换为鼠标事件
            QMouseEvent  *mouseenevt = static_cast<QMouseEvent*>(event);

            //判断鼠标左键点击
            if(mouseenevt->button() == Qt::LeftButton)
            {  qDebug()<<"label被点击";
            
                //emit apply_admin();         //发送一个信号
                
            }
        }
    }
    return  false;
}
7-给多个按钮绑定多个不同的事件

头文件添加

  bool eventFilter(QObject *target, QEvent *e);

.cpp文件添加


bool MainWindow::eventFilter(QObject *target, QEvent *e)      //前面要注册事件监听.给按钮控件注册的
{
    if(target == ui->deleteone)//按钮 deleteone的事件
    {
        if(e->type() == QEvent::MouseButtonDblClick) //双击事件
        {
        
        qDebug()<<"deleteone双击";
        
        }


        else if(e->type() == QEvent::QEvent::MouseButtonPress)//单击事件
        {
   qDebug()<<"deleteone单击";

        }

    }





    else if(target == ui->delete_2) //按钮delete_2的事件
    {
        if(e->type() == QEvent::MouseButtonDblClick) //双击事件
        {
           
   qDebug()<<"delete_2双击";
        }


        else if(e->type() == QEvent::QEvent::MouseButtonPress)//单击事件
        {

   qDebug()<<"delete_2单击";


        }

    }




    return 0;

}


8-选中 tablewidget 的任意行,进行删除操作

.cpp文件中

OnDelete(ui->tableWidget);//传入你要删除的任意行的那个表

void MainWindow:: OnDelete(QTableWidget* pTable)
{
    if (!pTable)
    {
        return;
    }
    std::vector<int> vecItemIndex;//保存选中行的行号
    QList<QTableWidgetItem*> selections = pTable->selectedItems();
    for (int i = 0; i < selections.size(); i++)
    {
        vecItemIndex.push_back(selections.at(i)->row());//存储选中的行
        //qDebug()<<selections.at(i)->row();
    }


    sort(vecItemIndex.rbegin(), vecItemIndex.rend());

    vecItemIndex.erase(std::unique(vecItemIndex.begin(), vecItemIndex.end()), vecItemIndex.end());//去除重复的行号
    //vecItemindex就存放着得到的行号
    int number =0 ;
    for (unsigned int k = 0 ; k < vecItemIndex.size(); k++)
    {
        number=vecItemIndex[k];//存放获取到的id
        int id=   ui->tableWidget->item(number,1)->text().toUInt();
        m_ptrStuSql->delStu(id);//调用m_ptrStuSql的delStu函数


    }

}
bool stuSql::delStu(int id)
{
    QSqlQuery sql(m_db);//执行sqllite语句前必须使用此句
    //注意字符串字段加引号
    auto ret= sql.exec(QString ("delete from username where id=%1").arg(id));
    qDebug()<<ret;
    return  0;
    
}
9-防止删除表的时候id不会清零,重新开始计数
void stuSql::clearStuTab()
{
    QSqlQuery sql(m_db);//执行sqllite语句前必须使用此句
    sql.exec(QString("delete from student "));
    sql.exec("DELETE FROM sqlite_sequence WHERE name='student'");//删除id自增
}
10-选中tableWidget的任意一行,获取一行信息

头文件

void  show_prodcut_sets(int i,int col)

.cpp文件

    connect(ui->tableWidget,SIGNAL(cellClicked(int,int)),this,SLOT(show_prodcut_sets(int,int)));

.cpp文件

void MainWindow::show_prodcut_sets(int i,int col)
{
    qDebug() << "所点击的单元格的row=" << i << ",col=" << col;//获取到了选中的行号和列号,我们只要行号
    // 获取所点击的单元格
    //学生信息部分(管理员才能看所有学生)
    ui->stuName->setText(  ui->tableWidget->item(i,2)->text());
    ui->stuGrade->setText( (ui->tableWidget->item(i,4)->text()));
    ui->stuiWechat->setText( ui->tableWidget->item(i,8)->text());
    ui->stuAge->setText( ui->tableWidget->item(i,3)->text());
    ui->stuScore->setText( ui->tableWidget->item(i,6)->text());
    ui->stiuphone->setText( ui->tableWidget->item(i,7)->text());
    ui->stiuId->setText( ui->tableWidget->item(i,1)->text());

    ui->stiuClass->setText( ui->tableWidget->item(i,5)->text());




    QTableWidgetItem* item = ui->tableWidget->item(i ,col);
    qDebug() << item->text();
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丁金金

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值