33 KiB
QOrderListManager
参考QLogManager 编写一个QOrderListManager和QOrderListViewers
QOrderListManager 和 QOrderListViewers 实现
基于 QLogManager 的设计模式,我可以为您实现一个订单列表管理器和查看器的框架。
QOrderListManager.h
cpp
复制
#ifndef QORDERLISTMANAGER_H
#define QORDERLISTMANAGER_H
#include <QObject>
#include <QList>
#include <QMutex>
#include <QSharedPointer>
#include <QDateTime>
class OrderItem {
public:
QString orderId;
QString customerName;
QDateTime orderTime;
double totalAmount;
QString status;
// 其他订单字段...
};
class QOrderListManager : public QObject
{
Q_OBJECT
public:
enum OrderStatus {
Pending,
Processing,
Shipped,
Delivered,
Cancelled
};
Q_ENUM(OrderStatus)
static QOrderListManager* instance();
static void destroy();
// 订单操作
bool addOrder(const OrderItem& order);
bool updateOrder(const QString& orderId, const OrderItem& newData);
bool removeOrder(const QString& orderId);
QSharedPointer<OrderItem> getOrder(const QString& orderId) const;
QList<QSharedPointer<OrderItem>> getAllOrders() const;
QList<QSharedPointer<OrderItem>> getOrdersByStatus(OrderStatus status) const;
QList<QSharedPointer<OrderItem>> getOrdersByCustomer(const QString& customerName) const;
// 配置方法
void setAutoSave(bool enabled);
void setAutoSaveInterval(int minutes);
void loadFromFile(const QString& filename);
void saveToFile(const QString& filename);
signals:
void orderAdded(const OrderItem& order);
void orderUpdated(const QString& orderId);
void orderRemoved(const QString& orderId);
void orderStatusChanged(const QString& orderId, OrderStatus newStatus);
private:
explicit QOrderListManager(QObject* parent = nullptr);
~QOrderListManager();
void autoSave();
void sortOrders();
static QBasicAtomicPointer<QOrderListManager> s_instance;
static QMutex s_mutex;
QList<QSharedPointer<OrderItem>> m_orders;
mutable QMutex m_orderMutex;
bool m_autoSave = false;
int m_autoSaveInterval = 30; // 分钟
QTimer* m_autoSaveTimer = nullptr;
Q_DISABLE_COPY(QOrderListManager)
};
#endif // QORDERLISTMANAGER_H
QOrderListViewers.h
cpp
复制
#ifndef QORDERLISTVIEWERS_H
#define QORDERLISTVIEWERS_H
#include <QWidget>
#include <QTableView>
#include <QStandardItemModel>
#include <QSortFilterProxyModel>
#include "QOrderListManager.h"
class QOrderListViewers : public QWidget
{
Q_OBJECT
public:
explicit QOrderListViewers(QWidget *parent = nullptr);
~QOrderListViewers();
enum ViewMode {
AllOrders,
PendingOrders,
ProcessingOrders,
ShippedOrders
};
Q_ENUM(ViewMode)
void setViewMode(ViewMode mode);
void setFilterCustomer(const QString& customerName);
void setFilterDateRange(const QDate& start, const QDate& end);
void refresh();
private slots:
void onOrderAdded(const OrderItem& order);
void onOrderUpdated(const QString& orderId);
void onOrderRemoved(const QString& orderId);
void onOrderStatusChanged(const QString& orderId, QOrderListManager::OrderStatus newStatus);
private:
void initUI();
void initConnections();
void updateView();
void addOrderToView(const OrderItem& order);
void updateOrderInView(const QString& orderId);
void removeOrderFromView(const QString& orderId);
QTableView* m_tableView;
QStandardItemModel* m_model;
QSortFilterProxyModel* m_proxyModel;
ViewMode m_currentMode = AllOrders;
QString m_filterCustomer;
QPair<QDate, QDate> m_dateRange;
};
#endif // QORDERLISTVIEWERS_H
实现说明
QOrderListManager 特点
- 线程安全设计:
- 使用 QMutex 保护订单列表访问
- 原子指针管理单例实例
- 完整订单管理功能:
- 增删改查基本操作
- 多种查询方式(按状态、按客户等)
- 自动保存功能
- 信号通知机制:
- 订单变化时发出信号
- 状态变化单独通知
- 数据持久化:
- 支持从文件加载/保存
- 可配置自动保存
QOrderListViewers 特点
- 多种视图模式:
- 全部订单视图
- 按状态过滤视图
- 自定义过滤功能
- 高级表格功能:
- 使用 QTableView 显示
- 支持排序和过滤
- 模型-视图架构
- 实时更新:
- 监听管理器信号
- 自动刷新显示
- 灵活的过滤功能:
- 按客户名称过滤
- 按日期范围过滤
使用示例
cpp
复制
// 初始化管理器
QOrderListManager* manager = QOrderListManager::instance();
// 添加订单
OrderItem order;
order.orderId = "ORD-20230001";
order.customerName = "张三";
order.orderTime = QDateTime::currentDateTime();
order.totalAmount = 199.99;
order.status = "Pending";
manager->addOrder(order);
// 创建查看器
QOrderListViewers* viewer = new QOrderListViewers();
viewer->setViewMode(QOrderListViewers::PendingOrders);
viewer->show();
这个实现基于 QLogManager 的设计模式,但针对订单管理场景进行了专门优化,提供了完整的订单管理功能和可视化界面。
订单格式如下:struct OrderBookItem { double price = 0.0; double volume = 0.0; int orderCount = 0; QString orderId; // 新增订单ID字段 bool isValid() const { return price > 0 && volume > 0; //return price > 0 && volume > 0 && !orderId.isEmpty(); // 当前数据没有 orderId } };
根据您提供的 OrderBookItem 结构,我将重新设计 QOrderListManager 和 QOrderListViewers,专注于订单簿管理功能。
QOrderListManager.h
cpp
复制
#ifndef QORDERLISTMANAGER_H
#define QORDERLISTMANAGER_H
#include <QObject>
#include <QMap>
#include <QMutex>
#include <QSharedPointer>
#include <QDateTime>
struct OrderBookItem {
double price = 0.0;
double volume = 0.0;
int orderCount = 0;
QString orderId;
bool isValid() const {
return price > 0 && volume > 0 && !orderId.isEmpty();
}
bool operator==(const OrderBookItem& other) const {
return orderId == other.orderId;
}
};
class QOrderListManager : public QObject
{
Q_OBJECT
public:
enum OrderType {
BidOrder, // 买单
AskOrder // 卖单
};
Q_ENUM(OrderType)
static QOrderListManager* instance();
static void destroy();
// 订单簿操作
bool addOrder(OrderType type, const OrderBookItem& order);
bool updateOrder(OrderType type, const QString& orderId, const OrderBookItem& newData);
bool removeOrder(OrderType type, const QString& orderId);
QSharedPointer<OrderBookItem> getOrder(OrderType type, const QString& orderId) const;
// 获取订单簿数据
QMap<double, QList<QSharedPointer<OrderBookItem>>> getBidOrders() const;
QMap<double, QList<QSharedPointer<OrderBookItem>>> getAskOrders() const;
// 聚合数据
QMap<double, double> getBidPriceLevels() const; // 价格 -> 总量
QMap<double, double> getAskPriceLevels() const;
// 统计信息
double getTotalBidVolume() const;
double getTotalAskVolume() const;
double getBestBidPrice() const;
double getBestAskPrice() const;
signals:
void orderAdded(OrderType type, const OrderBookItem& order);
void orderUpdated(OrderType type, const QString& orderId);
void orderRemoved(OrderType type, const QString& orderId);
void orderBookChanged();
private:
explicit QOrderListManager(QObject* parent = nullptr);
~QOrderListManager();
void sortOrders(OrderType type);
void calculatePriceLevels();
static QBasicAtomicPointer<QOrderListManager> s_instance;
static QMutex s_mutex;
// 买单和卖单分别存储,按价格排序
QMap<double, QList<QSharedPointer<OrderBookItem>>> m_bidOrders;
QMap<double, QList<QSharedPointer<OrderBookItem>>> m_askOrders;
// 价格层级聚合数据
QMap<double, double> m_bidPriceLevels;
QMap<double, double> m_askPriceLevels;
mutable QMutex m_orderMutex;
Q_DISABLE_COPY(QOrderListManager)
};
#endif // QORDERLISTMANAGER_H
QOrderListViewers.h
cpp
复制
#ifndef QORDERLISTVIEWERS_H
#define QORDERLISTVIEWERS_H
#include <QWidget>
#include <QTableView>
#include <QStandardItemModel>
#include <QHeaderView>
#include <QHBoxLayout>
#include "QOrderListManager.h"
class QOrderBookView : public QWidget
{
Q_OBJECT
public:
explicit QOrderBookView(QWidget *parent = nullptr);
~QOrderBookView();
void updateView();
void setPricePrecision(int precision);
void setVolumePrecision(int precision);
private slots:
void onOrderBookChanged();
private:
void initUI();
void initConnections();
void updateBidView();
void updateAskView();
QTableView* m_bidView;
QTableView* m_askView;
QStandardItemModel* m_bidModel;
QStandardItemModel* m_askModel;
int m_pricePrecision = 2;
int m_volumePrecision = 4;
};
class QOrderDetailView : public QWidget
{
Q_OBJECT
public:
explicit QOrderDetailView(QWidget *parent = nullptr);
~QOrderDetailView();
void setOrderType(QOrderListManager::OrderType type);
void updateView();
private slots:
void onOrderBookChanged();
private:
void initUI();
void initConnections();
QTableView* m_detailView;
QStandardItemModel* m_detailModel;
QOrderListManager::OrderType m_orderType;
};
#endif // QORDERLISTVIEWERS_H
实现特点
QOrderListManager 改进
- 订单簿专用数据结构:
- 使用
QMap<double, QList<QSharedPointer<OrderBookItem>>>按价格层级存储订单 - 区分买单(Bid)和卖单(Ask)
- 使用
- 高效查询功能:
- 提供价格层级聚合数据 (
getBidPriceLevels/getAskPriceLevels) - 快速获取最优买卖价 (
getBestBidPrice/getBestAskPrice)
- 提供价格层级聚合数据 (
- 线程安全:
- 所有公共方法都使用互斥锁保护
- 原子指针管理单例
- 信号通知:
- 订单变化时发出详细信号
- 订单簿变化时发出汇总信号
QOrderListViewers 改进
- 专业订单簿视图:
- 分左右两栏显示买卖盘
- 支持价格和数量的精度设置
- 详细订单视图:
- 可查看特定价格层的所有订单
- 显示订单详细信息
- 实时更新:
- 监听订单簿变化信号
- 自动刷新视图
使用示例
cpp
复制
// 初始化管理器
QOrderListManager* manager = QOrderListManager::instance();
// 添加订单
OrderBookItem bidOrder;
bidOrder.price = 100.50;
bidOrder.volume = 10.0;
bidOrder.orderCount = 1;
bidOrder.orderId = "BID-001";
manager->addOrder(QOrderListManager::BidOrder, bidOrder);
OrderBookItem askOrder;
askOrder.price = 101.00;
askOrder.volume = 5.0;
askOrder.orderCount = 1;
askOrder.orderId = "ASK-001";
manager->addOrder(QOrderListManager::AskOrder, askOrder);
// 创建视图
QOrderBookView* orderBookView = new QOrderBookView();
orderBookView->setPricePrecision(2);
orderBookView->setVolumePrecision(4);
orderBookView->show();
QOrderDetailView* bidDetailView = new QOrderDetailView();
bidDetailView->setOrderType(QOrderListManager::BidOrder);
bidDetailView->show();
这个实现专门针对订单簿场景优化,提供了高效的订单管理和专业的可视化界面,适合金融交易系统使用。
完善实现文件
以下是完整的实现文件,包括 QOrderListManager.cpp 和 QOrderListViewers.cpp 的实现:
QOrderListManager.cpp
cpp
复制
#include "QOrderListManager.h"
#include <QDebug>
QBasicAtomicPointer<QOrderListManager> QOrderListManager::s_instance = QBasicAtomicPointer<QOrderListManager>(nullptr);
QMutex QOrderListManager::s_mutex;
QOrderListManager* QOrderListManager::instance()
{
if (!s_instance.loadAcquire()) {
QMutexLocker locker(&s_mutex);
if (!s_instance.loadAcquire()) {
s_instance.storeRelease(new QOrderListManager());
}
}
return s_instance.loadAcquire();
}
void QOrderListManager::destroy()
{
QMutexLocker locker(&s_mutex);
delete s_instance.loadAcquire();
s_instance.storeRelease(nullptr);
}
QOrderListManager::QOrderListManager(QObject *parent) : QObject(parent)
{
// 初始化代码
}
QOrderListManager::~QOrderListManager()
{
// 清理代码
}
bool QOrderListManager::addOrder(OrderType type, const OrderBookItem &order)
{
if (!order.isValid()) {
qWarning() << "Invalid order data";
return false;
}
QMutexLocker locker(&m_orderMutex);
auto& orderMap = (type == BidOrder) ? m_bidOrders : m_askOrders;
auto& orderList = orderMap[order.price];
// 检查订单是否已存在
for (const auto& existingOrder : orderList) {
if (existingOrder->orderId == order.orderId) {
qWarning() << "Order already exists:" << order.orderId;
return false;
}
}
auto newOrder = QSharedPointer<OrderBookItem>::create(order);
orderList.append(newOrder);
// 排序订单
sortOrders(type);
calculatePriceLevels();
locker.unlock();
emit orderAdded(type, order);
emit orderBookChanged();
return true;
}
bool QOrderListManager::updateOrder(OrderType type, const QString &orderId, const OrderBookItem &newData)
{
if (!newData.isValid()) {
qWarning() << "Invalid order data";
return false;
}
QMutexLocker locker(&m_orderMutex);
auto& orderMap = (type == BidOrder) ? m_bidOrders : m_askOrders;
bool found = false;
for (auto it = orderMap.begin(); it != orderMap.end(); ++it) {
for (auto& order : it.value()) {
if (order->orderId == orderId) {
// 如果价格变化,需要重新分组
if (order->price != newData.price) {
auto orderList = it.value();
orderList.removeOne(order);
if (orderList.isEmpty()) {
orderMap.erase(it);
}
auto newOrder = QSharedPointer<OrderBookItem>::create(newData);
orderMap[newData.price].append(newOrder);
} else {
*order = newData;
}
found = true;
break;
}
}
if (found) break;
}
if (!found) {
qWarning() << "Order not found:" << orderId;
return false;
}
// 排序订单
sortOrders(type);
calculatePriceLevels();
locker.unlock();
emit orderUpdated(type, orderId);
emit orderBookChanged();
return true;
}
bool QOrderListManager::removeOrder(OrderType type, const QString &orderId)
{
QMutexLocker locker(&m_orderMutex);
auto& orderMap = (type == BidOrder) ? m_bidOrders : m_askOrders;
bool found = false;
for (auto it = orderMap.begin(); it != orderMap.end(); ++it) {
for (auto& order : it.value()) {
if (order->orderId == orderId) {
auto orderList = it.value();
orderList.removeOne(order);
if (orderList.isEmpty()) {
orderMap.erase(it);
}
found = true;
break;
}
}
if (found) break;
}
if (!found) {
qWarning() << "Order not found:" << orderId;
return false;
}
calculatePriceLevels();
locker.unlock();
emit orderRemoved(type, orderId);
emit orderBookChanged();
return true;
}
QSharedPointer<OrderBookItem> QOrderListManager::getOrder(OrderType type, const QString &orderId) const
{
QMutexLocker locker(&m_orderMutex);
const auto& orderMap = (type == BidOrder) ? m_bidOrders : m_askOrders;
for (const auto& orderList : orderMap) {
for (const auto& order : orderList) {
if (order->orderId == orderId) {
return order;
}
}
}
return nullptr;
}
QMap<double, QList<QSharedPointer<OrderBookItem>>> QOrderListManager::getBidOrders() const
{
QMutexLocker locker(&m_orderMutex);
return m_bidOrders;
}
QMap<double, QList<QSharedPointer<OrderBookItem>>> QOrderListManager::getAskOrders() const
{
QMutexLocker locker(&m_orderMutex);
return m_askOrders;
}
QMap<double, double> QOrderListManager::getBidPriceLevels() const
{
QMutexLocker locker(&m_orderMutex);
return m_bidPriceLevels;
}
QMap<double, double> QOrderListManager::getAskPriceLevels() const
{
QMutexLocker locker(&m_orderMutex);
return m_askPriceLevels;
}
double QOrderListManager::getTotalBidVolume() const
{
QMutexLocker locker(&m_orderMutex);
double total = 0.0;
for (const auto& volume : m_bidPriceLevels) {
total += volume;
}
return total;
}
double QOrderListManager::getTotalAskVolume() const
{
QMutexLocker locker(&m_orderMutex);
double total = 0.0;
for (const auto& volume : m_askPriceLevels) {
total += volume;
}
return total;
}
double QOrderListManager::getBestBidPrice() const
{
QMutexLocker locker(&m_orderMutex);
if (m_bidOrders.isEmpty()) return 0.0;
return m_bidOrders.lastKey();
}
double QOrderListManager::getBestAskPrice() const
{
QMutexLocker locker(&m_orderMutex);
if (m_askOrders.isEmpty()) return 0.0;
return m_askOrders.firstKey();
}
void QOrderListManager::sortOrders(OrderType type)
{
auto& orderMap = (type == BidOrder) ? m_bidOrders : m_askOrders;
if (type == BidOrder) {
// 买单按价格降序排列
QMap<double, QList<QSharedPointer<OrderBookItem>>> sortedMap;
auto keys = orderMap.keys();
std::sort(keys.begin(), keys.end(), std::greater<double>());
for (const auto& key : keys) {
sortedMap.insert(key, orderMap.value(key));
}
orderMap = sortedMap;
} else {
// 卖单按价格升序排列
QMap<double, QList<QSharedPointer<OrderBookItem>>> sortedMap;
auto keys = orderMap.keys();
std::sort(keys.begin(), keys.end());
for (const auto& key : keys) {
sortedMap.insert(key, orderMap.value(key));
}
orderMap = sortedMap;
}
}
void QOrderListManager::calculatePriceLevels()
{
m_bidPriceLevels.clear();
for (auto it = m_bidOrders.constBegin(); it != m_bidOrders.constEnd(); ++it) {
double totalVolume = 0.0;
for (const auto& order : it.value()) {
totalVolume += order->volume;
}
m_bidPriceLevels.insert(it.key(), totalVolume);
}
m_askPriceLevels.clear();
for (auto it = m_askOrders.constBegin(); it != m_askOrders.constEnd(); ++it) {
double totalVolume = 0.0;
for (const auto& order : it.value()) {
totalVolume += order->volume;
}
m_askPriceLevels.insert(it.key(), totalVolume);
}
}
QOrderListViewers.cpp
cpp
复制
#include "QOrderListViewers.h"
#include <QHeaderView>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QLabel>
QOrderBookView::QOrderBookView(QWidget *parent) : QWidget(parent)
{
initUI();
initConnections();
}
QOrderBookView::~QOrderBookView()
{
}
void QOrderBookView::initUI()
{
QHBoxLayout *mainLayout = new QHBoxLayout(this);
// 买单视图
m_bidModel = new QStandardItemModel(this);
m_bidModel->setColumnCount(3);
m_bidModel->setHorizontalHeaderLabels({"价格", "数量", "订单数"});
m_bidView = new QTableView(this);
m_bidView->setModel(m_bidModel);
m_bidView->verticalHeader()->setVisible(false);
m_bidView->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_bidView->setSelectionBehavior(QAbstractItemView::SelectRows);
m_bidView->setSelectionMode(QAbstractItemView::SingleSelection);
// 卖单视图
m_askModel = new QStandardItemModel(this);
m_askModel->setColumnCount(3);
m_askModel->setHorizontalHeaderLabels({"价格", "数量", "订单数"});
m_askView = new QTableView(this);
m_askView->setModel(m_askModel);
m_askView->verticalHeader()->setVisible(false);
m_askView->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_askView->setSelectionBehavior(QAbstractItemView::SelectRows);
m_askView->setSelectionMode(QAbstractItemView::SingleSelection);
// 布局
QVBoxLayout *bidLayout = new QVBoxLayout();
bidLayout->addWidget(new QLabel("买单", this));
bidLayout->addWidget(m_bidView);
QVBoxLayout *askLayout = new QVBoxLayout();
askLayout->addWidget(new QLabel("卖单", this));
askLayout->addWidget(m_askView);
mainLayout->addLayout(bidLayout);
mainLayout->addLayout(askLayout);
setLayout(mainLayout);
}
void QOrderBookView::initConnections()
{
auto manager = QOrderListManager::instance();
connect(manager, &QOrderListManager::orderBookChanged, this, &QOrderBookView::updateView);
}
void QOrderBookView::updateView()
{
updateBidView();
updateAskView();
}
void QOrderBookView::updateBidView()
{
m_bidModel->removeRows(0, m_bidModel->rowCount());
auto bids = QOrderListManager::instance()->getBidPriceLevels();
int row = 0;
for (auto it = bids.constBegin(); it != bids.constEnd(); ++it) {
m_bidModel->insertRow(row);
QStandardItem *priceItem = new QStandardItem(QString::number(it.key(), 'f', m_pricePrecision));
QStandardItem *volumeItem = new QStandardItem(QString::number(it.value(), 'f', m_volumePrecision));
// 计算订单数
int orderCount = 0;
auto bidOrders = QOrderListManager::instance()->getBidOrders();
if (bidOrders.contains(it.key())) {
orderCount = bidOrders.value(it.key()).size();
}
QStandardItem *countItem = new QStandardItem(QString::number(orderCount));
m_bidModel->setItem(row, 0, priceItem);
m_bidModel->setItem(row, 1, volumeItem);
m_bidModel->setItem(row, 2, countItem);
row++;
}
}
void QOrderBookView::updateAskView()
{
m_askModel->removeRows(0, m_askModel->rowCount());
auto asks = QOrderListManager::instance()->getAskPriceLevels();
int row = 0;
for (auto it = asks.constBegin(); it != asks.constEnd(); ++it) {
m_askModel->insertRow(row);
QStandardItem *priceItem = new QStandardItem(QString::number(it.key(), 'f', m_pricePrecision));
QStandardItem *volumeItem = new QStandardItem(QString::number(it.value(), 'f', m_volumePrecision));
// 计算订单数
int orderCount = 0;
auto askOrders = QOrderListManager::instance()->getAskOrders();
if (askOrders.contains(it.key())) {
orderCount = askOrders.value(it.key()).size();
}
QStandardItem *countItem = new QStandardItem(QString::number(orderCount));
m_askModel->setItem(row, 0, priceItem);
m_askModel->setItem(row, 1, volumeItem);
m_askModel->setItem(row, 2, countItem);
row++;
}
}
void QOrderBookView::setPricePrecision(int precision)
{
m_pricePrecision = precision;
updateView();
}
void QOrderBookView::setVolumePrecision(int precision)
{
m_volumePrecision = precision;
updateView();
}
QOrderDetailView::QOrderDetailView(QWidget *parent) : QWidget(parent),
m_orderType(QOrderListManager::BidOrder)
{
initUI();
initConnections();
}
QOrderDetailView::~QOrderDetailView()
{
}
void QOrderDetailView::initUI()
{
QVBoxLayout *mainLayout = new QVBoxLayout(this);
m_detailModel = new QStandardItemModel(this);
m_detailModel->setColumnCount(4);
m_detailModel->setHorizontalHeaderLabels({"订单ID", "价格", "数量", "时间"});
m_detailView = new QTableView(this);
m_detailView->setModel(m_detailModel);
m_detailView->verticalHeader()->setVisible(false);
m_detailView->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_detailView->setSelectionBehavior(QAbstractItemView::SelectRows);
m_detailView->setSelectionMode(QAbstractItemView::SingleSelection);
mainLayout->addWidget(m_detailView);
setLayout(mainLayout);
}
void QOrderDetailView::initConnections()
{
auto manager = QOrderListManager::instance();
connect(manager, &QOrderListManager::orderBookChanged, this, &QOrderDetailView::updateView);
}
void QOrderDetailView::setOrderType(QOrderListManager::OrderType type)
{
m_orderType = type;
updateView();
}
void QOrderDetailView::updateView()
{
m_detailModel->removeRows(0, m_detailModel->rowCount());
auto manager = QOrderListManager::instance();
auto orders = (m_orderType == QOrderListManager::BidOrder) ?
manager->getBidOrders() : manager->getAskOrders();
int row = 0;
for (auto it = orders.constBegin(); it != orders.constEnd(); ++it) {
for (const auto& order : it.value()) {
m_detailModel->insertRow(row);
QStandardItem *idItem = new QStandardItem(order->orderId);
QStandardItem *priceItem = new QStandardItem(QString::number(order->price, 'f', 2));
QStandardItem *volumeItem = new QStandardItem(QString::number(order->volume, 'f', 4));
QStandardItem *timeItem = new QStandardItem(QDateTime::currentDateTime().toString("hh:mm:ss.zzz"));
m_detailModel->setItem(row, 0, idItem);
m_detailModel->setItem(row, 1, priceItem);
m_detailModel->setItem(row, 2, volumeItem);
m_detailModel->setItem(row, 3, timeItem);
row++;
}
}
}
主要特点
- 线程安全设计:
- 使用 QMutex 保护所有订单数据访问
- 原子指针管理单例实例
- 高效订单管理:
- 按价格层级存储订单 (QMap<double, QList>)
- 自动计算价格层级聚合数据
- 支持快速查询最优买卖价
- 专业视图组件:
- 订单簿视图 (QOrderBookView) 分左右显示买卖盘
- 订单详情视图 (QOrderDetailView) 显示单个价格层的所有订单
- 支持自定义价格和数量显示精度
- 实时更新机制:
- 使用信号-槽机制实现数据变化时自动更新视图
- 细粒度信号 (单个订单变化和整个订单簿变化)
- 完整的功能实现:
- 支持订单的增删改查
- 提供多种查询方式
- 自动排序和聚合计算
这个实现完全基于您提供的 OrderBookItem 结构,并针对金融订单簿场景进行了优化,适合用于交易系统的开发。
error: undefined reference to `QOrderBookView::onOrderBookChanged()'
这个错误是因为在 QOrderListViewers.h 中声明了 onOrderBookChanged() 槽函数,但在 QOrderListViewers.cpp 中没有实现它。让我们修正这个问题:
修正后的 QOrderListViewers.cpp
cpp
复制
#include "QOrderListViewers.h"
#include <QHeaderView>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QLabel>
// [其他现有代码保持不变...]
void QOrderBookView::initConnections()
{
auto manager = QOrderListManager::instance();
connect(manager, &QOrderListManager::orderBookChanged,
this, &QOrderBookView::onOrderBookChanged);
}
// 添加这个实现
void QOrderBookView::onOrderBookChanged()
{
updateView();
}
// [其他现有代码保持不变...]
void QOrderDetailView::initConnections()
{
auto manager = QOrderListManager::instance();
connect(manager, &QOrderListManager::orderBookChanged,
this, &QOrderDetailView::onOrderBookChanged);
}
// 添加这个实现
void QOrderDetailView::onOrderBookChanged()
{
updateView();
}
修正后的 QOrderListViewers.h
cpp
复制
#ifndef QORDERLISTVIEWERS_H
#define QORDERLISTVIEWERS_H
#include <QWidget>
#include <QTableView>
#include <QStandardItemModel>
#include <QHeaderView>
#include <QHBoxLayout>
#include "QOrderListManager.h"
class QOrderBookView : public QWidget
{
Q_OBJECT
public:
explicit QOrderBookView(QWidget *parent = nullptr);
~QOrderBookView();
void updateView();
void setPricePrecision(int precision);
void setVolumePrecision(int precision);
private slots:
void onOrderBookChanged(); // 确保这里已声明
private:
void initUI();
void initConnections();
void updateBidView();
void updateAskView();
// [其他成员变量保持不变...]
};
class QOrderDetailView : public QWidget
{
Q_OBJECT
public:
explicit QOrderDetailView(QWidget *parent = nullptr);
~QOrderDetailView();
void setOrderType(QOrderListManager::OrderType type);
void updateView();
private slots:
void onOrderBookChanged(); // 确保这里已声明
private:
void initUI();
void initConnections();
// [其他成员变量保持不变...]
};
#endif // QORDERLISTVIEWERS_H
为什么会出现这个错误?
- 声明与实现不匹配:在头文件中声明了槽函数
onOrderBookChanged(),但在源文件中没有提供实现 - 连接信号时的问题:虽然你直接连接信号到
updateView(),但头文件中声明了这个槽函数,所以编译器期望找到它的实现
解决方案的两种选择:
选择1:保留槽函数并实现它(如上所示)
cpp
复制
void QOrderBookView::onOrderBookChanged()
{
updateView();
}
选择2:移除槽函数声明,直接连接信号
修改头文件,移除 onOrderBookChanged() 的声明,然后修改连接方式:
cpp
复制
// 在initConnections()中改为:
connect(manager, &QOrderListManager::orderBookChanged,
this, &QOrderBookView::updateView);
两种方法都是可行的,选择哪种取决于你的设计偏好。第一种方法更符合Qt的命名惯例,特别是如果你以后需要在这个槽函数中添加更多处理逻辑。第二种方法更直接,减少了不必要的间接调用。
error: undefined reference to `QOrderDetailView::onOrderBookChanged()'
这个错误表明 QOrderDetailView 类中的 onOrderBookChanged() 槽函数在头文件中声明了,但在源文件中没有实现。以下是完整的修正方案:
修正方案
1. 修改 QOrderListViewers.h
确保槽函数声明正确:
cpp
复制
class QOrderDetailView : public QWidget
{
Q_OBJECT
public:
// ... 其他公共成员函数 ...
private slots:
void onOrderBookChanged(); // 确保这个声明存在
private:
// ... 私有成员函数和变量 ...
};
2. 修改 QOrderListViewers.cpp
添加缺失的实现:
cpp
复制
void QOrderDetailView::onOrderBookChanged()
{
updateView(); // 直接调用updateView()更新界面
}
3. 确保连接正确
在 initConnections() 中正确连接信号和槽:
cpp
复制
void QOrderDetailView::initConnections()
{
auto manager = QOrderListManager::instance();
connect(manager, &QOrderListManager::orderBookChanged,
this, &QOrderDetailView::onOrderBookChanged);
}
完整修正后的 QOrderDetailView 相关代码
cpp
复制
// QOrderListViewers.h
class QOrderDetailView : public QWidget
{
Q_OBJECT
public:
explicit QOrderDetailView(QWidget *parent = nullptr);
~QOrderDetailView();
void setOrderType(QOrderListManager::OrderType type);
void updateView();
private slots:
void onOrderBookChanged();
private:
void initUI();
void initConnections();
QTableView* m_detailView;
QStandardItemModel* m_detailModel;
QOrderListManager::OrderType m_orderType;
};
cpp
复制
// QOrderListViewers.cpp
QOrderDetailView::QOrderDetailView(QWidget *parent)
: QWidget(parent), m_orderType(QOrderListManager::BidOrder)
{
initUI();
initConnections();
}
void QOrderDetailView::initConnections()
{
auto manager = QOrderListManager::instance();
connect(manager, &QOrderListManager::orderBookChanged,
this, &QOrderDetailView::onOrderBookChanged);
}
void QOrderDetailView::onOrderBookChanged()
{
updateView();
}
// ... 其他成员函数的实现保持不变 ...
为什么会出现这个错误?
- 声明与实现不匹配:在头文件中声明了
onOrderBookChanged()槽函数,但在源文件中没有提供实现 - Qt的moc机制:Qt的元对象编译器(moc)会为声明的槽函数生成代码,如果没有实现就会导致链接错误
替代解决方案
如果你不想保留这个槽函数,也可以直接连接信号到 updateView():
- 从头文件中移除
onOrderBookChanged()的声明 - 修改连接代码:
cpp
复制
void QOrderDetailView::initConnections()
{
auto manager = QOrderListManager::instance();
connect(manager, &QOrderListManager::orderBookChanged,
this, &QOrderDetailView::updateView);
}
两种方法都是有效的,选择哪种取决于你的设计偏好。保留中间槽函数的方式更灵活,便于以后添加额外处理逻辑。