@@ -0,0 +1,117 @@ | |||||
#include "customgraphics.h" | |||||
#include <QPainter> | |||||
#include <QGraphicsSceneMouseEvent> | |||||
#include <QMenu> | |||||
#include <QGraphicsScene> | |||||
// HmiComponent 基类实现 | |||||
HmiComponent::HmiComponent(QGraphicsItem *parent) : QGraphicsObject(parent) | |||||
{ | |||||
setFlag(QGraphicsItem::ItemIsMovable, true); | |||||
setFlag(QGraphicsItem::ItemIsSelectable, true); | |||||
setAcceptHoverEvents(true); | |||||
} | |||||
void HmiComponent::setColor(const QColor& color) { | |||||
if (m_color != color) { | |||||
m_color = color; | |||||
update(); | |||||
} | |||||
} | |||||
QColor HmiComponent::color() const { | |||||
return m_color; | |||||
} | |||||
void HmiComponent::setComponentName(const QString& name) { | |||||
m_componentName = name; | |||||
} | |||||
QString HmiComponent::componentName() const { | |||||
return m_componentName; | |||||
} | |||||
void HmiComponent::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) | |||||
{ | |||||
Q_UNUSED(option); | |||||
Q_UNUSED(widget); | |||||
painter->setRenderHint(QPainter::Antialiasing); | |||||
paintShape(painter); | |||||
if (isSelected()) { | |||||
painter->setBrush(Qt::NoBrush); | |||||
painter->setPen(QPen(Qt::darkRed, 2, Qt::DashLine)); | |||||
painter->drawRect(boundingRect()); | |||||
} | |||||
} | |||||
void HmiComponent::mousePressEvent(QGraphicsSceneMouseEvent *event) | |||||
{ | |||||
// 右键不触发选中信号,留给 contextMenuEvent 处理 | |||||
if (event->button() == Qt::LeftButton) { | |||||
emit selected(this); | |||||
} | |||||
QGraphicsObject::mousePressEvent(event); | |||||
} | |||||
// 实现 contextMenuEvent | |||||
void HmiComponent::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) | |||||
{ | |||||
// 右键点击时,先清空场景中的其他选中项,然后选中当前项 | |||||
scene()->clearSelection(); | |||||
setSelected(true); | |||||
emit selected(this); // 同样可以发出选中信号,以便更新属性面板等 | |||||
QMenu menu; | |||||
QAction *copyAction = menu.addAction("复制"); | |||||
QAction *deleteAction = menu.addAction("删除"); | |||||
// 使用 connect 将菜单动作的触发连接到信号的发射,“复制”和“删除” | |||||
connect(copyAction, &QAction::triggered, this, [this]() { | |||||
emit copyRequested(this); | |||||
}); | |||||
connect(deleteAction, &QAction::triggered, this, [this]() { | |||||
emit deleteRequested(this); | |||||
}); | |||||
// 在鼠标光标位置显示菜单 | |||||
menu.exec(event->screenPos()); | |||||
} | |||||
// HmiButton 类实现 | |||||
HmiButton::HmiButton(QGraphicsItem *parent) : HmiComponent(parent) { | |||||
m_color = Qt::gray; | |||||
m_componentName = "Button"; | |||||
} | |||||
QRectF HmiButton::boundingRect() const { | |||||
return QRectF(0, 0, 80, 30); | |||||
} | |||||
void HmiButton::paintShape(QPainter *painter) { | |||||
painter->setPen(Qt::NoPen); | |||||
painter->setBrush(m_color); | |||||
painter->drawRect(boundingRect()); | |||||
} | |||||
// HmiIndicator 类实现 | |||||
HmiIndicator::HmiIndicator(QGraphicsItem *parent) : HmiComponent(parent) { | |||||
m_color = Qt::green; | |||||
m_componentName = "Indicator"; | |||||
} | |||||
QRectF HmiIndicator::boundingRect() const { | |||||
return QRectF(0, 0, 30, 30); | |||||
} | |||||
void HmiIndicator::paintShape(QPainter *painter) { | |||||
painter->setPen(Qt::NoPen); | |||||
painter->setBrush(m_color); | |||||
painter->drawEllipse(boundingRect()); | |||||
} |
@@ -0,0 +1,72 @@ | |||||
#ifndef CUSTOMGRAPHICS_H | |||||
#define CUSTOMGRAPHICS_H | |||||
#include <QGraphicsObject> | |||||
// 只需要前向声明,因为头文件中只用到了指针 | |||||
class QPainter; | |||||
class QGraphicsSceneMouseEvent; | |||||
class QGraphicsSceneContextMenuEvent; | |||||
enum class ComponentType { | |||||
Button, | |||||
Indicator | |||||
}; | |||||
// HMI组件基类 | |||||
class HmiComponent : public QGraphicsObject | |||||
{ | |||||
Q_OBJECT | |||||
Q_PROPERTY(QColor color READ color WRITE setColor) | |||||
Q_PROPERTY(QString componentName READ componentName WRITE setComponentName) | |||||
signals: | |||||
void selected(HmiComponent* item); | |||||
// 为复制和删除请求添加信号 | |||||
void copyRequested(HmiComponent* item); | |||||
void deleteRequested(HmiComponent* item); | |||||
public: | |||||
explicit HmiComponent(QGraphicsItem *parent = nullptr); | |||||
void setColor(const QColor& color); | |||||
QColor color() const; | |||||
void setComponentName(const QString& name); | |||||
QString componentName() const; | |||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; | |||||
protected: | |||||
void mousePressEvent(QGraphicsSceneMouseEvent *event) override; | |||||
// 重写上下文菜单事件 | |||||
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override; | |||||
virtual void paintShape(QPainter* painter) = 0; | |||||
protected: | |||||
QColor m_color; | |||||
QString m_componentName; | |||||
}; | |||||
// 按钮类 | |||||
class HmiButton : public HmiComponent | |||||
{ | |||||
public: | |||||
HmiButton(QGraphicsItem *parent = nullptr); | |||||
QRectF boundingRect() const override; | |||||
protected: | |||||
void paintShape(QPainter *painter) override; | |||||
}; | |||||
// 指示灯类 | |||||
class HmiIndicator : public HmiComponent | |||||
{ | |||||
public: | |||||
HmiIndicator(QGraphicsItem *parent = nullptr); | |||||
QRectF boundingRect() const override; | |||||
protected: | |||||
void paintShape(QPainter *painter) override; | |||||
}; | |||||
#endif // CUSTOMGRAPHICS_H |
@@ -0,0 +1,148 @@ | |||||
#include "customgraphicsscene.h" | |||||
#include <QGraphicsSceneMouseEvent> | |||||
#include <QGraphicsView> | |||||
#include <QKeyEvent> | |||||
#include <QGuiApplication> | |||||
#include <QMenu> | |||||
// 实现新的构造函数 | |||||
CustomGraphicsScene::CustomGraphicsScene(QGraphicsView* view, QObject *parent) | |||||
: QGraphicsScene(parent), m_mode(Normal), m_view(view) | |||||
{ | |||||
// 断言确保传入的 view 是有效的 | |||||
Q_ASSERT(m_view); | |||||
} | |||||
void CustomGraphicsScene::setMode(Mode mode) | |||||
{ | |||||
if (m_mode == mode) return; | |||||
m_mode = mode; | |||||
// 根据模式设置光标 | |||||
if (m_mode == CreateItem) { | |||||
m_view->setCursor(Qt::CrossCursor); | |||||
} else { | |||||
m_view->setCursor(Qt::ArrowCursor); // 恢复为标准箭头光标 | |||||
} | |||||
} | |||||
// setComponentTypeToCreate 函数无需改动 | |||||
void CustomGraphicsScene::setComponentTypeToCreate(ComponentType type) | |||||
{ | |||||
m_componentTypeToCreate = type; | |||||
} | |||||
// mousePressEvent 函数无需改动 | |||||
void CustomGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) | |||||
{ | |||||
if (mouseEvent->button() != Qt::LeftButton) { | |||||
QGraphicsScene::mousePressEvent(mouseEvent); | |||||
return; | |||||
} | |||||
if (m_mode == CreateItem) { | |||||
HmiComponent* item = nullptr; | |||||
switch (m_componentTypeToCreate) { | |||||
case ComponentType::Button: | |||||
item = new HmiButton(); | |||||
break; | |||||
case ComponentType::Indicator: | |||||
item = new HmiIndicator(); | |||||
break; | |||||
} | |||||
if (item) | |||||
{ | |||||
item->setPos(mouseEvent->scenePos()); | |||||
if (item->scene() == nullptr) | |||||
{ | |||||
addItem(item); | |||||
emit componentCreated(item); | |||||
} | |||||
else | |||||
{ | |||||
// 如果 item 已经被添加到场景中,则删除它,避免内存泄漏 | |||||
delete item; | |||||
} | |||||
} | |||||
setMode(Normal); | |||||
} else { | |||||
QGraphicsScene::mousePressEvent(mouseEvent); | |||||
} | |||||
} | |||||
// mouseMoveEvent 函数无需改动 | |||||
void CustomGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) | |||||
{ | |||||
QGraphicsScene::mouseMoveEvent(mouseEvent); | |||||
} | |||||
// 修改或新增 keyPressEvent | |||||
void CustomGraphicsScene::keyPressEvent(QKeyEvent *keyEvent) | |||||
{ | |||||
// 退出创建模式 | |||||
if (keyEvent->key() == Qt::Key_Escape && m_mode == CreateItem) { | |||||
setMode(Normal); | |||||
keyEvent->accept(); | |||||
return; | |||||
} | |||||
// 处理删除、复制、粘贴 | |||||
if (selectedItems().isEmpty()) { | |||||
QGraphicsScene::keyPressEvent(keyEvent); | |||||
return; | |||||
} | |||||
switch (keyEvent->key()) { | |||||
case Qt::Key_Delete: | |||||
emit deleteRequestFromScene(); | |||||
keyEvent->accept(); | |||||
break; | |||||
case Qt::Key_C: | |||||
if (keyEvent->modifiers() & Qt::ControlModifier) { | |||||
emit copyRequestFromScene(); | |||||
keyEvent->accept(); | |||||
} | |||||
break; | |||||
case Qt::Key_V: | |||||
if (keyEvent->modifiers() & Qt::ControlModifier) { | |||||
// 获取最后一个鼠标事件的位置来确定粘贴位置 | |||||
emit pasteRequestFromScene(views().first()->mapToScene(views().first()->mapFromGlobal(QCursor::pos()))); | |||||
keyEvent->accept(); | |||||
} | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
QGraphicsScene::keyPressEvent(keyEvent); | |||||
} | |||||
void CustomGraphicsScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *contextMenuEvent) | |||||
{ | |||||
// 检查鼠标下方是否有图形项 | |||||
QGraphicsItem *item = itemAt(contextMenuEvent->scenePos(), views().first()->transform()); | |||||
if (!item) { | |||||
// 如果点击在空白处,则显示我们的粘贴菜单 | |||||
contextMenuEvent->accept(); | |||||
QMenu menu; | |||||
QAction *pasteAction = menu.addAction("粘贴"); | |||||
// 将菜单动作连接到场景的粘贴请求信号 | |||||
connect(pasteAction, &QAction::triggered, this, [this, contextMenuEvent]() { | |||||
emit pasteRequestFromScene(contextMenuEvent->scenePos()); | |||||
}); | |||||
menu.exec(contextMenuEvent->screenPos()); | |||||
} else { | |||||
// 如果点击在图形项上,则将事件传递给该图形项处理 | |||||
// (这会调用 HmiComponent::contextMenuEvent) | |||||
QGraphicsScene::contextMenuEvent(contextMenuEvent); | |||||
} | |||||
} |
@@ -0,0 +1,46 @@ | |||||
#ifndef CUSTOMGRAPHICSSCENE_H | |||||
#define CUSTOMGRAPHICSSCENE_H | |||||
#include <QGraphicsScene> | |||||
#include "customgraphics.h" | |||||
class QGraphicsSceneMouseEvent; | |||||
class QGraphicsSceneContextMenuEvent; | |||||
class QGraphicsView; | |||||
class QKeyEvent; | |||||
class CustomGraphicsScene : public QGraphicsScene | |||||
{ | |||||
Q_OBJECT | |||||
public: | |||||
enum Mode { Normal, CreateItem }; | |||||
explicit CustomGraphicsScene(QGraphicsView* view, QObject *parent = nullptr); | |||||
void setMode(Mode mode); | |||||
void setComponentTypeToCreate(ComponentType type); | |||||
signals: | |||||
void componentCreated(HmiComponent* item); | |||||
// 转发键盘操作请求 | |||||
void copyRequestFromScene(); | |||||
void pasteRequestFromScene(const QPointF& scenePos); // 传递粘贴位置 | |||||
void deleteRequestFromScene(); | |||||
protected: | |||||
void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) override; | |||||
// 在这里添加下面这行代码 | |||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) override; | |||||
void keyPressEvent(QKeyEvent *keyEvent) override; | |||||
void contextMenuEvent(QGraphicsSceneContextMenuEvent *contextMenuEvent) override; | |||||
private: | |||||
Mode m_mode; | |||||
ComponentType m_componentTypeToCreate; | |||||
QGraphicsView* m_view; | |||||
}; | |||||
#endif // CUSTOMGRAPHICSSCENE_H |
@@ -0,0 +1,154 @@ | |||||
#include "hmimodule.h" | |||||
#include <QGraphicsScene> | |||||
#include <QGraphicsView> // --- 确保包含 QGraphicsView 头文件 --- | |||||
#include <QDateTime> | |||||
// HMIModule 构造函数无需改动 | |||||
HMIModule::HMIModule(Ui::MainWindow* ui, QObject *parent) | |||||
: QObject{parent}, ui_(ui), m_scene(nullptr) | |||||
{} | |||||
// 封装设置图标和大小的通用函数 | |||||
void HMIModule::setButtonIcon(QAbstractButton *button, const QString &iconPath) | |||||
{ | |||||
button->setIcon(QIcon(iconPath)); | |||||
button->setIconSize(QSize(30, 30)); | |||||
} | |||||
void HMIModule::init() { | |||||
setButtonIcon(ui_->button, ":/resource/image/button.png"); | |||||
setButtonIcon(ui_->lamp, ":/resource/image/lamp.png"); | |||||
setButtonIcon(ui_->addPage, ":/resource/image/add.png"); | |||||
setButtonIcon(ui_->deletePage, ":/resource/image/delete.png"); | |||||
setButtonIcon(ui_->prePage, ":/resource/image/pre.png"); | |||||
setButtonIcon(ui_->nextPage, ":/resource/image/next.png"); | |||||
if (!ui_->hmiGraphicsView->scene()) { | |||||
// 创建场景时,将 view 指针传入 | |||||
m_scene = new CustomGraphicsScene(ui_->hmiGraphicsView, this); | |||||
m_scene->setSceneRect(0, 0, 800, 600); | |||||
ui_->hmiGraphicsView->setScene(m_scene); | |||||
} else { | |||||
m_scene = qobject_cast<CustomGraphicsScene*>(ui_->hmiGraphicsView->scene()); | |||||
Q_ASSERT(m_scene); | |||||
} | |||||
connect(ui_->button, &QPushButton::clicked, this, &HMIModule::prepareToCreateButton); | |||||
connect(ui_->lamp, &QPushButton::clicked, this, &HMIModule::prepareToCreateIndicator); | |||||
connect(m_scene, &CustomGraphicsScene::componentCreated, this, &HMIModule::onComponentCreated); | |||||
// 连接来自场景的键盘事件信号 | |||||
connect(m_scene, &CustomGraphicsScene::copyRequestFromScene, this, &HMIModule::onCopyRequested); | |||||
connect(m_scene, &CustomGraphicsScene::pasteRequestFromScene, this, &HMIModule::onPasteRequested); | |||||
connect(m_scene, &CustomGraphicsScene::deleteRequestFromScene, this, &HMIModule::onDeleteRequested); | |||||
} | |||||
// 辅助函数,用于设置新创建的组件 | |||||
void HMIModule::setupNewComponent(HmiComponent* item) | |||||
{ | |||||
if (!item) return; | |||||
// 连接所有需要的信号 | |||||
connect(item, &HmiComponent::selected, this, &HMIModule::onComponentSelected); | |||||
connect(item, &HmiComponent::copyRequested, this, &HMIModule::onCopyRequested); | |||||
connect(item, &HmiComponent::deleteRequested, this, &HMIModule::onDeleteRequested); | |||||
// 生成日志 | |||||
QString currentTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); | |||||
QString log = QString("[%1] 创建 %2 组件") | |||||
.arg(currentTime) | |||||
.arg(item->componentName()); | |||||
emit logMessageGenerated(log); | |||||
} | |||||
// 准备创建按钮的槽函数 | |||||
void HMIModule::prepareToCreateButton() | |||||
{ | |||||
m_scene->setComponentTypeToCreate(ComponentType::Button); | |||||
m_scene->setMode(CustomGraphicsScene::Mode::CreateItem); | |||||
} | |||||
// 准备创建指示灯的槽函数 | |||||
void HMIModule::prepareToCreateIndicator() | |||||
{ | |||||
m_scene->setComponentTypeToCreate(ComponentType::Indicator); | |||||
m_scene->setMode(CustomGraphicsScene::Mode::CreateItem); | |||||
} | |||||
// 处理新创建组件的槽函数 | |||||
void HMIModule::onComponentCreated(HmiComponent* item) | |||||
{ | |||||
setupNewComponent(item); | |||||
} | |||||
void HMIModule::onCopyRequested() | |||||
{ | |||||
QList<QGraphicsItem*> selected = m_scene->selectedItems(); | |||||
if (selected.isEmpty()) return; | |||||
// 只复制第一个选中的项目 | |||||
HmiComponent* itemToCopy = qgraphicsitem_cast<HmiComponent*>(selected.first()); | |||||
if (!itemToCopy) return; | |||||
// 存储组件信息到 "剪贴板" | |||||
if (dynamic_cast<HmiButton*>(itemToCopy)) { | |||||
m_copiedType = ComponentType::Button; | |||||
} else if (dynamic_cast<HmiIndicator*>(itemToCopy)) { | |||||
m_copiedType = ComponentType::Indicator; | |||||
} | |||||
m_copiedColor = itemToCopy->color(); | |||||
m_hasCopiedItem = true; | |||||
// 日志 | |||||
emit logMessageGenerated(QString("[%1] 复制组件: %2") | |||||
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) | |||||
.arg(itemToCopy->componentName())); | |||||
} | |||||
void HMIModule::onPasteRequested(const QPointF& scenePos) | |||||
{ | |||||
if (!m_hasCopiedItem) return; | |||||
HmiComponent* newItem = nullptr; | |||||
if (m_copiedType == ComponentType::Button) { | |||||
newItem = new HmiButton(); | |||||
} else { | |||||
newItem = new HmiIndicator(); | |||||
} | |||||
if (newItem) { | |||||
newItem->setColor(m_copiedColor); | |||||
// 为了避免完全重叠,给一个小的偏移量 | |||||
newItem->setPos(scenePos + QPointF(10, 10)); | |||||
// 使用辅助函数完成添加和信号连接 | |||||
// 注意:setupNewComponent内部会再次生成“创建”日志,这里是合理的 | |||||
setupNewComponent(newItem); | |||||
} | |||||
} | |||||
void HMIModule::onDeleteRequested() | |||||
{ | |||||
QList<QGraphicsItem*> selected = m_scene->selectedItems(); | |||||
if (selected.isEmpty()) return; | |||||
// 日志 | |||||
emit logMessageGenerated(QString("[%1] 删除 %2 个组件") | |||||
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) | |||||
.arg(selected.count())); | |||||
// 从后往前删,避免迭代器失效问题 | |||||
for (int i = selected.count() - 1; i >= 0; --i) { | |||||
QGraphicsItem* item = selected.at(i); | |||||
m_scene->removeItem(item); | |||||
delete item; // 释放内存 | |||||
} | |||||
} | |||||
// 统一处理选中事件的槽函数,无需修改 | |||||
void HMIModule::onComponentSelected(HmiComponent* item) | |||||
{ | |||||
// if (item) { | |||||
// qDebug() << "Component selected:" << item->componentName() | |||||
// << "Color:" << item->color(); | |||||
// // 未来可以在这里将item对象传递给属性编辑器 | |||||
// } | |||||
} |
@@ -0,0 +1,49 @@ | |||||
#ifndef HMIMODULE_H | |||||
#define HMIMODULE_H | |||||
#include <QObject> | |||||
#include "ui_MainWindow.h" | |||||
// #include "customgraphics.h" // 已被 customgraphicsscene.h 包含 | |||||
#include "customgraphicsscene.h" // 引入新的场景头文件 | |||||
class HMIModule : public QObject | |||||
{ | |||||
Q_OBJECT | |||||
public: | |||||
explicit HMIModule(Ui::MainWindow* ui, QObject *parent = nullptr); | |||||
void setButtonIcon(QAbstractButton* button, const QString& iconPath); | |||||
void init(); | |||||
private slots: | |||||
// 准备创建组件,而不是直接创建 | |||||
void prepareToCreateButton(); | |||||
void prepareToCreateIndicator(); | |||||
// 当场景创建了一个组件后,进行后续处理 | |||||
void onComponentCreated(HmiComponent* item); | |||||
void onComponentSelected(HmiComponent* item); | |||||
// 处理复制、粘贴、删除的槽函数 | |||||
void onCopyRequested(); | |||||
void onPasteRequested(const QPointF& scenePos); | |||||
void onDeleteRequested(); | |||||
// 一个用于发送日志消息的信号 | |||||
signals: | |||||
void logMessageGenerated(const QString& message); | |||||
private: | |||||
void setupNewComponent(HmiComponent* item); | |||||
private: | |||||
Ui::MainWindow* ui_; | |||||
CustomGraphicsScene* m_scene; | |||||
// 用于实现剪贴板功能的成员变量 | |||||
ComponentType m_copiedType; | |||||
QColor m_copiedColor; | |||||
bool m_hasCopiedItem = false; | |||||
}; | |||||
#endif // HMIMODULE_H |
@@ -0,0 +1,36 @@ | |||||
#include "mainwindow.h" | |||||
#include <QToolBar> | |||||
#include <QToolButton> | |||||
#include <QVBoxLayout> | |||||
#include <QButtonGroup> | |||||
MainWindow::MainWindow(QWidget *parent) | |||||
: QMainWindow(parent) | |||||
, ui_(new Ui::MainWindow) | |||||
{ | |||||
ui_->setupUi(this); | |||||
hmi_ = new HMIModule(ui_, this); | |||||
hmi_->init(); | |||||
initMainWindow(); | |||||
// 连接 HMIModule 的信号到 MainWindow 的槽 | |||||
connect(hmi_, &HMIModule::logMessageGenerated, this, &MainWindow::appendLog); | |||||
} | |||||
MainWindow::~MainWindow() | |||||
{ | |||||
delete ui_; | |||||
} | |||||
void MainWindow::initMainWindow() | |||||
{ | |||||
setWindowTitle("综合平台编辑器"); | |||||
setWindowIcon(QIcon(":/resource/image/editor.png")); | |||||
} | |||||
// 实现槽函数 | |||||
void MainWindow::appendLog(const QString& message) | |||||
{ | |||||
ui_->textEdit->append(message); | |||||
} |
@@ -0,0 +1,32 @@ | |||||
#ifndef MAINWINDOW_H | |||||
#define MAINWINDOW_H | |||||
#include <QMainWindow> | |||||
#include "hmimodule.h" | |||||
QT_BEGIN_NAMESPACE | |||||
namespace Ui { | |||||
class MainWindow; | |||||
} | |||||
QT_END_NAMESPACE | |||||
class MainWindow : public QMainWindow | |||||
{ | |||||
Q_OBJECT | |||||
public: | |||||
MainWindow(QWidget *parent = nullptr); | |||||
~MainWindow(); | |||||
private: | |||||
void initMainWindow(); | |||||
// 一个用于接收日志并更新UI的槽函数 | |||||
private slots: | |||||
void appendLog(const QString& message); | |||||
private: | |||||
Ui::MainWindow *ui_; | |||||
HMIModule* hmi_; | |||||
}; | |||||
#endif // MAINWINDOW_H |