Skip to content

Qt for Python

For discussion and questions about Qt for Python (PySide & Shiboken)

3.3k Topics 14.4k Posts
QtWS25 Last Chance
  • 1 Votes
    2 Posts
    304 Views
    @KevinAR said in How to Use Custom Fonts from Folder in PyQt6 Instead of Installed Fonts in Windows: But the font is not successfully applied in the GUI. But both screenshots look different? I also do not see any QFont constructor which takes path to a font file as first parameter. I think you have to use https://doc.qt.io/qt-6/qfontdatabase.html#addApplicationFont
  • 0 Votes
    10 Posts
    752 Views
    @TT-MS Ah, it's a feature! Thanks for the info, that helps!
  • QTreeView

    Solved 29 Oct 2024, 15:57
    0 Votes
    2 Posts
    158 Views
    Hi, To the best of my knowledge, no. The headers are populated by the model and are usually independent of the data. As for the number of columns, there's no restriction. Your model is responsible for returning the appropriate number.
  • This topic is deleted!

    Unsolved 29 Oct 2024, 15:34
    0 Votes
    1 Posts
    1 Views
    No one has replied
  • 0 Votes
    7 Posts
    281 Views
    That is very kind of you. You can get it from here [https://github.com/lerocha/chinook-database]. I see they have a MySql version which would have saved me a small amount of work but I got mine included in a book I bought to learn PyQt. I'm working under Linux so you should have no problems in that regard. Apart from the code that I posted before all you need is the connection and the various imports as follows from PySide6.QtWidgets import (QApplication, QMainWindow, QWidget, QTableView, QMessageBox, QVBoxLayout, QHBoxLayout, QLineEdit, QComboBox, QLabel,QPushButton, QDataWidgetMapper, QFormLayout, QSpinBox) from PySide6.QtCore import Qt, QSize, Signal from PySide6.QtGui import * from PySide6.QtSql import (QSqlDatabase, QSqlTableModel, QSqlRelation, QSqlRelationalTableModel, QSqlRelationalDelegate, QSqlQuery, QSqlQueryModel) import os import sys Good luck & thanks once again for your interest in this.
  • 0 Votes
    5 Posts
    265 Views
    @SGaist Yes it worked, instead of if source == combobox.view().viewport(): I replaced it with: if source == combobox.view(): And installed the filter both on the view and the viewport: combobox.view().viewport().installEventFilter(self) combobox.view().installEventFilter(self)
  • setting QMessage IconPixmap to the PyQt built-in icons

    Moved Unsolved 25 Oct 2024, 05:12
    0 Votes
    13 Posts
    901 Views
    @explorer100 Indeed, and fixed.
  • 1 Votes
    5 Posts
    471 Views
    It looks exactly like the bug reported there and it says it was fixed. I think we are ok to use Pyside6 without the addons for now. Everything works and I do not think we are missing any functionality. I reported it here as it looks like a bug and I thought it should have been reported and addressed in the future releases of PySide. Using option A is not an option for us. we have an old pipeline with hundreds of .ui files dynamically loaded all over the place. It is also a very convenient way to build interfaces and I'm not sure why anyone would want to add an extra step and generate the python classes manually.
  • 1 Votes
    3 Posts
    1k Views
    its only available in Linux based environment and not in windows
  • Layouting Issue with QScrollBar

    Solved 2 Jan 2024, 15:17
    0 Votes
    2 Posts
    325 Views
    Hi I managed to replicate the GooglePhotos ScrollBar with the following code snippet. Sadly I wasn't able to get the position of the handle of the scrollbar using any of the available methods offered by Qt. I ended up calculating the position myself in python and then moving the widget to the associated position. That is to say. None of the Methods like subControlRect() provided me with any information about the handle of the scrollbar. They always returned a QSomething() (Like QRect or QPoint) which was empty. That's why I ended up computing the position in python using the QPixelMetric, which was the only thing I could access in python. Here's the code snippet that ended up working for me: import math import sys from PyQt6.QtCore import Qt from PyQt6.QtGui import QPixmapCache from PyQt6.QtWidgets import ( QApplication, QLabel, QWidget, QMainWindow, QScrollBar, QHBoxLayout, QTextEdit, QGridLayout, QPushButton, QSlider, QStyle ) class RootWindow(QMainWindow): def __init__(self): super().__init__() self.sc = QScrollBar(Qt.Orientation.Vertical) self.dummy_widget = QWidget() self.dummy_widget.setMinimumWidth(100) self.dummy_widget.setMinimumHeight(500) self.placeholder = QWidget() self.placeholder_layout = QGridLayout() self.placeholder_layout.setSpacing(10) self.placeholder.setLayout(self.placeholder_layout) self.placeholder_layout.setContentsMargins(0, 0, 0, 0) self.style_sheet_input = QTextEdit() self.submit_btn = QPushButton("Submit") self.submit_btn.clicked.connect(self.set_style_sheet) self.scroll_max = QSlider(Qt.Orientation.Horizontal) self.scroll_max.valueChanged.connect(self.max_set) self.scroll_max.setMaximum(1000) self.scroll_max.setMinimum(50) self.page_size = QSlider(Qt.Orientation.Horizontal) self.page_size.valueChanged.connect(self.page_set) self.page_size.setMaximum(50) self.page_size.setMinimum(10) self.do_shit_btn = QPushButton("Do-Shit") self.do_shit_btn.clicked.connect(self.do_shit) self.placeholder_layout.addWidget(self.style_sheet_input, 0, 0, 1, 4) self.placeholder_layout.addWidget(self.submit_btn, 1, 2) self.placeholder_layout.addWidget(self.scroll_max, 1, 0) self.placeholder_layout.addWidget(self.page_size, 1, 1) self.placeholder_layout.addWidget(self.do_shit_btn, 1, 3) # self.sc = QScrollBar(Qt.Orientation.Horizontal) self.sc.setMaximum(20) self.sc.valueChanged.connect(self.value_reader) self.sc.sliderReleased.connect(self.hide_indicator) self.sc.sliderPressed.connect(self.show_indicator) self.l = QHBoxLayout() self.l.setContentsMargins(10, 10, 10, 10) self.l.setSpacing(10) # self.l = QVBoxLayout() self.dummy_widget.setLayout(self.l) self.l.addWidget(self.placeholder) self.l.addWidget(self.sc) self.setCentralWidget(self.dummy_widget) # Spacing self.upper_pad = QLabel("", self) self.upper_pad.setVisible(False) self.upper_pad.setStyleSheet("QLabel {background: rgba(255, 128, 0, 128);}") self.lower_pad = QLabel("", self) self.lower_pad.setVisible(False) self.lower_pad.setStyleSheet("QLabel {background: rgba(255, 128, 0, 128);}") # Arrows self.upper_arrow = QLabel("", self) self.upper_arrow.setVisible(False) self.upper_arrow.setStyleSheet("QLabel {background: rgba(128, 255, 0, 128);}") self.lower_arrow = QLabel("", self) self.lower_arrow.setVisible(False) self.lower_arrow.setStyleSheet("QLabel {background: rgba(128, 255, 0, 128);}") # Page self.upper_page = QLabel("", self) self.upper_page.setVisible(False) self.upper_page.setStyleSheet("QLabel {background: rgba(0, 255, 128, 128);}") self.lower_page = QLabel("", self) self.lower_page.setVisible(False) self.lower_page.setStyleSheet("QLabel {background: rgba(0, 255, 128, 128);}") # Scrollbar self.scrollbar = QLabel("", self) self.scrollbar.setVisible(False) self.scrollbar.setStyleSheet("QLabel {background: rgba(0, 128, 255, 128);}") self.indicator = QLabel("Indicator", self) self.indicator.setStyleSheet("QLabel {background: red;}") self.indicator.setVisible(True) self.indicator.setAlignment(Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter) self.indicator.setFixedHeight(26) self.indicator.setFixedWidth(100) def do_shit(self, *args, **kwargs): """ Function shows all overlays for debugging purposes (i.e. take a screenshot to make sure the calculations in python are correct """ print(f"Args {args}") print(f"Kwargs {kwargs}") self.indicator.setVisible(True) self.upper_pad.setVisible(True) self.lower_pad.setVisible(True) self.upper_arrow.setVisible(True) self.lower_arrow.setVisible(True) self.upper_page.setVisible(True) self.lower_page.setVisible(True) self.scrollbar.setVisible(True) def max_set(self, v: int): self.sc.setMaximum(v) self.sc.setValue(0) print(f"Max: {v}") def page_set(self, v: int): self.sc.setPageStep(v) self.sc.setValue(0) print(f"Page: {v}") def set_style_sheet(self): style_sheet = self.style_sheet_input.toPlainText() print(style_sheet) self.sc.setStyleSheet(style_sheet) def show_indicator(self): self.indicator.setVisible(True) self.upper_pad.setVisible(True) self.lower_pad.setVisible(True) self.upper_arrow.setVisible(True) self.lower_arrow.setVisible(True) self.upper_page.setVisible(True) self.lower_page.setVisible(True) self.scrollbar.setVisible(True) self.value_reader() def hide_indicator(self): self.indicator.setVisible(False) self.upper_pad.setVisible(False) self.lower_pad.setVisible(False) self.upper_arrow.setVisible(False) self.lower_arrow.setVisible(False) self.upper_page.setVisible(False) self.lower_page.setVisible(False) self.scrollbar.setVisible(False) def value_reader(self): """ This function is an implementation in python to get the QScrollBar().subControlRect() of the handle of the scrollbar. It then moves a QLabel to the position of the scrollbar such that the middle of the scrollbar and the middle of QLabel are on the same y-coordinate. Sadly, I couldn't find a way to make this work using the methods of Qt. Last I checked, subControlRect returns an empty QRect() for the Scrollbar handle. """ print(f"Scrollbar Size:", self.sc.size()) min_handle_height = self.sc.style().pixelMetric(QStyle.PixelMetric.PM_ScrollBarSliderMin) no_arrows = self.sc.height() - self.sc.width() * 2 relative = self.sc.value() / (self.sc.maximum() - self.sc.minimum()) # Height should be page step / document length bar_height_rel = self.sc.pageStep() / (self.sc.maximum() - self.sc.minimum() + self.sc.pageStep()) bar_height_px = math.floor(bar_height_rel * no_arrows) handle_height = max(min_handle_height, bar_height_px) print(handle_height) self.indicator.setText(str(self.sc.value())) movement_range = no_arrows - handle_height self.indicator.move(self.width() - self.sc.width() - 10 - self.indicator.width(), int(relative * movement_range + (handle_height / 2) + 10 + self.sc.width() - self.indicator.height() / 2)) # Spacing self.lower_pad.setFixedWidth(self.width()) self.lower_pad.setFixedHeight(10) self.lower_pad.move(0, self.height() - 10) self.upper_pad.setFixedWidth(self.width()) self.upper_pad.setFixedHeight(10) self.upper_pad.move(0, 0) # Arrows self.lower_arrow.setFixedHeight(self.sc.width()) self.lower_arrow.setFixedWidth(self.width()) self.lower_arrow.move(0, self.height() - 10 - self.sc.width()) self.upper_arrow.setFixedHeight(self.sc.width()) self.upper_arrow.setFixedWidth(self.width()) self.upper_arrow.move(0, 10) # Page self.lower_page.setFixedWidth(self.width()) self.lower_page.setFixedHeight(int(math.ceil(movement_range * (1 - relative)))) self.lower_page.move(0, 10 + self.sc.width() + int(movement_range * relative + handle_height)) self.upper_page.setFixedWidth(self.width()) self.upper_page.setFixedHeight(int(movement_range * relative)) self.upper_page.move(0, 10 + self.sc.width()) # Handle self.scrollbar.setFixedWidth(self.width()) self.scrollbar.setFixedHeight(handle_height) self.scrollbar.move(0, 10 + self.sc.width() + int(relative * movement_range)) # Getting position of # stl = self.style() # Doesn't work: v is empty QRect() # v = stl.subControlRect(stl.ComplexControl.CC_ScrollBar, None, stl.SubControl.SC_ScrollBarSlider, self.sc) # stl.subElement doesn't work because it has no scrollbar stuff if self.sc.isSliderDown(): print(f"Slider is down") else: print(f"Slider is up") if __name__ == '__main__': app = QApplication(sys.argv) x = app.style().pixelMetric(QApplication.style().PixelMetric.PM_ScrollBarExtent) print(x) print(QPixmapCache.cacheLimit()) QPixmapCache.setCacheLimit(1024) print(QPixmapCache.cacheLimit()) ex = RootWindow() ex.show() sys.exit(app.exec())
  • How to implement text ellipsis effect in QLabel?

    Solved 23 Oct 2024, 20:03
    0 Votes
    3 Posts
    422 Views
    @JonB Thank you very much! Following the example you provided, I successfully rewrote the component in Python, and the ellipsis functionality works perfectly. Moreover, the component fully supports QSS styling as well—it looks fantastic! Thanks again for your help! from PySide6.QtWidgets import QLabel from PySide6.QtCore import Qt from PySide6.QtGui import QFontMetrics class EllipsisLabel(QLabel): def __init__(self, text="", parent=None): super().__init__(parent) self._text = text self.setText(text) def setText(self, text): self._text = text self.updateText() def resizeEvent(self, event): super().resizeEvent(event) self.updateText() def updateText(self): metrics = QFontMetrics(self.font()) elided = metrics.elidedText(self._text, Qt.ElideRight, self.width()) super().setText(elided)
  • Disable python warnings on Qt Creator

    Solved 1 Dec 2021, 08:29
    0 Votes
    3 Posts
    1k Views
    This thead provides more information about disabling specific warnings.
  • This topic is deleted!

    Unsolved 22 Oct 2024, 13:30
    1 Votes
    11 Posts
    166 Views
  • QSliders in PyQt5 vs PySide6

    Unsolved 17 Oct 2024, 20:00
    0 Votes
    9 Posts
    1k Views
    @JonB @SGaist I have tried implementing QThreads. While the GUI does not freeze the response has a lot of inertia, by the time I finish moving the QSlider the app keeps updating the respective graphs and it is pretty annoying to use. I also tried to subclass QSlider and use a QTimer to make the signal emit 200ms after the valueChanged signal have been fired and the results are not good compared to PyQt5. Also, the sliderMoved signal behaves very similarly to valueChanged. Could I get some additional tips? I have tried to inspect the Qt5 and Qt6 implementation of QSlider but I honestly do not even know where to start looking at them. Any help is welcome. Thanks again!
  • This topic is deleted!

    Unsolved 21 Oct 2024, 12:22
    0 Votes
    1 Posts
    7 Views
    No one has replied
  • Eventfilter on text edit not working

    Solved 18 Oct 2024, 13:22
    0 Votes
    13 Posts
    774 Views
    @Nightmaster said in Eventfilter on text edit not working: My eventFilter method was indented two spaces too much. :) Which is one reason I am really not fond of Python....!
  • 0 Votes
    1 Posts
    121 Views
    No one has replied
  • Residual data in QImage after reinstantiating

    Solved 19 Oct 2024, 10:01
    0 Votes
    3 Posts
    166 Views
    Hi, Did you open a ticket to make this known ?
  • 0 Votes
    6 Posts
    425 Views
    Nice ! Glad you found out and thanks for sharing. That said, I would suggest to properly clean that state object.
  • 0 Votes
    9 Posts
    3k Views
    @MrAWD said in TypeError: __init__() missing 1 required positional argument: 'item': TypeError: __init__() missing 1 required positional argument: 'item' Well, I tried and PyQt6 reports same error. So this is not a PySide-only issue. But the PyQt6 gives a surprising clue: jon@ubuntu-22:~/QtTests/PyQt$ python3 multiinherit.py Traceback (most recent call last): File "/home/jon/QtTests/PyQt/multiinherit.py", line 21, in <module> win = MyWindow() ^^^^^^^^^^ File "/home/jon/QtTests/PyQt/multiinherit.py", line 16, in __init__ self.label = myClass("item") ^^^^^^^^^^^^^^^ File "/home/jon/QtTests/PyQt/multiinherit.py", line 10, in __init__ QLineEdit.__init__(self, parent) TypeError: HelperClass.__init__() missing 1 required positional argument: 'item' So although the error is shown beneath QLineEdit.__init__(self, parent) and PySide6 just says __init__() missing 1 required positional, PyQt6 says HelperClass.__init__() missing 1 required positional So it is complaining about HelperClass.__init__() not QLineEdit.__init__().... I am not a regular Python dev so I will leave it at that. UPDATE On a whim/hunch, I tried changing the order of your inheritance to: class myClass(HelperClass, QLineEdit) Lo and behold, this works fine under both PySide & PyQt! Now, it may be you were getting away with something which ought never to have worked on old PySide2. In C++ if you want to multi-inherit from a QObject type and a non-QObject type (not allowed to multi-inherit from QObject publicly) you must place the QObject one first in the list, to keep moc happy (https://doc.qt.io/qt-6/moc.html#multiple-inheritance-requires-qobject-to-be-first). To be fair, that is exactly what you non-working original did. I am finding the opposite is required to keep PyQt6/PySide6 happy here! Check that with the re-arranged order everything else, especially the QLineEdit functionality/signals, work. If so, my finding is that the reverse of what C++/moc wants is required for Py...! Go figure :) P.S. The error might have some relationship to https://forum.qt.io/post/755209 We have hit this issue too. PySide 6.5.0 appears to use the signature of the last super-class that is initialised for both of them. I know you are not using super(), but when it goes wrong in your original order maybe this is related to the "using the last signature encountered". Or, you might want to look at Christian Tismer's answer in https://bugreports.qt.io/browse/PYSIDE-2294 where he suggests combining the two separate __init__()s into a single super().__init__(a_value=a_value, b_value=b_value) You might also report your original code as a "bug" to the PySide folks and see what they have to say. Though the fact that it behaves the same as PyQt may indicate it is not their problem.