1010 QHBoxLayout ,
1111 QWidget ,
1212 QStyle ,
13+ QProxyStyle ,
1314 QToolTip ,
1415 QStyleOptionSlider ,
1516)
16- from AnyQt .QtCore import Qt , QRect
17- from AnyQt .QtGui import QPainter , QFontMetrics
17+ from AnyQt .QtCore import Qt , QRect , pyqtSignal as Signal
18+ from AnyQt .QtGui import QPainter , QFontMetrics , QPalette
1819
1920from Orange .widgets import gui
2021from Orange .widgets .settings import ContextSetting
3031
3132
3233class ScoringSheetTable (QTableWidget ):
34+ state_changed = Signal (int )
35+
3336 def __init__ (self , main_widget , parent = None ):
3437 """
3538 Initialize the ScoringSheetTable.
@@ -87,7 +90,44 @@ def handle_item_changed(self, item):
8790 It updates the slider value depending on the collected points.
8891 """
8992 if item .column () == 2 :
90- self .main_widget ._update_slider_value ()
93+ self .state_changed .emit (item .row ())
94+
95+
96+ class CustomSliderStyle (QProxyStyle ):
97+ """
98+ A custom slider handle style.
99+
100+ It draws a 2px wide black rectangle to replace the default handle.
101+ This is done to suggest to the user that the slider is not interactive.
102+ """
103+
104+ def drawComplexControl (self , cc , opt , painter , widget = None ):
105+ if cc != QStyle .CC_Slider :
106+ super ().drawComplexControl (cc , opt , painter , widget )
107+ return
108+
109+ # Make a copy of the style option and remove the handle subcontrol.
110+ slider_opt = QStyleOptionSlider (opt )
111+ slider_opt .subControls &= ~ QStyle .SC_SliderHandle
112+ super ().drawComplexControl (cc , slider_opt , painter , widget )
113+
114+ # Get the rectangle for the slider handle.
115+ handle_rect = self .subControlRect (cc , opt , QStyle .SC_SliderHandle , widget )
116+
117+ # Draw a simple 2px wide black rectangle as the custom handle.
118+ painter .save ()
119+ painter .setPen (Qt .NoPen )
120+ painter .setBrush (QPalette ().color (QPalette .WindowText ))
121+ h = handle_rect .height ()
122+ painter .drawRoundedRect (
123+ QRect (
124+ handle_rect .center ().x () - 2 , handle_rect .y () + int (0.2 * h ),
125+ 4 , int (0.6 * h )
126+ ),
127+ 3 ,
128+ 3 ,
129+ )
130+ painter .restore ()
91131
92132
93133class RiskSlider (QWidget ):
@@ -103,12 +143,13 @@ def __init__(self, points, probabilities, parent=None):
103143 self .layout .setContentsMargins (
104144 self .leftMargin , self .topMargin , self .rightMargin , self .bottomMargin
105145 )
146+ self .setMouseTracking (True )
106147
107148 # Setup the labels
108149 self .setup_labels ()
109150
110- # Create the slider
111151 self .slider = QSlider (Qt .Horizontal , self )
152+ self .slider .setStyle (CustomSliderStyle ())
112153 self .slider .setEnabled (False )
113154 self .layout .addWidget (self .slider )
114155
@@ -267,7 +308,8 @@ def handle_hover_event(self, pos):
267308 probability = self .probabilities [value ]
268309 tooltip = str (
269310 f"<b>{ self .target_class } </b>\n "
270- f"<hr style='margin: 0px; padding: 0px; border: 0px; height: 1px; background-color: #000000'>"
311+ "<hr style='margin: 0px; padding: 0px; border: 0px; "
312+ "height: 1px; background-color: #000000'>"
271313 f"<b>Points:</b> { int (points )} <br>"
272314 f"<b>Probability:</b> { probability :.1f} %"
273315 )
@@ -366,6 +408,7 @@ def _setup_gui(self):
366408
367409 self .coefficient_table = ScoringSheetTable (main_widget = self , parent = self )
368410 gui .widgetBox (self .mainArea ).layout ().addWidget (self .coefficient_table )
411+ self .coefficient_table .state_changed .connect (self ._update_slider_value )
369412
370413 self .risk_slider = RiskSlider ([], [], self )
371414 gui .widgetBox (self .mainArea ).layout ().addWidget (self .risk_slider )
0 commit comments