2010-08-03 47 views
3

在Mac和Gnome上,本地應用程序使用應用程序首選項對話框,可以在選擇設置時立即應用所選設置。在Windows和(我認爲)KDE上,僅當按下「應用」或「確定」按鈕時才應用首選項。在Mac,Gnome,KDE和Windows上使用Qt的平臺本機首選項對話框

是否有內置的Qt好吃的東西爲你做這個,或者你必須包括在對話框代碼的幾個#ifdef的來處理這個(Q_WS_WINQ_WS_MACQ_WS_X11)?

如果你以前做過這樣的事情(即使使用#ifdef's),你能分享一些骨架代碼嗎?

回答

0

看起來像你必須旋轉自己的。以下是我們解決方案的重要部分。如果有人這麼傾向,這可能會泛化。由於我們的業務規則可能會破壞其他應用程序,因此我也可以假設某些事情。肘節是可在編譯時定義宏: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

QSettings是跨平臺的抽象可以用於保存偏好,所以希望避免使用#IFDEFs

我也發現它有非常好的表現。實際上,這很好,我剛剛安裝了一個事件監聽器,並在每個事件中調用了save()

窗體類包含一個事件過濾器是這樣的:

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中保存/恢復它的每個屬性也是整潔的。如果你有幾十個/數百個偏好,這可能是合適的。我完成後會回到這裏。

相關問題