前三篇介紹的 QListWidget、QTreeWidget、QTableWidget 皆屬「Item View 類別」(便利類),雖易用但功能受限、缺乏即時同步機制。本篇正式進入 **Model/View 架構** 核心,以最簡單的 QStringListModel 為例,展示「資料與視圖分離」的強大優勢。
QStringListModel 封裝 QStringList)。QListView)。操作流程:修改 Model → Model 發出信號 → View 自動更新,開發者專注資料邏輯,無需手動同步 UI。
class MyListView : public QWidget
{
Q_OBJECT
public:
MyListView();
private slots:
void insertData();
void deleteData();
void showData();
private:
QStringListModel *model;
QListView *listView;
};
MyListView::MyListView()
{
model = new QStringListModel(this);
QStringList data;
data << "Letter A" << "Letter B" << "Letter C";
model->setStringList(data); // 載入初始資料
listView = new QListView(this);
listView->setModel(model); // 綁定 Model
// 三個按鈕:插入、刪除、顯示
QPushButton *insertBtn = new QPushButton(tr("Insert"), this);
QPushButton *delBtn = new QPushButton(tr("Delete"), this);
QPushButton *showBtn = new QPushButton(tr("Show"), this);
QHBoxLayout *btnLayout = new QHBoxLayout;
btnLayout->addWidget(insertBtn);
btnLayout->addWidget(delBtn);
btnLayout->addWidget(showBtn);
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(listView);
mainLayout->addLayout(btnLayout);
setLayout(mainLayout);
connect(insertBtn, SIGNAL(clicked()), this, SLOT(insertData()));
connect(delBtn, SIGNAL(clicked()), this, SLOT(deleteData()));
connect(showBtn, SIGNAL(clicked()), this, SLOT(showData()));
}
void MyListView::insertData()
{
bool ok;
QString text = QInputDialog::getText(this, tr("Insert"),
tr("Please input new data:"),
QLineEdit::Normal,
tr("You are inserting new data."), &ok);
if (!ok) return;
int row = listView->currentIndex().row(); // 取得目前選中列
model->insertRows(row, 1); // 在該列插入 1 筆空白資料
QModelIndex index = model->index(row); // 取得新列的 ModelIndex
model->setData(index, text); // 寫入文字
listView->setCurrentIndex(index);
listView->edit(index); // 進入編輯模式
}
關鍵 API:insertRows(int row, int count, const QModelIndex &parent) 由 QAbstractListModel 提供,QStringListModel 覆寫實作。
void MyListView::deleteData()
{
if (model->rowCount() > 1) { // 至少保留 1 列,避免邏輯錯誤
model->removeRows(listView->currentIndex().row(), 1);
}
}
void MyListView::showData()
{
QStringList data = model->stringList(); // 直接取得底層 QStringList
QString str;
foreach (QString s, data) str += s + "\n";
QMessageBox::information(this, tr("Data"), str);
}

透過 QStringListModel 與 QListView,我們體驗到 Model/View 的核心優勢:**所有操作針對資料模型,視圖自動同步**;開發者無需管理 UI 狀態,專注業務邏輯。這正是 Qt Model/View 架構的精髓所在。
本文出自 “豆子空間” 博客,請務必保留此出處:https://devbean.blog.51cto.com/448512/265057