Best practices: factoring code to create a custom slider
-
Hi. I've been working on a custom slider inheriting QLineEdit and using a specific slider in Blender for reference. Namely this one:
I started out by breaking down the different states and then putting down the logic in the three methods: mousePressEvent, mouseMoveEvent and mouseReleaseEvent. All of that is working great. I'm not sure if I can handle it cleaner, but if possible, I'd love to know.
This is my logic:def keyPressEvent(self, event): if event.key() == QtCore.Qt.Key_Return or event.key() == QtCore.Qt.Key_Enter: if self.inputMode: print('pressed enter in input mode, go to default mode and set inputMode to False') self.inputMode = False else: print('pressed enter in default mode, go to input mode') # if any other key pressed else: return super(CustomLineEdit, self).keyPressEvent(event) def mousePressEvent(self, event): if event.button() == QtCore.Qt.LeftButton: if not self.inputMode: print('go to select mode') if self.inputMode: print('stay in input mode') super().mousePressEvent(event) def mouseMoveEvent(self, event): if not self.inputMode: print('dragging the bar') self.dragMode = True if self.inputMode: print('dragging the text in input field') super().mouseMoveEvent(event) def mouseReleaseEvent(self, event): if event.button() == QtCore.Qt.LeftButton: if self.dragMode: print('go to default state') self.dragMode = False elif not self.dragMode and not self.inputMode: print('go to input mode') self.inputMode = True elif self.inputMode: super().mouseReleaseEvent(event)
My concern is how to deal with the stylesheets because there are three different ways the slider can look like. default_mode, select_mode and input_mode
First I put each style in a dictionary and initialized them in an init method. The problem is of course that it's run only once on startup and since I have variables that are used in the stylesheet to update the "progressbar", the bar doesn't increase or decrease as I move the slider.I have a few other ideas, but I'm looking into what would be the best approach from more experienced programmers.
I was thinking I could put the dictionary in an update method that I run before I'm calling the appropriate key for my stylesheet with setStyleSheet. Something like:self.update() self.setStyleSheet(self.stylesheets['default]['stylesheet'])
Thanks!
-
@Geuse
I don't know whether doing all this in aQLineEdit
is necessarily the best choice. Did you look at eitherQSlider
orQProgressBar
, perhaps subclassing and painted by you? However, let's assumeQLineEdit
is what you decide you want.Then what is your question/problem about stylesheet? If you need to change that according to what "mode" the slider is in then just call
setStyleSheet()
in your various...Event()
methods. -
@JonB hey thanks. Well I need an inputfield too, that's why I used this widget and found code to create this colored slider. But if there's an easier method, I'd love to know. I'm just a beginner.
My question about stylesheests is that I rather have the styles declared in one place so I can easily modify, then just call the appropriate style when setting the style sheets in my code for when it has to change. I'm just wondering about the best approach to do this.
-
I agree with @JonB that QLineEdit would not be my first choice. We have similar cases where we use a QStackedWidget with a QLineEdit and a slider to switch between the two. In other instances Qt will put an edit widget over the current widget (e.g. in table widgets). These would be the usual approached to solve this problem differently.
However, I would advice against using several stylesheets for your QLineEdit and switching between them. You can have a single stylesheet together with dynamic properties. Have a look at the documentation: https://doc.qt.io/qt-6/stylesheet-examples.html#customizing-using-dynamic-properties
Just use an enum for your different modes and check inside the stylesheet the value of your mode to do different styles.