2016-03-02 117 views
1

我已經爲執行一些幾何計算的腳本編寫了GUI。某些數值範圍會破壞計算(例如找到兩個不相交的形狀)。在這些情況下,我引發異常。我想阻止用戶調整spinbox值,超出引發異常的地步。如何防止QDoubleSpinBox更改值

我試着覆蓋QDoubleSpinBox的驗證方法。當我用鍵盤手動輸入數值時,這很好用。但是,這並不妨礙我點擊向上和向下的箭頭。

我該如何限制用戶在可接受範圍之外啓動數值的能力?

注意:實際的some_complicated_function涉及來自5個不同旋轉箱的值。

from PyQt4 import QtCore, QtGui 
import sys 

def some_complicated_function(val_a): 
    if val_a + 3 < 10: 
     return True 
    else: 
     raise Exception("Giant number!") 

class SpinBoxSpecial(QtGui.QDoubleSpinBox): 
    def validate(self, value, pos): 
#   print float(value) 
     try: 
      some_complicated_function(float(value)) 
      print "yup" 
      return QtGui.QValidator.Acceptable, QtGui.QValidator.Acceptable 
     except: 
      print "nope" 
      return QtGui.QValidator.Invalid, QtGui.QValidator.Invalid 

a = QtGui.QApplication(sys.argv)  
w = QtGui.QMainWindow() 
w.resize(320, 100) 
w.setWindowTitle("PyQT Python Widget!") 

spinbox = SpinBoxSpecial(w) 
spinbox.move(20, 20) 
spinbox.CorrectionMode = QtGui.QAbstractSpinBox.CorrectToPreviousValue 

w.show() 

sys.exit(a.exec_()) 

編輯: 的基本要求是:我要調用一個函數時(通過鼠標或鍵盤)一個紡紗器的值更改。如果該函數引發異常,我希望spinbox的值恢復到原來的值。

+0

[QDoubleSpinBox.setRange(http://doc.qt.io/qt-4.8/qdoublespinbox.html#setRange)。 – ekhumoro

+0

嗨@ekhumoro,我不想只設置範圍。範圍非常活躍。例如第一個紡紗箱的範圍可能是tan()和cos()和點產品的函數,以及來自其他紡紗箱的其他值的交叉產品。我可以重新實現這個邏輯,但是異常是從另一個我想要抽象的類生成的。 – BenB

+0

在這種情況下,您應該提供一個更實際的示例,以正確表示您嘗試解決的實際問題。 – ekhumoro

回答

1

這裏有一個簡單的方法來動態地設置在紡紗器的範圍:

class SpinBoxSpecial(QtGui.QDoubleSpinBox): 
    def __init__(self, parent=None): 
     super(SpinBoxSpecial, self).__init__(parent) 
     self._last = self.value() 
     self.valueChanged.connect(self.handleValueChanged) 

    def handleValueChanged(self, value): 
     try: 
      some_complicated_function(float(value)) 
      print "yup", value 
      self._last = value 
     except: 
      print "nope", value 
      if value > self._last: 
       self.setMaximum(self._last) 
      else: 
       self.setMinimum(self._last) 

編輯

剛剛意識到上面,如果值是直接輸入將無法正常工作,因爲它可能會過早修復最小/最大值。因此,也許這將是更好:

def handleValueChanged(self, value): 
     try: 
      some_complicated_function(float(value)) 
      print "yup", value 
      self._last = value 
     except: 
      print "nope", value 
      self.setValue(self._last) 
+0

接受編輯。設置最大值和最小值不是解決方案,因爲複雜的函數不一定是恆定的或線性的(例如,更改一個旋轉框的值可能會改變另一個旋轉框的可接受值)。但是,編輯可以做到這一點。 – BenB

+0

雖然如果有一種方法可以將點擊向上和向下箭頭的行爲綁定到更改文本的行爲上,那將會更受歡迎。 – BenB