Qt 6.12 LTS is out! See what's new in the release
blog
Blank space at the top of QScrollBar
-
Hello. I am creating some Qt Widgets from the application (without QT Creator form).
The full code:
from PySide6.QtWidgets import QScrollArea, QDialog, QComboBox, QLabel, QGroupBox, QCheckBox, QPushButton, QGridLayout, QVBoxLayout, QHBoxLayout, QSpacerItem, QSizePolicy, QFormLayout from PySide6.QtSerialPort import QSerialPortInfo, QSerialPort from PySide6.QtCore import Qt,QTimer,Signal from PySide6.QtGui import QFont, QIcon from dataclasses import dataclass @dataclass class SerialSettings: name: str baudRate: int stringBaudRate: str dataBits: int stringDataBits: str parity: int stringParity: str stopBits: int stringStopBits: str flowControl: int stringFlowControl: str class SettingsWindow(QDialog): settings_applied = Signal(str) # New signal to indicate the directory currently being downloaded def __init__(self, parent=None): super(SettingsWindow, self).__init__(parent) self.setWindowTitle("Settings") self.setModal(True) # This makes the dialog modal self.setWindowFlags(Qt.Dialog | Qt.WindowCloseButtonHint | Qt.FramelessWindowHint) # Layouts self.setFixedWidth(300) # Set the desired width in pixels self.mainLayout = QVBoxLayout(self) self.setLayout(self.mainLayout) self.createParameterBox() self.createSelectBox() self.createApplyButton() # Apply unified stylesheet self.setStyleSheet(self.getStyleSheet()) # Set font for the entire window font = QFont("Arial", 10) self.setFont(font) self.applyButton.clicked.connect(self.apply) self.closeButton.clicked.connect(self.reject) self.ui_serialPortInfoListBox.currentIndexChanged.connect(self.showPortInfo) self.fillPortsParameters() self.fillPortsInfo() self.updateSettings() def createParameterBox(self): self.parametersBox = QGroupBox("Select Parameters") self.parametersLayout = QFormLayout(self.parametersBox) self.ui_baudRateBox = QComboBox() self.ui_dataBitsBox = QComboBox() self.ui_parityBox = QComboBox() self.ui_stopBitsBox = QComboBox() self.ui_flowControlBox = QComboBox() self.parametersLayout.addRow(QLabel("BaudRate:"), self.ui_baudRateBox) self.parametersLayout.addRow(QLabel("Data bits:"), self.ui_dataBitsBox) self.parametersLayout.addRow(QLabel("Parity:"), self.ui_parityBox) self.parametersLayout.addRow(QLabel("Stop bits:"), self.ui_stopBitsBox) self.parametersLayout.addRow(QLabel("Flow control:"), self.ui_flowControlBox) self.mainLayout.addWidget(self.parametersBox) def createSelectBox(self): # Create the group box for serial port selection self.selectBox = QGroupBox("Select Serial Port") self.selectLayout = QFormLayout(self.selectBox) # Create UI components self.ui_serialPortInfoListBox = QComboBox(self) self.descriptionLabel = QLabel("Description:") self.manufacturerLabel = QLabel("Manufacturer:") self.serialNumberLabel = QLabel("Serial Number:") self.locationLabel = QLabel("Location:") self.vidLabel = QLabel("Vendor ID:") self.pidLabel = QLabel("Product ID:") # Add components to the form layout within the group box self.selectLayout.addRow(self.ui_serialPortInfoListBox) self.selectLayout.addRow(self.descriptionLabel) self.selectLayout.addRow(self.manufacturerLabel) self.selectLayout.addRow(self.serialNumberLabel) self.selectLayout.addRow(self.locationLabel) self.selectLayout.addRow(self.vidLabel) self.selectLayout.addRow(self.pidLabel) # Create a scroll area and set the group box as its widget self.scrollArea = QScrollArea(self) self.scrollArea.setWidgetResizable(True) # Allows resizing of the content self.scrollArea.setWidget(self.selectBox) # Set the group box as the content of the scroll area # Add the scroll area to the main layout instead of the group box directly self.mainLayout.addWidget(self.scrollArea) def createApplyButton(self): self.horizontalLayout = QHBoxLayout() self.applyButton = QPushButton("Apply") self.applyButton.setIcon(QIcon.fromTheme("dialog-ok-apply")) self.closeButton = QPushButton("Close") self.closeButton.setIcon(QIcon.fromTheme("dialog-close")) self.horizontalLayout.addWidget(self.applyButton) self.horizontalLayout.addWidget(self.closeButton) self.mainLayout.addLayout(self.horizontalLayout) def getStyleSheet(self): return """ QDialog { background-color: #242C34; color: #FFFFFF; } QGroupBox { background-color: #3B4252; border: 1px solid #4C566A; border-radius: 5px; margin-top: 20px; } QGroupBox::title { color: #FFFFFF; subcontrol-origin: margin; subcontrol-position: top center; padding: 10px; } QLabel { color: #D8DEE9; } QComboBox, QCheckBox, QPushButton { background-color: #8A9C97; color: #D8DEE9; border: 1px solid #5E81AC; border-radius: 3px; padding: 5px; } QPushButton { background-color: #8A9C97; padding: 10px; font-weight: bold; } QPushButton:hover { background-color: #8FA047; } QComboBox:hover { background-color: #8FA047; } QComboBox QAbstractItemView { background-color: #434C5E; selection-background-color: #81A1C1; color: white; } """ def showPortInfo(self, idx): if idx == -1: return data = self.ui_serialPortInfoListBox.itemData(idx) if data is None: self.descriptionLabel.setText("Description: N/A") self.manufacturerLabel.setText("Manufacturer: N/A") self.serialNumberLabel.setText("Serial Number: N/A") self.locationLabel.setText("Location: N/A") self.vidLabel.setText("Vendor ID: N/A") self.pidLabel.setText("Product ID: N/A") return self.descriptionLabel.setText(f"Description: {data[1]}") self.manufacturerLabel.setText(f"Manufacturer: {data[2]}") self.serialNumberLabel.setText(f"Serial Number: {data[3]}") self.locationLabel.setText(f"Location: {data[4]}") self.vidLabel.setText(f"Vendor ID: {data[5]}") self.pidLabel.setText(f"Product ID: {data[6]}") def apply(self): self.updateSettings() self.settings_applied.emit(self.m_currentSettings.name) self.accept() def fillPortsParameters(self): # Note that QSerialPort's baud rate constants are used here as item data. self.ui_baudRateBox.addItem("115200", QSerialPort.Baud115200) self.ui_baudRateBox.addItem("9600", QSerialPort.Baud9600) self.ui_baudRateBox.addItem("19200", QSerialPort.Baud19200) self.ui_baudRateBox.addItem("38400", QSerialPort.Baud38400) self.ui_baudRateBox.addItem("Custom", None) # This is for custom baud rate, assuming None is intentional self.ui_dataBitsBox.addItem("5", QSerialPort.Data5) self.ui_dataBitsBox.addItem("6", QSerialPort.Data6) self.ui_dataBitsBox.addItem("7", QSerialPort.Data7) self.ui_dataBitsBox.addItem("8", QSerialPort.Data8) self.ui_dataBitsBox.setCurrentIndex(3) self.ui_parityBox.addItem("None", QSerialPort.NoParity) self.ui_parityBox.addItem("Even", QSerialPort.EvenParity) self.ui_parityBox.addItem("Odd", QSerialPort.OddParity) self.ui_parityBox.addItem("Mark", QSerialPort.MarkParity) self.ui_parityBox.addItem("Space", QSerialPort.SpaceParity) self.ui_stopBitsBox.addItem("1", QSerialPort.OneStop) self.ui_stopBitsBox.addItem("2", QSerialPort.TwoStop) self.ui_flowControlBox.addItem("None", QSerialPort.NoFlowControl) self.ui_flowControlBox.addItem("RTS/CTS", QSerialPort.HardwareControl) self.ui_flowControlBox.addItem("XON/XOFF", QSerialPort.SoftwareControl) def fillPortsInfo(self): self.ui_serialPortInfoListBox.clear() infos = QSerialPortInfo.availablePorts() for info in infos: data = [ info.portName(), info.description(), info.manufacturer(), info.serialNumber(), info.systemLocation(), hex(info.vendorIdentifier()) if info.vendorIdentifier() else "N/A", hex(info.productIdentifier()) if info.productIdentifier() else "N/A", ] self.ui_serialPortInfoListBox.addItem(data[0], data) self.ui_serialPortInfoListBox.addItem("Custom", None) def updateSettings(self): current_index = self.ui_baudRateBox.currentIndex() baudRate = int(self.ui_baudRateBox.currentText()) if current_index == 4 else self.ui_baudRateBox.itemData(current_index) self.m_currentSettings = SerialSettings( name=self.ui_serialPortInfoListBox.currentText(), baudRate=baudRate, stringBaudRate=self.ui_baudRateBox.currentText(), dataBits=self.ui_dataBitsBox.currentData(), stringDataBits=self.ui_dataBitsBox.currentText(), parity=self.ui_parityBox.currentData(), stringParity=self.ui_parityBox.currentText(), stopBits=self.ui_stopBitsBox.currentData(), stringStopBits=self.ui_stopBitsBox.currentText(), flowControl=self.ui_flowControlBox.currentData(), stringFlowControl=self.ui_flowControlBox.currentText(), ) def settings(self): return self.m_currentSettingsIt creates the following window:

I am really frustrated that there is this blank space out there for no reason and I cannot find a way to get rid of it. I would appreciate if someone could help me out here! I use PySide6
-
Ahh I figured. This was due to:
QGroupBox { background-color: #3B4252; border: 1px solid #4C566A; border-radius: 5px; margin-top:20px; }margin-top:20px; cause this issue
-
S SGaist moved this topic from General and Desktop on
-
S SGaist has marked this topic as solved on