Qt 本身有提供 QDoubleSpinBox 這個元件(官網),可以提供使用者來輸入浮點數(小數),不過他基本上並不支援「科學記號」(科學記數法、Scientific notation、維基百科),所以如果要輸入極大的數字、或是相當接近 0 的小數時,都會相當麻煩。
查了一下,Qt 似乎沒有特別針對科學記號設計類似的元件,所以如果有這樣的需求,就得自己來了。
針對這個問題,網路上可以找到一些討論,也有一些實作,但是看起來好像都很複雜?
後來 Heresy 自己玩了一下,發現其實只要繼承 QDoubleSpinBox 並搭配 QDoubleValidator(官網)的話,其實可以相對簡單地建立出一個支援科學記號的版本。
下面這個 QScientificSpinBox,就是一個簡單的實作:
class QScientificSpinBox : public QDoubleSpinBox { public: virtual QString textFromValue(double value) const { return QString("%1").arg(value); } virtual QValidator::State validate(QString &text, int &pos) const { return m_Validator.validate(text, pos); } protected: QDoubleValidator m_Validator; };
基本上,就是多了一個用來驗證輸入數值是否符合標準的 QDoubleValidator,然後重新實作 textFromValue() 和 validate() 這兩個函式就可以了!而雖然說是重新實作,但是實際上也只是簡單地呼叫一些 Qt 提供的函式而已。
其中,textFromValue() 是把數值轉換成文字的方法,validate() 則是用來驗證使用者的輸入是否符合規範用的。
在顯示的時候,Qt 則是會根據數字,來選擇要呈現的形式;如果是 0.0001 就會直接顯示一般的數值,如果再小一點、變成 0.00001 的話,則是會被轉換成科學記號、以 1e-5 的形式來顯示。
如果希望修改顯示的方法的話,理論上就是去修改 textFromValue() 這個函式,自己去控制怎麼把 double 轉成 QString 了。