diff --git a/QTradeProgram.VC.VC.opendb b/QTradeProgram.VC.VC.opendb new file mode 100644 index 0000000..282fc24 Binary files /dev/null and b/QTradeProgram.VC.VC.opendb differ diff --git a/QTradeProgram.VC.db b/QTradeProgram.VC.db index a26d33c..36af000 100644 Binary files a/QTradeProgram.VC.db and b/QTradeProgram.VC.db differ diff --git a/Sqbase/ordertypedelegate.cpp b/Sqbase/ordertypedelegate.cpp index 879ed46..22b3e85 100644 --- a/Sqbase/ordertypedelegate.cpp +++ b/Sqbase/ordertypedelegate.cpp @@ -69,4 +69,47 @@ QString NumberFormatDelegate::displayText(const QVariant &value, const QLocale & } return QStyledItemDelegate::displayText(value, locale); +} + + +HighlightDelegate::HighlightDelegate(QObject *parent) + : QStyledItemDelegate(parent) +{ +} + +void HighlightDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QStyleOptionViewItem opt = option; + initStyleOption(&opt, index); + + // 检查是否需要高亮 - 通过映射到源模型获取高亮状态 + QAbstractItemModel *model = const_cast(index.model()); + QSortFilterProxyModel *proxyModel = qobject_cast(model); + + bool isHighlighted = false; + if (proxyModel) { + QModelIndex sourceIndex = proxyModel->mapToSource(index); + isHighlighted = sourceIndex.data(IsHighlightedRole).toBool(); + } + else { + isHighlighted = index.data(IsHighlightedRole).toBool(); + } + + if (isHighlighted) { + // 设置高亮背景 + painter->fillRect(opt.rect, QColor(255, 192, 203)); // 浅黄色背景 + // 设置加粗字体 + QFont boldFont = opt.font; + boldFont.setBold(true); + painter->setFont(boldFont); + + // 绘制文本 + painter->setPen(opt.palette.color(QPalette::Text)); + painter->drawText(opt.rect, opt.displayAlignment, opt.text); + } + else { + // 正常绘制 + QStyledItemDelegate::paint(painter, opt, index); + } } \ No newline at end of file diff --git a/Sqbase/ordertypedelegate.h b/Sqbase/ordertypedelegate.h index ced64bd..fa1f34b 100644 --- a/Sqbase/ordertypedelegate.h +++ b/Sqbase/ordertypedelegate.h @@ -3,8 +3,15 @@ #include #include +#include #include + +// 在文件顶部添加高亮角色定义 +enum CustomRoles { + IsHighlightedRole = Qt::UserRole + 100 +}; + /* 订单类型单元格渲染委托 */ class OrderTypeDelegate : public QStyledItemDelegate { @@ -33,4 +40,19 @@ public: QString displayText(const QVariant &value, const QLocale &locale) const override; }; -#endif // ORDERTYPEDELEGATE_H + +// 新大单高亮委托 +class HighlightDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + explicit HighlightDelegate(QObject *parent = nullptr); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + + // 可选:如果需要编辑器,可以重写createEditor等方法 +}; + +#endif // HIGHLIGHTDELEGATE_H + diff --git a/Sqbase/qbigordermanager.cpp b/Sqbase/qbigordermanager.cpp index 90f948d..18782be 100644 --- a/Sqbase/qbigordermanager.cpp +++ b/Sqbase/qbigordermanager.cpp @@ -71,7 +71,7 @@ bool QBigOrderManager::addBigOrder(const BigOrderInfo &order) locker.unlock(); // Ƚٷź emit bigOrderAdded(order); - + emit markBigOrderSignal(); return true; diff --git a/Sqbase/qbigorderviewer.cpp b/Sqbase/qbigorderviewer.cpp index 9fd5fa5..f47acf7 100644 --- a/Sqbase/qbigorderviewer.cpp +++ b/Sqbase/qbigorderviewer.cpp @@ -15,32 +15,14 @@ #include #include -//// ==================== OrderTypeDelegate ==================== -//OrderTypeDelegate::OrderTypeDelegate(QObject *parent) -// : QStyledItemDelegate(parent) -//{ -//} -// -//void OrderTypeDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, -// const QModelIndex &index) const -//{ -// if (!index.isValid()) return; -// -// QString type = index.data(Qt::DisplayRole).toString(); -// if (type == "买入") { -// painter->fillRect(option.rect, QColor(255, 230, 230)); // 买入订单浅红背景 -// } else if (type == "卖出") { -// painter->fillRect(option.rect, QColor(230, 255, 230)); // 卖出订单浅绿背景 -// } -// QStyledItemDelegate::paint(painter, option, index); -//} // ==================== QBigOrderViewer ==================== QBigOrderViewer::QBigOrderViewer(QWidget *parent) : QWidget(parent), m_model(new QStandardItemModel(0, 7, this)), m_proxyModel(new QSortFilterProxyModel(this)), - m_typeDelegate(new OrderTypeDelegate(this)) + m_typeDelegate(new OrderTypeDelegate(this)), + m_lastOrderDelegate(new HighlightDelegate(this)) { initUI(); initConnections(); @@ -120,9 +102,12 @@ void QBigOrderViewer::initUI() // m_tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); m_tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); - // 默认按时间列(第6列,索引5)升序排序 + // 设置高亮委托到所有列 + m_tableView->setItemDelegate(m_lastOrderDelegate); + + // 默认按时间列(第6列,索引5)升序排序 -> 新插入的行放在最顶上,故修改为降序排序 @2025.08.30 stone const int timeColumnIndex = 6; - m_proxyModel->sort(timeColumnIndex, Qt::AscendingOrder); + m_proxyModel->sort(timeColumnIndex, Qt::DescendingOrder); mainLayout->addWidget(m_tableView); @@ -226,17 +211,60 @@ void QBigOrderViewer::applyFilters() } } +//void QBigOrderViewer::onBigOrderAdded(const BigOrderInfo &order) +//{ +// auto newOrder = QSharedPointer::create(order); +// m_allOrders.append(newOrder); +// if (matchesFilter(newOrder)) { +// m_currentOrders.append(newOrder); +// +// // 高效插入单行 +// int row = m_model->rowCount(); +// m_model->insertRow(row); +// setRowData(row, newOrder); +// } +//} + void QBigOrderViewer::onBigOrderAdded(const BigOrderInfo &order) { auto newOrder = QSharedPointer::create(order); m_allOrders.append(newOrder); + + // 应用过滤条件 if (matchesFilter(newOrder)) { m_currentOrders.append(newOrder); - // 高效插入单行 - int row = m_model->rowCount(); + // 在源模型的首行插入 + int row = 0 ; m_model->insertRow(row); setRowData(row, newOrder); + + // 设置高亮标记 + for (int col = 0; col < m_model->columnCount(); ++col) { + QModelIndex index = m_model->index(row, col); + m_model->setData(index, true, IsHighlightedRole); + } + + // 通知视图更新 + QModelIndex topLeft = m_model->index(row, 0); + QModelIndex bottomRight = m_model->index(row, m_model->columnCount() - 1); + emit m_model->dataChanged(topLeft, bottomRight); + + // 2秒后取消高亮 + QTimer::singleShot(2000, this, [this, row]() { + for (int col = 0; col < m_model->columnCount(); ++col) { + QModelIndex index = m_model->index(row, col); + m_model->setData(index, false, IsHighlightedRole); + } + + // 通知视图更新 + QModelIndex topLeft = m_model->index(row, 0); + QModelIndex bottomRight = m_model->index(row, m_model->columnCount() - 1); + emit m_model->dataChanged(topLeft, bottomRight); + }); + + // 确保代理模型按时间降序排序,新数据在顶部 + m_proxyModel->sort(6, Qt::DescendingOrder); } } @@ -253,13 +281,26 @@ void QBigOrderViewer::setRowData(int row, QSharedPointer order) QString::number(order->price, 'f', 2)); m_model->setData(m_model->index(row, 5), QString::number(order->level)); - QString str = order->svrRecvTime.mid(11); - if (str == nullptr) - { - QDateTime dateTime = QDateTime::currentDateTime(); - str = dateTime.toString("hh:mm:ss"); + // 确保时间格式正确,用于排序 + QString timeStr; + if (order->svrRecvTime.length() >= 11) { + timeStr = order->svrRecvTime.mid(11); } - m_model->setData(m_model->index(row, 6), str); + else { + QDateTime dateTime = QDateTime::currentDateTime(); + timeStr = dateTime.toString("hh:mm:ss"); + } + m_model->setData(m_model->index(row, 6), timeStr); + + // 添加一个隐藏的时间戳列用于精确排序 + QDateTime fullDateTime; + if (order->svrRecvTime.length() >= 19) { + fullDateTime = QDateTime::fromString(order->svrRecvTime.left(19), "yyyy-MM-dd hh:mm:ss"); + } + else { + fullDateTime = QDateTime::currentDateTime(); + } + m_model->setData(m_model->index(row, 6), fullDateTime, Qt::UserRole + 101); // 使用自定义角色存储完整时间戳 } bool QBigOrderViewer::matchesFilter(QSharedPointer order) diff --git a/Sqbase/qbigorderviewer.h b/Sqbase/qbigorderviewer.h index 5a30103..933990c 100644 --- a/Sqbase/qbigorderviewer.h +++ b/Sqbase/qbigorderviewer.h @@ -50,6 +50,7 @@ private: QStandardItemModel *m_model; QSortFilterProxyModel *m_proxyModel; OrderTypeDelegate *m_typeDelegate; + HighlightDelegate *m_lastOrderDelegate; // 数据存储 QList> m_allOrders; diff --git a/Sqbase/qhistoryorderdialog.cpp b/Sqbase/qhistoryorderdialog.cpp index 1e78778..7b1424c 100644 --- a/Sqbase/qhistoryorderdialog.cpp +++ b/Sqbase/qhistoryorderdialog.cpp @@ -22,6 +22,7 @@ QHistoryOrderDialog::QHistoryOrderDialog(QWidget *parent) m_proxyModel(new QSortFilterProxyModel(this)), m_typeDelegate(new OrderTypeDelegate(this)), m_numberDelegate(new NumberFormatDelegate(this)) + { setWindowTitle("ʷѯ"); setMinimumSize(800, 600); diff --git a/Sqbase/qhistoryorderdialog.h b/Sqbase/qhistoryorderdialog.h index c615fdf..7c7e64c 100644 --- a/Sqbase/qhistoryorderdialog.h +++ b/Sqbase/qhistoryorderdialog.h @@ -52,6 +52,7 @@ private: QStandardItemModel *m_model; QSortFilterProxyModel *m_proxyModel; + // ί NumberFormatDelegate *m_numberDelegate; OrderTypeDelegate *m_typeDelegate; diff --git a/Sqbase/qorderprocessor.cpp b/Sqbase/qorderprocessor.cpp index 295da63..05a9b7e 100644 --- a/Sqbase/qorderprocessor.cpp +++ b/Sqbase/qorderprocessor.cpp @@ -241,7 +241,7 @@ void QOrderProcessor::internalProcess(const OrderBookData& orderData) try { const auto result = findExtremeOrders(orderData); - + for (int i = 0; i < result.size(); i++) { if(result.at(i).isBigOrder) diff --git a/config/replyCodeList.csv b/config/replyCodeList.csv index 8d50b0c..f2d51cb 100644 --- a/config/replyCodeList.csv +++ b/config/replyCodeList.csv @@ -1,9 +1,9 @@ Ʊ,ֵ 09885,200000 -00581,300000 +00581,30000 03383,800000 02666,500000 00839,500000 06098,600000 -06865,150000 -00700,10000 +06865,10000 +00700,1000