c++qtsettingsprecision

Qt - Set global precision for all tables and models in a program


I will preface this question by mentioning I'm honestly not even sure what I'm trying to do is possible. I've worked with Qt for a while now and never tried to do anything like this, and I've found next to nothing online about how to accomplish my goal, so it may well not be something that Qt can do. I figured it still couldn't hurt to ask in case I'm overlooking something.

I am working on a very large project (~200 files/classes in all) in Qt Creator 3.0.1 (based on Qt 5.2.1). Within this program we have a lot of tables that display numeric data, using probably a dozen or so different model classes fr different tables.

Today my project lead requested that a feature be added to our settings (which we store using the QSettings class) to allow our users to set the decimal precision of any numeric data that is displayed in a table anywhere in the program. I know how to do this using std::setPrecision() and calling QSettings::value().toInt() to get the stored precision. However, it seems like that would have to be done explicitly every time a value is returned by a Model class's data() function, which would literally mean adding that function call hundreds of different places in our code. This seems extremely bulky and tedious, and also very prone to causing bugs, since with so many places in the code that would need it, it would be very easy to accidentally overlook places where it should be used. Also, this would be rather tedious in the future if we end up adding new dialogs with table displays and new models, since those new ones would also need that function called every time a number is needed.

It seems like a very simple, efficient, and elegant way to solve this issue would be if Qt had a way to store a global precision for not just one dialog or one model class, but for the entire project. That way, instead of needing to use setPrecision() every time a number is displayed in a dialog, the program would already know how many places after the decimal to show. It seems like using this as some kind of meta-variable for the program as a whole would save tons of time and effort changing everything over now and adding things in the future. However like I said above, I do not know if it is even possible in Qt to specify for a whole program something like precision in display dialogs. If anyone has any ideas how to do something like this, or any other way to specify precision in models without needing to refer to precision each time a value is added to a display, I'd really appreciate any help. Thanks!


Solution

  • Your models should not care about the format of displayed data. What you can do is to inherit from QStyledItemDelegate and override displayText method.

    The method can look something like:

    QString BaseItemDelegate::displayText(const QVariant &value, 
                                          const QLocale &locale) const
    {
        if (value.type() == QVariant::Double) {
            //here you can retrieve precision of displayed double 
            //from some settings object
            return QLocale().toString(value.toDouble(), 'f', 2);
        }
    
        return QStyledItemDelegate::displayText(value, locale);
    }
    

    Then you can attach this delegate to your views (QAbstractItemView::setItemDelegate()). Of course you must make your models to return double instead of preformatted strings.