一、前言
地图按钮很常见,这也是用户给钱就干的一个模块。设备现场提供了对应的地图文件,其实就是图片文件,做的简单点就是直接CAD图纸转成jpg,做的精致点就是搞了3D风格的立体样式图片,其实还是图片,并不是真正的3D,看起来像是3D的感觉。很多人看到效果图都来问这个3D怎么实现的,真正的3D实现都非常复杂,需要懂opengl,网页上用的是webgl,当然也有不少的轮子可以直接使用。
地图按钮就是一个终端传感器作为一个按钮点,分布在对应的图片文件上,其实就是父类设置为label,label显示对应的图片。图片大小的算法,目前采用的当前分辨率计算,当前分辨率减去上下左右的尺寸就是图片应该的尺寸,拉伸填充显示,所以要求用户提供的图片最好按照现场电脑的分辨率比例来设置,这样不会显得拉伸变形,后期这一块需要改进算法,难点就是按钮在设置界面的相对位置不好计算,除非是绘制上去的。
地图按钮几个特色功能:
- 从内存中而不是文件取图片显示,响应速度微秒级别。
- 报警自动切换到对应的地图。
- 不同状态不同颜色显示,报警红色或者黄色闪烁。
- 按钮位置在编辑状态下,任意拖动,自动保存。
- 提供缩略图导航,可手动切换。
- 在线状态显示对应的值和单位符号,离线状态显示位置编号。
二、功能特点
2.1 软件模块
2.2 基础功能
2.3 特色功能
三、体验地址
四、效果图
五、相关代码
void DeviceHelper::initDeviceButton(QLabel *label){ if (labMap == NULL) { return; } //先清空原来的 bool isMain = (labMap == label); if (isMain) { qDeleteAll(btns); btns.clear(); } else { qDeleteAll(btns2); btns2.clear(); } for (int i = 0; i setButtonStyle(DeviceButton::ButtonStyle_Msg2); btn->resize(AppData::DeviceWidth, AppData::DeviceHeight); btn->setText(QString(“%1”).arg(DbData::NodeInfo_PositionID.at(i))); btn->setButtonColor(isMain ? DeviceButton::ButtonColor_Black : DeviceButton::ButtonColor_Green); btn->setCanMove(!isMain); //设置弱属性 btn->setProperty(“nodeID”, DbData::NodeInfo_NodeID.at(i)); btn->setProperty(“positionID”, DbData::NodeInfo_PositionID.at(i)); btn->setProperty(“deviceName”, DbData::NodeInfo_DeviceName.at(i)); btn->setProperty(“nodeName”, DbData::NodeInfo_NodeName.at(i)); btn->setProperty(“nodeAddr”, DbData::NodeInfo_NodeAddr.at(i)); btn->setProperty(“nodeType”, DbData::NodeInfo_NodeType.at(i)); btn->setProperty(“nodeSign”, DbData::NodeInfo_NodeSign.at(i)); btn->setProperty(“nodeImage”, DbData::NodeInfo_NodeImage.at(i)); //设置位置 int x = DbData::NodeInfo_NodeX.at(i); int y = DbData::NodeInfo_NodeY.at(i); btn->move(x, y); if (isMain) { btns << btn; QObject::connect(btn, SIGNAL(doubleClicked()), AppEvent::Instance(), SLOT(slot_doubleClicked())); } else { btns2 height(); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); //绘制背景图 QImage img(imgName); if (!img.isNull()) { img = img.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); painter.drawImage(0, 0, img); } //计算字体 QFont font; font.setPixelSize(height * 0.37); font.setBold(true); //自动计算文字绘制区域,绘制防区号 QRectF rect = this->rect(); if (buttonStyle == ButtonStyle_Police) { double y = (30 * height / 60); rect = QRectF(0, y, width, height – y); } else if (buttonStyle == ButtonStyle_Bubble) { double y = (8 * height / 60); rect = QRectF(0, 0, width, height – y); } else if (buttonStyle == ButtonStyle_Bubble2) { double y = (13 * height / 60); rect = QRectF(0, 0, width, height – y); font.setPixelSize(width * 0.33); } else if (buttonStyle == ButtonStyle_Msg) { double y = (17 * height / 60); rect = QRectF(0, 0, width, height – y); } else if (buttonStyle == ButtonStyle_Msg2) { double y = (17 * height / 60); rect = QRectF(0, 0, width, height – y); } //绘制文字标识 painter.setFont(font); painter.setPen(Qt::white); painter.drawText(rect, Qt::AlignCenter, text);}bool DeviceButton::eventFilter(QObject *watched, QEvent *event){ //识别鼠标 按下+移动+松开+双击 等事件 QMouseEvent *mouseEvent = static_cast(event); if (event->type() == QEvent::MouseButtonPress) { //限定鼠标左键 if (mouseEvent->button() == Qt::LeftButton) { lastPoint = mouseEvent->pos(); isPressed = true; emit clicked(); return true; } } else if (event->type() == QEvent::MouseMove) { //允许拖动并且鼠标按下准备拖动 if (canMove && isPressed) { int dx = mouseEvent->pos().x() – lastPoint.x(); int dy = mouseEvent->pos().y() – lastPoint.y(); this->move(this->x() + dx, this->y() + dy); return true; } } else if (event->type() == QEvent::MouseButtonRelease) { isPressed = false; } else if (event->type() == QEvent::MouseButtonDblClick) { emit doubleClicked(); } return QWidget::eventFilter(watched, event);}