Qt C : статический список семейств шрифтов

#c #qt #static #initialization

#c #qt #статический #инициализация

Вопрос:

Возможно, это скорее общий вопрос программирования на C , чем специфичный для Qt. Проблема, с которой я сталкиваюсь, связана со статическими элементами и их инициализацией.

У меня есть класс табличной модели, который наследует QAbstractTableModel, и я хочу, чтобы у каждого был список всех семейств системных шрифтов, использующих QFontDatabase:: families(). Я пытаюсь сделать этот список семейств статичным, чтобы он заполнялся только один раз. Каков наилучший способ сделать это? У меня возникли проблемы с пониманием того, как инициализировать список, поскольку он статичен. Вот пример того, что я имею в виду:

 
class Model : public QAbstractTableModel
{
public:
    Model();
protected:
    static QStringList fontFamilies;
}

Model::Model() : QAbstractTableModel(0)
{
    fontFamilies = QFontDatabase().families();
}
  

Я думаю, что я не должен инициализировать в конструкторе (и я на самом деле не пробовал приведенный выше код, чтобы посмотреть, что скажет компилятор), но я не уверен, как подойти к этому. Я не думаю, что смогу сделать

 
QStringList Model::fontFamilies = QFontDatabase().families();

  

Спасибо, если вы можете оказать какую-либо помощь!

Ответ №1:

Нетривиальная инициализация статических переменных обычно проблематична. Функции, которые вы вызываете для инициализации, могут зависеть от ресурсов, которые еще не инициализированы на данный момент. И у вас нет контроля над порядком, какой статический файл инициализируется первым.

Использование конструктора — неплохая идея. Вам просто нужно убедиться, что вы инициализируете статику только один раз:

 Model::Model() : QAbstractTableModel(0)
{
    if(fontFamilies.isEmpty())
        fontFamilies = QFontDatabase().families();
}
  

Или вместо статической переменной-члена используйте функцию доступа со статическим local. Статический локальный файл будет выделен и инициализирован только при вызове функции. Скорее всего, это произойдет после инициализации библиотеки Qt:

 const QStringList amp; Model::fontFamilies()
{
    static QStringList fm = QFontDatabase().families();
    return fm;
}
  

Ответ №2:

Статический элемент данных должен быть определен вне класса.

 class Model : public QAbstractTableModel
{
public:
   Model();
protected:
    static QStringList fontFamilies;
}
QStringList Model::fontFamilies = QFontDatabase().families();
  

Это должно сработать

Комментарии:

1. Спасибо за ответ. У меня возникла проблема с этим — все компилируется нормально, но я получаю ошибку segfault при попытке запустить программу. У меня была такая же проблема ранее, и я думаю, что причина в том, что QApplication необходимо инициализировать, прежде чем можно будет инициализировать QFontDatabase, и поскольку это статично, это вызывает проблемы. Я предполагаю, что это не связанная проблема, но знаете ли вы что-нибудь об этом?

2. Что касается ошибки segfault, вы можете попробовать valgrind, если вы используете Linux. Это поможет вам очень быстро определить проблему.

3. Ошибка segfault, вероятно, вызвана неправильным порядком инициализации статики. Для QFontDatabase может потребоваться некоторый ресурс, который недоступен при выделении статики.