Can't read custom type from QSettings
-
I am trying to read a small struct from my ini file using QSettings. Writing works fine, but when I try to read it back I always get the default value out of QVariant.
This is the structure definition:
struct CellSize { int font; int cell; }; inline QDataStream& operator<<(QDataStream& out, const CharTableView::CellSize& v) { out << v.font << v.cell; return out; } inline QDataStream& operator>>(QDataStream& in, CharTableView::CellSize& v) { int font, cell; in >> font >> cell; v.font = font; v.cell = cell; return in; } inline bool operator==(const CharTableView::CellSize& a, const CharTableView::CellSize& b) { return a.font == b.font && a.cell == b.cell; } Q_DECLARE_METATYPE(CharTableView::CellSize)
I am writing with
m_settings.setValue(Settings::TableCellSize, QVariant::fromValue<CharTableView::CellSize>(CharTableView::CellSizeSmall));
. I assume this is working fine because the gibberish inside the ini file is consistent with the UI changes. My reading code isCharTableView::CellSize tableCellSize = m_settings.value(Settings::TableCellSize).value<CharTableView::CellSize>();
and it always gives me {0, 0}.
I have tried to set some breakpoints and, basically, the first breakpoint that gets triggered is the one after I've read the value from QSettings, which is {0, 0} as always. Then after a while a breakpoint inside operator>> gets triggered and the values of font and cell inside the operator function are correct. What's happening? -
I solved the issue! I had to add
qRegisterMetaType<CharTableView::CellSize>()
inside CharTableView constructor.
However, the documentation wasn't really clear on that matter, as it stated thatQ_DECLARE_METATYPE()
is enough for QVariant and you only needqRegisterMetaType<T>()
to use custom types in signal-slot connections. The curious thing is that the data were actually being read correctly insideoperator>>
but, without the qRegisterMetaType<T>() magic, it happened only after the main window had already show up on screen. I wonder what was happening behind the scenes. -
Hi and welcome to devnet,
Might be a silly question but are you sure the file loaded is the correct one when you read it ?
Usually QSettings object are created within the method that will access them rather than as class members.
-
@SGaist Thank you very much for your answer! Yes, the file is correct and I have no issue reading other settings (basic C++ types). This is the only value that I can't read. I'm gonna try declaring QSettings inside the function and see what happens.
-
Try also inspecting the QVariant content using qDebug. You might want to implement the QDebug stream operator like you did for QDataStream.
-
I solved the issue! I had to add
qRegisterMetaType<CharTableView::CellSize>()
inside CharTableView constructor.
However, the documentation wasn't really clear on that matter, as it stated thatQ_DECLARE_METATYPE()
is enough for QVariant and you only needqRegisterMetaType<T>()
to use custom types in signal-slot connections. The curious thing is that the data were actually being read correctly insideoperator>>
but, without the qRegisterMetaType<T>() magic, it happened only after the main window had already show up on screen. I wonder what was happening behind the scenes. -
When you use custom types, it's pretty usual to register them all before building any of the widgets that will use them as part of your application startup sequence after you created your QApplication object.