#ifndef CARRAYMODEL_H
#define CARRAYMODEL_H
#include <QAbstractItemModel>
#include <QStyledItemDelegate>
#include <QItemDelegate>
#include <vector>
#include <QVector>
class QTableView;
class QSqlQueryModel;
class QLabel;
class QLineEdit;
class QPushButton;
class CArrayModel : public QAbstractTableModel
{
public:
CArrayModel(QObject *parent = 0);
//設置總數據
void SetArrayData(const QVector<QVector<QString>> &map);
//獲得總數據
//std::map<int, QString> GetArrayData();
//設置頁數據
void SetCurPage(int iPage);
//獲得當前頁
int GetCurPage();
//獲得總頁數
int GetPageCount();
//設置每頁數據條數
void SetPageSize(int iPageSize);
//獲得每頁數據條數
int GetPageSize();
//總行數
int RowCount() const;
public:
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
//bool setData(const QModelIndex &index, const QVariant &value,int role = Qt::EditRole);
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
void refrushModel();
private:
//QString currencyAt(int offset) const;
// std::map<int, QString> m_mpData; //總數據
// std::map<int, QString> m_mpPageData;//每頁數據
QVector<QVector<QString>> m_mpData; //總數據
QVector<QVector<QString>> m_mpPageData;//每頁數據
int m_iPageSize; //每頁數據條數
int m_iCurPage; //當前頁
};
//只讀委托(給索引列使用)
class ReadOnlyDelegate : public QItemDelegate
{
Q_OBJECT
public:
ReadOnlyDelegate(QObject *parent = 0): QItemDelegate(parent) { }
QWidget *createEditor(QWidget*parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
return NULL;
}
};
//值列
class ValueDelegate : public QItemDelegate
{
Q_OBJECT
public:
ValueDelegate(QObject *parent = 0): QItemDelegate(parent) { }
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
void setEditorData(QWidget *editor, const QModelIndex &index) const;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
#endif // CARRAYMODEL_H
#include "carraymodel.h"
#include <QLineEdit>
CArrayModel::CArrayModel(QObject *parent)
: QAbstractTableModel(parent)
{
}
//設置Model數據
void CArrayModel::SetArrayData(const QVector<QVector<QString>> &map)
{
m_mpData = map;
}
//獲得總數據
//std::map<int, QString> CArrayModel::GetArrayData()
//{
// return m_mpData;
//}
//總行數
int CArrayModel::RowCount() const
{
return m_mpData.size();
}
//設置頁數據
void CArrayModel::SetCurPage(int iPage)
{
//當前頁必須小於總頁數
if (iPage < GetPageCount())
{
m_iCurPage = iPage;
//查詢起始索引
int iStart = m_iPageSize * m_iCurPage;
//查詢結束索引
int iend = 0;
//如果本頁可以填滿
if (iStart + m_iPageSize < RowCount())
{
iend = iStart + m_iPageSize;
}
//如果本頁不可以填滿
else
{
iend = RowCount() - 1;
}
//填充當前頁數據
m_mpPageData.clear();
for (int i = iStart; i <= iend; ++i)
{
m_mpPageData.push_back(m_mpData.at(i));
/*
auto it = m_mpData.find(i);
if (it == m_mpData.end())
{
return;
}
m_mpPageData.insert(std::pair<int, QString>(i, it->second));
*/
}
}
return;
}
//獲得當前頁
int CArrayModel::GetCurPage()
{
return m_iCurPage;
}
//獲得總頁數
int CArrayModel::GetPageCount()
{
return (RowCount() % m_iPageSize == 0)
? (RowCount() / m_iPageSize)
: (RowCount() / m_iPageSize + 1);
}
//設置每頁數據條數
void CArrayModel::SetPageSize(int iPageSize)
{
if (iPageSize <= 0)
{
return;
}
m_iPageSize = iPageSize;
SetCurPage(0);
//刷新Model,否則TableView不會刷新顯示
refrushModel();
}
//獲得每頁數據條數
int CArrayModel::GetPageSize()
{
return m_iPageSize;
}
//行數
int CArrayModel::rowCount(const QModelIndex & parent) const
{
return m_iPageSize;
}
//列數
int CArrayModel::columnCount(const QModelIndex & parent) const
{
//僅僅有兩列數據
return 3;
}
void CArrayModel::refrushModel()
{
beginResetModel();
endResetModel();
}
QVariant CArrayModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
{
return QVariant();
}
if (role == Qt::TextAlignmentRole)
{
return int(Qt::AlignCenter | Qt::AlignVCenter);
}
else if (role == Qt::DisplayRole)
{
// if ( 0 == index.column())
// {
// //如果處於最后一頁,索引沒必要全部列出,只列出范圍內的
// if (index.row() + m_iCurPage * m_iPageSize > this->RowCount())
// {
// return QVariant();
// }
// return index.row() + m_iCurPage * m_iPageSize;
// }
//else
{
if (m_mpPageData.size() > index.row())
{
if (m_mpPageData[0].size() > index.column())
{
return m_mpPageData[index.row()][index.column()];
}
}
return QVariant();
}
// else if (1 == index.column())
// {
// auto it = m_mpPageData.find(index.row() + m_iCurPage * m_iPageSize);
// if (it != m_mpPageData.end())
// {
// return it->second;
// }
// }
}
return QVariant();
}
Qt::ItemFlags CArrayModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return Qt::ItemIsEnabled;
return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
}
/*
bool CArrayModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (index.isValid() && role == Qt::EditRole)
{
QVariant oldData = data(index, Qt::EditRole);
QString strold = oldData.toString();
QString strnew = value.toString();
//相同則不編輯
if (strnew.compare(strold) == 0)
{
return true;
}
//計算實際數據的下標
int dataindex = index.row() + m_iCurPage * m_iPageSize;
//改變總數據集
auto it = m_mpData.find(dataindex);
if (it != m_mpData.end())
{
it->second = strnew;
}
//改變當頁數據集
auto itcur = m_mpPageData.find(dataindex);
if (itcur != m_mpPageData.end())
{
itcur->second = strnew;
}
return true;
}
return false;
}
*/
QVariant CArrayModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole)
{
return QVariant();
}
if (0 == section)
{
return QStringLiteral("索引");
}
else if (1 == section)
{
return QStringLiteral("值");
}
else if (2 == section)
{
return "測試";
}
}
//QString CArrayModel::currencyAt(int offset) const
//{
// auto it = m_mpData.find(offset);
// if (it != m_mpData.end())
// {
// return it->second;
// }
// return QString();
//}
//樣式定制
void ValueDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
if (!index.isValid())
{
// 如果當前項具有焦點,它就繪制一個焦點矩形(不重要)
drawFocus(painter, option, option.rect);
}
else
{
QItemDelegate::paint(painter, option, index);
}
}
QWidget *ValueDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QLineEdit *editor = new QLineEdit(parent);
return editor;
}
void ValueDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
QString text = index.model()->data(index, Qt::EditRole).toString();
QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
lineEdit->setText(text);
}
void ValueDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
QString text = lineEdit->text();
model->setData(index, text, Qt::EditRole);
}
void ValueDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
editor->setGeometry(option.rect);
}
#ifndef MYMAINWINDOW_H
#define MYMAINWINDOW_H
#include <QObject>
#include <QWidget>
#include "carraymodel.h"
#include <QKeyEvent>
#include <QTableView>
#include <QHeaderView>
#include <QSplitter>
//自定義窗口類
class MyMainWindow : public QWidget
{
Q_OBJECT
public:
MyMainWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0);
~MyMainWindow();
void keyPressEvent(QKeyEvent *event);
//槽函數
private slots:
void OnFirstButtonClick(); //首頁按鈕按下
void OnLastButtonClick(); //末頁按鈕按下
void OnPrevButtonClick(); //前一頁按鈕按下
void OnNextButtonClick(); //后一頁按鈕按下
void OnSwitchPageButtonClick(); //轉到頁按鈕按下
void OnIndexButtonClick(); //轉到索引按鈕按下
void OnSetPageSizeButtonClick(); //設置每頁顯示行數按鈕按下
private :
void MyCreateWindow(); //創建窗口
void SetTableView(); //設置表格
void UpdateStatus(); //刷新狀態
private:
CArrayModel *m_pDataModel; //數據模型
QTableView *tableView; //數據表
QLineEdit *switchPageLineEdit; //轉到頁輸入框
QPushButton *m_pFirstPageBtn; //首頁按鈕
QPushButton *m_pLastPageBtn; //末頁按鈕
QPushButton *prevButton; //前一頁按鈕
QPushButton *nextButton; //下一頁按鈕
QPushButton *switchPageButton; //轉到頁按鈕
QLineEdit *m_pIndexEdit; //索引輸入框
QPushButton *m_pGoIndexBtn; //按索引跳轉按鈕
QLabel *totalPageLabel; //總數頁文本
QLabel *currentPageLabel; //當前頁文本
QLineEdit *m_pPerPageCountEdit; //每頁顯示行數
QPushButton *m_pSetPerPageCountBtn;//設置每頁顯示行數按鈕
enum {PageRecordCount = 10}; //默認每頁顯示記錄數
};
#endif // MYMAINWINDOW_H
#include "mymainwindow.h"
#include <QLineEdit>
#include <QPushButton>
#include <QLabel>
#include <QMessageBox>
#include <QHBoxLayout>
MyMainWindow::MyMainWindow(QWidget *parent, Qt::WindowFlags flags) : QWidget(parent, flags)
{
//創建窗口
MyCreateWindow();
//設置表格
SetTableView();
//翻頁按鈕
connect((const QObject *)m_pFirstPageBtn, SIGNAL(clicked()),this, SLOT(OnFirstButtonClick()));
connect((const QObject *)m_pLastPageBtn, SIGNAL(clicked()),this, SLOT(OnLastButtonClick()));
connect((const QObject *)prevButton, SIGNAL(clicked()),this, SLOT(OnPrevButtonClick()));
connect((const QObject *)nextButton, SIGNAL(clicked()),this, SLOT(OnNextButtonClick()));
connect((const QObject *)m_pGoIndexBtn, SIGNAL(clicked()),this, SLOT(OnIndexButtonClick()));
connect(m_pIndexEdit, SIGNAL(returnPressed()), this, SLOT(OnIndexButtonClick()));
//跳轉按鈕和跳轉到頁回車相應
connect((const QObject *)switchPageButton,SIGNAL(clicked()), this, SLOT(OnSwitchPageButtonClick()));
connect(switchPageLineEdit, SIGNAL(returnPressed()), this, SLOT(OnSwitchPageButtonClick()));
//設置每頁顯示行數按鈕
connect(m_pPerPageCountEdit, SIGNAL(returnPressed()), this, SLOT(OnSetPageSizeButtonClick()));
connect((const QObject *)m_pSetPerPageCountBtn, SIGNAL(clicked()), this, SLOT(OnSetPageSizeButtonClick()));
}
MyMainWindow::~MyMainWindow()
{
}
//對鍵盤事件處理
void MyMainWindow::keyPressEvent(QKeyEvent *event)
{
switch(event->key())
{
//進行界面退出,重寫Esc鍵,否則重寫reject()方法
case Qt::Key_Escape:
this->close();
break;
default:
QWidget::keyPressEvent(event);
}
}
//創建窗口
void MyMainWindow::MyCreateWindow()
{
//設置窗口屬性
setMinimumSize(600,400);
setWindowTitle(QStringLiteral("查看數組"));
m_pFirstPageBtn = new QPushButton(QStringLiteral("首頁"));
prevButton = new QPushButton(QStringLiteral("上一頁"));
nextButton = new QPushButton(QStringLiteral("下一頁"));
m_pLastPageBtn = new QPushButton(QStringLiteral("末頁"));
//一直按下持續執行功能打開,提升瀏覽體驗
prevButton->setAutoRepeat(true);
nextButton->setAutoRepeat(true);
QLabel *switchPage = new QLabel(QStringLiteral(" 第"));
switchPageLineEdit = new QLineEdit;
switchPageLineEdit->setFixedWidth(40);
QLabel *page = new QLabel(QStringLiteral("頁"));
switchPageButton = new QPushButton(QStringLiteral("轉到"));
switchPageButton->setFixedWidth(40);
QLabel *pIndexLabel = new QLabel(QStringLiteral(" 索引"));
m_pIndexEdit = new QLineEdit;
m_pIndexEdit->setFixedWidth(40);
m_pGoIndexBtn = new QPushButton(QStringLiteral("轉到"));
m_pGoIndexBtn->setFixedWidth(40);
//操作布局
QHBoxLayout *operatorLayout = new QHBoxLayout;
operatorLayout->addWidget(m_pFirstPageBtn);
operatorLayout->addWidget(prevButton);
operatorLayout->addWidget(nextButton);
operatorLayout->addWidget(m_pLastPageBtn);
operatorLayout->addWidget(switchPage);
operatorLayout->addWidget(switchPageLineEdit);
operatorLayout->addWidget(page);
operatorLayout->addWidget(switchPageButton);
operatorLayout->addWidget(pIndexLabel);
operatorLayout->addWidget(m_pIndexEdit);
operatorLayout->addWidget(m_pGoIndexBtn);
operatorLayout->addWidget(new QSplitter());
//狀態
totalPageLabel = new QLabel;
totalPageLabel->setFixedWidth(90);
currentPageLabel = new QLabel;
currentPageLabel->setFixedWidth(90);
QLabel *pPerPageCountDisLabel = new QLabel(QStringLiteral("每頁顯示"));
m_pPerPageCountEdit = new QLineEdit;
m_pPerPageCountEdit->setFixedWidth(40);
QLabel *pPerPageCountLineLabel = new QLabel(QStringLiteral("行"));
m_pSetPerPageCountBtn = new QPushButton(QStringLiteral("設置"));
m_pSetPerPageCountBtn->setFixedWidth(40);
//狀態布局
QHBoxLayout *statusLayout = new QHBoxLayout;
statusLayout->addWidget(totalPageLabel);
statusLayout->addWidget(currentPageLabel);
statusLayout->addWidget(pPerPageCountDisLabel);
statusLayout->addWidget(m_pPerPageCountEdit);
statusLayout->addWidget(pPerPageCountLineLabel);
statusLayout->addWidget(m_pSetPerPageCountBtn);
statusLayout->addWidget(new QSplitter());
//設置表格屬性
tableView = new QTableView;
tableView->verticalHeader()->hide();//隱藏垂直索引
tableView->setEditTriggers( QAbstractItemView::AllEditTriggers);
tableView->horizontalHeader()->setStretchLastSection(true); //設置充滿表寬度
//tableView->setSelectionBehavior(QAbstractItemView::SelectRows); //整行選中的方式
tableView->setAlternatingRowColors(true);
tableView->setStyleSheet("QTableView{"> rgb(186, 202, 224);"
"alternate-"> rgb(212, 212, 212);}");
tableView->horizontalHeader()->resizeSection(0,70); //設置表頭第一列的寬度為150
tableView->horizontalHeader()->setFixedHeight(25); //設置表頭的高度
tableView->setStyleSheet("selection-"); //設置選中背景色
tableView->horizontalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}"); //設置表頭背景色
//窗口布局
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->addLayout(operatorLayout);
mainLayout->addWidget(tableView);
mainLayout->addLayout(statusLayout);
}
// 設置表格
void MyMainWindow::SetTableView()
{
//聲明查詢模型
m_pDataModel = new CArrayModel;
//std::map<int, QString> map;
QVector<QVector<QString>> vecInfo;
for (int i = 0; i < 100; ++i)
{
QVector<QString> vec(3);
vec[0] = QString::number(i+1);
vec[1] = "hello" + QString::number(i+1);
vec[2] = "test" + QString::number(i+1);
//QString str = QString("%1").arg(QString::number(i));
//map.insert(std::pair<int, QString>(i, str));
vecInfo.push_back(vec);
}
m_pDataModel->SetArrayData(vecInfo);
//設置每頁數據條數
m_pDataModel->SetPageSize(PageRecordCount);
//設置模型
tableView->setModel(m_pDataModel);
//設置委托
//tableView->setItemDelegateForColumn(0, new ReadOnlyDelegate(this));
// tableView->setItemDelegateForColumn(1, new ValueDelegate(this));
//刷新狀態
UpdateStatus();
return;
}
//刷新界面狀態
void MyMainWindow::UpdateStatus()
{
//刷新表格
tableView->reset();
//總頁數
QString szPageCountText = QString(QStringLiteral("總共%1頁")).arg(QString::number(m_pDataModel->GetPageCount()));
totalPageLabel->setText(szPageCountText);
//設置當前頁文本
int iCurPage = m_pDataModel->GetCurPage() + 1;
QString szCurrentText = QString(QStringLiteral("當前第%1頁")).arg(QString::number(iCurPage));
currentPageLabel->setText(szCurrentText);
//每頁顯示行數
QString strPerPageCount = QString(QStringLiteral("%1")).arg(QString::number(m_pDataModel->GetPageSize()));
m_pPerPageCountEdit->setText(strPerPageCount);
//當前第一頁,且總共只有一頁
if (1 == iCurPage && 1 == m_pDataModel->GetPageCount())
{
m_pFirstPageBtn->setEnabled(false);
m_pLastPageBtn->setEnabled(false);
prevButton->setEnabled(false);
nextButton->setEnabled(false);
}
//當前第一頁,且總頁數大於1頁
else if(1 == iCurPage && m_pDataModel->GetPageCount() > 1)
{
m_pFirstPageBtn->setEnabled(false);
m_pLastPageBtn->setEnabled(true);
prevButton->setEnabled(false);
nextButton->setEnabled(true);
}
//當前是最后一頁
else if(iCurPage == m_pDataModel->GetPageCount())
{
m_pFirstPageBtn->setEnabled(true);
m_pLastPageBtn->setEnabled(false);
prevButton->setEnabled(true);
nextButton->setEnabled(false);
}
//中間頁
else
{
m_pFirstPageBtn->setEnabled(true);
m_pLastPageBtn->setEnabled(true);
prevButton->setEnabled(true);
nextButton->setEnabled(true);
}
return;
}
//首頁按鈕按下
void MyMainWindow::OnFirstButtonClick()
{
m_pDataModel->SetCurPage(0);
UpdateStatus();
}
//末頁按鈕按下
void MyMainWindow::OnLastButtonClick()
{
m_pDataModel->SetCurPage(m_pDataModel->GetPageCount() - 1);
UpdateStatus();
}
//前一頁按鈕按下
void MyMainWindow::OnPrevButtonClick()
{
m_pDataModel->SetCurPage(m_pDataModel->GetCurPage() - 1);
UpdateStatus();
}
//后一頁按鈕按下
void MyMainWindow::OnNextButtonClick()
{
m_pDataModel->SetCurPage(m_pDataModel->GetCurPage() + 1);
UpdateStatus();
}
//轉到索引按鈕按下
void MyMainWindow::OnIndexButtonClick()
{
//得到輸入字符串
QString szText = m_pIndexEdit->text();
//數字正則表達式
QRegExp regExp("-?[0-9]*");
//判斷是否為數字
if(!regExp.exactMatch(szText))
{
QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("請輸入數字"));
return;
}
//是否為空
if(szText.isEmpty())
{
QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("請輸入跳轉索引"));
return;
}
//得到頁數
int Index = szText.toInt();
//判斷是否有指定頁
if(Index >= m_pDataModel->RowCount() || Index < 0)
{
QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("索引超出范圍,請重新輸入"));
return;
}
//記錄查詢
m_pDataModel->SetCurPage(Index / m_pDataModel->GetPageSize());
//刷新狀態
UpdateStatus();
return;
}
//轉到頁按鈕按下
void MyMainWindow::OnSwitchPageButtonClick()
{
//得到輸入字符串
QString szText = switchPageLineEdit->text();
//數字正則表達式
QRegExp regExp("-?[0-9]*");
//判斷是否為數字
if(!regExp.exactMatch(szText))
{
QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("請輸入數字"));
return;
}
//是否為空
if(szText.isEmpty())
{
QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("請輸入跳轉頁面"));
return;
}
//得到頁數
int pageIndex = szText.toInt();
//判斷是否有指定頁
if(pageIndex > m_pDataModel->GetPageCount() || pageIndex < 1)
{
QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("頁面超出范圍,請重新輸入"));
return;
}
//記錄查詢
m_pDataModel->SetCurPage(pageIndex - 1);
//刷新狀態
UpdateStatus();
return;
}
//設置每頁顯示行數
void MyMainWindow::OnSetPageSizeButtonClick()
{
//得到輸入字符串
QString szText = m_pPerPageCountEdit->text();
//數字正則表達式
QRegExp regExp("-?[0-9]*");
//判斷是否為數字
if(!regExp.exactMatch(szText))
{
QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("請輸入數字"));
return;
}
//是否為空
if(szText.isEmpty())
{
QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("請輸入設置的行數"));
return;
}
//得到行數
int Index = szText.toInt();
//判斷范圍是否合理
// if(Index > m_pDataModel->RowCount() || Index <= 0)
// {
// QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("設置值超出范圍,請重新輸入"));
// return;
// }
//設置每頁容量
m_pDataModel->SetPageSize(Index);
//刷新狀態
UpdateStatus();
return;
}