pyapp-kit / superqt

Missing widgets and components for Qt-python
https://pyapp-kit.github.io/superqt/
BSD 3-Clause "New" or "Revised" License
209 stars 37 forks source link

Adding Multi-range slider to Main Window in PyQt5 application #35

Open ShirinNajdi opened 3 years ago

ShirinNajdi commented 3 years ago

Hi,

I am trying to add multi-range slider as a widget to the MainWindow of an application. When I run the demo_widget.py everything is alright. However if I try to add multi-range slider to a frame or layout in my MainWindow, it looks like that the style is changed and I just see one slider and nothing else.

Would you please let me know how should I solve it?

tlambert03 commented 3 years ago

Hi @ShirinNajdi, can you please paste your code here just to make sure we're addressing your exact issue?

ShirinNajdi commented 3 years ago

Thanks for the reply. yes, I am providing you an example of what I am trying to do. In the output as you may see, the slider is in the left side with only one slider and a different style! I created the mainWindow with Designer and I'm trying to add the multi-range slider in my Python script.

    import sys
    from superqt import QRangeSlider
    from PyQt5 import QtWidgets, QtCore, QtGui

    class Ui_mainWindow(object):
        def setupUi(self, mainWindow):
            mainWindow.setObjectName("mainWindow")
            mainWindow.resize(1360, 750)
            sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
            sizePolicy.setHorizontalStretch(1)
            sizePolicy.setVerticalStretch(1)
            sizePolicy.setHeightForWidth(mainWindow.sizePolicy().hasHeightForWidth())
            mainWindow.setSizePolicy(sizePolicy)
            mainWindow.setMinimumSize(QtCore.QSize(1360, 750))
            mainWindow.setMaximumSize(QtCore.QSize(1360, 771))
            self.centralwidget = QtWidgets.QWidget(mainWindow)
            sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
            sizePolicy.setHorizontalStretch(0)
            sizePolicy.setVerticalStretch(0)
            sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth())
            self.centralwidget.setSizePolicy(sizePolicy)
            self.centralwidget.setMinimumSize(QtCore.QSize(1360, 750))
            self.centralwidget.setMaximumSize(QtCore.QSize(1360, 750))
            self.centralwidget.setObjectName("centralwidget")
            self.frame = QtWidgets.QFrame(self.centralwidget)
            self.frame.setGeometry(QtCore.QRect(0, 0, 1600, 950))
            self.frame.setMinimumSize(QtCore.QSize(1600, 950))
            self.frame.setMaximumSize(QtCore.QSize(1600, 950))
            self.frame.setStyleSheet("background-color: rgb(232, 241, 248);")
            self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
            self.frame.setFrameShadow(QtWidgets.QFrame.Sunken)
            self.frame.setObjectName("frame")

    class MainWindow(QtWidgets.QMainWindow, Ui_mainWindow):
        def __init__(self, parent=None):
            super(MainWindow, self).__init__(parent)
            self.setupUi(self)

            self.slider = QRangeSlider()
            self.slider.setMinimum(0)
            self.slider.setMaximum(200)
            self.slider.setValue((0, 40, 80, 160))
            # self.slider.setGeometry(500, 200, 50, 200)
            layout = QtWidgets.QVBoxLayout(self.frame)
            layout.setContentsMargins(0, 0, 0, 0)
            layout.addWidget(self.slider)

    if __name__ == "__main__":
        app = QtWidgets.QApplication(sys.argv)
        myGUI = MainWindow()
        myGUI.showMaximized()
        myGUI.show()

        sys.exit(app.exec_())
tlambert03 commented 3 years ago

thanks for the example... you need to give a layout to your central widget. (you've added a frame to the central_widgt, and a layout to the frame, but no layout to the central widget.) . here's a an example of a main window, with a central widget that has a frame, and that frame has a slider:

from superqt import QRangeSlider
from superqt.qtcompat import QtWidgets, QtCore

class Window(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        central = QtWidgets.QWidget()
        frame = QtWidgets.QFrame()
        frame.setLayout(QtWidgets.QVBoxLayout())
        central.setLayout(QtWidgets.QVBoxLayout())
        central.layout().addWidget(frame)

        self.slider = QRangeSlider(QtCore.Qt.Horizontal)
        self.slider.setMinimum(0)
        self.slider.setMaximum(200)
        self.slider.setValue((0, 40, 80, 160))

        frame.layout().addWidget(self.slider)
        self.setCentralWidget(central)

if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    myGUI = Window()
    myGUI.show()
    app.exec_()

in general, it looks like you could benefit from using layouts as opposed setting sizes manually: have a look at the layout docs here: https://doc.qt.io/qt-5/layout.html

ShirinNajdi commented 3 years ago

I adapted your code to my original program and strangely it happened again! Then I noticed that in my original program, I add background colour to the frame. When I added the same line of the code to your code, the style of the slider changed again. Please test this code and let me know your idea.

from superqt import QRangeSlider
from superqt.qtcompat import QtWidgets, QtCore

class Window(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        central = QtWidgets.QWidget()
        frame = QtWidgets.QFrame()
        frame.setLayout(QtWidgets.QVBoxLayout())
        frame.setStyleSheet("background-color: rgb(232, 241, 248)")
        central.setLayout(QtWidgets.QVBoxLayout())
        central.layout().addWidget(frame)

        self.slider = QRangeSlider(QtCore.Qt.Horizontal)
        self.slider.setMinimum(0)
        self.slider.setMaximum(200)
        self.slider.setValue((0, 40, 80, 160))

        frame.layout().addWidget(self.slider)
        self.setCentralWidget(central)

if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    myGUI = Window()
    myGUI.show()
    app.exec_()

By the way thanks for the tips and the link about the layouts.

tlambert03 commented 3 years ago

ah! yes I can repeat it now, thanks. let me see what I can figure out.

ShirinNajdi commented 3 years ago

Hi, are there any updates regarding this issue?

tlambert03 commented 3 years ago

nope sorry, this is essentially a bug. superqt uses stylesheets to color in the "bar" on sliders, I haven't yet figured out why that's conflicting with the background-color stylesheet that you're using in your example. and I'm afraid i won't be able to get to it in the next week or two

ShirinNajdi commented 3 years ago

nope sorry, this is essentially a bug. superqt uses stylesheets to color in the "bar" on sliders, I haven't yet figured out why that's conflicting with the background-color stylesheet that you're using in your example. and I'm afraid i won't be able to get to it in the next week or two

Thanks for the reply. I understand. Meanwhile I am still working with it and will update you if I get any hint about the cause.

IsolatedSushi2 commented 2 years ago

I'm also having this issue, is there any progress yet?

Gaalee commented 2 years ago

Hi, i found a "fix" with the example used in this post. Add QFrame when setting up the StyleSheet and it work.

frame.setStyleSheet("QFrame {background-color: rgb(0, 0, 0);}")