C++ 내부 데이터 변경시 QML Viewer 업데이트
261
작성한 질문수 3
안녕하세요 강사님~
위젯에서 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에도 정상적으로 반영될 것입니다. 데이터 업데이트 로직을 확인하고 적절한 시점에 모델 변경 사항을 알리는 처리를 추가해보세요.
Build system의 Obs 에 관한 질문
1
29
2
로드맵 재수강 로드맵 할인문의
1
43
2
강의 재수강 문의
1
54
2
강의 연장 문의
1
79
2
강의 연장 질문
1
60
2
22강 후반부와 23강 전반부의 내용이 겹칩니다.
1
58
1
"ProgressBar"의 'indeterminate" 및 "value" 관계 문의드려요.
1
196
2
"Desaturate" 코드 오타일까요?
1
152
2
Qt5Compat.GraphicalEffects 비활성화 문제 문의
1
215
2
SquareButton 내 width/height가 필요한가요?
1
205
2
"focus: true"는 한 번만 선언해주면 되나요?
1
127
1
Qt Android Serial port
0
333
1
Qt 라이센스 문의
2
1629
1
기존에 작성된 Widget 화면을 재사용하는 방법이 있을까요?
1
327
1
Kit Selection에서 다음으로 넘어가지 않습니다.
1
268
1
우분투 22.04에서 6.2 버전 qtquick으로 프로젝트를 만들수가없습니다
2
1377
1
.pro rename 방법
0
322
1
Qt_Quick 수업자료
1
263
1
horizontalCenter에대해 질문 드립니다.
1
288
1
현재 강좌가 "QML 입문편"입니다. 후속 강좌가 있나요? ( 중/고급 )
1
355
1
VS Tools로 VS환경에서 QML을 개발할때 인텔리센스, 자동완성 기능
2
786
2
첨부파일 요청
1
549
1
qmlRegisterType을 매번 수동으로 입력해줘야 할까요?
1
572
1
Qt quick Application qmake빌드 오류
1
1416
2





