引言
当数据库记录数很多的时候,如果将它全部显示到一个视图(view)中,长长的滚轮,拖动看起来会很累。这个时候给数据表加一个翻页的功能,每页限制显示一定数量的记录,这样会显得更合理一点。
于是我这边就写了个小Demo,用来实现一个简易的翻页功能。
效果
思路
主要用了SQL中的LIMIT项。
LIMIT简单用法
LIMIT子句用于对整个SELECT语句返回的行数设置限制。
看下两个小例子,
筛选出数据表table1中前1000条记录。
SELECT * FROM table1 LIMIT 1000;
筛选出数据表table1中第1001条开始,后1000条记录,即1001-2000条记录。
SELECT * FROM table1 LIMIT 1000, 1000;
button配合SQL语句
其实每个翻页操作按钮都对应SQL语句,看起来好像是单纯的翻页操作。
代码
Demo链接
Demo链接
提取码:l9cc
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSqlQueryModel>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_prePage_clicked();
void on_pushButton_nextPage_clicked();
void on_pushButton_firstPage_clicked();
void on_pushButton_lastPage_clicked();
void upDatePageInfo();
void on_pushButton_gotoPage_clicked();
private:
Ui::MainWindow *ui;
QSqlQueryModel *m_model;
int m_nCurrentPage;
int m_nPageCount;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTableView>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>
/* 每页显示的行数 */
#define LINESPPAGE 1000
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_nCurrentPage = 1;
m_model = new QSqlQueryModel;
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("test.db");
bool ok = db.open();
if (!ok) qDebug()<<db.lastError();
m_model->setQuery(QString("select * from TH015A limit 0, '%1'").arg(LINESPPAGE));
m_model->setHeaderData(0, Qt::Horizontal, tr("时间"));
m_model->setHeaderData(1, Qt::Horizontal, tr("压力(KPa)"));
m_model->setHeaderData(2, Qt::Horizontal, tr("密度(g/L)"));
m_model->setHeaderData(3, Qt::Horizontal, tr("温度(℃)"));
m_model->setHeaderData(4, Qt::Horizontal, tr("地址"));
QSqlQuery query("select * from TH015A");
query.last();
m_nPageCount = query.at()/LINESPPAGE + 1;
ui->lineEdit_pageCount->setText(QString("共%1页").arg(m_nPageCount));
ui->lineEdit_currentPage->setText(QString("第%1页").arg(m_nCurrentPage));
ui->tableView->setModel(m_model);
}
MainWindow::~MainWindow()
{
delete ui;
}
/* 上一页 */
void MainWindow::on_pushButton_prePage_clicked()
{
if (m_nCurrentPage <= 1)
{
return;
}
m_model->setQuery(QString("select * from TH015A limit '%1', '%2'").arg(LINESPPAGE*(m_nCurrentPage-2)).arg(LINESPPAGE));
m_nCurrentPage--;
upDatePageInfo();
}
/* 下一页 */
void MainWindow::on_pushButton_nextPage_clicked()
{
if (m_nCurrentPage >= m_nPageCount)
{
return;
}
m_model->setQuery(QString("select * from TH015A limit '%1', '%2'").arg(LINESPPAGE*m_nCurrentPage).arg(LINESPPAGE));
m_nCurrentPage++;
upDatePageInfo();
}
/* 首页 */
void MainWindow::on_pushButton_firstPage_clicked()
{
m_model->setQuery(QString("select * from TH015A limit '%1', '%2'").arg(LINESPPAGE*0).arg(LINESPPAGE));
m_nCurrentPage = 1;
upDatePageInfo();
}
/* 末页 */
void MainWindow::on_pushButton_lastPage_clicked()
{
m_model->setQuery(QString("select * from TH015A limit '%1', '%2'").arg(LINESPPAGE*(m_nPageCount-1)).arg(LINESPPAGE));
m_nCurrentPage = m_nPageCount;
upDatePageInfo();
}
/* 更新显示页 */
void MainWindow::upDatePageInfo()
{
QSqlQuery query("select * from TH015A");
query.last();
m_nPageCount = query.at()/LINESPPAGE + 1;
ui->lineEdit_pageCount->setText(QString("共%1页").arg(m_nPageCount));
ui->lineEdit_currentPage->setText(QString("第%1页").arg(m_nCurrentPage));
}
/* 跳转 */
void MainWindow::on_pushButton_gotoPage_clicked()
{
int nPage = ui->lineEdit_gotoPage->text().toInt();
m_model->setQuery(QString("select * from TH015A limit '%1', '%2'").arg(LINESPPAGE*(nPage-1)).arg(LINESPPAGE));
m_nCurrentPage = nPage;
upDatePageInfo();
}
mainwindow.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>799</width>
<height>497</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QTableView" name="tableView"/>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="pushButton_prePage">
<property name="text">
<string>上一页</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_nextPage">
<property name="text">
<string>下一页</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_firstPage">
<property name="text">
<string>首页</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_lastPage">
<property name="text">
<string>尾页</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_gotoPage">
<property name="title">
<string/>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QPushButton" name="pushButton_gotoPage">
<property name="text">
<string>跳转</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_gotoPage">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_currentPage">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_pageCount">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>799</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
.pro
#-------------------------------------------------
#
# Project created by QtCreator 2020-01-03T10:41:04
#
#-------------------------------------------------
QT += core gui sql
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = sqlPage
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
CONFIG += c++11
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
总结
在对较大的数据量进行操作的时候,时间和空间资源都会消耗较大,尤其是空间,拿本例来说,如果数据量特别大,你需要在程序中用较大的空间去临时存储,才能做到筛选数据显示。
本例中用时间置换了空间,使每次翻页操作的执行都要重新查询数据库,来替代程序中大数据存储。