작성
·
130
0
안녕하세요 강사님~
위젯에서 QML로 갈아타면서 나이가 들어서 그런지 손에 익숙해지는데 시간이 걸리네요 ㅜ
다름이 아니라 C++로직에서 처리된 내용을 효율적으로 QML VIewer를 업데이트 하는 방안을 고민하고 있습니다.
예를 들어서
로직 내부에는 N개의 센서를 오브젝트로 관리하여 특정 주기로 센서의 객체를 업데이트하고 있습니다.
저희는 로직에서 관리하는 N개 센서 오브젝트를 AbstractiveListModel를 상속받아 모델 클래스를 하나 구현하여 센서 오브젝트의 포이터를 리스트로 관리하고 있습니다.
그리고 QML Viewer에서는 이 모델을 이용하여 그리드로 표현하고 해당 그리드 셀은 센서의 여러 정보를 출력해주고 있습니다.
내부적으로 데이터는 업데이트가 되고 있는데 그리드에 그려진 여러 셀들의 정보는 변하지 않습니다.
화면을 전환하여 다시 그리드 화면이 다시 그려질 때만 데이터가 변경이 되네요.
글로 충분히 전달이 될지 몰라서 모델 코드와 QML 코드를 같이 보내드립니다.
[ fr_model_device.cpp ]
#include "fr_model_device.h"
#include <QDebug>
FR_Model_Device::FR_Model_Device(QObject *parent)
: QAbstractListModel(parent)
{
}
int FR_Model_Device::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_data.size();
}
QVariant FR_Model_Device::data(const QModelIndex &index, int role) const
{
if (index.isValid() && index.row() >= 0 && index.row() < m_data.size()) {
FR_Device_TreeItem *dev = m_data[index.row()];
switch(role)
{
case DevInfo_Name:
return dev->m_devInfo.m_sDevName;
case DevInfo_Serial:
return dev->m_devInfo.m_sSerialNo;
case DevInfo_Index:
return dev->m_devInfo.m_nDevNo;
case DevInfo_Event:
return dev->m_devInfo.m_nCur_Event;
case DevInfo_Limit_1:
return dev->m_devInfo.m_event_limit_lv1;
case DevInfo_Limit_2:
return dev->m_devInfo.m_event_limit_lv2;
case DevInfo_InputLock:
return dev->m_devInfo.m_nInputLock;
case DevInfo_OutputLock:
return dev->m_devInfo.m_nOutputLock;
}
}
return {};
}
QHash<int, QByteArray> FR_Model_Device::roleNames() const
{
static QHash<int, QByteArray> roles;
roles[DevInfo_Name] = "name";
roles[DevInfo_Serial] = "serial";
roles[DevInfo_Index] = "index";
roles[DevInfo_Event] = "event";
roles[DevInfo_Limit_1] = "limit_1";
roles[DevInfo_Limit_2] = "limit_2";
roles[DevInfo_InputLock] = "inputLock";
roles[DevInfo_OutputLock] = "outputLock";
return roles;
}
void FR_Model_Device::slot_SetDeviceList(QList<FR_Device_TreeItem *> devList)
{
m_data = devList;
}
// 방안을 찾다가 이 부분도 추가해 보았는데 업데이트가 되질 않네요.
void FR_Model_Device::slot_DataChanged()
{
QModelIndex topLeft = index( 0, 0 );
QModelIndex bottomRight = index(this->rowCount()-1, 1);
emit dataChanged( topLeft, bottomRight );
}
[Qml]
import QtQuick 2.15
import QtQuick.Controls 2.15
Rectangle{
id: screen3
anchors.fill: parent
// color: "blue"
Image {
id: backgroundImage
anchors.fill: screen3
source: "qrc:/content/image/stockWallpaper.jpg"
}
GridView {
id: gridView
anchors.fill: parent
anchors {
left: parent.left
right: parent.right
top: parent.top
bottom: parent.bottom
margins: 10
}
model: Fr3000_Controller.modelForCurDev
cellHeight: 150
cellWidth: 150
delegate: Rectangle{
id: grid_item
width: 130
height: 130
color: "lightgray"
radius: 5
Rectangle {
width: 120
height: 120
anchors.centerIn: grid_item
color: "gray"
radius: 5
Text{
font.pixelSize: 10
font.bold: true
color: "white"
text: "[Name]: " + name + "\n" +
"[Serial]: " + serial + "\n" +
"[DevNo]: " + index + "\n" +
"[Event]: " + event + "\n" +
"[Limit_1]: " + limit_1 + "\n" +
"[Limit_2]: " + limit_2 + "\n" +
"[InputLock]: " + inputLock + "\n" +
"[OutputLock]: " + outputLock
}
MouseArea {
anchors.fill: parent
onClicked: console.log("Clicked Device")
}
}
}
}
}
끝까지 읽어주셔서
감사합니다.
답변 1
0
안녕하세요, 인프런 AI 인턴입니다.
주영대감님, QML Viewer와 C++ 데이터의 동기화 문제로 보이네요. 데이터가 업데이트된 후 QML 그리드 뷰에 반영되지 않는 문제는 일반적으로 두 가지 이유에서 발생할 수 있습니다.
첫째, slot_SetDeviceList
함수에서 데이터 리스트를 업데이트할 때 기존 데이터와 새 데이터 간의 변경 사항을 뷰에 알리는 처리가 누락된 경우입니다. 모델의 데이터를 새로운 리스트로 업데이트하고 밖으로 알릴 때에는 beginResetModel()
과 endResetModel()
을 호출하여 뷰에게 모델이 전면적으로 변경되었음을 알려야 합니다. 예를 들어, slot_SetDeviceList(QList<FR_Device_TreeItem *> devList)
함수 내에 다음과 같이 수정할 수 있습니다.
void FR_Model_Device::slot_SetDeviceList(QList<FR_Device_TreeItem *> devList)
{
beginResetModel();
m_data = devList;
endResetModel();
}
둘째, 뷰에 바로 변경 사항을 반영하기 위해선 모델의 데이터 변경을 알리는 dataChanged()
시그널을 올바르게 호출해야 합니다. slot_DataChanged()
함수에서 dataChanged()
시그널을 발생시키는 부분은 잘 작성되었으나, 이 함수가 적절하게 호출되고 있는지 확인해보세요. 만약 센서 데이터가 업데이트될 때마다 slot_DataChanged()
가 호출되지 않는다면, 데이터가 변경될 때 이 함수를 호출하는 로직을 추가해주세요.
이렇게 모델의 변경 사항을 적절히 뷰에 알리면, C++ 내의 데이터 업데이트가 QML Viewer에도 정상적으로 반영될 것입니다. 데이터 업데이트 로직을 확인하고 적절한 시점에 모델 변경 사항을 알리는 처리를 추가해보세요.