活动介绍

为什么model.rowcount显示不及时,经常显示为0 qt cpp

时间: 2025-03-22 16:03:58 浏览: 31
<think>好的,用户的问题是关于Qt C++中model.rowCount()经常显示为0的情况,为什么会出现这种延迟。我需要先回忆一下Qt的模型视图架构,特别是Model/View的设计模式。 首先,可能的原因是模型的数据加载是异步的。比如,如果使用QSqlQueryModel或自定义的模型,可能在后台线程中加载数据,这时候主线程调用rowCount()的时候数据还没加载完,所以返回0。这时候需要检查数据加载是否完成,或者是否使用了异步操作。 另一个常见的情况是模型没有正确初始化或重置。比如,在模型的数据被设置之前就调用了rowCount(),或者在数据变化后没有及时通知视图更新。这时候可能需要调用beginResetModel()和endResetModel(),或者在数据变化后发出layoutChanged信号,确保视图知道数据已经更新。 还有可能是模型的结构问题。例如,树形结构模型中,rowCount()返回的是直接子项的数量,如果父节点没有正确设置,可能会返回0。需要确认是否正确实现了parent()和index()方法,特别是对于层次结构的模型。 另外,内存中的数据可能尚未提交到模型。比如,在批量添加数据时,如果使用了beginInsertRows()和endInsertRows(),但在调用这两个函数之前就查询rowCount(),那么结果可能不正确。这时候需要确保在修改数据前后正确使用这些函数,并且及时提交更改。 还有可能是视图没有及时刷新。有时候即使模型的数据已经更新,视图可能没有立即重绘,这时候可能需要手动调用view的update()或者reset()方法,或者检查是否有事件循环没有被处理,比如在长时间的操作中没有调用processEvents(),导致界面没有及时更新。 此外,线程安全问题也需要考虑。如果模型在一个线程中被修改,而在另一个线程中被访问,没有正确的同步机制,比如使用信号槽或者互斥锁,可能导致rowCount()返回过时的值。需要检查是否跨线程操作模型,并确保线程安全。 可能用户没有正确连接相关的信号和槽。比如,当模型数据变化时,应该发出rowsInserted等信号,视图会自动更新。如果这些信号没有正确触发,视图可能不会刷新,导致rowCount()看似没有更新。 还有一种情况是代理模型的使用。如果用户使用了QSortFilterProxyModel,可能需要确保源模型正确,并且代理模型的过滤条件设置正确,否则rowCount()可能返回0,尤其是在过滤条件过于严格的情况下。 总结一下,可能的原因包括:异步加载、模型未正确初始化或重置、层次结构模型的问题、数据未提交、视图未刷新、线程安全问题、信号槽未连接、代理模型配置错误等。需要根据具体情况逐一排查,比如检查数据加载流程是否正确,是否在数据就绪后才调用rowCount(),是否使用了正确的模型通知方法,以及线程和信号槽的处理是否恰当。</think>在Qt C++中,`model.rowCount()`显示为0通常与模型数据加载机制和Qt的事件循环有关。以下是逐步排查和解决方案: --- ### **1. 模型数据未就绪(异步加载)** - **典型场景**:使用`QSqlQueryModel`、网络请求或后台线程加载数据时 - **现象**:主线程在数据加载完成前调用`rowCount()` - **解决方案**: ```cpp // 显式等待数据加载完成(仅适用于同步操作) while (model.canFetchMore()) { model.fetchMore(); } // 或通过信号槽监听数据就绪 connect(&model, &QSqlQueryModel::rowsInserted, [=](){ qDebug() << "实际行数:" << model.rowCount(); }); ``` --- ### **2. 未正确重置模型** - **典型错误**:修改数据后未通知视图更新 - **解决方案**: ```cpp // 重置模型 model.beginResetModel(); // 更新数据... model.endResetModel(); // 或局部更新 model.insertRows(0, newRowCount); model.layoutChanged(); // 触发视图刷新 ``` --- ### **3. 树形结构模型错误** - **常见于**:`QAbstractItemModel`子类未正确处理父子关系 - **验证方法**: ```cpp // 检查父节点是否有效 qDebug() << "根节点行数:" << model.rowCount(QModelIndex()); ``` - **注意**:树形模型中`rowCount()`的返回值取决于父节点参数 --- ### **4. 数据提交延迟** - **批量插入时**必须包裹插入操作: ```cpp model.beginInsertRows(parent, start, end); // 插入数据... model.endInsertRows(); // 此时rowCount()才会更新 ``` --- ### **5. 事件循环未处理** - **典型场景**:在耗时操作中未及时处理事件 - **修复方法**: ```cpp // 在循环中强制处理事件 for (int i = 0; i < 1000; ++i) { // 长时间操作... QCoreApplication::processEvents(); } ``` --- ### **6. 线程安全问题** - **跨线程操作模型时**必须使用信号槽: ```cpp // 在工作线程完成数据加载后 emit dataReady(); // 在主线程连接信号 connect(workerThread, &Worker::dataReady, &model, [&](){ model.reloadData(); // 确保在主线程操作模型 }); ``` --- ### **7. 代理模型配置错误** - **检查代理模型过滤条件**: ```cpp QSortFilterProxyModel proxy; proxy.setSourceModel(&sourceModel); proxy.setFilterWildcard("*"); // 临时禁用过滤 qDebug() << proxy.rowCount(); // 验证源模型是否正常 ``` --- ### **调试建议** 1. 在调用`rowCount()`前后添加日志: ```cpp qDebug() << "Before update:" << model.rowCount(); // 更新模型操作... qDebug() << "After update:" << model.rowCount(); ``` 2. 重写模型的`rowCount()`方法,添加断点观察调用栈 --- 通过以上步骤可定位具体原因。大多数情况下,问题源于模型数据加载的异步性(需等待`rowsInserted`信号)或未正确触发模型更新通知。
阅读全文

相关推荐

D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:13: error: class 'view::equipment::kchangemanage' does not have any field named 'm_model' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp: In constructor 'view::equipment::kchangemanage::kchangemanage(QWidget*)': D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:13:7: error: class 'view::equipment::kchangemanage' does not have any field named 'm_model' 13 | , m_model(nullptr) // 初始化模型指针 | ^~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:14: error: class 'view::equipment::kchangemanage' does not have any field named 'm_currentMatchIndex' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:14:7: error: class 'view::equipment::kchangemanage' does not have any field named 'm_currentMatchIndex' 14 | , m_currentMatchIndex(-1) { // 初始化匹配索引 | ^~~~~~~~~~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:27: error: no declaration matches 'void view::equipment::kchangemanage::setModel(QAbstractItemModel*)' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp: At global scope: D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:27:6: error: no declaration matches 'void view::equipment::kchangemanage::setModel(QAbstractItemModel*)' 27 | void kchangemanage::setModel(QAbstractItemModel *model) { | ^~~~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:27:6: note: no functions named 'void view::equipment::kchangemanage::setModel(QAbstractItemModel*)' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:1: In file included from D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:1: In file included from D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:1: D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.h:15:7: note: 'class view::equipment::kchangemanage' defined here 15 | class kchangemanage : public QDialog { | ^~~~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:45: error: 'm_matchedRows' was not declared in this scope D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp: In member function 'void view::equipment::kchangemanage::on_find_clicked()': D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:45:5: error: 'm_matchedRows' was not declared in this scope 45 | m_matchedRows.clear(); // 清空历史匹配结果 | ^~~~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:46: error: 'm_currentMatchIndex' was not declared in this scope D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:46:5: error: 'm_currentMatchIndex' was not declared in this scope 46 | m_currentMatchIndex = -1; | ^~~~~~~~~~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:48: error: 'm_model' was not declared in this scope; did you mean 'modfl'? D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:48:10: error: 'm_model' was not declared in this scope; did you mean 'modfl'? 48 | if (!m_model) { | ^~~~~~~ | modfl D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:55: error: 'm_model' was not declared in this scope; did you mean 'modfl'? D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:55:29: error: 'm_model' was not declared in this scope; did you mean 'modfl'? 55 | for (int row = 0; row < m_model->rowCount(); ++row) { | ^~~~~~~ | modfl D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:70: error: 'm_model' was not declared in this scope; did you mean 'modfl'? D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:70:31: error: 'm_model' was not declared in this scope; did you mean 'modfl'? 70 | QModelIndex targetIndex = m_model->index(m_matchedRows.first(), 0); | ^~~~~~~ | modfl D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:77: error: 'm_matchedRows' was not declared in this scope D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp: In member function 'void view::equipment::kchangemanage::on_next_clicked()': D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:77:9: error: 'm_matchedRows' was not declared in this scope 77 | if (m_matchedRows.isEmpty()) { | ^~~~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:82: error: 'm_currentMatchIndex' was not declared in this scope D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:82:5: error: 'm_currentMatchIndex' was not declared in this scope 82 | m_currentMatchIndex = (m_currentMatchIndex + 1) % m_matchedRows.size(); | ^~~~~~~~~~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:82: error: 'm_matchedRows' was not declared in this scope D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:82:55: error: 'm_matchedRows' was not declared in this scope 82 | m_currentMatchIndex = (m_currentMatchIndex + 1) % m_matchedRows.size(); | ^~~~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:83: error: 'm_model' was not declared in this scope; did you mean 'modfl'? D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:83:31: error: 'm_model' was not declared in this scope; did you mean 'modfl'? 83 | QModelIndex targetIndex = m_model->index(m_matchedRows[m_currentMatchIndex], 0); | ^~~~~~~ | modfl D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:90: error: 'm_matchedRows' was not declared in this scope D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp: In member function 'void view::equipment::kchangemanage::on_before_clicked()': D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:90:9: error: 'm_matchedRows' was not declared in this scope 90 | if (m_matchedRows.isEmpty()) { | ^~~~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:95: error: 'm_currentMatchIndex' was not declared in this scope D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:95:5: error: 'm_currentMatchIndex' was not declared in this scope 95 | m_currentMatchIndex = (m_currentMatchIndex - 1 + m_matchedRows.size()) % m_matchedRows.size(); | ^~~~~~~~~~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:95: error: 'm_matchedRows' was not declared in this scope D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:95:54: error: 'm_matchedRows' was not declared in this scope 95 | m_currentMatchIndex = (m_currentMatchIndex - 1 + m_matchedRows.size()) % m_matchedRows.size(); | ^~~~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:96: error: 'm_model' was not declared in this scope; did you mean 'modfl'? D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:96:31: error: 'm_model' was not declared in this scope; did you mean 'modfl'? 96 | QModelIndex targetIndex = m_model->index(m_matchedRows[m_currentMatchIndex], 0); | ^~~~~~~ | modfl D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:121: error: 'm_model' was not declared in this scope; did you mean 'modfl'? D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp: In member function 'void view::equipment::kchangemanage::on_change_clicked()': D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:121:33: error: 'm_model' was not declared in this scope; did you mean 'modfl'? 121 | QModelIndex nameIndex = m_model->index(row, nameColumn); | ^~~~~~~ | modfl D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:129: error: 'fliterModel' was not declared in this scope D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:129:40: error: 'fliterModel' was not declared in this scope 129 | if (auto proxyModel = qobject_cast<fliterModel::FilterProxyMdel*>(m_model)) { | ^~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:129: error: parse error in template argument list D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:129:27: error: parse error in template argument list 129 | if (auto proxyModel = qobject_cast<fliterModel::FilterProxyMdel*>(m_model)) { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:129: error: 'm_model' was not declared in this scope; did you mean 'modfl'? D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:129:71: error: 'm_model' was not declared in this scope; did you mean 'modfl'? 129 | if (auto proxyModel = qobject_cast<fliterModel::FilterProxyMdel*>(m_model)) { | ^~~~~~~ | modfl D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:134: error: 'm_model' was not declared in this scope; did you mean 'modfl'? D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:134:9: error: 'm_model' was not declared in this scope; did you mean 'modfl'? 134 | if (m_model->submit()) { // 源模型提交到数据库 | ^~~~~~~ | modfl D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:163: error: 'm_model' was not declared in this scope; did you mean 'modfl'? D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp: In member function 'void view::equipment::kchangemanage::on_deleteButton_clicked()': D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:163:14: error: 'm_model' was not declared in this scope; did you mean 'modfl'? 163 | if (!m_model->removeRow(row)) { | ^~~~~~~ | modfl D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:170: error: 'fliterModel' was not declared in this scope D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:170:40: error: 'fliterModel' was not declared in this scope 170 | if (auto proxyModel = qobject_cast<fliterModel::FilterProxyMdel*>(m_model)) { | ^~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:170: error: parse error in template argument list D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:170:27: error: parse error in template argument list 170 | if (auto proxyModel = qobject_cast<fliterModel::FilterProxyMdel*>(m_model)) { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:170: error: 'm_model' was not declared in this scope; did you mean 'modfl'? D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:170:71: error: 'm_model' was not declared in this scope; did you mean 'modfl'? 170 | if (auto proxyModel = qobject_cast<fliterModel::FilterProxyMdel*>(m_model)) { | ^~~~~~~ | modfl D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:175: error: 'm_model' was not declared in this scope; did you mean 'modfl'? D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:175:9: error: 'm_model' was not declared in this scope; did you mean 'modfl'? 175 | if (m_model->submit()) { | ^~~~~~~ | modfl mingw32-make.exe[2]:-1: *** [CMakeFiles\LabNexus.dir\build.make:269: CMakeFiles/LabNexus.dir/view/equipmentManage/kchangemanage.cpp.obj] Error 1 mingw32-make.exe[1]:-1: *** [CMakeFiles\Makefile2:114: CMakeFiles/LabNexus.dir/all] Error 2 mingw32-make.exe:-1: *** [Makefile:100: all] Error 2 D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:13: error: Member initializer 'm_model' does not name a non-static data member or base class D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:14: error: Member initializer 'm_currentMatchIndex' does not name a non-static data member or base class D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:27: error: Out-of-line definition of 'setModel' does not match any declaration in 'view::equipment::kchangemanage' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:28: error: Use of undeclared identifier 'm_model'; did you mean 'model'? (fix available) D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:27: 'model' declared here D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:29: error: Use of undeclared identifier 'm_model'; did you mean 'model'? (fix available) D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:27: 'model' declared here D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:30: error: Use of undeclared identifier 'm_model'; did you mean 'model'? (fix available) D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:27: 'model' declared here D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:45: error: Use of undeclared identifier 'm_matchedRows' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:46: error: Use of undeclared identifier 'm_currentMatchIndex' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:48: error: Use of undeclared identifier 'm_model' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:55: error: Use of undeclared identifier 'm_model' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:56: error: Use of undeclared identifier 'm_model' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:57: error: Use of undeclared identifier 'm_model' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:59: error: Use of undeclared identifier 'm_matchedRows' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:63: error: Use of undeclared identifier 'm_matchedRows' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:69: error: Use of undeclared identifier 'm_currentMatchIndex' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:70: error: Use of undeclared identifier 'm_model' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:70: error: Use of undeclared identifier 'm_matchedRows' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:77: error: Use of undeclared identifier 'm_matchedRows' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:82: error: Use of undeclared identifier 'm_currentMatchIndex' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:82: error: Use of undeclared identifier 'm_currentMatchIndex' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:82: error: Use of undeclared identifier 'm_matchedRows' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:83: error: Use of undeclared identifier 'm_matchedRows' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:83: error: Use of undeclared identifier 'm_model' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:90: error: Use of undeclared identifier 'm_matchedRows' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:95: error: Use of undeclared identifier 'm_currentMatchIndex' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:95: error: Use of undeclared identifier 'm_currentMatchIndex' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:95: error: Use of undeclared identifier 'm_matchedRows' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:95: error: Use of undeclared identifier 'm_matchedRows' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:96: error: Use of undeclared identifier 'm_matchedRows' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:96: error: Use of undeclared identifier 'm_model' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:121: error: Use of undeclared identifier 'm_model' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:122: error: Use of undeclared identifier 'm_model' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:129: error: Use of undeclared identifier 'fliterModel' (fix available) D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:129: error: Expected expression D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:129: error: Use of undeclared identifier 'm_model' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:134: error: Use of undeclared identifier 'm_model' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:163: error: Use of undeclared identifier 'm_model' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:170: error: Use of undeclared identifier 'fliterModel' (fix available) D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:170: error: Expected expression D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:170: error: Use of undeclared identifier 'm_model' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:175: error: Use of undeclared identifier 'm_model' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:83: error: Use of undeclared identifier 'm_currentMatchIndex' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:96: error: Use of undeclared identifier 'm_currentMatchIndex'

D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:19: error: 'setModel' was not declared in this scope; did you mean 'setModal'? D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp: In constructor 'view::equipment::kchangemanage::kchangemanage(QWidget*)': D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:19:5: error: 'setModel' was not declared in this scope; did you mean 'setModal'? 19 | setModel(model); // 设置模型到成员变量 | ^~~~~~~~ | setModal D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:26: error: no declaration matches 'void view::equipment::kchangemanage::setModel(QAbstractItemModel*)' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp: At global scope: D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:26:6: error: no declaration matches 'void view::equipment::kchangemanage::setModel(QAbstractItemModel*)' 26 | void kchangemanage::setModel(QAbstractItemModel *model) { | ^~~~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:26:6: note: no functions named 'void view::equipment::kchangemanage::setModel(QAbstractItemModel*)' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:1: In file included from D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:1: In file included from D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:1: D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.h:15:7: note: 'class view::equipment::kchangemanage' defined here 15 | class kchangemanage : public QDialog { | ^~~~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:41: error: 'searchEquipment' was not declared in this scope D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp: In member function 'void view::equipment::kchangemanage::on_find_clicked()': D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:41:46: error: 'searchEquipment' was not declared in this scope 41 | QList<QMap<QString, QVariant>> results = searchEquipment(keyword, -1, ""); // 仅按名称模糊查找 | ^~~~~~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:63: error: no declaration matches 'QList<QMap<QString, QVariant> > view::equipment::kchangemanage::searchEquipment(const QString&, int, const QString&)' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp: At global scope: D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:63:32: error: no declaration matches 'QList<QMap<QString, QVariant> > view::equipment::kchangemanage::searchEquipment(const QString&, int, const QString&)' 63 | QList<QMap<QString, QVariant>> kchangemanage::searchEquipment(const QString &nameKeyword, int classId, const QString &status) { | ^~~~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:63:32: note: no functions named 'QList<QMap<QString, QVariant> > view::equipment::kchangemanage::searchEquipment(const QString&, int, const QString&)' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.h:15:7: note: 'class view::equipment::kchangemanage' defined here 15 | class kchangemanage : public QDialog { | ^~~~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:109: error: 'class QAbstractItemModel' has no member named 'select' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp: In member function 'void view::equipment::kchangemanage::on_change_clicked()': D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:109:18: error: 'class QAbstractItemModel' has no member named 'select' 109 | m_model->select(); // 刷新模型数据 | ^~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:134: error: 'deleteEquipmentByNumbers' was not declared in this scope D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp: In member function 'void view::equipment::kchangemanage::on_deleteButton_clicked()': D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:134:19: error: 'deleteEquipmentByNumbers' was not declared in this scope 134 | int deleted = deleteEquipmentByNumbers({equipmentNumber}); | ^~~~~~~~~~~~~~~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:136: error: 'class QAbstractItemModel' has no member named 'select' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:136:18: error: 'class QAbstractItemModel' has no member named 'select' 136 | m_model->select(); // 刷新模型数据 | ^~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:143: error: no declaration matches 'int view::equipment::kchangemanage::deleteEquipmentByNumbers(const QStringList&)' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp: At global scope: D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:143:5: error: no declaration matches 'int view::equipment::kchangemanage::deleteEquipmentByNumbers(const QStringList&)' 143 | int kchangemanage::deleteEquipmentByNumbers(const QStringList &equipmentNumbers) { | ^~~~~~~~~~~~~ D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:143:5: note: no functions named 'int view::equipment::kchangemanage::deleteEquipmentByNumbers(const QStringList&)' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.h:15:7: note: 'class view::equipment::kchangemanage' defined here 15 | class kchangemanage : public QDialog { | ^~~~~~~~~~~~~ mingw32-make.exe[2]:-1: *** [CMakeFiles\LabNexus.dir\build.make:269: CMakeFiles/LabNexus.dir/view/equipmentManage/kchangemanage.cpp.obj] Error 1 mingw32-make.exe[1]:-1: *** [CMakeFiles\Makefile2:114: CMakeFiles/LabNexus.dir/all] Error 2 mingw32-make.exe:-1: *** [Makefile:100: all] Error 2 D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:19: error: Use of undeclared identifier 'setModel'; did you mean 'setModal'? (fix available) D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:26: error: Out-of-line definition of 'setModel' does not match any declaration in 'view::equipment::kchangemanage' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:41: error: Use of undeclared identifier 'searchEquipment' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:63: error: Out-of-line definition of 'searchEquipment' does not match any declaration in 'view::equipment::kchangemanage' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:109: error: No member named 'select' in 'QAbstractItemModel' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:134: error: Use of undeclared identifier 'deleteEquipmentByNumbers' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:136: error: No member named 'select' in 'QAbstractItemModel' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:143: error: Out-of-line definition of 'deleteEquipmentByNumbers' does not match any declaration in 'view::equipment::kchangemanage' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:154: error: No matching member function for call to 'replace' D:\QT_PROGRAM\LabNexus\view\equipmentManage\kchangemanage.cpp:157: error: No member named 'rowsAffected' in 'service::DatabaseManager'

根据上述文件完善equipment_home.h .cpp .h // // Created by gouzuang on 25-7-7. // #include “data_EquipmentManage.h” namespace data::Equipment { void dropDB() { QFile dbFile(path); if (dbFile.exists()) { if (dbFile.remove()) { log(LogLevel::INFO) << “数据库文件删除成功”< loadFullEquipmentRecords() { QList<fullEquipmentRecord> records; service::DatabaseManager db(path); // 使用 JOIN 查询将实例表和类别表关联起来 // i 是 instance 的别名, c 是 class 的别名 QString queryString = R"( SELECT i.id, i.name, i.status, i.created_at, i.class_id, c.name AS type_name FROM equipment_instance AS i JOIN equipment_class AS c ON i.class_id = c.id )"; auto results = db.executeQueryAndFetchAll(queryString); for (const auto &row : results) { fullEquipmentRecord rec; rec.id = row["id"].toInt(); rec.name = row["name"].toString(); rec.status = row["status"].toString(); rec.inDate = row["created_at"].toDateTime(); rec.class_id = row["class_id"].toInt(); rec.type = row["type_name"].toString(); records.append(rec); } return records; } namespace EquipmentClass { void createEquipmentClassTable() { service::DatabaseManager db(path); if (!db.tableExists("equipment_class")) { QString createTableQuery = R"( CREATE TABLE equipment_class ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, description TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, amount INTEGER NOT NULL DEFAULT 0 ) )"; db.executeNonQuery(createTableQuery); log(service::LogLevel::DATA) << "设备类别表创建成功"; } else { log(service::LogLevel::INFO) << "设备类别表已存在"; } } } namespace EquipmentInstnace { void createEquipmentInstanceTable() { service::DatabaseManager db(path); if (!db.tableExists("equipment_instance")) { QString createTableQuery = R"( CREATE TABLE equipment_instance ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, class_id INTEGER NOT NULL, status TEXT NOT NULL DEFAULT '可用', created_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (class_id) REFERENCES equipment_class (id) ON DELETE CASCADE ) )"; if (db.executeNonQuery(createTableQuery)) { log(service::LogLevel::DATA) << "设备实例表创建成功"; } else { log(service::LogLevel::ERR) << "设备实例表创建失败"; } } else { log(service::LogLevel::INFO) << "设备实例表已经存在"; } } } } .cpp // // Created by gouzuang on 25-7-6. // #include “equipment_home.h” #include “ui_equipment_home.h” #include “kaddmanage.h” #include “kchangemanage.h” #include “kdeletemanage.h” #include “applysee.h” #include “exam.h” #include #include “module/data/data_Booking.h” #include “module/data/data_EquipmentManage.h” #include // Qt 6 需包含 namespace view::equipment { equipment_home::equipment_home(QWidget *parent) : QWidget(parent), ui(new view::equipment::Ui::equipment_home) { ui->setupUi(this); } equipment_home::~equipment_home() { delete ui; } void equipment_home::on_zclose_clicked() //关闭应用 { this->close(); } // equipment_home.cpp void equipment_home::on_kadd_clicked() //添加器材 { // 创建对话框并设置父对象(自动内存管理) kaddmanage *dialog = new kaddmanage(this); // 连接对话框的dataAdded信号到主界面的刷新函数(on_kreall_clicked) connect(dialog, &kaddmanage::dataAdded, this, [this]() { on_kreall_clicked(); // 调用整理库数据功能,刷新tableView }); // 显示对话框(模态或非模态均可,此处用show()非模态) dialog->show(); } void equipment_home::on_kreall_clicked() //整理库数据 { // 1. 确保数据库及表结构存在(原有功能) data::Equipment::buildDB(); // 2. 加载所有设备完整记录 QList<data::Equipment::fullEquipmentRecord> records = data::Equipment::loadFullEquipmentRecords(); // 3. 按 "item" 字段升序排序(假设 "item" 对应设备名称 "name" 字段) // 使用 Qt 的字符串比较(支持本地化,类似Excel排序) std::sort(records.begin(), records.end(), [](const data::Equipment::fullEquipmentRecord& a, const data::Equipment::fullEquipmentRecord& b) { return QString::localeAwareCompare(a.name, b.name) < 0; // 升序排列 }); // 4. 将排序后的数据展示到 tableView(假设 UI 中构件名为 tableView) // 清空原有数据 QStandardItemModel* model = qobject_cast<QStandardItemModel*>(ui->tableView->model()); if (!model) { model = new QStandardItemModel(this); // 设置表头(仅首次初始化时设置) model->setHorizontalHeaderLabels({ "ID", "设备名称", "状态", "创建时间", "类别ID", "类别名称" }); ui->tableView->setModel(model); } model->removeRows(0, model->rowCount()); // 清空旧数据 // 填充排序后的数据 for (const auto& rec : records) { QList<QStandardItem*> items; items << new QStandardItem(QString::number(rec.id)) // ID << new QStandardItem(rec.name) // 设备名称(排序字段) << new QStandardItem(rec.status) // 状态 << new QStandardItem(rec.inDate.toString("yyyy-MM-dd hh:mm:ss")) // 创建时间 << new QStandardItem(QString::number(rec.class_id)) // 类别ID << new QStandardItem(rec.type); // 类别名称 model->appendRow(items); } // 可选:自动调整列宽 ui->tableView->resizeColumnsToContents(); log(service::LogLevel::INFO) << "数据库整理完成"; } void equipment_home::on_kchange_clicked() //修改库数据 { kchangemanage *dialog = new kchangemanage(this); dialog->show(); } void equipment_home::on_kdel_clicked() //删除库数据 { kdeletemanage *dialog = new kdeletemanage(this); dialog->show(); } void equipment_home::on_kexam_clicked() //检查和审批审查 { // TODO: 实现检查和审批审查功能 } void equipment_home::on_kseeborrow_clicked() { // 创建一个对话框 QDialog dialog(this); dialog.setWindowTitle("借用日志"); // 创建一个 QTableView QTableView tableView; // 创建一个模型(示例中使用 QStandardItemModel) QStandardItemModel model(0, 3); // 3 列:ID、设备名称、借用日期 model.setHorizontalHeaderLabels(QStringList() << "ID" << "设备名称" << "借用日期"); // 添加示例数据 QList<QStandardItem *> items; for (int i = 0; i < 5; ++i) { // 添加5行示例数据 items.append(new QStandardItem(QString::number(i + 1))); items.append(new QStandardItem("设备 " + QString::number(i + 1))); items.append(new QStandardItem("2024-11-01")); model.appendRow(items); items.clear(); // 清空 items 以准备下一行 } // 设置模型到 QTableView tableView.setModel(&model); // 创建布局并添加 QTableView QVBoxLayout layout(&dialog); layout.addWidget(&tableView); // 显示对话框 dialog.setLayout(&layout); dialog.exec(); } void equipment_home::on_seefix_clicked() { QDialog dialog(this); dialog.setWindowTitle("维修日志"); QTableView tableView; QStandardItemModel model(0, 3); // 3 列:ID、设备名称、维修日期 model.setHorizontalHeaderLabels(QStringList() << "ID" << "设备名称" << "维修日期"); // 添加示例数据 QList<QStandardItem *> items; for (int i = 0; i < 3; ++i) { items.append(new QStandardItem(QString::number(i + 1))); items.append(new QStandardItem("设备 " + QString::number(i + 1))); items.append(new QStandardItem("2024-10-15")); model.appendRow(items); items.clear(); } tableView.setModel(&model); QVBoxLayout layout(&dialog); layout.addWidget(&tableView); dialog.setLayout(&layout); dialog.exec(); } void equipment_home::on_outdata_clicked() { QDialog dialog(this); dialog.setWindowTitle("超期预警"); QTableView tableView; QStandardItemModel model(0, 3); // 3 列:ID、设备名称、超期天数 model.setHorizontalHeaderLabels(QStringList() << "ID" << "设备名称" << "超期天数"); QList<QStandardItem *> items; for (int i = 0; i < 2; ++i) { items.append(new QStandardItem(QString::number(i + 1))); items.append(new QStandardItem("设备 " + QString::number(i + 1))); items.append(new QStandardItem(QString::number(i + 5))); // 超期天数 model.appendRow(items); items.clear(); } tableView.setModel(&model); QVBoxLayout layout(&dialog); layout.addWidget(&tableView); dialog.setLayout(&layout); dialog.exec(); } void equipment_home::on_blacklist_clicked() { QDialog dialog(this); dialog.setWindowTitle("黑名单"); QTableView tableView; QStandardItemModel model(0, 2); // 2 列:用户ID、用户名 model.setHorizontalHeaderLabels(QStringList() << "用户ID" << "用户名"); QList<QStandardItem *> items; for (int i = 0; i < 4; ++i) { items.append(new QStandardItem(QString::number(i + 1001))); items.append(new QStandardItem("用户 " + QString::number(i + 1))); model.appendRow(items); items.clear(); } tableView.setModel(&model); QVBoxLayout layout(&dialog); layout.addWidget(&tableView); dialog.setLayout(&layout); dialog.exec(); } void equipment_home::on_searchbtn_clicked() //索引 { // TODO: 实现搜索功能 } } // view::equipment 使其在各函数中注释的功能完整且可在qt creator上正确构建及运行(所有更改不要省略,更改位置请注释出)

// // Created by gouzuang on 25-7-6. // #include "equipment_home.h" #include "ui_equipment_home.h" #include "kaddmanage.h" #include "kchangemanage.h" #include "kdeletemanage.h" #include "applysee.h" #include "exam.h" #include <QStandardItemModel> // 补充Qt模型头文件 #include <QTableView> // 补充表格视图头文件 #include <QSortFilterProxyModel> // 新增:用于排序过滤 #include <QMessageBox> // 新增:用于错误提示 #include "module/data/data_Booking.h" #include "module/data/data_EquipmentManage.h" #include "service/logger/logger.h" // 补充日志头文件 namespace view::equipment { equipment_home::equipment_home(QWidget *parent) : QWidget(parent), ui(new Ui::equipment_home) { ui->setupUi(this); // 初始化表格视图(可选:设置排序功能) ui->tableView->setSortingEnabled(true); // 允许点击表头排序 on_kreall_clicked(); // 初始化时加载数据 } equipment_home::~equipment_home() { delete ui; } void equipment_home::on_zclose_clicked() { // 关闭应用 this->close(); } void equipment_home::on_kadd_clicked() { // 添加器材 kaddmanage *dialog = new kaddmanage(this); // 连接对话框的dataAdded信号(假设kaddmanage声明了该信号) connect(dialog, &kaddmanage::dataAdded, this, [this]() { on_kreall_clicked(); // 刷新数据 }); dialog->exec(); // 使用exec()模态对话框,确保数据添加后立即刷新 } void equipment_home::on_kreall_clicked() { // 整理库数据 // 1. 确保数据库及表结构存在 data::Equipment::buildDB(); // 2. 加载所有设备完整记录(添加错误处理) QList<data::Equipment::fullEquipmentRecord> records; try { records = data::Equipment::loadFullEquipmentRecords(); } catch (const std::exception &e) { QMessageBox::critical(this, "数据加载失败", QString("错误:%1").arg(e.what())); return; } // 3. 按设备名称升序排序(使用Qt内置排序,替代std::sort) QSortFilterProxyModel proxy; proxy.setSourceModel(new QStandardItemModel()); proxy.setFilterCaseSensitivity(Qt::CaseInsensitive); proxy.sort(1, Qt::AscendingOrder); // 第2列(设备名称)升序 // 4. 填充表格视图 QStandardItemModel *model = new QStandardItemModel(this); model->setHorizontalHeaderLabels({ "ID", "设备名称", "状态", "创建时间", "类别ID", "类别名称" }); for (const auto &rec : records) { QList<QStandardItem*> items; items << new QStandardItem(QString::number(rec.id)) << new QStandardItem(rec.name) << new QStandardItem(rec.status) << new QStandardItem(rec.inDate.toString("yyyy-MM-dd hh:mm:ss")) << new QStandardItem(QString::number(rec.class_id)) << new QStandardItem(rec.type); model->appendRow(items); } // 设置模型到表格视图(支持排序) ui->tableView->setModel(model); ui->tableView->resizeColumnsToContents(); log(service::LogLevel::INFO) << "数据库整理完成,共加载" << records.size() << "条记录"; } void equipment_home::on_kchange_clicked() { // 修改库数据 kchangemanage *dialog = new kchangemanage(this); // 可选:传递当前选中的设备ID到对话框 QModelIndexList selected = ui->tableView->selectionModel()->selectedRows(); if (!selected.isEmpty()) { int selectedId = selected.first().data().toInt(); dialog->setTargetEquipmentId(selectedId); // 假设对话框有此接口 } dialog->exec(); on_kreall_clicked(); // 修改后刷新数据 } void equipment_home::on_kdel_clicked() { // 删除库数据 QModelIndexList selected = ui->tableView->selectionModel()->selectedRows(); if (selected.isEmpty()) { QMessageBox::information(this, "提示", "请选择要删除的设备"); return; } int selectedId = selected.first().data().toInt(); if (QMessageBox::question(this, "确认删除", "是否删除选中的设备?") == QMessageBox::Yes) { // 调用数据层删除逻辑(假设data::Equipment有删除接口) // bool success = data::Equipment::deleteEquipment(selectedId); // if (success) { // on_kreall_clicked(); // } on_kreall_clicked(); // 示例刷新 } } void equipment_home::on_kexam_clicked() { // 检查和审批审查 exam *dialog = new exam(this); dialog->exec(); } void equipment_home::on_kseeborrow_clicked() { // 查看借用日志 QDialog dialog(this); dialog.setWindowTitle("借用日志"); QTableView tableView(&dialog); QStandardItemModel model(0, 3); model.setHorizontalHeaderLabels({"ID", "设备名称", "借用日期"}); // 示例数据(实际应从预订数据库查询) // auto borrowRecords = data::Booking::loadBookingRecordsByEquipmentId(equipmentId); for (int i = 0; i < 5; ++i) { model.appendRow({ new QStandardItem(QString::number(i+1)), new QStandardItem("设备 " + QString::number(i+1)), new QStandardItem("2024-11-01") }); } tableView.setModel(&model); QVBoxLayout layout(&dialog); layout.addWidget(&tableView); dialog.resize(600, 400); // 设置对话框大小 dialog.exec(); } void equipment_home::on_seefix_clicked() { // 查看维修日志(类似借用日志) QDialog dialog(this); dialog.setWindowTitle("维修日志"); QTableView tableView(&dialog); QStandardItemModel model(0, 3); model.setHorizontalHeaderLabels({"ID", "设备名称", "维修日期"}); for (int i = 0; i < 3; ++i) { model.appendRow({ new QStandardItem(QString::number(i+1)), new QStandardItem("设备 " + QString::number(i+1)), new QStandardItem("2024-10-15") }); } tableView.setModel(&model); QVBoxLayout layout(&dialog); layout.addWidget(&tableView); dialog.resize(600, 400); dialog.exec(); } void equipment_home::on_outdata_clicked() { // 超期预警 QDialog dialog(this); dialog.setWindowTitle("超期预警"); QTableView tableView(&dialog); QStandardItemModel model(0, 3); model.setHorizontalHeaderLabels({"ID", "设备名称", "超期天数"}); for (int i = 0; i < 2; ++i) { model.appendRow({ new QStandardItem(QString::number(i+1)), new QStandardItem("设备 " + QString::number(i+1)), new QStandardItem(QString::number(i+5)) }); } tableView.setModel(&model); QVBoxLayout layout(&dialog); layout.addWidget(&tableView); dialog.resize(600, 400); dialog.exec(); } void equipment_home::on_blacklist_clicked() { // 查看黑名单 QDialog dialog(this); dialog.setWindowTitle("黑名单"); QTableView tableView(&dialog); QStandardItemModel model(0, 2); model.setHorizontalHeaderLabels({"用户ID", "用户名"}); for (int i = 0; i < 4; ++i) { model.appendRow({ new QStandardItem(QString::number(i+1001)), new QStandardItem("用户 " + QString::number(i+1)) }); } tableView.setModel(&model); QVBoxLayout layout(&dialog); layout.addWidget(&tableView); dialog.resize(600, 400); dialog.exec(); } void equipment_home::on_searchbtn_clicked() { // 搜索功能(示例:按设备名称过滤) QString keyword = ui->searchEdit->text().trimmed(); // 假设UI有searchEdit输入框 if (keyword.isEmpty()) { on_kreall_clicked(); // 清空搜索时显示所有数据 return; } QStandardItemModel *model = qobject_cast<QStandardItemModel*>(ui->tableView->model()); if (!model) return; // 过滤设备名称列(第2列,索引1) for (int row = 0; row < model->rowCount(); ++row) { bool visible = model->item(row, 1)->text().contains(keyword, Qt::CaseInsensitive); ui->tableView->setRowHidden(row, !visible); } } } // view::equipment 三个假设部分请通过代码补充建立在函数体中,并调整其在ui合适位置

#include "GActionFlow_Standard.h" #include "GActionFlow.h" #include "mhtparser.h" #include "ALTableTool.h" #include <algorithm> // 包含算法头文件 #include <QPushButton> #include "CGlobalVariant.h" #include <QSplineSeries> extern GActionFlow m_GActionFlow; extern MhtParser m_MhtParser; extern ALTableTool m_TableTool; extern CGlobalVariant m_Global; GActionFlow_Standard::GActionFlow_Standard() { } GActionFlow_Standard::~GActionFlow_Standard() { } // 导入傲来标准值流程 void GActionFlow_Standard::SFL_Action_ALStandardValue() { FinallyLoadStandard = false; // 读取data文件数据 QByteArray arr; if (-1 == m_GActionFlow.readDataFile(arr)) { QMessageBox::warning(NULL, "Failed!", m_GActionFlow.m_qstrError); return; } // 解析数据 QVector<ALData> vec_Data; if (-1 == m_GActionFlow.handleDataForAl(arr, vec_Data)) { QMessageBox::warning(NULL, "Failed!", m_GActionFlow.m_qstrError); return; } //将.data数据写到View上 StandardData2table(vec_Data); // 计算标准值平均值 StandardhowAvgData(); FinallyLoadStandard = true; } // 导入Pro10标准值流程 void GActionFlow_Standard::SFL_Action_Pro10StandardValue() { FinallyLoadStandard = false; // 读取data文件数据 QByteArray arr; if (-1 == m_GActionFlow.readDataFile(arr)) { QMessageBox::warning(NULL, "Failed!", m_GActionFlow.m_qstrError); return; } // 解析数据 QVector<ALData> vec_Data; if (-1 == m_GActionFlow.handleDataForPro10(arr, vec_Data)) { QMessageBox::warning(NULL, "Failed!", m_GActionFlow.m_qstrError); return; } //将.data数据写到View上 StandardData2table(vec_Data); // 计算标准值平均值 StandardhowAvgData(); FinallyLoadStandard = true; } void GActionFlow_Standard::SFL_Action_HRStandardValue(QTabWidget* tabWidget) { // 读取.mht文件 QVector<tagMeasurement> tagMeasureMent; if (-1 == m_GActionFlow.readMhtFile(tagMeasureMent)) { QMessageBox::warning(NULL, "Failed!", m_GActionFlow.m_qstrError); return; } // 将原始数据采用动态标签页的方式加载显示 Hr2Table(tagMeasureMent, tabWidget); } int GActionFlow_Standard::StandardData2table(QVector<ALData> vec_Data) { m_GActionFlow.row = 0; m_GActionFlow.col = 0; m_GActionFlow.Frequency = 110; m_GActionFlow.UnitConversion = 1000; m_GActionFlow.setItem(m_GActionFlow.row, m_GActionFlow.col, "频率:", Qt::green, Qt::yellow); m_GActionFlow.setItem(m_GActionFlow.row, m_GActionFlow.col + 1, QString::number(m_GActionFlow.Frequency), Qt::green, Qt::yellow); m_GActionFlow.setItem(m_GActionFlow.row, m_GActionFlow.col + 2, "单位:", Qt::green, Qt::yellow); m_GActionFlow.setItem(m_GActionFlow.row, m_GActionFlow.col + 3, QString::number(m_GActionFlow.UnitConversion), Qt::green, Qt::yellow); m_GActionFlow.row = 1; standard_start_row = m_GActionFlow.row; m_GActionFlow.setItem(m_GActionFlow.row, m_GActionFlow.col, "标准值", Qt::black, QColor(244, 164, 96)); m_GActionFlow.data2table(vec_Data); standard_end_row = m_GActionFlow.row; return 0; } // HR数据显示到table int GActionFlow_Standard::Hr2Table(QVector<tagMeasurement>& tagMeasureMent, QTabWidget* tabWidget) { int size = tagMeasureMent.size(); if (size <= 0) { m_strError = "没有数据用于显示"; return -1; } std::set<int> mySet; QVector<tagMeasurement> tagMeasureMentMTF; QVector<tagMeasurement> tagMeasureMentTF; QVector<tagMeasurement> tagMeasureMentTilt; SpliitMeasurement(tagMeasureMent, tabWidget, tagMeasureMentMTF, tagMeasureMentTF, tagMeasureMentTilt, mySet); ShowtagMeasureMentTilt(tagMeasureMentTilt); int tfStartRow; ShowtagMeasureMentMTF(tfStartRow, tagMeasureMentMTF); auto max = *std::max_element(mySet.begin(), mySet.end()); for (int i = 0; i < max; i++) { hr_source_rows[i] = tfStartRow; hr_source_cols[i] = 0; } int start4finadatarow = tfStartRow; ShowtagMeasureMentTF(start4finadatarow, tagMeasureMentTF); QMap<int, QMap<double, tagTableSections>> map_uutNumber4TableSections; ShortTFTableSections(tagMeasureMentTF, map_uutNumber4TableSections); FreashTfTable(); Measurement2TFTable(map_uutNumber4TableSections); return 0; } int GActionFlow_Standard::StandardhowAvgData() { standard_avg_row = standard_end_row + 1; standard_mtfandpeak_row = standard_avg_row + 1; m_GActionFlow.setItem(standard_avg_row, 0, "Avg:", Qt::green); m_GActionFlow.setItem(standard_mtfandpeak_row, 0, "MTFPeakAvg", Qt::gray); m_GActionFlow.row = standard_avg_row; StandardShowAvgData4EFL(); StandardShowAvgData4FFL(); StandardShowAvgData4MTF(); StandardShowAvgData4FS(); StandardShowAvgData4PEAK(); StandardShowAvgData4DOF(); StandardShowAvgData4MTFPeakAvg(); return 0; } int GActionFlow_Standard::StandardShowAvgData4EFL() { return m_GActionFlow.ShowAvgDataCol(standard_start_row, standard_end_row, m_GActionFlow.efl_col, m_GActionFlow.efl_col, standard_avg_row); } int GActionFlow_Standard::StandardShowAvgData4FFL() { return m_GActionFlow.ShowAvgDataCol(standard_start_row, standard_end_row, m_GActionFlow.ffl_col, m_GActionFlow.ffl_col, standard_avg_row); } int GActionFlow_Standard::StandardShowAvgData4MTF() { return m_GActionFlow.ShowAvgDataCol(standard_start_row, standard_end_row, m_GActionFlow.mtf_start_col, m_GActionFlow.mtf_end_col, standard_avg_row); } int GActionFlow_Standard::StandardShowAvgData4FS() { return m_GActionFlow.ShowAvgDataCol(standard_start_row, standard_end_row, m_GActionFlow.fs_start_col, m_GActionFlow.fs_end_col, standard_avg_row); } int GActionFlow_Standard::StandardShowAvgData4PEAK() { return m_GActionFlow.ShowAvgDataCol(standard_start_row, standard_end_row, m_GActionFlow.peak_start_col, m_GActionFlow.peak_end_col, standard_avg_row); } int GActionFlow_Standard::StandardShowAvgData4DOF() { return m_GActionFlow.ShowAvgDataCol(standard_start_row, standard_end_row, m_GActionFlow.dof_start_col, m_GActionFlow.dof_end_col, standard_avg_row); } int GActionFlow_Standard::StandardShowAvgData4MTFPeakAvg() { int temp = 0; for (int i = m_GActionFlow.mtf_start_col; i <= m_GActionFlow.mtf_end_col; i++) { QString avg1 = m_GActionFlow.theModel4Corr->headerData(i, Qt::Horizontal).toString() + m_GActionFlow.theModel4Corr->headerData(standard_avg_row, Qt::Vertical).toString(); QString avg2 = m_GActionFlow.theModel4Corr->headerData(m_GActionFlow.peak_start_col + temp++, Qt::Horizontal).toString() + m_GActionFlow.theModel4Corr->headerData(standard_avg_row, Qt::Vertical).toString(); QString str = QString("=(%1+%2)/2").arg(avg1).arg(avg2); m_GActionFlow.setItem(standard_mtfandpeak_row, i, str, Qt::gray); } return 0; } int GActionFlow_Standard::SpliitMeasurement(QVector<tagMeasurement>& tagMeasureMent, QTabWidget* tabWidget, QVector<tagMeasurement>& tagMeasureMentMTF, QVector<tagMeasurement>& tagMeasureMentTF, QVector<tagMeasurement>& tagMeasureMentTilt, std::set<int>& mySet) { int currentModelsSize = 0; int currentRowsSize = 0; int currentColsSize = 0; int number = 0; for (int i = 0; i < tagMeasureMent.size(); i++) { tagMeasurement measurement = tagMeasureMent.at(i); QString name = measurement.fileName; if (isFormatValidMTF(name)) { tagMeasureMentMTF.append(measurement); number = name.split("-").at(1).toInt(); } else if (isFormatValidTF(name)) { tagMeasureMentTF.append(measurement); number = name.split("-").at(1).toInt(); } else if (isFormatValidTilt(name)) { tagMeasureMentTilt.append(measurement); number = name.split("-").at(0).toInt(); } else { continue; } mySet.insert(number); int index = number - 1; // 索引应该退一位 ensureIndexExists(hr_source_models, currentModelsSize, index); ensureIndexExists(hr_source_rows, currentRowsSize, index); ensureIndexExists(hr_source_cols, currentColsSize, index); m_TableTool.findOrAddPage(tabWidget, QString::number(number), hr_source_models[index]); // 定位到具体页 } return 0; } int GActionFlow_Standard::ShowtagMeasureMentMTF(int& tfStartRow, QVector<tagMeasurement> tagMeasureMentMTF) { tfStartRow = 0; for each (tagMeasurement measurement in tagMeasureMentMTF) { QString name = measurement.fileName; QStringList list = name.split("-"); int number = list.at(1).toInt(); int index = number - 1; QStandardItemModel* model = hr_source_models[index]; int row = hr_source_rows[index]; int col = hr_source_cols[index]; int nextTableStartCol = 0; // 单个table开始列 int startRow = row;// 单个table初始行 QString angle = measurement.tagParam.tagMTFvsImageHeight.param.value("Sample Azimuth").trimmed(); m_TableTool.setItem(model, row++, col, angle); m_TableTool.setItem(model, row++, col, measurement.tagTable.tagMTFvsImageHeight.title); QVector<QStringList> datas = measurement.tagTable.tagMTFvsImageHeight.tableData; for (int j = 1; j < datas.size(); j++) { QStringList data = datas.at(j); int thisTableStartCol = col; for (int i = 0; i < data.size() - 1; i++) { QString var = data.at(i); m_TableTool.setItem(model, row, col++, var); } row++; nextTableStartCol = col + 1; col = thisTableStartCol; } // 存入下一个table tfStartRow = row + 1; row = startRow; hr_source_cols[index] = nextTableStartCol; // 间隔1列存储新的table } return 0; } int GActionFlow_Standard::ShowtagMeasureMentTF(int& start4finadatarow, QVector<tagMeasurement> tagMeasureMentTF) { for each (tagMeasurement measurement in tagMeasureMentTF) { QString name = measurement.fileName; QStringList list = name.split("-"); int number = list.at(1).toInt(); int ang = list.at(2).toInt(); int index = number - 1; QStandardItemModel* model = hr_source_models[index]; int row = hr_source_rows[index]; int col = hr_source_cols[index]; int nextTableStartCol = 0; // 单个table开始列 int startRow = row;// 单个table初始行 QString angle = measurement.tagParam.tagFieldFocus2DTangential.param.value("Sample Azimuth"); m_TableTool.setItem(model, row++, col, angle); m_TableTool.setItem(model, row++, col, measurement.tagTable.tagFieldFocus2DTangential.title); tagMeasurementTable table = measurement.tagTable.tagFieldFocus2DTangential; QVector<QStringList> datas = table.tableData; for (int j = 1; j < datas.size(); j++) { QStringList data = datas.at(j); int thisTableStartCol = col; for (int i = 0; i < data.size(); i++) { QString var = data.at(i); m_TableTool.setItem(model, row, col++, var); } row++; nextTableStartCol = col + 1; col = thisTableStartCol; } row++; angle = measurement.tagParam.tagFieldFocus2DSagittal.param.value("Sample Azimuth"); m_TableTool.setItem(model, row++, col, angle); m_TableTool.setItem(model, row++, col, measurement.tagTable.tagFieldFocus2DSagittal.title); table = measurement.tagTable.tagFieldFocus2DSagittal; datas = table.tableData; for (int j = 1; j < datas.size(); j++) { QStringList data = datas.at(j); int thisTableStartCol = col; for (int i = 0; i < data.size(); i++) { QString var = data.at(i); m_TableTool.setItem(model, row, col++, var); } row++; nextTableStartCol = col + 1; col = thisTableStartCol; } // 存入下一个table start4finadatarow = row + 1; row = startRow; hr_source_cols[index] = nextTableStartCol; // 间隔1列存储新的table } return 0; } int GActionFlow_Standard::ShortTFTableSections(QVector<tagMeasurement> tagMeasureMentTF, QMap<int, QMap<double, tagTableSections>>& map_uutNumber4TableSections) { int uutIndex = 1; while (true) { QMap<double, tagTableSections> map; // 存入角度,table for (int i = 0; i < tagMeasureMentTF.size(); i++) { tagMeasurement mea = tagMeasureMentTF.at(i); QString name = mea.fileName; QStringList list = name.split("-"); int uutNum = list[1].toInt(); int angle = list[2].remove(".mht").toDouble(); if (uutIndex == uutNum) { tagTableSections sections = mea.tagTable; map.insert(angle, sections); } } if (map.size() == 0) { break; } map_uutNumber4TableSections.insert(uutIndex, map); uutIndex++; } return 0; } int GActionFlow_Standard::Measurement2TFTable(QMap<int, QMap<double, tagTableSections>> map_uutNumber4TableSections) { QVector<QStringList> qvec_CamAngleTableCol; GetCamAngleTableCol(qvec_CamAngleTableCol); double angle = 0; int tabcol = 0; for (int i = 0; i < map_uutNumber4TableSections.size(); i++) { QMap<double, tagTableSections> map = map_uutNumber4TableSections.value(i + 1); int camNum = 1; int endRow = 0; QVector<QStringList> qvec_st; while (camNum < 13) { if (1 != GetCamAngleTableCol(qvec_CamAngleTableCol, camNum, angle, tabcol)) { break; } QStringList listS; QStringList listT; QStringList listFFL; QString titleSag = "S" + QString::number(camNum); listS.push_back(titleSag); QString titleTan = "T" + QString::number(camNum); listT.push_back(titleTan); camNum++; tagTableSections sections = map.value(angle); QVector<QStringList> tableData_sag = sections.tagFieldFocus2DSagittal.tableData; //int startRow = row; for (int j = 1; j < tableData_sag.size(); j++) { QStringList list = tableData_sag.at(j); QString ffl = list.at(0); listFFL.push_back(ffl); if (j == 1)// j=1筛选的FFL一列内容 { continue; } QString sag = list.at(tabcol - 1); sag = QString::number(sag.toDouble() * 100); listS.push_back(sag); //m_TableTool.setItem(model, row++, col, sag); } if (qvec_st.size() == 0) { qvec_st.push_back(listFFL); } //row = startRow; //col++; QVector<QStringList> tableData_tan = sections.tagFieldFocus2DTangential.tableData; for (int j = 2; j < tableData_tan.size(); j++) { QStringList list = tableData_sag.at(j); QString tan = list.at(tabcol - 1); tan = QString::number(tan.toDouble() * 100); listT.push_back(tan); //m_TableTool.setItem(model, row++, col, tan); } //endRow = row; //row = titleRow; //col++; qvec_st.push_back(listS); qvec_st.push_back(listT); } map_TfTable.insert(i + 1, qvec_st); //row = endRow + 1; //col = 1; } return 0; } int GActionFlow_Standard::ShowTFTableAndChart(QGridLayout* layout, QTableView* view) { int row = tf_start_row; int col = 1; QStandardItemModel* model = theModel4Tf; for (int i = 0; i < map_TfTable.size(); i++) { QVector<QStringList> vec = map_TfTable.value(i + 1); UpDataOneTableAndChart(vec, model, row, col, layout, view); } return 0; } int GActionFlow_Standard::UpDataOneTableAndChart(QVector<QStringList> one, QStandardItemModel* model, int& row, int& col, QGridLayout* layout, QTableView* view) { if (one.isEmpty()) { return -1; } // 缓存表格视图 m_currentTableView = view; DraggableChartView* chartView; QChart* chart; QValueAxis* axisX; QValueAxis* axisY; NewChart(chartView, chart, view); QStringList fflList = one.at(0); QString min = *std::min_element(fflList.begin(), fflList.end()); QString max = *std::max_element(fflList.begin(), fflList.end()); NewAxisX(chart, axisX, min.toDouble(), max.toDouble()); NewAxisY(chart, axisY, 0, 100); QString name = ""; int titleRow = row; int rowEnd = 0; // 更新一个表格 for (int j = 1; j < one.size(); j++) { QStringList list = one.at(j); QVector<QPointF> points; for (int k = 0; k < list.size(); k++) { QString var = list.at(k); QString ffl = fflList.at(k); if (k == 0) { name = var; } if (k != 0) { QPointF f; f.setX(ffl.toDouble()); f.setY(var.toDouble()); points.push_back(f); } m_TableTool.setItem(model, row, col, var); m_TableTool.setItem(model, row, 0, ffl); row++; } NewSeries(chartView, chart, axisX, axisY, points, name); rowEnd = row; row = titleRow; col++; } // 增添放Chart的空位 for (int i = titleRow; i < rowEnd; i++) { for (int j = col; j < col + 10; j++) { m_TableTool.setItem(model, i, j, ""); } } // 保存图表位置 ChartPosition pos; pos.startRow = titleRow; pos.startCol = col; pos.endRow = titleRow + 20; pos.endCol = col+ 8; // 更新位置 updateChartPosition(view, chartView, pos); row = rowEnd + 1; col = 1; return 0; } int GActionFlow_Standard::NewChart(DraggableChartView*& chartView, QChart*& chart, QTableView* view) { // 创建图表视图 chartView = new DraggableChartView(view->viewport()); chartView->setRenderHint(QPainter::Antialiasing); //抗锯齿 chartView->setRubberBand(QChartView::NoRubberBand); // 禁止缩放 // 设置透明背景 chartView->setStyleSheet("background: transparent;"); chartView->setAttribute(Qt::WA_TranslucentBackground); chart = new QChart; chart->setTheme(QChart::ChartThemeLight); chart->setTitle("Through Focus Curves"); // 禁用图表本身的交互标志 chart->setAcceptHoverEvents(false); chartView->setChart(chart); chartView->show(); // 连接信号 QObject::connect(chartView, &DraggableChartView::seriesFocusChanged, this, &GActionFlow_Standard::showQLineSeriesLinkTable); return 0; } int GActionFlow_Standard::NewAxisX(QChart*& chart, QValueAxis*& axisX, double min, double max) { //创建坐标轴X axisX = new QValueAxis; axisX->setRange(min, max); axisX->setTitleText("FFL [mm]"); axisX->setTickCount(8); axisX->setLabelFormat("%.3f"); axisX->setLabelsAngle(-30); axisX->setGridLineVisible(false); axisX->setMinorGridLineVisible(false); chart->addAxis(axisX, Qt::AlignBottom); return 0; } int GActionFlow_Standard::NewAxisY(QChart *& chart, QValueAxis *& axisY, double min, double max) { //创建坐标轴Y axisY = new QValueAxis; axisY->setRange(min, max); // 设置范围 axisY->setTitleText("MTF [%]"); //设置标题 axisY->setTickCount((max - min) / 10.0); // 设置刻度数量(包括最小和最大值) axisY->setLabelFormat("%d"); // 设置标签格式 chart->addAxis(axisY, Qt::AlignLeft); return 0; } int GActionFlow_Standard::NewSeries(DraggableChartView*& chartView, QChart*& chart, QValueAxis* axisX, QValueAxis* axisY, QVector<QPointF> points, QString seriesName) { // 创建数据序列 QSplineSeries *series = new QSplineSeries(); series->setName(seriesName); series->append(points.toList()); series->setVisible(true); // 设置系列样式 QPen pen; pen.setWidth(2); pen.setColor(QColor(rand() % 256, rand() % 256, rand() % 256)); series->setPen(pen); // 创建散点序列(用于显示选中的点) QtCharts::QScatterSeries *selectedPoint = new QtCharts::QScatterSeries(); selectedPoint->setMarkerShape(QScatterSeries::MarkerShapeCircle); selectedPoint->setMarkerSize(10.0); // 放大显示点 selectedPoint->setColor(Qt::red); // 红色高亮 selectedPoint->setName(""); selectedPoint->hide(); // 关键调用:隐藏图例项 // 添加到图表 chart->addSeries(series); chart->addSeries(selectedPoint); chart->legend()->setAlignment(Qt::AlignRight); chart->legend()->setVisible(true); // 将序列附加到坐标轴 series->attachAxis(axisX); series->attachAxis(axisY); selectedPoint->attachAxis(axisX); selectedPoint->attachAxis(axisY); // 添加悬停效果 QObject::connect(series, &QSplineSeries::hovered, [series, chartView](const QPointF& point, bool state) { if (state) { QPen hoverPen = series->pen(); hoverPen.setWidth(4); series->setPen(hoverPen); chartView->setCursor(Qt::PointingHandCursor); } else { QPen normalPen = series->pen(); normalPen.setWidth(2); series->setPen(normalPen); chartView->setCursor(Qt::ArrowCursor); } }); // 注册到图表视图 chartView->registerSeries(series, selectedPoint); return 0; } int GActionFlow_Standard::GetCamAngleTableCol(QVector<QStringList>& qvec_CamAngleTableCol) { QStandardItemModel* model = theModel4Tf; int row = 1; int col = 0; for (int row = 1; row < model->rowCount(); row++) { QStringList list; if (model->item(row, col) != nullptr) { QString camNumber = model->item(row, col)->text(); QString angle = model->item(row, col + 1)->text(); QString table_col = model->item(row, col + 2)->text(); list.push_back(camNumber); list.push_back(angle); list.push_back(table_col); qvec_CamAngleTableCol.push_back(list); } } return 0; } int GActionFlow_Standard::GetCamAngleTableCol(QVector<QStringList>& qvec_CamAngleTableCol, int cam, double & angle, int & tableCol) { if (qvec_CamAngleTableCol.size() <= 0) { return -1; } for (int i = 0; i < qvec_CamAngleTableCol.size(); i++) { QStringList list = qvec_CamAngleTableCol.at(i); if (list.first().toInt() == cam) { angle = list.at(1).toDouble(); tableCol = list.at(2).toInt(); return 1; } } return 0; } int GActionFlow_Standard::ShowtagMeasureMentTilt(QVector<tagMeasurement> tagMeasureMentTilt) { for each (tagMeasurement measurement in tagMeasureMentTilt) { QString name = measurement.fileName; QStringList list = name.split("-"); int number = list.at(0).toInt(); int index = number - 1; int nextTableStartCol = 0; // 单个table开始列 int startRow = hr_source_rows[index];// 单个table初始行 QString angle = list.at(1) + "°"; QStandardItemModel* model = hr_source_models[index]; m_TableTool.setItem(model, startRow, hr_source_cols[index]++, angle); m_TableTool.setItem(model, hr_source_rows[index]++, hr_source_cols[index]--, measurement.tagTable.tagFieldFocus2DSagittal.title); QVector<QStringList> datas = measurement.tagTable.tagFieldFocus2DSagittal.tableData; } return 0; } bool GActionFlow_Standard::isFormatValidMTF(const QString & input) { QRegularExpressionMatch matchMtf = regexMtf.match(input); if (matchMtf.hasMatch()) { return true; } return false; } bool GActionFlow_Standard::isFormatValidTF(const QString & input) { QRegularExpressionMatch matchTf = regexTF.match(input); if (matchTf.hasMatch()) { return true; } // 返回是否匹配成功 return false; } bool GActionFlow_Standard::isFormatValidTilt(const QString & input) { QRegularExpressionMatch matchTilt = regexTilt.match(input); if (matchTilt.hasMatch()) { return true; } // 返回是否匹配成功 return false; } void GActionFlow_Standard::InitView4Tf(QTableView *& view) { theModel4Tf = new QStandardItemModel(); view->setModel(theModel4Tf); } void GActionFlow_Standard::updateChartPosition(QTableView* view, DraggableChartView* chartView, ChartPosition pos) { // 此处可以添加图表位置管理逻辑 // 例如存储图表位置信息以便后续访问 Q_UNUSED(view); Q_UNUSED(chartView); Q_UNUSED(pos); if (!chartView->isVisible()) { return; } QRect rect = calculateChartGeometry(view, pos.startRow, pos.startCol, pos.endRow, pos.endCol); chartView->setGeometry(rect); chartView->raise(); // 确保在最上层 } QRect GActionFlow_Standard::calculateChartGeometry(QTableView* view, int startRow, int startCol, int endRow, int endCol) { // 计算图表在表格中的位 int x = view->columnViewportPosition(startCol); int width = view->columnViewportPosition(endCol) + view->columnWidth(endCol) - x; // 垂直位置(从第2行开始,到倒数第2行结束) int y = view->rowViewportPosition(startRow); int height = view->rowViewportPosition(endRow) + view->rowHeight(endRow) - y; // 添加边距 int margin = 10; return QRect(x + margin, y + margin, width - 2 * margin, height - 2 * margin); } void GActionFlow_Standard::FreashTfTable() { QStandardItemModel* model = theModel4Tf; int row = 0; int col = 0; m_TableTool.setItem(model, row, col++, "相机序号"); m_TableTool.setItem(model, row, col++, "角度"); m_TableTool.setItem(model, row, col++, "对应列"); col = 0; row++; m_TableTool.setItem(model, row, col, "1"); m_TableTool.setItem(model, row, col + 1, "0"); m_TableTool.setItem(model, row, col + 2, "4"); row++; m_TableTool.setItem(model, row, col, "2"); m_TableTool.setItem(model, row, col + 1, "0"); m_TableTool.setItem(model, row, col + 2, "3"); row++; m_TableTool.setItem(model, row, col, "3"); m_TableTool.setItem(model, row, col + 1, "90"); m_TableTool.setItem(model, row, col + 2, "5"); row++; m_TableTool.setItem(model, row, col, "4"); m_TableTool.setItem(model, row, col + 1, "0"); m_TableTool.setItem(model, row, col + 2, "5"); row++; m_TableTool.setItem(model, row, col, "5"); m_TableTool.setItem(model, row, col + 1, "90"); m_TableTool.setItem(model, row, col + 2, "3"); row++; m_TableTool.setItem(model, row, col, "6"); m_TableTool.setItem(model, row, col + 1, "126.87/135"); m_TableTool.setItem(model, row, col + 2, "6"); row++; m_TableTool.setItem(model, row, col, "7"); m_TableTool.setItem(model, row, col + 1, "36.87/45"); m_TableTool.setItem(model, row, col + 2, "6"); row++; m_TableTool.setItem(model, row, col, "8"); m_TableTool.setItem(model, row, col + 1, "126.87/135"); m_TableTool.setItem(model, row, col + 2, "2"); row++; m_TableTool.setItem(model, row, col, "9"); m_TableTool.setItem(model, row, col + 1, "36.87/45"); m_TableTool.setItem(model, row, col + 2, "2"); tf_start_row = row + 2; } void GActionFlow_Standard::showQLineSeriesLinkTable(QSplineSeries* focusedSeries) { if (!m_currentTableView) { return; } //// 清除之前的选择 //m_currentTableView->selectionModel()->clearSelection(); clearHighlights(); if (focusedSeries == nullptr) { return; } // 获取表格模型 QStandardItemModel* model = qobject_cast<QStandardItemModel*>(m_currentTableView->model()); if (!model) { return; } QVector<double> ffl; QVector<double> st; const auto points = focusedSeries->points(); for (int i = 0; i < points.size(); i++) { QPointF f = points.at(i); ffl.push_back(f.x()); st.push_back(f.y()); } QMap<int, int> mapFFl; QMap<int, int> mapST; // 表格上寻找符合的数(x轴数据) for (int row = 0; row < model->rowCount(); row++) { int col = 0; // x轴参数对应第一列 // 检查连续行是否有足够的数据 if (row + ffl.size() > model->rowCount()) { continue; } bool allMatch = true; for (int i = 0; i < ffl.size(); i++) { if (model->item(row + i, col) == nullptr) { allMatch = false; break; } QString var = model->item(row + i, col)->text(); if (ffl.at(i) != var.toDouble()) // 使用精度比较浮点数 { allMatch = false; break; } } if (allMatch) { for (int i = 0; i < ffl.size(); i++) { mapFFl.insert(row + i, col); } break; } } QList<int> keys = mapFFl.keys(); if (keys.isEmpty()) return; // 没有找到匹配的FFL数据 // 表格上寻找符合的数(y轴数据) for (int col = 1; col < model->columnCount(); col++) { int startRow = keys.first(); // 检查连续行是否有足够的数据 if (startRow + st.size() > model->rowCount()) { continue; } bool allMatch = true; for (int i = 0; i < st.size(); i++) { if (model->item(startRow + i, col) == nullptr) { allMatch = false; break; } QString var = model->item(startRow + i, col)->text(); if (st.at(i) != var.toDouble()) // 使用精度比较浮点数 { allMatch = false; break; } } if (allMatch) { for (int i = 0; i < st.size(); i++) { mapST.insert(startRow + i, col); } break; } } // 框选显示 if (!mapFFl.isEmpty()) { highlightRegion(mapFFl, QColor(128, 0, 128, 100)); // 紫色半透明 } if (!mapST.isEmpty()) { highlightRegion(mapST, QColor(0, 0, 255, 100)); // 蓝色半透明 } } // 高亮显示连续区域(只绘制外框) void GActionFlow_Standard::highlightRegion(const QMap<int, int>& cellMap, const QColor& color) { if (!m_currentTableView) return; QStandardItemModel* model = qobject_cast<QStandardItemModel*>(m_currentTableView->model()); if (!model) return; // 获取区域的边界 int minRow = INT_MAX, maxRow = INT_MIN; int minCol = INT_MAX, maxCol = INT_MIN; for (auto it = cellMap.constBegin(); it != cellMap.constEnd(); ++it) { int row = it.key(); int col = it.value(); if (row < minRow) minRow = row; if (row > maxRow) maxRow = row; if (col < minCol) minCol = col; if (col > maxCol) maxCol = col; } // 获取视觉矩形 QRect visualRect = getVisualRect(minRow, minCol, maxRow, maxCol); if (visualRect.isEmpty()) return; // 创建自定义覆盖层 HighlightOverlay* overlay = new HighlightOverlay(m_currentTableView->viewport(), color); overlay->setGeometry(visualRect); overlay->show(); m_overlays.append(overlay); } // 获取视觉区域矩形 QRect GActionFlow_Standard::getVisualRect(int startRow, int startCol, int endRow, int endCol) const { if (!m_currentTableView || !m_currentTableView->model()) return QRect(); QModelIndex topLeft = m_currentTableView->model()->index(startRow, startCol); QModelIndex bottomRight = m_currentTableView->model()->index(endRow, endCol); if (!topLeft.isValid() || !bottomRight.isValid()) return QRect(); QRect rect1 = m_currentTableView->visualRect(topLeft); QRect rect2 = m_currentTableView->visualRect(bottomRight); return rect1.united(rect2); } // 清除所有高亮 void GActionFlow_Standard::clearHighlights() { // 删除所有覆盖层 for (QWidget* overlay : m_overlays) { overlay->deleteLater(); } m_overlays.clear(); } /** * 确保指针数组在指定索引处存在有效对象 * * @param hr_source_models 指向指针数组的三级指针(允许修改原始数组) * @param currentSize 指向当前数组大小的指针(允许修改大小值) * @param index 需要确保存在的索引位置 */ void GActionFlow_Standard::ensureIndexExists(QStandardItemModel **& hr_source_models, int& currentSize, int index) { if (index < 0) { throw std::invalid_argument("索引不能为负数"); } // 检查是否需要扩容 if (index >= currentSize) { // 计算新大小(至少比所需索引大1) int newSize = index + 1; // 创建新数组 QStandardItemModel** newArray = new QStandardItemModel*[newSize](); // 初始化为 nullptr // 复制旧数据(如果存在) if (hr_source_models != nullptr) { for (int i = 0; i < currentSize; ++i) { newArray[i] = (hr_source_models)[i]; } delete[] hr_source_models; // 删除旧数组 } // 初始化新增元素 for (int i = currentSize; i < newSize; ++i) { newArray[i] = new QStandardItemModel(); // 创建新对象 } // 更新指针和大小 hr_source_models = newArray; currentSize = newSize; } // 确保索引处对象有效 if ((hr_source_models)[index] == nullptr) { (hr_source_models)[index] = new QStandardItemModel(); } } void GActionFlow_Standard::ensureIndexExists(int*& row, int& currentSize, int index) { if (index < 0) { throw std::invalid_argument("索引不能为负数"); } // 检查是否需要扩容 if (index >= currentSize) { // 计算新大小(至少比所需索引大1) int newSize = index + 1; // 创建新数组 int* newArray = new int[newSize](); // 初始化为 nullptr // 复制旧数据(如果存在) if (row != nullptr) { for (int i = 0; i < currentSize; ++i) { newArray[i] = (row)[i]; } delete[] row; // 删除旧数组 } // 初始化新增元素 for (int i = currentSize; i < newSize; ++i) { newArray[i] = 0; // 创建新对象 } // 更新指针和大小 row = newArray; currentSize = newSize; } // 确保索引处对象有效 if ((hr_source_models)[index] == nullptr) { (hr_source_models)[index] = new QStandardItemModel(); } } QList<QTableView*> GActionFlow_Standard::findViewsByModel(QStandardItemModel * model) { QList<QTableView*> result; // 获取所有顶层窗口 const QWidgetList topLevelWidgets = QApplication::topLevelWidgets(); for (QWidget* widget : topLevelWidgets) { // 递归搜索所有 QTableView const QList<QTableView*> tableViews = widget->findChildren<QTableView*>(); for (QTableView* view : tableViews) { // 检查视图的模型是否匹配目标模型 if (view->model() == model) { result.append(view); } } } return result; } void GActionFlow_Standard::ensureRectItemsExist(QStandardItemModel * model, const QRect & rect) { if (!model) { qWarning() << "Model is null!"; return; } // 获取矩形区域边界 int topRow = rect.top(); int bottomRow = rect.bottom(); int leftCol = rect.left(); int rightCol = rect.right(); // 验证矩形边界是否有效 if (topRow < 0 || leftCol < 0 || bottomRow < topRow || rightCol < leftCol) { qWarning() << "Invalid rectangle coordinates:" << rect; return; } // 调整模型大小以确保矩形区域存在 if (model->rowCount() <= bottomRow) { model->setRowCount(bottomRow + 1); } if (model->columnCount() <= rightCol) { model->setColumnCount(rightCol + 1); } //// 遍历矩形区域内的所有单元格 //for (int row = topRow; row <= bottomRow; ++row) //{ // for (int col = leftCol; col <= rightCol; ++col) // { // // 检查单元格是否存在 // if (!model->item(row, col)) // { // // 创建新单元格并设置默认值 // QStandardItem* newItem = new QStandardItem(); // newItem->setText(QString("R%1C%2").arg(row).arg(col)); // newItem->setData(QColor(Qt::lightGray), Qt::BackgroundRole); // model->setItem(row, col, newItem); // qDebug() << "Created item at:" << row << col; // } // } //} } const QRegularExpression GActionFlow_Standard::regexMtf("^MTF-\\d+-\\d+\\.mht$"); const QRegularExpression GActionFlow_Standard::regexTF("^TF-\\d+-\\d+\\.mht$"); const QRegularExpression GActionFlow_Standard::regexTilt("^\\d+-\\d+\\.mht$");点击曲线后,legend不要更改

#include "c.h"//借还管理 #include "ui_c.h" #include "a.h" C::C(QWidget *parent) : QMainWindow(parent) , ui(new Ui::C) { ui->setupUi(this); this->setWindowTitle("借还管理"); QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); // SQLite示例 db.setDatabaseName("D:/qtfile/serve1/data.db"); // 数据库文件路径 if (!db.open()) { qDebug() << "数据库连接失败:" << db.lastError().text(); return; } //创建表 QSqlQuery query; if (!query.exec("CREATE TABLE IF NOT EXISTS equipment (" "id INTEGER PRIMARY KEY AUTOINCREMENT," "name TEXT NOT NULL," "type TEXT NOT NULL," "status INTEGER DEFAULT 0," "lend_out_date DATE," "return_date DATE," "people TEXT NOT NULL," "phone TEXT NOT NULL);")) { qDebug() << "建表错误:" << query.lastError().text(); } //插入两条数据 QSqlQuery checkQuery("SELECT COUNT(*) FROM equipment;"); if (checkQuery.next() && checkQuery.value(0).toInt() == 0) { QSqlQuery insertQuery; // 第一条数据 insertQuery.prepare("INSERT INTO equipment (name, type, status, lend_out_date,return_date,people,phone) " "VALUES (:name, :type, :status, :date_1, :date_2, :people, :phone)"); insertQuery.bindValue(":name", "光谱分析仪"); insertQuery.bindValue(":type", "实验室设备"); insertQuery.bindValue(":status", 0); insertQuery.bindValue(":date_1", QDate(2023, 5, 10)); insertQuery.bindValue(":date_2", QDate()); insertQuery.bindValue(":people", "张洪平"); insertQuery.bindValue(":phone", "19923688556"); if (!insertQuery.exec()) { qDebug() << "插入数据失败:" << insertQuery.lastError().text(); } // 第二条数据 insertQuery.prepare("INSERT INTO equipment (name, type, status, lend_out_date, return_date, people, phone ) " "VALUES (:name, :type, :status, :date_1, :date_2, :people, :phone)"); insertQuery.bindValue(":name", "离心机"); insertQuery.bindValue(":type", "生物设备"); insertQuery.bindValue(":status", 1); insertQuery.bindValue(":date_1", QDate(2022, 11, 20)); insertQuery.bindValue(":date_2", QDate(2023, 7, 9)); insertQuery.bindValue(":people", "张洪平"); insertQuery.bindValue(":phone", "19923688556"); if (!insertQuery.exec()) { qDebug() << "插入数据失败:" << insertQuery.lastError().text(); } } model = new QSqlTableModel(this); model->setTable("equipment"); // 设置数据库表名 model->setEditStrategy(QSqlTableModel::OnManualSubmit); // 手动提交修改 model->setSort(model->fieldIndex("ID"),Qt::AscendingOrder);//按id排序 model->select();//加载数据 // 设置列标题 model->setHeaderData(0, Qt::Horizontal, tr("ID")); model->setHeaderData(1, Qt::Horizontal, tr("设备名称")); model->setHeaderData(2, Qt::Horizontal, tr("设备类型")); model->setHeaderData(3, Qt::Horizontal, tr("借还状态")); model->setHeaderData(4, Qt::Horizontal, tr("借出日期")); model->setHeaderData(5,Qt::Horizontal, tr("归还日期")); model->setHeaderData(6, Qt::Horizontal, tr("借用人")); model->setHeaderData(7,Qt::Horizontal, tr("手机")); // 加载数据 if (!model->select()) { qDebug() << "数据加载失败:" << model->lastError().text(); } ui->tableView->setModel(model);//绑定模型 ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection); ui->tableView->setModel(model); ui->tableView->resizeColumnsToContents(); // 自动调整列宽 ui->tableView->show(); } C::~C() { delete ui; } void C::on_pushButton_clicked()//返回按钮 { A *w=new A(); w->show(); this->hide(); } void C::on_pushButton_2_clicked()//退出按钮 { this->close(); } //借出记录 void C::on_action_triggered() { model->setFilter(""); } //归还记录 void C::on_action_2_triggered(){ model->setFilter("status <> 0");// 排除状态为0的记录 } void C::on_action_3_triggered() { QDialog dialog(this); dialog.setWindowTitle("添加新记录"); dialog.setMinimumWidth(300); // 创建布局 QVBoxLayout *mainLayout = new QVBoxLayout(&dialog); QFormLayout *formLayout = new QFormLayout(); // 创建输入控件 QLineEdit *nameEdit = new QLineEdit(&dialog);//equipment QLineEdit *typeEdit = new QLineEdit(&dialog); QLineEdit *lend_out_dateEdit = new QLineEdit(&dialog); QLineEdit *peopleEdit= new QLineEdit(&dialog); QLineEdit *phoneEdit= new QLineEdit(&dialog); // 添加控件到表单 formLayout->addRow("设备名称:", nameEdit); formLayout->addRow("设备类型:", typeEdit); formLayout->addRow("借出时间:", lend_out_dateEdit); formLayout->addRow("借用人:", peopleEdit); formLayout->addRow("手机·:", phoneEdit); // 创建按钮 QDialogButtonBox *buttonBox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog); mainLayout->addLayout(formLayout); mainLayout->addWidget(buttonBox); // 连接按钮信号 connect(buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); // 显示对话框并处理结果 if (dialog.exec() == QDialog::Accepted) { // 获取输入值 QString name = nameEdit->text().trimmed(); QString type = typeEdit->text().trimmed(); QString date_1= lend_out_dateEdit->text().trimmed(); QString date_2= ""; QString status = "0"; QString people = peopleEdit->text().trimmed(); QString phone = phoneEdit->text().trimmed(); // 验证输入 if (name.isEmpty()) { QMessageBox::warning(this, "输入错误", "设备名不能为空"); return; } // 在模型末尾插入新行 int rowNum = model->rowCount(); model->insertRow(rowNum); // 设置新记录的值 model->setData(model->index(rowNum, model->fieldIndex("ID")), rowNum+1); model->setData(model->index(rowNum, model->fieldIndex("设备名称")), name); model->setData(model->index(rowNum, model->fieldIndex("设备类型")), type); model->setData(model->index(rowNum, model->fieldIndex("借还状态")), status); model->setData(model->index(rowNum, model->fieldIndex("借用时间")), date_1); model->setData(model->index(rowNum, model->fieldIndex("归还时间")), date_2); model->setData(model->index(rowNum, model->fieldIndex("借用人")),people); model->setData(model->index(rowNum, model->fieldIndex("手机")), phone); // 自动滚动到新添加的行 ui->tableView->scrollToBottom(); } } 为什么最终table view仅显示了ID

QVariant attendanceRecordModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); if (index.column() == 7) { if (role == Qt::EditRole || role == Qt::DecorationRole || role == Qt::DisplayRole) { QByteArray imageData = QSqlTableModel::data(index, Qt::EditRole).toByteArray(); if (role == Qt::EditRole || role == Qt::DisplayRole) { return imageData; } if (!imageData.isEmpty()) { QPixmap pixmap; if (pixmap.loadFromData(imageData)) { return pixmap.scaled(130, 110, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); } } } return QVariant(); } //编辑和显示模式确保模型可以拿到数据 if (role == Qt::DisplayRole || role == Qt::EditRole) { return QSqlTableModel::data(index, role); } return QVariant(); } QVariant attendanceRecordModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::CheckStateRole && orientation == Qt::Horizontal && section == 8) { if (selectedIds.size() == rowCount()) return Qt::Checked; else if (selectedIds.isEmpty()) return Qt::Unchecked; else return Qt::PartiallyChecked; } if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { switch (section) { case 0: return "序号"; case 1: return "工号"; case 2: return "姓名"; case 3: return "设备编号"; case 4: return "部门"; case 5: return "考勤状态"; case 6: return "打卡时间"; case 7: return "照片"; default: return QVariant(); } } return QVariant(); }在这个代码的基础上修改,让第九列显示复选框,同时表头也要有复选框,显示全选+复选框

#include "kchangemanage.h" #include "ui_kchangemanage.h" #include <QSqlTableModel> // 包含QSqlTableModel头文件 #include <QMessageBox> #include <QItemSelectionModel> #include "module/model/EquipmentDataModel.h" #include "module/model/filterproxymdel.h" using namespace view::equipment; kchangemanage::kchangemanage(QWidget *parent) : QDialog(parent), ui(new Ui::kchangemanage), m_model(nullptr), m_currentMatchIndex(-1) { ui->setupUi(this); //初始化模型 dataModel::EquipmentDataModel *modelRent = new dataModel::EquipmentDataModel(this); fliterModel::FilterProxyMdel *rentFilterProxyMdel = new fliterModel::FilterProxyMdel(this); rentFilterProxyMdel->setSourceModel(modelRent); //给视图指定模型 ui->tableView_change->setModel(rentFilterProxyMdel); ui->tableView_change->hideColumn(dataModel::EquipmentDataModel::Col_ID); ui->tableView_change->hideColumn(dataModel::EquipmentDataModel::Col_Count); ui->tableView_change->hideColumn(dataModel::EquipmentDataModel::Col_RentId); ui->tableView_change->hideColumn(dataModel::EquipmentDataModel::Col_ClassId); // 调整列宽以显示数据 ui->tableView_change->resizeColumnsToContents(); ui->tableView_change->horizontalHeader()->setStretchLastSection(true); // 加载数据 modelRent->fetchData(); // 调试信息 qDebug() << "Model row count:" << modelRent->rowCount(); qDebug() << "Model column count:" << modelRent->columnCount(); modelRent->select(); setModel(modelRent); // 调用类成员函数 } kchangemanage::~kchangemanage() { delete ui; } // 实现setModel(补充类作用域) void kchangemanage::setModel(QAbstractItemModel *model) { m_model = model; ui->tableView_change->setModel(m_model); } void kchangemanage::on_find_clicked() { QString keyword = ui->equipmentNameEdit->text().trimmed(); if (keyword.isEmpty()) { QMessageBox::warning(this, "提示", "请输入查找关键词!"); return; } // 调用成员函数获取匹配行号(返回模型中的行号列表) m_matchedRows = searchEquipment(keyword); m_currentMatchIndex = m_matchedRows.isEmpty() ? -1 : 0; if (m_matchedRows.isEmpty()) { QMessageBox::information(this, "查找结果", "未找到匹配项!"); return; } // 定位第一个匹配行 QModelIndex targetIndex = m_model->index(m_matchedRows.first(), 0); ui->tableView_change->selectionModel()->select(targetIndex, QItemSelectionModel::SelectCurrent); ui->tableView_change->scrollTo(targetIndex); } // 实现searchEquipment(返回模型中的匹配行号) QList<int> kchangemanage::searchEquipment(const QString &keyword) { QList<int> matchedRows; if (!m_model) return matchedRows; // 遍历模型所有行,检查设备名称列是否包含关键词(假设名称在第1列) for (int row = 0; row < m_model->rowCount(); ++row) { QModelIndex nameIndex = m_model->index(row, 1); // 第2列(0-based) QString name = m_model->data(nameIndex).toString(); if (name.contains(keyword, Qt::CaseInsensitive)) { matchedRows.append(row); } } return matchedRows; } void kchangemanage::on_change_clicked() { if (m_currentMatchIndex == -1 || m_matchedRows.isEmpty()) { QMessageBox::warning(this, "提示", "请先查找需要替换的设备!"); return; } QString newValue = ui->changeValueEdit->text().trimmed(); if (newValue.isEmpty()) { QMessageBox::warning(this, "错误", "替换值不能为空!"); return; } // 获取当前行的设备编号(假设编号在第0列) int currentRow = m_matchedRows[m_currentMatchIndex]; QModelIndex numberIndex = m_model->index(currentRow, 0); QString equipmentNumber = m_model->data(numberIndex).toString(); // 执行数据库更新(使用QSqlTableModel的setData方法,自动提交) QSqlTableModel *sqlModel = qobject_cast<QSqlTableModel*>(m_model); if (!sqlModel) { QMessageBox::critical(this, "错误", "模型类型不支持更新!"); return; } // 更新名称列(假设名称在第1列) if (sqlModel->setData(sqlModel->index(currentRow, 1), newValue)) { sqlModel->submitAll(); // 提交所有更改 sqlModel->select(); // 刷新数据(QSqlTableModel的select方法) QMessageBox::information(this, "成功", "替换完成!"); } else { QMessageBox::critical(this, "失败", "替换失败:" + sqlModel->lastError().text()); } } void kchangemanage::on_deleteButton_clicked() { if (m_currentMatchIndex == -1 || m_matchedRows.isEmpty()) { QMessageBox::warning(this, "提示", "请先查找需要删除的设备!"); return; } // 确认删除 if (QMessageBox::question(this, "确认", "是否删除选中设备?") != QMessageBox::Yes) { return; } // 获取当前行的设备编号(第0列) int currentRow = m_matchedRows[m_currentMatchIndex]; QModelIndex numberIndex = m_model->index(currentRow, 0); QString equipmentNumber = m_model->data(numberIndex).toString(); // 调用成员函数删除(返回成功行数) int deleted = deleteEquipmentByNumbers({equipmentNumber}); if (deleted > 0) { // 刷新模型(QSqlTableModel的select方法) QSqlTableModel *sqlModel = qobject_cast<QSqlTableModel*>(m_model); if (sqlModel) sqlModel->select(); m_matchedRows.removeAll(currentRow); // 移除匹配行 m_currentMatchIndex = -1; QMessageBox::information(this, "成功", "删除完成!"); } else { QMessageBox::critical(this, "失败", "删除失败!"); } } // 实现deleteEquipmentByNumbers(使用QSqlTableModel删除) int kchangemanage::deleteEquipmentByNumbers(const QStringList &equipmentNumbers) { int deletedCount = 0; QSqlTableModel *sqlModel = qobject_cast<QSqlTableModel*>(m_model); if (!sqlModel) return deletedCount; for (const QString &number : equipmentNumbers) { // 定位要删除的行 QModelIndexList indexes = sqlModel->match( sqlModel->index(0, 0), // 从第0行第0列开始(设备编号列) Qt::DisplayRole, number, 1, // 只找第一个匹配项 Qt::MatchExactly ); if (!indexes.isEmpty()) { int row = indexes.first().row(); if (sqlModel->removeRow(row)) { // 删除行 deletedCount++; } } } sqlModel->submitAll(); // 提交删除操作 return deletedCount; } void kchangemanage::on_next_clicked() { if (m_matchedRows.isEmpty()) return; m_currentMatchIndex = (m_currentMatchIndex + 1) % m_matchedRows.size(); QModelIndex targetIndex = m_model->index(m_matchedRows[m_currentMatchIndex], 0); ui->tableView_change->selectionModel()->select(targetIndex, QItemSelectionModel::SelectCurrent); ui->tableView_change->scrollTo(targetIndex); } void kchangemanage::on_before_clicked() { if (m_matchedRows.isEmpty()) return; m_currentMatchIndex = (m_currentMatchIndex - 1 + m_matchedRows.size()) % m_matchedRows.size(); QModelIndex targetIndex = m_model->index(m_matchedRows[m_currentMatchIndex], 0); ui->tableView_change->selectionModel()->select(targetIndex, QItemSelectionModel::SelectCurrent); ui->tableView_change->scrollTo(targetIndex); } void kchangemanage::on_cancelButton_clicked() { this->close(); } 根据构造函数内容补全更正使功能完善可用

大家在看

recommend-type

ELEC5208 Group project submissions.zip_furniturer4m_smart grid_悉

悉尼大学ELEC5208智能电网project的很多组的报告和code都在里面,供学习和参考
recommend-type

基于python单通道脑电信号的自动睡眠分期研究

【作品名称】:基于python单通道脑电信号的自动睡眠分期研究 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【项目介绍】:网络结构(具体可查看network.py文件): 网络整体结构类似于TinySleepNet,对RNN部分进行了修改,增加了双向RNN、GRU、Attention等网络结构,可根据参数进行调整选择。 定义了seq_len参数,可以更灵活地调整batch_size与seq_len。 数据集加载(具体可查看dataset.py文件) 直接继承自torch的Dataset,并定义了seq_len和shuffle_seed,方便调整输入,并复现实验。 训练(具体可查看train.py文件): 定义并使用了focal loss损失函数 在实验中有使用wandb,感觉用起来还挺方便的,非常便于实验记录追溯 测试(具体可查看test.py文件): 可以输出accuracy、mf1、recall_confusion_matrics、precision_confusion_matrics、f1
recommend-type

bid格式文件电子标书阅读器.zip

软件介绍: bid格式招投标文件阅读器,可以打开浏览、管理电子招标文件,如果打不开标书文件,请按下面步骤检查:1、请查看招标文件(.bid文件)是否下载完全,请用IE下载工具下载;2、查看IE浏览器版本,如果版本低于IE8,低于IE8版本的请升级为IE8浏览器。
recommend-type

机器翻译WMT14数据集

机器翻译WMT14数据集,ACL2014公布的share task,很多模型都在这上benchmark
recommend-type

高通QXDM使用手册.pdf

高通QXDM使用手册,介绍高通QXDM工具软件的使用,中文版的哦。

最新推荐

recommend-type

C#类库封装:简化SDK调用实现多功能集成,构建地磅无人值守系统

内容概要:本文介绍了利用C#类库封装多个硬件设备的SDK接口,实现一系列复杂功能的一键式调用。具体功能包括身份证信息读取、人证识别、车牌识别(支持臻识和海康摄像头)、LED显示屏文字输出、称重数据读取、二维码扫描以及语音播报。所有功能均被封装为简单的API,极大降低了开发者的工作量和技术门槛。文中详细展示了各个功能的具体实现方式及其应用场景,如身份证读取、人证核验、车牌识别等,并最终将这些功能整合到一起,形成了一套完整的地磅称重无人值守系统解决方案。 适合人群:具有一定C#编程经验的技术人员,尤其是需要快速集成多种硬件设备SDK的应用开发者。 使用场景及目标:适用于需要高效集成多种硬件设备SDK的项目,特别是那些涉及身份验证、车辆管理、物流仓储等领域的企业级应用。通过使用这些封装好的API,可以大大缩短开发周期,降低维护成本,提高系统的稳定性和易用性。 其他说明:虽然封装后的API极大地简化了开发流程,但对于一些特殊的业务需求,仍然可能需要深入研究底层SDK。此外,在实际部署过程中,还需考虑网络环境、硬件兼容性等因素的影响。
recommend-type

Teleport Pro教程:轻松复制网站内容

标题中提到的“复制别人网站的软件”指向的是一种能够下载整个网站或者网站的特定部分,然后在本地或者另一个服务器上重建该网站的技术或工具。这类软件通常被称作网站克隆工具或者网站镜像工具。 描述中提到了一个具体的教程网址,并提到了“天天给力信誉店”,这可能意味着有相关的教程或资源可以在这个网店中获取。但是这里并没有提供实际的教程内容,仅给出了网店的链接。需要注意的是,根据互联网法律法规,复制他人网站内容并用于自己的商业目的可能构成侵权,因此在此类工具的使用中需要谨慎,并确保遵守相关法律法规。 标签“复制 别人 网站 软件”明确指出了这个工具的主要功能,即复制他人网站的软件。 文件名称列表中列出了“Teleport Pro”,这是一款具体的网站下载工具。Teleport Pro是由Tennyson Maxwell公司开发的网站镜像工具,允许用户下载一个网站的本地副本,包括HTML页面、图片和其他资源文件。用户可以通过指定开始的URL,并设置各种选项来决定下载网站的哪些部分。该工具能够帮助开发者、设计师或内容分析人员在没有互联网连接的情况下对网站进行离线浏览和分析。 从知识点的角度来看,Teleport Pro作为一个网站克隆工具,具备以下功能和知识点: 1. 网站下载:Teleport Pro可以下载整个网站或特定网页。用户可以设定下载的深度,例如仅下载首页及其链接的页面,或者下载所有可访问的页面。 2. 断点续传:如果在下载过程中发生中断,Teleport Pro可以从中断的地方继续下载,无需重新开始。 3. 过滤器设置:用户可以根据特定的规则过滤下载内容,如排除某些文件类型或域名。 4. 网站结构分析:Teleport Pro可以分析网站的链接结构,并允许用户查看网站的结构图。 5. 自定义下载:用户可以自定义下载任务,例如仅下载图片、视频或其他特定类型的文件。 6. 多任务处理:Teleport Pro支持多线程下载,用户可以同时启动多个下载任务来提高效率。 7. 编辑和管理下载内容:Teleport Pro具备编辑网站镜像的能力,并可以查看、修改下载的文件。 8. 离线浏览:下载的网站可以在离线状态下浏览,这对于需要测试网站在不同环境下的表现的情况十分有用。 9. 备份功能:Teleport Pro可以用来备份网站,确保重要数据的安全。 在实际使用此类工具时,需要注意以下几点: - 著作权法:复制网站内容可能侵犯原作者的版权,因此在使用此类工具时,必须确保有合法权利去下载和使用目标网站的内容。 - 服务条款:许多网站的服务条款明确禁止未经授权的网站克隆。因此,在使用此类软件之前,应当仔细阅读并遵守目标网站的服务条款。 - 数据隐私:下载含有个人数据的网站可能触及隐私保护法律,特别是在欧洲通用数据保护条例(GDPR)等法规的环境下。 - 网络安全:随意下载网站可能导致恶意软件和病毒的传播,用户应当使用最新的反病毒软件,并在安全的环境中进行操作。 综上所述,虽然“复制别人网站的软件”在技术上是可行的,且可以用于多种正当目的,但在使用此类工具时,必须遵守法律法规和道德规范,不可侵犯他人的合法权益。
recommend-type

【跨平台开发者的必读】:解决Qt5Widgetsd.lib目标计算机类型冲突终极指南

# 1. 跨平台开发与Qt框架简介 跨平台开发已经成为现代软件开发中不可或缺的一部分,它使得开发者能够构建出能够在多种操作系统上运行的应用程序,从而触及更广泛的用户群体。在这其中,Qt框架作为一套成熟的跨平台应用程序和用户界面框架,扮演着关键角色。Qt不仅仅是一个跨平台的工具集,它的设计哲学还包含了模块化和可扩展性,使其能够适应各种规模和复杂度的项目。本章节我们将简要介绍
recommend-type

普通RNN结构和特点

<think>首先,用户的问题是:“我想了解普通RNN的结构及其特点请问RNN循环神经网络结构特点工作原理”。这涉及到RNN的结构、特点和工作原理。根据系统级指令:-所有行内数学表达式必须使用$...$格式。-独立公式必须使用$$...$$格式并单独成段。-LaTeX语法正确。-使用中文回答。-生成相关问题。-回答中引用的段落末尾自然地添加引用标识。用户可见层指令:-回答结构清晰,帮助用户逐步解决问题。-保证回答真实可靠。参考站内引用:-引用[1]:关于RNN的基本介绍,为什么需要RNN。-引用[2]:关于RNN的工作原理、结构图,以及与其他网络的比较。用户上一次的问题和我的回答:用户是第一次
recommend-type

探讨通用数据连接池的核心机制与应用

根据给定的信息,我们能够推断出讨论的主题是“通用数据连接池”,这是一个在软件开发和数据库管理中经常用到的重要概念。在这个主题下,我们可以详细阐述以下几个知识点: 1. **连接池的定义**: 连接池是一种用于管理数据库连接的技术,通过维护一定数量的数据库连接,使得连接的创建和销毁操作更加高效。开发者可以在应用程序启动时预先创建一定数量的连接,并将它们保存在一个池中,当需要数据库连接时,可以直接从池中获取,从而降低数据库连接的开销。 2. **通用数据连接池的概念**: 当提到“通用数据连接池”时,它意味着这种连接池不仅支持单一类型的数据库(如MySQL、Oracle等),而且能够适应多种不同数据库系统。设计一个通用的数据连接池通常需要抽象出一套通用的接口和协议,使得连接池可以兼容不同的数据库驱动和连接方式。 3. **连接池的优点**: - **提升性能**:由于数据库连接创建是一个耗时的操作,连接池能够减少应用程序建立新连接的时间,从而提高性能。 - **资源复用**:数据库连接是昂贵的资源,通过连接池,可以最大化现有连接的使用,避免了连接频繁创建和销毁导致的资源浪费。 - **控制并发连接数**:连接池可以限制对数据库的并发访问,防止过载,确保数据库系统的稳定运行。 4. **连接池的关键参数**: - **最大连接数**:池中能够创建的最大连接数。 - **最小空闲连接数**:池中保持的最小空闲连接数,以应对突发的连接请求。 - **连接超时时间**:连接在池中保持空闲的最大时间。 - **事务处理**:连接池需要能够管理不同事务的上下文,保证事务的正确执行。 5. **实现通用数据连接池的挑战**: 实现一个通用的连接池需要考虑到不同数据库的连接协议和操作差异。例如,不同的数据库可能有不同的SQL方言、认证机制、连接属性设置等。因此,通用连接池需要能够提供足够的灵活性,允许用户配置特定数据库的参数。 6. **数据连接池的应用场景**: - **Web应用**:在Web应用中,为了处理大量的用户请求,数据库连接池可以保证数据库连接的快速复用。 - **批处理应用**:在需要大量读写数据库的批处理作业中,连接池有助于提高整体作业的效率。 - **微服务架构**:在微服务架构中,每个服务可能都需要与数据库进行交互,通用连接池能够帮助简化服务的数据库连接管理。 7. **常见的通用数据连接池技术**: - **Apache DBCP**:Apache的一个Java数据库连接池库。 - **C3P0**:一个提供数据库连接池和控制工具的开源Java框架。 - **HikariCP**:目前性能最好的开源Java数据库连接池之一。 - **BoneCP**:一个高性能的开源Java数据库连接池。 - **Druid**:阿里巴巴开源的一个数据库连接池,提供了对性能监控的高级特性。 8. **连接池的管理与监控**: 为了保证连接池的稳定运行,开发者需要对连接池的状态进行监控,并对其进行适当的管理。监控指标可能包括当前活动的连接数、空闲的连接数、等待获取连接的请求队列长度等。一些连接池提供了监控工具或与监控系统集成的能力。 9. **连接池的配置和优化**: 连接池的性能与连接池的配置密切相关。需要根据实际的应用负载和数据库性能来调整连接池的参数。例如,在高并发的场景下,可能需要增加连接池中连接的数量。另外,适当的线程池策略也可以帮助连接池更好地服务于多线程环境。 10. **连接池的应用案例**: 一个典型的案例是电商平台在大型促销活动期间,用户访问量激增,此时通用数据连接池能够保证数据库操作的快速响应,减少因数据库连接问题导致的系统瓶颈。 总结来说,通用数据连接池是现代软件架构中的重要组件,它通过提供高效的数据库连接管理,增强了软件系统的性能和稳定性。了解和掌握连接池的原理及实践,对于任何涉及数据库交互的应用开发都至关重要。在实现和应用连接池时,需要关注其设计的通用性、配置的合理性以及管理的有效性,确保在不同的应用场景下都能发挥出最大的效能。
recommend-type

【LabVIEW网络通讯终极指南】:7个技巧提升UDP性能和安全性

# 摘要 本文系统介绍了LabVIEW在网络通讯中的应用,尤其是针对UDP协议的研究与优化。首先,阐述了UDP的原理、特点及其在LabVIEW中的基础应用。随后,本文深入探讨了通过调整数据包大小、实现并发通信及优化缓冲区管理等技巧来优化UDP性能的LabVIEW方法。接着,文章聚焦于提升UDP通信安全性,介绍了加密技术和认证授权机制在LabVIEW中的实现,以及防御网络攻击的策略。最后,通过具体案例展示了LabVIEW在实时数据采集和远程控制系统中的高级应用,并展望了LabVIEW与UDP通讯技术的未来发展趋势及新兴技术的影响。 # 关键字 LabVIEW;UDP网络通讯;性能优化;安全性;
recommend-type

简要介绍cnn卷积神经网络

<think>首先,用户的问题是:“我想了解卷积神经网络的基本概念和原理 请问CNN卷积神经网络简介及其工作原理”。所以,我需要基于提供的引用材料,构建一个清晰的回答。 引用材料总结: - [^1]: CNN的核心思想是局部感受野、权值共享和时间或空间亚采样,提供位移、尺度、形变不变性。三大特色:局部感知、权重共享和多卷积核。 - [^2]: CNN是一种前馈神经网络,由卷积层和池化层组成,特别在图像处理方面出色。与传统多层神经网络相比,CNN加入了卷积层和池化层,使特征学习更有效。 - [^3]: CNN与全连接神经网络的区别:至少有一个卷积层提取特征;神经元局部连接和权值共享,减少参数数
recommend-type

基于ASP的深度学习网站导航系统功能详解

从给定文件中我们可以提取以下IT知识点: ### 标题知识点 #### "ASP系统篇" - **ASP技术介绍**:ASP(Active Server Pages)是一种服务器端的脚本环境,用于创建动态交互式网页。ASP允许开发者将HTML网页与服务器端脚本结合,使用VBScript或JavaScript等语言编写代码,以实现网页内容的动态生成。 - **ASP技术特点**:ASP适用于小型到中型的项目开发,它可以与数据库紧密集成,如Microsoft的Access和SQL Server。ASP支持多种组件和COM(Component Object Model)对象,使得开发者能够实现复杂的业务逻辑。 #### "深度学习网址导航系统" - **深度学习概念**:深度学习是机器学习的一个分支,通过构建深层的神经网络来模拟人类大脑的工作方式,以实现对数据的高级抽象和学习。 - **系统功能与深度学习的关系**:该标题可能意味着系统在进行网站分类、搜索优化、内容审核等方面采用了深度学习技术,以提供更智能、自动化的服务。然而,根据描述内容,实际上系统并没有直接使用深度学习技术,而是提供了一个传统的网址导航服务,可能是命名上的噱头。 ### 描述知识点 #### "全后台化管理,操作简单" - **后台管理系统的功能**:后台管理系统允许网站管理员通过Web界面执行管理任务,如内容更新、用户管理等。它通常要求界面友好,操作简便,以适应不同技术水平的用户。 #### "栏目无限分类,自由添加,排序,设定是否前台显示" - **动态网站结构设计**:这意味着网站结构具有高度的灵活性,支持创建无限层级的分类,允许管理员自由地添加、排序和设置分类的显示属性。这种设计通常需要数据库支持动态生成内容。 #### "各大搜索和站内搜索随意切换" - **搜索引擎集成**:网站可能集成了外部搜索引擎(如Google、Bing)和内部搜索引擎功能,让用户能够方便地从不同来源获取信息。 #### "网站在线提交、审阅、编辑、删除" - **内容管理系统的功能**:该系统提供了一个内容管理平台,允许用户在线提交内容,由管理员进行审阅、编辑和删除操作。 #### "站点相关信息后台动态配置" - **动态配置机制**:网站允许管理员通过后台系统动态调整各种配置信息,如网站设置、参数调整等,从而实现快速的网站维护和更新。 #### "自助网站收录,后台审阅" - **网站收录和审核机制**:该系统提供了一套自助收录流程,允许其他网站提交申请,由管理员进行后台审核,决定是否收录。 #### "网站广告在线发布" - **广告管理功能**:网站允许管理员在线发布和管理网站广告位,以实现商业变现。 #### "自动生成静态页 ver2.4.5" - **动态与静态内容**:系统支持动态内容的生成,同时也提供了静态页面的生成机制,这可能有助于提高网站加载速度和搜索引擎优化。 #### "重写后台网址分类管理" - **系统优化与重构**:提到了后台网址分类管理功能的重写,这可能意味着系统进行了一次重要的更新,以修复前一个版本的错误,并提高性能。 ### 标签知识点 #### "ASP web 源代码 源码" - **ASP程序开发**:标签表明这是一个ASP语言编写的网站源代码,可能是一个开源项目,供开发者下载、研究或部署到自己的服务器上。 ### 压缩包子文件名称列表知识点 #### "深度学习(asp)网址导航程序" - **文件内容和类型**:文件列表中提到的“深度学习(asp)网址导航程序”表明这是一个ASP语言编写的网址导航系统程序,可能包含了系统安装和配置需要的所有源文件。 通过以上分析,我们可以得出这个ASP系统是一个传统的网址导航系统,以后台管理为核心功能,并没有实际运用到深度学习技术。系统的主要功能包括对网站内容、分类、搜索引擎、广告位、以及其他网站相关信息的管理。它可能还提供了一个平台,供用户提交网址,供管理员审核并收录到导航中。源代码可能以ASP语言编写,并在文件中包含了所有必要的程序文件。
recommend-type

【Oracle数据泵进阶技巧】:避免ORA-31634和ORA-31664错误的终极策略

# 1. Oracle数据泵技术概述 ## Oracle数据泵技术简介 Oracle数据泵(Data Pump)是一种用于高效地在Oracle数据库之间传输数据和元数据的工具。它从Oracle 10g版本开始引入,提供了快速且灵活的数据导入导出功能。数据泵技术优于旧版的`imp`和`exp`工具,因为它支持多线程,可以在导入和导出过程中显著提高性能。 ## 数据泵的核心优势 数据泵的核心优势在于它能并行处理数据,支持大对象(LOBs)和网络传输。它还允许用户自定义数据和对象的传输方式,以及可以控制传输过程中的各种细节,如过滤对象、调整数据缓冲区大小、并行度和网络数据包大小等。 ## 数据
recommend-type

多头注意力机制的时间复杂度

<think>首先,用户的问题是:“我想计算多头注意力机制的时间复杂度 请问多头注意力机制的时间复杂度计算方法”。我需要基于提供的引用和系统级指令来回答。 关键引用: - 引用[1]:提到Transformer模型的计算时间复杂度主要由自注意力机制的O(n²·d)决定。 - 引用[2]:详细解释了注意力机制的计算复杂度,包括QK转置的复杂度为O(N²d),内存需求为N² + Nd。 - 引用[3]:提到原始注意力机制的时间复杂度为O(n²d),并讨论了优化方法如稀疏注意力和线性注意力。 - 引用[4]:涉及多头注意力的未来趋势,但没有直接给出计算方法。 用户的问题是计算多头注意力机制的时间