天天看點

【2021-1-5】QT+SQLsever資料庫的資料管理系統

QT+SQLsever資料庫的資料管理系統

  • ​​目錄​​
  • ​​登入界面​​
  • ​​統計圖表制作​​
  • ​​QT界面之間傳遞參數​​
  • ​​左鍵點選tablevie後跳出菜單​​
  • ​​點選表格在label上顯示圖檔、下載下傳、上傳到資料庫​​
  • ​​儲存widget為PDF​​
  • ​​儲存tableview為Excel​​
  • ​​lineedit美化,combo box 美化​​
  • ​​作者有話說​​

目錄

該系統的功能有:圖表顯示,圖像界面對資料的增删改查,界面跳轉緩沖進度條,開機界面,角色管理等。

登入界面

【2021-1-5】QT+SQLsever資料庫的資料管理系統

資料庫連接配接:

/********************************資料庫連接配接******************************/
    QSqlDatabase db=QSqlDatabase::addDatabase("QODBC");
    db.setDatabaseName(QString("DRIVER={SQL SERVER};"
                               "SERVER=%1;" //伺服器名稱
                               "DATABASE=%2;"//資料庫名
                               "UID=%3;"//登入名
                               "PWD=%4;"//密碼
                               ).arg("……")
                                .arg("……")
                                .arg("……")
                                .arg("……"));
     if (!db.open())
     {
          qDebug()<<"connect sql server failed!";//資料庫登入失敗時輸出
     }else
     {
          qDebug()<<"connect sql server successfully!";//資料庫登入成功時輸出
     }      

回車快捷鍵:

/************Enter鍵按鈕快捷鍵***********/
    ui->pushButton->setDefault(true);//按鈕預設選中
    ui->pushButton->setShortcut(QKeySequence::InsertParagraphSeparator);//将小鍵盤Enter鍵與登入按鈕綁定在一起
    ui->pushButton->setShortcut(Qt::Key_Enter);//将字母區Enter鍵與登入按鈕綁定在一起
    ui->pushButton->setShortcut(Qt::Key_Return);//将小鍵盤Enter鍵與登入按鈕綁定在一起      

視窗關閉詢問是否退出:

#include <QCloseEvent>

void closeEvent(QCloseEvent *event);

/*************視窗關閉時詢問是否退出*************/
void Denglu::closeEvent(QCloseEvent *event)
{
   QMessageBox::StandardButton result=QMessageBox::question(this, "确認", "确定要退出本系統嗎?",
                      QMessageBox::Yes|QMessageBox::No |QMessageBox::Cancel,
                      QMessageBox::No);

    if (result==QMessageBox::Yes)
        event->accept();
    else
        event->ignore();
}      

輸入框提示:

ui->lineEdit->setPlaceholderText("請輸入!");      

界面跳轉緩沖:

#include <QProgressDialog>
#include <QTimer>


           //跳轉到主界面
           this->hide();
            //建立對象,參數含義:對話框正文,取消按鈕名稱,進度條範圍
            QProgressDialog *pd;
            pd = new QProgressDialog("正在跳轉...","取消",0,100,this);
            //模态對話框
            pd->setWindowModality(Qt::WindowModal);
            //如果進度條運作的時間小于5,進度條就不會顯示,預設是4S
            //pd->setMinimumDuration(5);
            //設定标題
            pd->setWindowTitle("界面跳轉中請稍後");
            //處理過程。。。
            pd->setRange(0, 100000);
            pd->setMinimumDuration(0);
            pd->setAttribute(Qt::WA_DeleteOnClose, true);
            //QProgressBar q;
            for (int i = 0; i < 100000; i++)
            {
               pd->setValue(i);
               QCoreApplication::processEvents();
                       if(pd->wasCanceled())
                           break;
            }
           MainWindow *w = new MainWindow;
           w->show();
           pd->hide();      

統計圖表制作

柱狀圖制作:

/*****************柱狀圖************************/
void MainWindow::onLine(){
    /******************定義變量****************/
    int i =0;
    int j =0;
    int x[200];//數字存儲
    int y[200];
    for(j=0;j<200;j++){
        x[j]=0;
        y[j]=0;
    }
    QString n0[200];//商品資訊名稱
    QString n1[100];//維修單産品類型
    QString n2[3000];//送貨單名稱及規格
    int n3[3000];//送貨單名稱及規格,數量
    QString str;
    QSqlQuery query;
    int a=0,b=0;
    /*************執行**********/
    i=0;
    str = QString("select 名稱 from 商品資訊");
    query.exec(str);
        while(query.next()){
            n0[i] = query.value(0).toString();
            i++;
        }
    i=0;
    str = QString("select 産品類型 from 維修售後統計表 where 修好日期>'%1'and 修好日期<'%2'").arg(time1).arg(time2);
        query.exec(str);
        while(query.next()){
            n1[i] = query.value(0).toString();
            i++;
        }
    i=0;
    str = QString("select 名稱及規格,sum(出庫數量) from (select 名稱及規格,sum(送貨單.數量) as 出庫數量 from 送貨單,商品資訊 where 商品資訊.名稱=送貨單.名稱及規格 and (送貨單.消息類型='正常' or 送貨單.消息類型='贈送' or 送貨單.消息類型='現金') and 送貨日期>'%1'and 送貨日期<'%2'group by 名稱及規格 union select 名稱及規格,-sum(送貨單.數量) from 送貨單,商品資訊 where 商品資訊.名稱=送貨單.名稱及規格 and 送貨單.消息類型='退貨'and 送貨日期>'%1'and 送貨日期<'%2'group by 名稱及規格)as a group by 名稱及規格").arg(time3).arg(time4);
            query.exec(str);
            while(query.next()){
                n2[i] = query.value(0).toString();
                n3[i] = query.value(1).toInt();
                i++;
            }
            for(i=0;i<200;i++){
                for(j=0;j<100;j++){ 
                    if(n0[i]==n2[j]){
                        y[i]=n3[j];
                    }
                    if(n0[i]==n1[j]){
                        x[i]=x[i]+1;
                    }
                }
            }
            QString str02 = QString("select 産品類型 from 維修售後統計表 where 修好日期>'%1'and 修好日期<'%2'").arg(time1).arg(time2);
            query.exec(str02);
            while (query.next()) {
                a++;
            }
            ui->la1->setText(QString::number(a));
            for(j=0;j<200;j++){
                b += y[j];
            }
            ui->la3->setText(QString::number(b));
        /******************畫柱狀圖*******************/
        QBarSet *set0 = new QBarSet("XXXXX");
        QBarSet *set1 = new QBarSet("XXXXX");
        for(j=0;j<200;j++){
          *set0 << x[j];
          *set1 << y[j];
        }
        QBarSeries *series = new QBarSeries();
        QBarSeries *series1 = new QBarSeries();
        series->append(set0);
        series1->append(set1);

        series->setLabelsPosition(QAbstractBarSeries::LabelsInsideEnd); // 設定資料系列标簽的位置于資料柱内測上方
        series->setLabelsVisible(true); // 設定顯示資料系列标簽
        connect(series, SIGNAL(hovered(bool, int, QBarSet*)), this, SLOT(sltTooltip(bool, int, QBarSet*)));
        series1->setLabelsPosition(QAbstractBarSeries::LabelsInsideEnd); // 設定資料系列标簽的位置于資料柱内測上方
        series1->setLabelsVisible(true); // 設定顯示資料系列标簽
        connect(series1, SIGNAL(hovered(bool, int, QBarSet*)), this, SLOT(sltTooltip_2(bool, int, QBarSet*)));

        QChart *chart = new QChart();
        QChart *chart1 = new QChart();
        chart->addSeries(series);
        chart1->addSeries(series1);
        chart->setTitle("XXXXXX表");
        chart1->setTitle("XXXXX表");
        chart->setAnimationOptions(QChart::SeriesAnimations);
        chart1->setAnimationOptions(QChart::SeriesAnimations);

        for(i=0;i<200;i++){
            categories << n0[i];
            categories1 << n0[i];
        }
        QBarCategoryAxis *axis = new QBarCategoryAxis();
        QBarCategoryAxis *axis1 = new QBarCategoryAxis();
        axis->append(categories);
        axis1->append(categories1);
        axis->setGridLineVisible(true);
        axis1->setGridLineVisible(true);

        chart->createDefaultAxes();//建立預設的左側的坐标軸(根據 QBarSet 設定的值)
        chart1->createDefaultAxes();
        chart->setAxisX(axis, series);//設定坐标軸
        chart1->setAxisX(axis1,series1);

        chart->legend()->setVisible(true); //設定圖例為顯示狀态
        chart1->legend()->setVisible(true);
        chart->legend()->setAlignment(Qt::AlignBottom);//設定圖例的顯示位置在底部
        chart1->legend()->setAlignment(Qt::AlignBottom);//設定圖例的顯示位置在底部
        ui->chart->setChart(chart);
        ui->chart_2->setChart(chart1);
}      

滑鼠懸停提示:

/*****************滑鼠懸停提示*********************/
void MainWindow::sltTooltip(bool b , int i, QBarSet* bar){
    if(b){
        ui->chart->setStyleSheet("QToolTip{border:1px solid rgb(118, 118, 118); background-color: #ffffff; color:#484848; font-size:12px;}"); //設定邊框, 邊框色, 背景色, 字型色, 字号
        ui->chart->setToolTip("X: "+categories.at(i)+"\n"+QString("Y: %1 ").arg(bar->at(i)));
    }else{
        ui->chart->setStyleSheet("QToolTip{border:1px solid rgb(118, 118, 118); background-color: #ffffff; color:#484848; font-size:12px;}"); //設定邊框, 邊框色, 背景色, 字型色, 字号
        ui->chart->setToolTip("滑鼠所處位置無資料");
    }
}      

QT界面之間傳遞參數

定義全局變量:

int a;
extern int a ;      

信号與槽連接配接:

#include <QProgressDialog>
#include <QTimer>

private slots:
    void onUpdate();
signals:
    void sendData(QString);   //用來傳遞資料的信号
this->hide();
    //建立對象,參數含義:對話框正文,取消按鈕名稱,進度條範圍
            QProgressDialog *pd;
            pd = new QProgressDialog("正在跳轉...","取消",0,100,this);
            //模态對話框
            pd->setWindowModality(Qt::WindowModal);
            //如果進度條運作的時間小于5,進度條就不會顯示,預設是4S
            //pd->setMinimumDuration(5);
            //設定标題
            pd->setWindowTitle("界面跳轉中請稍後");
            //處理過程。。。
            pd->setRange(0, 100000);
            pd->setMinimumDuration(0);
            pd->setAttribute(Qt::WA_DeleteOnClose, true);
            //QProgressBar q;
            for (int i = 0; i < 100000; i++)
            {
               pd->setValue(i);
            }
            Peijianxijiexiugai *p = new Peijianxijiexiugai;
            p->show();
            connect(this, SIGNAL(sendData(QString)),p, SLOT(receiveData(QString)));
            emit sendData(modelid);
           pd->hide();      

左鍵點選tablevie後跳出菜單

private:
    Ui::Peijianxijie *ui;
    QSqlQueryModel *model = new QSqlQueryModel;
    QString modelid;
    QString date1;
    QString date2;
    QString name;
    
modelid=model->data(model->index(index.row(),0)).toString();//擷取選中行資料
    name=model->data(model->index(index.row(),1)).toString();
    date1=model->data(model->index(index.row(),4)).toString();
    date2=model->data(model->index(index.row(),5)).toString();
    ui->l1->setText(date1);
    ui->l2->setText(date2);

    QMenu *menu = new QMenu(this);
    QAction *LookZhuban = new QAction(tr("……"), this);
    QAction *LookShou = new QAction(tr("……"), this);
    QAction *Update = new QAction(tr("……"),this);
    LookZhuban->setData(0);
    Update->setData(1);
    LookShou->setData(3);
    menu->addAction(Update);
    menu->addAction(LookZhuban);
    menu->addAction(LookShou);
    connect(LookZhuban, SIGNAL(triggered()), this, SLOT(onb1()));
    connect(LookShou, SIGNAL(triggered()), this, SLOT(onb2()));
    connect(Update, SIGNAL(triggered()), this, SLOT(onUpdate()));
    menu->exec(cursor().pos());
    //釋放記憶體
    QList<QAction*> list = menu->actions();
    foreach (QAction* pAction, list) delete pAction;
    delete menu;      

點選表格在label上顯示圖檔、下載下傳、上傳到資料庫

圖檔上傳:

QString id = ui->lineEdit_3->text();
    if(id==NULL){
           QMessageBox::question(NULL, "消息提示框", "請輸入id号", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
       }else{
           //擷取圖檔檔案
           QString strFileName = QFileDialog::getOpenFileName(this, tr("Open Image"), ".", tr("Image Files(*.jpg *.png *.bmp)"));
           if (strFileName.isEmpty())
           {
           QMessageBox::information(NULL, tr("Warning"), tr("You didn't select any files."));
           return;
           }

           //插入資料庫 TEST_PIC為資料庫表明  CONTENT為存儲照片字段 為Blob類型
           //将照片以二進制流的方式存到資料庫
           QPixmap pixmap(strFileName);
           QByteArray byteArray = QByteArray();
           QBuffer buffer(&byteArray);
           buffer.open(QIODevice::WriteOnly);
           pixmap.save(&buffer,"png",0);

           QString strQSL = QString("update XXXXX表 set 照片=? where id = '%1'").arg(id);
           QSqlQuery query;
           query.prepare(strQSL);
           query.addBindValue(byteArray);
           int a = query.exec();
           if(a){
               QMessageBox::question(NULL, "消息提示框", "上傳成功,請更新表格檢視", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
           }else{
               QMessageBox::question(NULL, "消息提示框", "上傳失敗", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
           }
       }      

圖檔下載下傳:

QString id = ui->lineEdit_3->text();
    if(id==NULL){
           QMessageBox::question(NULL, "消息提示框", "請輸入id号", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
       }else{
           //從資料庫讀取照片
           QByteArray byteText;
           QString strsql = QString("select 照片 from XXXXX表 where id='%1'").arg(id);
           QSqlQuery query;
           query.exec(strsql);
           while(query.next()){
             byteText = query.value(0).toByteArray();
           }
           if(byteText.size()==0){
              QMessageBox::question(NULL, "消息提示框", "導出失敗,該條消息中照片清單為空。", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
           }else{
               QString filename1 = QFileDialog::getSaveFileName(this,tr("Save Image"),"",tr("Images (*.png)")); //選擇路徑
               QString strsql = QString("select 照片 from XXXXX表 where id='%1' ").arg(id);
               int a = query.exec(strsql);
               bool b;
               while (query.next()) {
                 byteText = query.value(0).toByteArray();
                 QPixmap pix;
                 pix.loadFromData(byteText,"png");
                 b = pix.save(QString(filename1));//儲存從資料庫讀取的照片到本地
               }
               if(a&&b){
                   QMessageBox message(QMessageBox::NoIcon,  "消息提示框",  "檔案已成功導出,是否打開檔案", QMessageBox::Yes | QMessageBox::No, NULL);
                    if(message.exec() == QMessageBox::Yes)
                   {
                        QDesktopServices::openUrl(QUrl::fromLocalFile(filename1));
                   }
               }else{
                   QMessageBox::question(NULL, "消息提示框", "照片下載下傳失敗", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
               }
           }
       }      

圖檔顯示:

QString id = ui->lineEdit_3->text();
    if(id==NULL){
           QMessageBox::question(NULL, "消息提示框", "請輸入id号", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
       }else{
           //從資料庫讀取照片
           QByteArray byteText;
           QString strsql = QString("select 照片 from XXXXX表 where id='%1'").arg(id);
           QSqlQuery query;
           query.exec(strsql);
           while(query.next()){
             byteText = query.value(0).toByteArray();
           }
           if(byteText.size()==0){
              QMessageBox::question(NULL, "消息提示框", "顯示失敗,該條消息中照片清單為空。", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
           }else{
               //QString filename1 = QFileDialog::getSaveFileName(this,tr("Save Image"),"",tr("Images (*.png)")); //選擇路徑
               QString strsql = QString("select 照片 from XXXXX表 where id='%1' ").arg(id);
               query.exec(strsql);
               while (query.next()) {
                 byteText = query.value(0).toByteArray();
                 QPixmap pix;
                 pix.loadFromData(byteText,"png");
                 ui->label_3->setPixmap(pix);
               }
           }
       }      

儲存widget為PDF

QPrinter printer_pixmap(QPrinter::HighResolution);
    printer_pixmap.setPageSize(QPrinter::A4);  //設定紙張大小為A4
    printer_pixmap.setOutputFormat(QPrinter::PdfFormat);  //設定輸出格式為pdf
    QString filename1 = QFileDialog::getSaveFileName(this,tr("Save PDF"),"",tr("PDF (*.pdf)")); //選擇路徑
    if(filename1 !=""){
    printer_pixmap.setOutputFileName(filename1);   //設定輸出路徑
    QPixmap pixmap = QPixmap::grabWidget(ui->widget, ui->widget->rect());  //擷取界面的圖檔


    QPainter painter_pixmap;
    painter_pixmap.begin(&printer_pixmap);
    QRect rect = painter_pixmap.viewport();
    int multiple = rect.width()/pixmap.width();
    painter_pixmap.scale(multiple, multiple); //将圖像(所有要畫的東西)在pdf上放大multiple-1倍
    painter_pixmap.drawPixmap(40, 10, pixmap);  //畫圖
    painter_pixmap.end();

    QMessageBox message(QMessageBox::NoIcon,  "消息提示框",  "檔案已成功導出,是否打開檔案", QMessageBox::Yes | QMessageBox::No, NULL);
     if(message.exec() == QMessageBox::Yes)
    {
         QDesktopServices::openUrl(QUrl::fromLocalFile(filename1));
    }
    }      

儲存tableview為Excel

private slots:
     void Table2ExcelByHtml(QTableView *tableView, QString &title);


void MainWindow::Table2ExcelByHtml(QTableView *tableView, QString &title)
{
    QString fileName = QFileDialog::getSaveFileName(tableView, "儲存",QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "Excel 檔案(*.xls *.xlsx)");
    if(fileName != "")
    {
        QAxObject *excel = new QAxObject;
        if(excel->setControl("Excel.Application")) //連接配接Excel控件
        {
            excel->dynamicCall("SetVisible (bool Visible)","false"); //不顯示窗體
            excel->setProperty("DisplayAlerts", false); //不顯示任何警告消息,如果為true那麼在關閉是會出現類似"檔案已修改,是否儲存"的提示
            QAxObject *workBooks = excel->querySubObject("WorkBooks");//擷取工作簿集合
            workBooks->dynamicCall("Add"); //建立一個工作簿
            QAxObject *workBook = excel->querySubObject("ActiveWorkBook"); //擷取目前工作簿
            QAxObject *workSheet = workBook->querySubObject("Worksheets(int)", 1);

            int colCount = tableView->model()->columnCount();
            int rowCount = tableView->model()->rowCount();

            QAxObject *cell, *col;

            //标題行
            cell = workSheet->querySubObject("Cells(int, int)", 1, 1);
            cell->dynamicCall("SetValue(const QString&)", title);
            cell->querySubObject("Font")->setProperty("Size", 18);
            //調整行高
            workSheet->querySubObject("Range(const QString&)", "1:1")->setProperty("RowHeight", 30);
            //合并标題行
            QString cellTitle;
            cellTitle.append("A1:");
            cellTitle.append(QChar(colCount - 1 + 'A'));
            cellTitle.append(QString::number(1));
            QAxObject *range = workSheet->querySubObject("Range(const QString&)", cellTitle);
            range->setProperty("WrapText", true);
            range->setProperty("MergeCells", true);
            range->setProperty("HorizontalAlignment", -4108);
            range->setProperty("VertivcalAlignment", -4108);

            //列标題
            for (int i = 0; i < colCount; i++)
            {
                QString columnName;
                columnName.append(QChar(i + 'A'));
                columnName.append(":");
                columnName.append(QChar(i + 'A'));
                col = workSheet->querySubObject("Columns(const QString&)", columnName);
                col->setProperty("ColumnWidth", tableView->columnWidth(i)/6);
                cell = workSheet->querySubObject("Cells(int, int)", 2, i+1);
                columnName = tableView->model()->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString();
                cell->dynamicCall("SetValue(const QString&)", columnName);
                cell->querySubObject("Font")->setProperty("Bold", true);
                cell->querySubObject("Interior")->setProperty("Color", QColor(191, 191, 191));
                cell->setProperty("HorizontalAlignment", -4108);
                cell->setProperty("VertivcalAlignment", -4108);
            }

            //處理資料
            for (int i = 0; i < rowCount; i++)
            {
                for (int j = 0; j < colCount; j++)
                {
                    QModelIndex index = tableView->model()->index(i, j);
                    QString strData = tableView->model()->data(index).toString();
                    workSheet->querySubObject("Cells(int, int)", i + 3, j + 1)->dynamicCall("SetValue(const QString&)", strData);
                }
            }

            //畫框線
            QString l_range;
            l_range.append("A2:");
            l_range.append(colCount -1 + 'A');
            l_range.append(QString::number(tableView->model()->rowCount() + 2));
            range = workSheet->querySubObject("Range(const QString&)", l_range);
            range->querySubObject("Borders")->setProperty("LineStyle", QString::number(1));
            range->querySubObject("Borders")->setProperty("Color", QColor(0, 0, 0));

            //調整資料區行高
            QString rowsName;
            rowsName.append("2:");
            rowsName.append(QString::number(tableView->model()->rowCount() + 2));
            range = workSheet->querySubObject("Range(const QString&)", rowsName);
            range->setProperty("RowHeight", 20);
            workBook->dynamicCall("SaveAs(const QString&)", QDir::toNativeSeparators(fileName)); //儲存到fileName

            workBook->dynamicCall("Close()"); //關閉工作簿
            excel->dynamicCall("Quit()"); //關閉excel
            delete  excel;
            excel = NULL;
            QMessageBox message(QMessageBox::NoIcon,  "消息提示框",  "檔案已成功導出,是否打開檔案", QMessageBox::Yes | QMessageBox::No, NULL);
            //message.setWindowFlags(Qt::WindowStaysOnTopHint);
             if(message.exec() == QMessageBox::Yes)
            {
                 QDesktopServices::openUrl(QUrl::fromLocalFile(fileName));
            }
        }
        else
        {
            QMessageBox::warning(NULL, tr("錯誤"), tr("未能建立 Excel 對象,請安裝 Microsoft Excel。"), QMessageBox::Apply);
        }
    }
}

void MainWindow::on_pushButton_8_clicked()
{
    QString fileName = "Excel";

    Table2ExcelByHtml(ui->tableView, fileName);
}      

lineedit美化,combo box 美化

【2021-1-5】QT+SQLsever資料庫的資料管理系統
【2021-1-5】QT+SQLsever資料庫的資料管理系統

美化:

/*下拉清單框*/

QComboBox
{
    background:white;
    padding-left:5px ;
    border-top-left-radius:3px;
    border-top-right-radius:3px;
    border: 1px solid rgb(0 ,0 , 0);//邊框顔色設定
}

QComboBox::drop-down
{
    width:20px;
    border:0px; 
    border-radius:0px; 
    background:white; 
    border-left:0px ; 
    padding-right:5px;
    border:none;
    
    border-image: url(:/jpg/11.png);
}      
ui->LineEdit_3->setStyleSheet("*{font-family:Microsoft YaHei;font-size:12px;}QLineEdit{font-size:13px;background:transparent;border:none;border-bottom:1px solid rgb(229, 229, 229);}QLineEdit:hover{border-bottom:1px solid rgb(193,193, 193);}QLineEdit:focus{border-bottom:1px solid rgb(18, 183, 245);}");      

作者有話說

工程部分代碼放上來以便我下次使用,部分注釋是錯誤的請仔細辨識。

更多内容詳見微信公衆号:Python研究所