Platform Settings Dialog with Qt on Mac, Gnome, KDE, and Windows

On Mac and Gnome, native applications use the application settings dialog, which immediately applies the selected settings as they are selected. On Windows and (I think) KDE, preferences only apply when the Apply or OK button is clicked.

Is there any built-in Qt for this, or you need to add more #ifdefin the dialogue code to handle it ( Q_WS_WIN, Q_WS_MAC, Q_WS_X11)?

If you did something similar before (even using #ifdef), could you share the skeletal code about how you removed it?

+3
source share
2 answers

Sounds like you need to spin. These are the important parts of our decision. This can probably be generalized if someone is so inclined. I can also assume certain things due to our business rules that may violate other applications. A switch is a macro that can be determined at compile time:YOUR_APP_APPLY_PREFERENCES_IMMEDIATELY

preferences_dialog.h

class PreferencesDialog : public QDialog {
  Q_OBJECT

public:
  explicit PreferencesDialog(... various arguments ...,
                             QWidget *parent);
private slots:
  void ModifyMapLanguages();

private:
  void ApplyLanguageChanges(const QList<Language> &languages,
                            const QHash<LanguageKey, LanguageKey> &renames);
  void Initialize();

#ifndef YOUR_APP_APPLY_PREFERENCES_IMMEDIATELY
public slots:
  void accept();
private slots:
  void ApplyDialog();
private:
  QList<Language> pending_languages_;
  QHash<LanguageKey, LanguageKey> pending_language_renames_;
#endif
};

preferences_dialog.cpp

#include "forms/preferences_dialog.h"
#include "ui_preferences_dialog.h"

PreferencesDialog::PreferencesDialog(... various arguments ...,
                                     QWidget *parent) :
    QDialog(parent),
    ... various initializers ... {
  ui->setupUi(this);
  Initialize();
}

void PreferencesDialog::ApplyLanguageChanges(
    const QList<Language> &languages,
    const QHash<LanguageKey, LanguageKey> &renames) {
  // Do the actual changes here, whether immediate or postponed
}

void PreferencesDialog::Initialize() {
  // Disable the minimize and maximize buttons.
  Qt::WindowFlags flags = this->windowFlags();
  flags |= Qt::CustomizeWindowHint;
  flags &= ~Qt::WindowMinMaxButtonsHint;
  setWindowFlags(flags);

// buttons is the QDialogButtonBox with Ok, Cancel, and Apply buttons
#ifdef YOUR_APP_APPLY_PREFERENCES_IMMEDIATELY      
  ui->buttons->setVisible(false);
#else
  QPushButton *apply_button = ui->buttons->button(QDialogButtonBox::Apply);
  connect(apply_button, SIGNAL(clicked()), SLOT(ApplyDialog()));
#endif    
}

void PreferencesDialog::ModifyMapLanguages() {
  // Get the changes; in my case, they are coming from a dialog wizard
  LanguageSetupWizard wizard(map_->languages(), true, this);
  wizard.setWindowModality(Qt::WindowModal);
  if (QDialog::Accepted == wizard.exec()) {  
#ifdef YOUR_APP_APPLY_PREFERENCES_IMMEDIATELY
    ApplyLanguageChanges(wizard.languages(), wizard.language_renames());
#else
    pending_languages_ = wizard.languages();
    pending_language_renames_ = wizard.language_renames();
#endif
  }
}

#ifndef YOUR_APP_APPLY_PREFERENCES_IMMEDIATELY

void PreferencesDialog::ApplyDialog() {
  if (!pending_languages_.isEmpty()) {
    ApplyLanguageChanges(pending_languages_, pending_language_renames_);
  }
}

void PreferencesDialog::accept() {
  ApplyDialog();
  QDialog::accept();
}
#endif
0
source

QSettings is a cross-platform abstraction that can be used to preserve preferences, so hopefully this eliminates the use of#IFDEFs

I also found that it has really good performance. So good that I just installed an event listener and named save()for each individual event.

, :

def __init__(self, *args, **kwargs):
    # ....
    self.installEventFilter(self)
    # ....

def eventFilter(self, obj, event):
    self.save()
    return False

save() :

self.app.settings.setValue(self.state_key, self.header.saveState())
self.app.settings.setValue(self.geometry_key, self.header.saveGeometry())
self.app.settings.setValue("connect_timeout_spinBox_value", self.connect_timeout_spinBox.value())
self.app.settings.setValue("reveal_downloads_checkbox_checked", self.reveal_downloads_checkbox.checkState())

, , , , .

(-) , save() s , QSettings .

, / QSettings, . , / . , .

0

Source: https://habr.com/ru/post/1757827/


All Articles