在 Qt 框架中,模板方法模式(Template Method Pattern)被廣泛應用于框架的設計中,通過定義算法骨架并允許子類在不改變結構的情況下重寫部分步驟。以下是 Qt 中典型的應用場景及示例:
1. 事件處理(Event Handling)
Qt 的事件處理機制是模板方法模式的典型應用。基類(如QObject
或QWidget
)定義了事件處理的整體流程,子類通過重寫虛函數實現具體邏輯。
// 基類QObject中的事件處理骨架
bool QObject::event(QEvent *event) {switch (event->type()) {case QEvent::MouseButtonPress:return mousePressEvent(static_cast<QMouseEvent*>(event));case QEvent::KeyPress:return keyPressEvent(static_cast<QKeyEvent*>(event));// 其他事件類型...default:return false;}
}// 子類重寫具體事件處理
class MyWidget : public QWidget {
protected:void mousePressEvent(QMouseEvent *event) override {qDebug() << "Mouse pressed at" << event->pos();}
};
2. 繪制流程(Paint Event)
QWidget
的paintEvent
方法定義了繪制的骨架,子類通過重寫paintEvent
實現自定義繪制。
// 基類QWidget中的繪制流程
void QWidget::paintEvent(QPaintEvent *event) {QPainter painter(this);// 基類可能執行初始化或通用繪制drawBackground(&painter); // 基類可能提供默認實現drawContents(&painter); // 子類需重寫的核心邏輯
}// 子類實現具體繪制
class MyWidget : public QWidget {
protected:void drawContents(QPainter *painter) override {painter->drawText(rect(), Qt::AlignCenter, "Hello Qt!");}
};
3. 模型 - 視圖架構(Model-View)
QAbstractItemModel
作為模型的基類,定義了數據訪問的骨架,子類通過重寫虛函數提供具體實現。
// 基類QAbstractItemModel的骨架方法
int QAbstractItemModel::rowCount(const QModelIndex &parent = QModelIndex()) const {return 0; // 默認實現,子類需重寫
}QVariant QAbstractItemModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const {return QVariant(); // 默認實現,子類需重寫
}// 子類實現具體數據模型
class MyModel : public QAbstractItemModel {
public:int rowCount(const QModelIndex &parent) const override {return 10; // 返回數據行數}QVariant data(const QModelIndex &index, int role) const override {if (role == Qt::DisplayRole)return QString("Item %1").arg(index.row());return QVariant();}
};
4. 對話框操作(Dialogs)
QDialog
的accept()
和reject()
方法定義了對話框關閉的骨架,子類可重寫這些方法執行自定義邏輯。
// 基類QDialog的默認實現
void QDialog::accept() {done(QDialog::Accepted); // 關閉對話框
}// 子類擴展關閉行為
class MyDialog : public QDialog {
public:void accept() override {// 執行自定義邏輯qDebug() << "Saving data before closing...";QDialog::accept(); // 調用基類關閉邏輯}
};
5. 網絡通信(Networking)
QTcpSocket
的信號與槽機制中,數據讀取的流程由基類定義,子類通過重寫readyRead()
等槽函數處理數據。
// 基類QTcpSocket的流程(偽代碼)
void QTcpSocket::processRead() {while (hasPendingData()) {readData(); // 基類讀取數據emit readyRead(); // 觸發信號}
}// 子類處理數據
class MySocket : public QTcpSocket {Q_OBJECT
public:void readyRead() override {QByteArray data = readAll();qDebug() << "Received:" << data;}
};
Qt 通過模板方法模式實現了框架的靈活性和可擴展性,開發者可通過子類化和重寫虛函數輕松擴展功能。典型場景包括事件處理、繪制、模型 - 視圖、對話框操作等。這種模式降低了代碼重復,同時保持了框架的統一結構。