QT模型视图结构
QT的模型视图结构分为模型(Model)、视图(View)和代理(Delegate)。模型与数据源通信,并为其他部件提供接口;视图从模型中获得用来引用数据条目的模型索引(Model Index);代理负责绘制数据条目,当编辑条目时,代理和模型直接进行通信。
数据发生改变时,模型发出信号通知视图
用户对界面进行操作,视图发出信号
代理发出信号告知模型和视图编辑器目前的状态
list.setSelectionModel(tree.selectionModel()); //设置QListView对象与QTreeView对象使用相同的选择模型
/* QListView对象显示QTreeView双击选的目录下的所有文件和目录 */
QObject::connect(&tree, SIGNAL(doubleClicked(QModelIndex)), &list, SLOT(setRootIndex(QModelIndex)));
自定义模型
class DiyModel: public QAbstractItemModel
{
Q_OBJECT
public:
explicit DiyModel(QObject* parent);
~DiyModel();
/* 以下函数在查询Model数据时使用,其中,data、index、parent、rowCount、columnCount为纯虚函数 */
QVariant headerData(int section, Qt::Orientation orientation,int role = Qt::DisplayRole) const override;
QVariant data(const QModelIndex &index, int role) const override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &index) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
private:
}
class DiyTableModel: public QAbstractTableModel
{
Q_OBJECT
public:
explicit DiyTableModel(QObject* parent);
~DiyTableModel();
/* 以下函数在查询Model数据时使用,其中,data、rowCount、columnCount为纯虚函数 */
QVariant headerData(int section, Qt::Orientation orientation,int role = Qt::DisplayRole) const override;
QVariant data(const QModelIndex &index, int role) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
private:
}
自定义视图:实现纯虚函数,重载功能所需的函数
class DiyView: public QAbstractItemView
{
Q_OBJECT
public:
explicit DiyView(QWidget* parent);
~DiyView();
/* 以下函数在查询Model数据时使用,其中,visualRect、scrollTo、indexAt、moveCursor、horizontalOffset、verticalOffset、isIndexHidden、setSelection、visualRegionForSelection为纯虚函数 */
QRect visualRect(const QModelIndex &index) const{};
void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible){};
QModelIndex indexAt(const QPoint &point) const;
QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers){};
int horizontalOffset() const{};
int verticalOffset() const{};
bool isIndexHidden(const QModelIndex &index) const{};
void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command);
QRegion visualRegionForSelection(const QItemSelection &selection) const{};
void paintEvent(QPaintEvent *event)
private:
}
代理
class DiyDelegate: public QItemDelegate
{
Q_OBJECT
public:
explicit DiyDelegate(QObject* parent);
/* 创建由参数中的index指定的表项数据的编辑控件,并对控件内容进行限定 */
QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
/* 设置控件显示的数据,将model中的数据更新至delegate中 */
void setEditorData(QWidget* editor, const QModelIndex& index) const;
/* 将delegate中对数据的改变更新至model中 */
void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const;
/* 更新控件区的显示 */
void updateEditorGeometry(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
}
QWidget* DiyDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
QDateTimeEdit* editor=new QDateTimeEdit(parent);
editor->setDisplayFormat("yyyy-mm-dd");
editor->setCalendarPopup(true);
/* 调用QObject类的installEventFilter函数安装事件过滤器,使DiyDelegate能够捕获QDateTimeEdit对象的事件 */
editor->installEventFilter(const_cast<DiyDelegate*>(this));
return editor;
}
void DiyDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
{
QString dateStr=index.model()->data(index).toString();
QDtae date=QDate::fromString(dateStr, Qt::ISODate);
QDateTimeEdit* edit=static_cast<QDateTimeEdit*>(editor);
edit->setDate(date);
}
void DiyDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{
QDateTimeEdit* edit=static_cast<QDateTimeEdit*>(editor);
QDtae date=edit->date();
model->setDta(index, QVariant(date.toString(Qt::ISODate)));
}
void DiyDelegate::updateEditorGeometry(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
editor->setGeometry(option.rect);
}