struct status_t{ QDateTime datetime; // a datetime last point bool state; // a state car in last point (move or stop) float power; // a voltage network car in last point float battery; // a voltage battery device in last point int speed; // a speed car in last point QPointF coord; // a coordinates last point int sat; // a count sattelite in last point bool communication; // a communication with car (active or inactive)};
#ifndef QTABLECARS_H #define QTABLECARS_H //--------------------- #include <QTableWidget> #include <QHeaderView> #include <QHBoxLayout> #include <QLabel> #include <QToolTip> #include <QDebug> #include "qstatuscars.h" #include "qstatusitem.h" //----------------------------------- class QTableCars: public QTableWidget { Q_OBJECT public: QTableCars(QWidget* parent = nullptr); ~QTableCars(); public slots: void slotUpdateStatusCars(QStatusCars::statuses_t& statuses); signals: void updateItem(int, QPointF, const QString&); private: void createItems(QStatusCars::statuses_t& statuses); void createItem(int row, int id, QStatusCars::status_t& status); int findItem(int id); void updateStatus(int row, int id, QStatusCars::status_t& status); };#endif // QTABLECARS_H
#include "qtablecars.h"//--------------------------------------QTableCars::QTableCars(QWidget* parent): QTableWidget(parent){ setSelectionBehavior(QAbstractItemView::SelectRows); setSelectionMode(QAbstractItemView::SingleSelection); setShowGrid(false); horizontalHeader()->hide(); verticalHeader()->hide(); setStyleSheet("QTableWidget::item { background-color: white; border: 1px solid #e0e0e0; }" "QTableWidget::item:selected { background-color: #c0c0c0; }");}//-----------------------QTableCars::~QTableCars(){}//----------------------------------------------------------------------void QTableCars::slotUpdateStatusCars(QStatusCars::statuses_t& statuses){ if(this->rowCount() == 0) { createItems(statuses); return; } for(int key: statuses.keys()) { int row = findItem(key); if(row != -1) { updateStatus(row, key, statuses[key]); } else { row = rowCount(); insertRow(row); createItem(row, key, statuses[key]); } } resizeColumnsToContents(); resizeRowsToContents();}//-------------------------------------------------------------void QTableCars::createItems(QStatusCars::statuses_t& statuses){ if(statuses.isEmpty()) return; setRowCount(statuses.size()); setColumnCount(6); int rowCount = 0; for(int id: statuses.keys()) { createItem(rowCount, id, statuses[id]); rowCount++; } resizeColumnsToContents(); resizeRowsToContents();}//-------------------------------------------------------------------------void QTableCars::createItem(int row, int id, QStatusCars::status_t& status){ QStatusItem* item_id = new QStatusItem(QStatusItem::QTextRole); QStatusItem* item_speed = new QStatusItem(QStatusItem::QTextRole); QStatusItem* item_state = new QStatusItem; QStatusItem* item_battery = new QStatusItem; QStatusItem* item_satellite = new QStatusItem; QStatusItem* item_communication = new QStatusItem; setCellWidget(row, 0, item_id); setCellWidget(row, 1, item_speed); setCellWidget(row, 2, item_state); setCellWidget(row, 3, item_battery); setCellWidget(row, 4, item_satellite); setCellWidget(row, 5, item_communication); updateStatus(row, id, status);}//------------------------------int QTableCars::findItem(int id){ for(int row = 0; row < rowCount(); row++) { QStatusItem* wgt = qobject_cast<QStatusItem*>(cellWidget(row, 0)); if(wgt && id == wgt->text().toInt()) return row; } return -1;}//---------------------------------------------------------------------------void QTableCars::updateStatus(int row, int id, QStatusCars::status_t& status){ emit updateItem(id, status.coord, QString::number(status.speed)); QStatusItem* item_id = static_cast<QStatusItem*>(cellWidget(row, 0)); QStatusItem* item_speed = static_cast<QStatusItem*>(cellWidget(row, 1)); QStatusItem* item_state = static_cast<QStatusItem*>(cellWidget(row, 2)); QStatusItem* item_battery = static_cast<QStatusItem*>(cellWidget(row, 3)); QStatusItem* item_satellite = static_cast<QStatusItem*>(cellWidget(row, 4)); QStatusItem* item_communication = static_cast<QStatusItem*>(cellWidget(row, 5)); if(item_id) { item_id->setContent(QString::number(id)); QString tooltip = "ID: " + QString::number(id) + "\n"; tooltip += "Speed: " + QString::number(status.speed) + "km/h" + "\n"; tooltip += "Fixed satellite: " + QString::number(status.sat) + "\n"; tooltip += "Last position: " + QString::number(status.coord.y()) + ", " + QString::number(status.coord.x()) + "\n"; tooltip += "Last point: " + status.datetime.toString("dd.MM.yyyy - hh:mm:ss"); item_id->setToolTip(tooltip); item_id->setStyleSheet("background: white; color: black;"); } else return; QString str; if(item_speed && status.speed > 0) { if(status.communication) { item_speed->setStyleSheet("color: green;"); str = tr("Last state: movement"); } else { item_speed->setStyleSheet("color: red;"); str = tr("Last state: movement (no communication)"); } item_speed->setContent(QString::number(status.speed) + "km/h"); } else if(item_speed) { item_speed->setContent(""); str = tr("Last state: stop"); } if(status.state && item_state) item_state->setContent(":/icons/icons/move.png"); else if(item_state) item_state->setContent(":/icons/icons/stop.png"); item_state->setToolTip(str); item_state->setStyleSheet("background: white;"); if(status.power < 10.0f && item_battery) item_battery->setContent(":/icons/icons/battery.png"); else if(item_battery) item_battery->setContent(""); if(status.sat == 0 && item_satellite) { item_satellite->setContent(":/icons/icons/satellite.png"); str = tr("No satellites"); } else if(item_satellite) { item_satellite->setContent(""); str = tr("Fixed: ") + QString::number(status.sat) + tr(" satellites"); } item_satellite->setToolTip(str); item_satellite->setStyleSheet("background: white;"); if(!status.communication && item_communication) { item_communication->setContent(":/icons/icons/disconnected.png"); str = tr("No connection\nLast point: ") + status.datetime.toString("dd.MM.yyyy - hh:mm:ss"); } else if(item_communication) { item_communication->setContent(""); str = tr("Last point: ") + status.datetime.toString("dd.MM.yyyy - hh:mm:ss"); } item_communication->setToolTip(str); item_communication->setStyleSheet("background: white;"); setRowHeight(row, item_state->width()); setColumnWidth(0, item_id->width()); setColumnWidth(1, item_speed->width()); setColumnWidth(2, item_state->width()); setColumnWidth(3, item_battery->width()); setColumnWidth(4, item_satellite->width()); setColumnWidth(5, item_communication->width());}
#ifndef QSTATUSITEM_H #define QSTATUSITEM_H //---------------- #include <QWidget> #include <QLabel> #include <QHBoxLayout> #include <QHelpEvent> #include <QToolTip> #include <QDebug> //------------------- class QStatusTooltip; //------------------------------- class QStatusItem: public QWidget { Q_OBJECT public: enum Role{QIconRole = Qt::UserRole + 100, QTextRole}; public: explicit QStatusItem(Role role = QIconRole, QWidget* parent = nullptr); ~QStatusItem(); void setContent(const QString& name); QSize sizeHint() const; QString text() const; private: QLabel* m_item; QHBoxLayout* m_layout; Role m_role; QStatusTooltip* m_tooltip; };#endif // QSTATUSITEM_H
#include "qstatusitem.h"//---------------------------------------------------QStatusItem::QStatusItem(Role role, QWidget* parent): QWidget(parent), m_item(nullptr), m_layout(nullptr), m_role(role), m_tooltip(nullptr){ m_item = new QLabel(this); m_layout = new QHBoxLayout; m_layout->setContentsMargins(0, 0, 0, 0); m_layout->setMargin(0); m_layout->setSpacing(0); m_layout->addWidget(m_item); m_layout->setAlignment(Qt::AlignCenter); setLayout(m_layout); m_item->setStyleSheet("background: none");}//-------------------------QStatusItem::~QStatusItem(){ if(m_item) delete m_item; if(m_layout) delete m_layout;}//-----------------------------------------------void QStatusItem::setContent(const QString& name){ QSize size_item; if(m_role == QIconRole) { m_item->setPixmap(QPixmap(name)); const QPixmap* pixmap_item = m_item->pixmap(); if(pixmap_item) size_item = pixmap_item->size(); else size_item = QSize(0, 0); } else { QFont font = m_item->font(); QFontMetrics fm(font); size_item = QSize(fm.width(name)*1.2, fm.height()*1.2); m_item->setAlignment(Qt::AlignCenter); m_item->setText(name); } resize(size_item);}//---------------------------------QSize QStatusItem::sizeHint() const{ return size();}//-------------------------------QString QStatusItem::text() const{ return m_item->text();}
void QTableCars::updateStatus(int row, int id, QStatusCars::status_t& status){ emit updateItem(id, status.coord, QString::number(status.speed)); QStatusItem* item_id = static_cast<QStatusItem*>(cellWidget(row, 0)); QStatusItem* item_speed = static_cast<QStatusItem*>(cellWidget(row, 1)); QStatusItem* item_state = static_cast<QStatusItem*>(cellWidget(row, 2)); QStatusItem* item_battery = static_cast<QStatusItem*>(cellWidget(row, 3)); QStatusItem* item_satellite = static_cast<QStatusItem*>(cellWidget(row, 4)); QStatusItem* item_communication = static_cast<QStatusItem*>(cellWidget(row, 5)); if(item_id) { item_id->setContent(QString::number(id)); QString tooltip = "ID: " + QString::number(id) + "\n"; tooltip += "Speed: " + QString::number(status.speed) + "km/h" + "\n"; tooltip += "Fixed satellite: " + QString::number(status.sat) + "\n"; tooltip += "Last position: " + QString::number(status.coord.y()) + ", " + QString::number(status.coord.x()) + "\n"; tooltip += "Last point: " + status.datetime.toString("dd.MM.yyyy - hh:mm:ss"); item_id->setToolTip(tooltip); item_id->setStyleSheet("background: white; color: black;"); } else return; QString str; if(item_speed && status.speed > 0) { if(status.communication) { item_speed->setStyleSheet("color: green;"); str = tr("Last state: movement"); } else { item_speed->setStyleSheet("color: red;"); str = tr("Last state: movement (no communication)"); } item_speed->setContent(QString::number(status.speed) + "km/h"); } else if(item_speed) { item_speed->setContent(""); str = tr("Last state: stop"); } if(status.state && item_state) item_state->setContent(":/icons/icons/move.png"); else if(item_state) item_state->setContent(":/icons/icons/stop.png"); item_state->setToolTip(str); item_state->setStyleSheet("background: white;"); if(status.power < 10.0f && item_battery) item_battery->setContent(":/icons/icons/battery.png"); else if(item_battery) item_battery->setContent(""); if(status.sat == 0 && item_satellite) { item_satellite->setContent(":/icons/icons/satellite.png"); str = tr("No satellites"); } else if(item_satellite) { item_satellite->setContent(""); str = tr("Fixed: ") + QString::number(status.sat) + tr(" satellites"); } item_satellite->setToolTip(str); item_satellite->setStyleSheet("background: white;"); if(!status.communication && item_communication) { item_communication->setContent(":/icons/icons/disconnected.png"); str = tr("No connection\nLast point: ") + status.datetime.toString("dd.MM.yyyy - hh:mm:ss"); } else if(item_communication) { item_communication->setContent(""); str = tr("Last point: ") + status.datetime.toString("dd.MM.yyyy - hh:mm:ss"); } item_communication->setToolTip(str); item_communication->setStyleSheet("background: white;"); setRowHeight(row, item_state->width()); setColumnWidth(0, item_id->width()); setColumnWidth(1, item_speed->width()); setColumnWidth(2, item_state->width()); setColumnWidth(3, item_battery->width()); setColumnWidth(4, item_satellite->width()); setColumnWidth(5, item_communication->width());}
void QModelCars::addCar(int id, QStatusCars::status_t& status){ if(m_statuses.keys().contains(id)) return; int row = rowCount(); insertRow(row);}