2016-08-18 13 views
3

從我所看到的,任何基於Range的小部件的行爲都由Adjustements定義。有沒有官方的方式在GTK中創建離散值範圍構件?

由於似乎沒有官方的方法來將範圍限制爲幾個離散值,我嘗試了很多方法來實際重置值。

什麼是有效的,但不是最優的,只是取當前值,並確定哪個有效的離散值是最接近該連續值,並使用它。

但我想要的是直觀地將滑塊凍結到當前位置,直到用戶抓住足夠的距離,然後立刻將其值更改爲下一個有效值。

我希望用戶瞭解並感覺這些是離散值。上述工作解決方案的問題在於,測試該程序的3名用戶告訴我,我應該在顯示的數字中加入更多數字,並認爲這種變化是持續的。

注意:「官方」是指Adjustements類的「隱藏」選項或子類(如果可以的話)。如果不是這樣,那麼任何合理有效的方法都可以達到這樣的要求(即,對於簡單的滑塊,不要使用50%的CPU!)。特別是,我不要求爲「最好的方式」來做到這一點。

+0

確實[這](https://developer.gnome.org/gtk3/stable/ GtkScale.html#gtk-scale-add-mark)做你需要的嗎?我自己沒有用過,所以我不確定。 – andlabs

+0

嗯,這是一個很好的建議,但它混合了不好的表現和行爲。設想一個範圍從0到100的滑塊,每個整數值都有一個這樣的標記:這會很難看。 – JohnW

回答

4

看來你可以只覆蓋change-value信號:

class DiscreteScale(Gtk.Scale): 
    def __init__(self, values, *args, **kwargs): 
     super().__init__(*args, **kwargs) 

     values.sort() 
     self.values= values 

     adjustment= self.get_adjustment() 
     adjustment.set_lower(values[0]) 
     adjustment.set_upper(values[-1]) 

     self.__changed_value_id= self.connect('change-value', self.__change_value) 

    def __change_value(self, scale, scroll_type, value): 
     # find the closest valid value 
     value= self.__closest_value(value) 
     # emit a new signal with the new value 
     self.handler_block(self.__changed_value_id) 
     self.emit('change-value', scroll_type, value) 
     self.handler_unblock(self.__changed_value_id) 
     return True #prevent the signal from escalating 

    def __closest_value(self, value): 
     return min(self.values, key=lambda v:abs(value-v)) 

小演示:

w= Gtk.Window() 
s= DiscreteScale([0, 1, 5, 20, 22]) 
w.add(s) 
w.set_size_request(500, 50) 

w.connect('delete-event', Gtk.main_quit) 
w.show_all() 
Gtk.main() 
相關問題