界面如下:
dialog.h
#ifndef ZONE_DIALOG_H
#define ZONE_DIALOG_H
#include <QWidget>
#include <QVBoxLayout>
#include <QTableView>
#include <QStandardItemModel>
#include <QPushButton>
#include <QTextEdit>
#include <QLabel>
#include "zone/zone_delegate.h"
#include "zone/zone_table_view.h"
class ZoneDialog :public QWidget
{
public:
ZoneDialog( QWidget * parent= nullptr);
void init();
protected:
void resizeEvent(QResizeEvent *event)override;
private:
void IintWidget();
void InitTableView(QVBoxLayout *mainVbox);
void InitLayout(QVBoxLayout *mainVbox);
void InitConnect();
void UpdateView();
void DymicDisplay(int index);
void ScrollBarChange(int value);
void GetModelData();
// [] slot
void DeleteButtonClicked();
void DelegateClicked(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles);
// []
ZoneTableView *tableView_ {nullptr};
QStandardItemModel *model_ {nullptr};
ComboBoxDelegate *comboBoxDelegate_{nullptr};
// QWidget *tabelWidget_;
QPushButton *deleteButton_;
QTextEdit *inputEdit_ {nullptr};
QTextEdit *displayEdit_{nullptr};
int baseIndex_ {0};
};
#endif // ZONE_DIALOG_H
dialog.cpp
#include <QScrollBar>
#include "zone_dialog.h"
namespace {
const int MAX_COL = 10;
const int MAX_ROW = 6;
const int SHOW_LINE = 10;
}
ZoneDialog::ZoneDialog( QWidget *parent):QWidget(parent)
{
}
void ZoneDialog::init()
{
// this->show();
this->setMinimumSize(720,640);
IintWidget();
UpdateView();
InitConnect();
}
void ZoneDialog::resizeEvent(QResizeEvent *event)
{
}
void ZoneDialog::IintWidget()
{
QVBoxLayout *mainVbox = new QVBoxLayout;
inputEdit_ =new QTextEdit;
displayEdit_ = new QTextEdit;
displayEdit_->setReadOnly(true);
InitTableView(mainVbox);
InitLayout(mainVbox);
}
void ZoneDialog::InitTableView(QVBoxLayout *mainVbox)
{
// // 创建视图
// QWidget *tabelWidget = new QWidget(this);
tableView_ = new ZoneTableView(this);
tableView_->setFixedHeight(this->height() / 2);
// tableView_->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked);
// 设置选择行为为选择单元格时整行高亮显示
tableView_->setSelectionBehavior(QAbstractItemView::SelectItems);
// 设置为单选模式
tableView_->setSelectionMode(QAbstractItemView::SingleSelection);
// // 创建模型
model_ =new QStandardItemModel();
model_->setHorizontalHeaderLabels({"Column 1", "Column 2", "Column 3"});
tableView_->setModel(model_);
mainVbox->addWidget(tableView_);
}
void ZoneDialog::InitLayout(QVBoxLayout *mainVbox)
{
deleteButton_ = new QPushButton("Delete");
mainVbox->addWidget(deleteButton_);
QHBoxLayout *hbox = new QHBoxLayout;
hbox->addWidget(inputEdit_);
hbox->addWidget(displayEdit_);
mainVbox->addLayout(hbox);
this->setLayout(mainVbox);
}
void ZoneDialog::InitConnect()
{
connect(tableView_->verticalScrollBar(), &QScrollBar::valueChanged, this ,&ZoneDialog::ScrollBarChange);
// connect(comboBoxDelegate_, &ComboBoxDelegate::CheckBoxStatusSg, this ,&ZoneDialog::DelegateCheckBox);
connect(deleteButton_,&QPushButton::clicked, this, &ZoneDialog::DeleteButtonClicked);
connect(model_, &QStandardItemModel::dataChanged, this, &ZoneDialog::DelegateClicked);
}
void ZoneDialog::UpdateView()
{
QStandardItem *newItem = nullptr;
// 设置model, model 目前只设置前十个
for (int row = 0; row < MAX_COL; row++) {
for (int col = 0; col < MAX_ROW; ++col){
if (col == 0) {
newItem = new QStandardItem(false);
}else if (col == 1) {
newItem = new QStandardItem("abc");
// model_->setData(index, Qt::Unchecked, Qt::CheckStateRole);
}else if(col == 2) {
newItem = new QStandardItem("aaa");
} else{
newItem = new QStandardItem("");
}
model_->setItem(row, col, newItem);
}
}
for (int row = 0; row < MAX_COL; row++) {
for (int col = 0; col < MAX_ROW; ++col){
QModelIndex index = model_->index(row, col, QModelIndex());
model_->setData(index, QVariant(false), Qt::CheckStateRole);
}
}
// 设置代理
comboBoxDelegate_ = new ComboBoxDelegate();
comboBoxDelegate_->Init();
comboBoxDelegate_->setHiddenRow(0);
tableView_->setItemDelegate(comboBoxDelegate_);
//将前十个数据默认显示,或者全部的数据
int baseShow = (model_->rowCount() > SHOW_LINE) ? SHOW_LINE : model_->rowCount();
for (int index = 0; index <= baseShow ; index++) {
for (int col = 0; col < MAX_ROW; ++col){
tableView_->openPersistentEditor(model_->index(index,col));
}
}
baseIndex_ = 0;
}
void ZoneDialog::ScrollBarChange(int value)
{
int barSize = value;
if(value == tableView_->verticalScrollBar()->maximum()) {
// 滑动到了底部
barSize = tableView_->verticalScrollBar()->size().width();
}
DymicDisplay(barSize);
}
// 得到model中的数据
void ZoneDialog::GetModelData()
{
for (int row = 0; row < model_->rowCount(); ++row) {
for (int column = 0; column < model_->columnCount(); ++column) {
QModelIndex index = model_->index(row, column);
QVariant data = model_->data(index, Qt::DisplayRole); // 获取显示角色的数据
qDebug() << "Data at row" << row << "column" << column << ":" << data.toString();
}
}
}
// 删除键按下的时候
void ZoneDialog::DeleteButtonClicked()
{
for (int row = 0; row < model_->rowCount(); row++ ) {
QModelIndex index = model_->index(row, 0); // 获取索引
qDebug() <<"---------------------------- "<< index.data().toBool();
if (index.data(Qt::CheckStateRole).toBool() == true) {
model_->removeRow(row); // 删除第3行
row = row - 1;
}
}
tableView_->update();
}
void ZoneDialog::DelegateClicked(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
qDebug() <<"----------------------aaaaaaaaaaaaaaa------ ";
if (topLeft.column() == 0 && topLeft.column() == bottomRight.column()) { // 只点击一个
qDebug() << " <<<<<<<<<<<<<<<<<<<< " << topLeft << bottomRight;
// int row = topLeft.row();
// QModelIndex index = model_->index(row, 0);
// QString value = "";
// index.data().toString();
// model_->setData(index, value, Qt::DisplayRole);
// model.setData(index, Qt::Unchecked, Qt::CheckStateRole);
}
}
// 动态的显示代理
void ZoneDialog::DymicDisplay(int indexRow)
{
int max = indexRow - baseIndex_;
if (max > 0) {
for (int index = baseIndex_ ; index < indexRow + max; index++) {
for (int col = 0; col < MAX_ROW; ++col){
tableView_->openPersistentEditor(model_->index(index + SHOW_LINE,col,QModelIndex()));
}
}
baseIndex_ = indexRow;
}
}
delegate.h
#ifndef ZONE_DELEAGTE
#define ZONE_DELEAGTE
#include <QItemDelegate>
#include <QComboBox>
#include <QDebug>
#include <QLabel>
#include <QToolButton>
#include <QRadioButton>
#include <QLabel>
#include <QCheckBox>
#include <QButtonGroup>
#include<QAbstractButton>
#include <QStyledItemDelegate>
#include <QPainter>
class ComboBoxDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
ComboBoxDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {}
void Init();
void setHiddenRow(int row)
{
hiddenRow_ = row;
}
// 创建编辑器
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
// 设置编辑器数据
void setEditorData(QWidget *editor, const QModelIndex &index) const override ;
// 将编辑器的数据写回到模型
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override ;
// 更新编辑器的几何属性
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
// // 设置显示
// void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
// void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
// {
// // if (index.column() == hiddenRow_) {
// // // 如果是被隐藏的行,不绘制内容
// // return;
// // }
// if (index.column() == hiddenRow_) {
// }
// else {
// // painter->fillRect(option.rect, option.palette.highlight());
// QStyledItemDelegate::paint(painter, option, index);
// return;
// }
// }
signals:
void CheckBoxStatusSg(const QModelIndex &index,bool isStatus);
private:
void ButtonGroupSlot(QAbstractButton *button);
QButtonGroup *group_;
int hiddenRow_{-1};
};
#endif
delegate.cpp
#include "zone_delegate.h"
#include "zone_line_edit.h"
#include "zone_chekbox.h"
#include <QHBoxLayout>
void ComboBoxDelegate::Init()
{
group_ = new QButtonGroup(this);
group_->setExclusive(false);
// 连接按钮组的信号到槽函数 // 可以删除
// QObject::connect(group_, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked), this,&ComboBoxDelegate::ButtonGroupSlot) ;
}
QWidget *ComboBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (!index.isValid()) {
return nullptr;
}
// 创建一个下拉框
// if (index.column() == 0) {
// if (group_ == nullptr) {
// return nullptr;
// }
// // 创建一个 QCheckBox 控件
// QCheckBox *checkBox = new QCheckBox(parent);
// // ZoneChekbox * checkBox = new ZoneChekbox(parent);
// // checkBox->Init();
// // 创建垂直布局管理器
// checkBox->resize(parent->size());
// // connect(checkBox,&ZoneChekbox::CheckStatusChangeSg,[index](bool check){
// // emit CheckBoxStatusSg(index,check);
// // });
// return checkBox;
// } else
if (index.column() == 1) {
ZoneLineEdit * lineEdit = new ZoneLineEdit(parent);
// lineEdit->setText("abc");
return lineEdit;
} else if(index.column() == 2){
QComboBox *comboBox = new QComboBox(parent);
comboBox->addItem("Option 1");
comboBox->addItem("Option 2");
comboBox->addItem("Option 3");
return comboBox;
} else if (index.column() == 5) {
QLabel *label = new QLabel(parent);
return label;
}
return nullptr;
}
void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
if (!index.isValid()) {
return;
}
// 从模型中获取数据并设置给下拉框
// if (index.column() == 0) {
// // 不知道为啥不会触发这个事件
// qDebug() << "0000000000000000000000000000000";
// // ZoneChekbox *checkBox = dynamic_cast<ZoneChekbox *>(editor);
// QCheckBox *checkBox = dynamic_cast<QCheckBox *>(editor);
// bool check = index.model()->data(index, Qt::CheckStateRole).toBool();
// checkBox->setChecked(check);
// }else
if (index.column() == 1) {
QString value = index.model()->data(index, Qt::DisplayRole).toString();
ZoneLineEdit *edit = dynamic_cast<ZoneLineEdit *>(editor);
edit->setText(value);
} else if (index.column() == 2) {
QString value = index.model()->data(index, Qt::DisplayRole).toString();
QComboBox *comboBox = dynamic_cast<QComboBox *>(editor);
comboBox->addItem(value);
comboBox->setCurrentText(value);
} else if (index.column() == 5) {
// 最后一个数据处理
}
}
void ComboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
if (!index.isValid()) {
return;
}
// if (index.column() == 0) {
// QCheckBox *checkBox = dynamic_cast<QCheckBox *>(editor);
// // ZoneChekbox *checkBox = dynamic_cast<ZoneChekbox *>(editor);
// bool isChecked = checkBox->isChecked();
// model->setData(index, isChecked, Qt::CheckStateRole);
// } else
if (index.column() == 1){
ZoneLineEdit *edit = dynamic_cast<ZoneLineEdit *>(editor);
QString value = edit->text();
model->setData(index, value, Qt::DisplayRole);
}else if (index.column() == 2) {
QComboBox *comboBox = dynamic_cast<QComboBox *>(editor);
QString value = comboBox->currentText();
model->setData(index, value, Qt::EditRole);
} else if (index.column() == 5) {
// 最后一个数据处理
}
}
void ComboBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (!index.isValid()) {
return;
}
editor->setGeometry(option.rect);
}
QSize ComboBoxDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (index.column() == 0) {
return QSize(30, 30); // 设置按钮大小
}
}
// void ComboBoxDelegate::ButtonGroupSlot(QAbstractButton *button)
// {
// QButtonGroup *group = dynamic_cast<QButtonGroup*>(button->group());
// QCheckBox *checkBox = dynamic_cast<QCheckBox*>(button);
// if (group != nullptr ) {
// int index = group->id(button);
// bool isChecked = checkBox->isChecked();
// emit CheckBoxStatusSg(index,isChecked );
// }
// }
zoen_tableView:
#ifndef ZONE_TABLE_VIEW_H
#define ZONE_TABLE_VIEW_H
#include <QTableView>
#include <QDebug>
#include <QMouseEvent>
class ZoneTableView : public QTableView {
public:
ZoneTableView(QWidget *parent);
protected:
void mousePressEvent(QMouseEvent *event) override ;
};
#endif // ZONE_TABLE_VIEW_H
#include "zone_chekbox.h"
ZoneTableView::ZoneTableView(QWidget *parent) : QTableView(parent) {}
void ZoneTableView::mousePressEvent(QMouseEvent *event)
{
QModelIndex index = indexAt(event->pos());
if (index.isValid()) {
qDebug() << "Clicked on empty space" << index.row() << index.column();
// 在这里发送自定义的信号
// emit customSignal();
if (index.column() == 0) {
// QCheckBox *checkBox = dynamic_cast<QCheckBox *>(this->indexWidget(index));
// if (checkBox != nullptr) {
// bool check = checkBox->isChecked();
// checkBox->setChecked(!check);
// this->model()->setData(index, QVariant(!check), Qt::CheckStateRole);
// }
bool check = index.data(Qt::CheckStateRole).toBool();
this->model()->setData(index, QVariant(!check), Qt::CheckStateRole);
} else if ( index.column() == 1) {
} else if (index.column() == 4) {
}
}
QTableView::mousePressEvent(event);
}
line
#ifndef ZONE_LINE_EDIT_H
#define ZONE_LINE_EDIT_H
#include <QLineEdit>
#include <QKeyEvent>
class ZoneLineEdit :public QLineEdit
{
Q_OBJECT
public:
ZoneLineEdit(QWidget *parent = nullptr);
// void keyPressEvent(QKeyEvent *) override;
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
};
#endif // ZONE_LINE_EDIT_H
#include "zone_line_edit.h"
ZoneLineEdit::ZoneLineEdit(QWidget *parent): QLineEdit(parent)
{
setReadOnly(true); // 设置为只读
installEventFilter(this); // 安装事件过滤器
}
bool ZoneLineEdit::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::MouseButtonDblClick) {
setReadOnly(false); // 双击时设为可编辑
return true;
} else if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) {
setReadOnly(true); // 按下Enter键时设为不可编辑
return true;
}
} else if (event->type() == QEvent::FocusOut) {
setReadOnly(true); // 失去焦点时设为不可编辑
return true;
}
return QLineEdit::eventFilter(obj, event);
}