Skip to content

Qt for Python

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

3.3k Topics 14.5k Posts
  • PySide6 D-Bus Signal Interface Not Emitting or Discoverable

    2
    0 Votes
    2 Posts
    225 Views
    SGaistS
    Hi and welcome to devnet, Thanks for the detailed post and sorry I can't help you directly. Things that would help further: which version of PySide6 are you using ? which Linux distribution are you running ? which version of DBus do you have ?
  • shiboken6-genpyi with C++ class mapped to primitive type (dict)

    Solved
    3
    0 Votes
    3 Posts
    288 Views
    SGaistS
    Hi, Glad you found out and thanks for sharing ! Would you mind posting the fixed version ? That might be useful to someone in the future.
  • importing PySide6 or shiboken6 removes trace callback

    Solved
    7
    1 Votes
    7 Posts
    570 Views
    B
    @ctismer Thanks for fixing the problem.
  • How to set the QGraphicsDropShadowEffect on the drop down menu of a QComboBox?

    Moved Unsolved
    6
    0 Votes
    6 Posts
    461 Views
    M
    @Shankarlinga-M I did some testing and it seems that the style from QStyleFactory can override the behavior of effects in the combobox's view() and view().viewport() You can try printing the available styles and changing them like this: print(QStyleFactory.keys()) app = QApplication(sys.argv) app.setStyle(QStyleFactory.create('Windows')) It also seems that the QGraphicsDropShadowEffect() expands the bounding box of the widget you apply it to, but doesn't expand the bounding box of the combobox.view()
  • How to Keep PyQt6 Window Always on Top on macOS

    Unsolved
    4
    0 Votes
    4 Posts
    459 Views
    SGaistS
    I tested your code on 14.7.3 removing all things that would not work such as the label stuff and it behaves correctly with PyQt6 6.7.1 as well as 6.8.1. Which version of PyQt6 are you using ?
  • In QMenu, the mouse hover cannot be set

    Unsolved
    1
    0 Votes
    1 Posts
    163 Views
    No one has replied
  • PyQt TableWidget abilities

    Unsolved qt for python python pyside pyside2
    3
    0 Votes
    3 Posts
    375 Views
    SGaistS
    Hi and welcome to devnet, What exactly are you after ? Did you already went through the documentation of the corresponding class ? Did you check the examples using it ?
  • Unable to make use of QBoundingVolume

    Unsolved pyside python qt for python
    1
    0 Votes
    1 Posts
    153 Views
    No one has replied
  • 0 Votes
    2 Posts
    288 Views
    D
    On Stack Overflow, my question was closed due to "debugging details." I made a bunch of changes based on the comments to that questions and have a smaller example that strips out the thumbnail generation but still has the same issue. https://stackoverflow.com/questions/79504092/with-pyqt6-calling-setcurrentindex-and-scrollto-is-inconsistant-with-a-custom-ql Here's the new minimal example if anyone wants to take a stab at it: import sys from os import listdir from os.path import isfile, join, basename from functools import lru_cache from queue import Queue, Empty from random import shuffle from typing import Optional from PyQt6 import QtCore from PyQt6.QtCore import QSize, Qt, pyqtSlot, QModelIndex, QAbstractListModel, QVariant, QThread, pyqtSignal from PyQt6.QtGui import QImage, QPixmap from PyQt6.QtWidgets import QApplication, QListView, QAbstractItemView, QListWidget, QWidget, QStyle, QMainWindow class ThumbLoaderThread(QThread): thumbnail_loaded = pyqtSignal(str, QImage) def __init__(self): super().__init__() self.thumbnail_queue = Queue() self.error_icon = QWidget().style().standardIcon(QStyle.StandardPixmap.SP_DialogCancelButton).pixmap(250, 250).toImage() def add_thumbnail(self, filename: str): self.thumbnail_queue.put(filename) def run(self) -> None: print('Starting Thumbnailer Thread') while not self.isInterruptionRequested(): try: filename = self.thumbnail_queue.get(timeout=1) thumb = self.__load_thumb(filename) if thumb: self.thumbnail_loaded.emit(filename, thumb) else: self.thumbnail_loaded.emit(filename, self.error_icon) except Empty: ... @lru_cache(maxsize=5000) def __load_thumb(self, filename): print(f'Loading Thumbnail For {filename}') # In the real application, I use openCV to create a thumbnail here # For right now, we're just using a standard image return QWidget().style().standardIcon(QStyle.StandardPixmap.SP_FileIcon).pixmap(250, 250).toImage() class FileListModel(QAbstractListModel): numberPopulated = pyqtSignal(int) def __init__(self, dir_path: str): super().__init__() self.thumbnail_thread = ThumbLoaderThread() self.thumbnail_thread.thumbnail_loaded.connect(self.thumbnail_generated) self.thumbnail_thread.start() self.files = [] self.loaded_file_count = 0 self.set_dir_path(dir_path) def thumbnail_generated(self, filename: str, thumbnail: QImage): idx = self.index_for_filename(filename) if idx >= 0: q_idx = self.createIndex(idx, 0) self.files[idx]['thumbnail'] = QPixmap.fromImage(thumbnail) self.dataChanged.emit(q_idx, q_idx) def index_for_filename(self, filename) -> int: for index, item in enumerate(self.files): if item.get('filename') == filename: return index return -1 def rowCount(self, parent: QModelIndex = QtCore.QModelIndex()) -> int: return 0 if parent.isValid() else self.loaded_file_count def set_dir_path(self, dir_path: str): self.beginResetModel() self.files = [] self.loaded_file_count = 0 only_files = [f for f in listdir(dir_path) if isfile(join(dir_path, f))] # The full program has sorting # In this minimal example, we'll just shuffle the order shuffle(only_files) for f in only_files: vid = join(dir_path, f) self.files.append({'filename': vid, 'thumbnail': None}) self.endResetModel() def data(self, index: QModelIndex, role: int = Qt.ItemDataRole.DisplayRole): if not index.isValid(): return QVariant() if index.row() >= len(self.files) or index.row() < 0: return QVariant() filename = self.files[index.row()]['filename'] thumbnail = self.files[index.row()]['thumbnail'] if role == Qt.ItemDataRole.DisplayRole: return QVariant(basename(filename)) if role == Qt.ItemDataRole.DecorationRole: if thumbnail: return thumbnail else: self.thumbnail_thread.add_thumbnail(filename) return QWidget().style().standardIcon(QStyle.StandardPixmap.SP_BrowserReload) if role == Qt.ItemDataRole.SizeHintRole: return QSize(250, 250 + 25) return QVariant() def fetchMore(self, parent: QModelIndex) -> None: if parent.isValid(): return remainder = len(self.files) - self.loaded_file_count items_to_fetch = min(100, remainder) if items_to_fetch <= 0: print("No More Items to Fetch") return print(f'Loaded Items: {self.loaded_file_count} / Items to Fetch: {items_to_fetch}') self.beginInsertRows(QModelIndex(), self.loaded_file_count, self.loaded_file_count + items_to_fetch - 1) self.loaded_file_count += items_to_fetch self.endInsertRows() self.numberPopulated.emit(items_to_fetch) def get_file_index(self, filename: str) -> Optional[int]: for i, file in enumerate(self.files): if file['filename'] == filename: return i def canFetchMore(self, parent: QModelIndex) -> bool: if parent.isValid(): return False can_fetch = self.loaded_file_count < len(self.files) return can_fetch class MediaBrowser(QListView): def __init__(self, dir_path): super().__init__() self.setLayoutMode(QListView.LayoutMode.Batched) self.setBatchSize(10) self.setUniformItemSizes(True) self.current_directory = dir_path self.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection) self.setViewMode(QListWidget.ViewMode.IconMode) self.setResizeMode(QListWidget.ResizeMode.Adjust) self.setIconSize(QSize(250, 250)) self.file_list_model = FileListModel(dir_path) self.setModel(self.file_list_model) self.selectionModel().selectionChanged.connect(self.selection_change) self.current_file = None def mousePressEvent(self, event): """Prevent context menu from also selecting a file""" if event.type() == QtCore.QEvent.Type.MouseButtonPress: if event.button() == Qt.MouseButton.RightButton: # In our minimalistic example, right click # Means we will shuffle self.chdir(self.current_directory) if self.current_file: idx = self.model().get_file_index(self.current_file) print(f'Attempting to select and scroll to {self.current_file} at index {idx}') q_idx = self.model().createIndex(idx, 0) if not q_idx.isValid(): print('Index is invalid') self.setCurrentIndex(q_idx) self.scrollTo(q_idx) else: super(MediaBrowser, self).mousePressEvent(event) def chdir(self, directory: str): print(f'Change Directory {directory}.') self.current_directory = directory self.load_files(directory) @pyqtSlot() def selection_change(self): selected = self.selectionModel().selectedIndexes() if len(selected) != 1: print(f'Invalid Selection {selected}') else: s = selected[0] print(f'Item Selection {s}') self.current_file = self.get_model_filename(s.row()) def showEvent(self, event): super().showEvent(event) QApplication.processEvents() def all_files(self): return self.file_list_model.files def get_model_filename(self, index): return self.all_files()[index]['filename'] def load_files(self, dir_path): try: self.file_list_model.set_dir_path(dir_path) except PermissionError as e: print(f'{e.strerror}') class MainWindow(QMainWindow): def __init__(self): super().__init__() browser = MediaBrowser("/tmp/media") self.setCentralWidget(browser) def main(): app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec()) if __name__ == '__main__': main()
  • Using aiohttp with QtAsyncio

    Unsolved
    10
    0 Votes
    10 Posts
    2k Views
    F
    For the record, there is https://bugreports.qt.io/browse/PYSIDE-2713 . Contributions for this would be very welcome.
  • What is the corresponding dbus type for `uint32` and `Vardict` in Qt?

    Unsolved
    1
    0 Votes
    1 Posts
    159 Views
    No one has replied
  • using qt designer to connect a widget to a method

    Unsolved
    4
    0 Votes
    4 Posts
    378 Views
    SGaistS
    You're welcome ! I'll put it in a different way: it gives you more control and it's also easier to reason about when reading the code. In any case, since you have the answer you sought, please mark the thread as solved using the Topic Tools button or the three dotted menu beside the answer your deem correct so other forum users may know a solution has been found :-)
  • readyRead signal not activating while using QSerialProt

    Solved
    5
    0 Votes
    5 Posts
    439 Views
    jsulmJ
    @Adar70 said in readyRead signal not activating while using QSerialProt: I don't know how to make it more robust Don't rely on the number of times readyRead is emitted. Instead accumulate the received data until you received all you expect to receive.
  • Using Signals in QGraphicsItem

    Solved
    25
    0 Votes
    25 Posts
    2k Views
    SGaistS
    @JonB I misread the code ! We are in the territory where your solution (using __init__) is the way to go. Multiple inheritance in Python is quite tricky... QObject expects an optional parent parameter which is not given here but it's not expecting the parameters for the QGraphicsLineItem constructor hence the failure. You can try to use the kwargs trick however it won't work either as it's not part of any of the method signature and thus can't work either.
  • How to structure this project?

    Solved
    8
    0 Votes
    8 Posts
    635 Views
    D
    That is great. Thank you very much for your time and help. Would you have any (open source) pyqt projects you would recommend to look at and learn from? I've got a couple of good books but they usually have small examples focused on specific topics, not complete projects. I'm currently mostly looking at how https://github.com/dietervansteenwegen/serial-tool is set up and try to understand and copy (if it makes sense) that.
  • How to vertically center align the QLabel and a QWidget of a QFormLayout row ?

    Solved
    6
    0 Votes
    6 Posts
    633 Views
    N
    Hmmm... actually, I finally made it : and the solution was... to remove margins from theQHBoxLayout of the QWidget ! Jesus ! I'll have to carefully remember that one 😅
  • PyQt5 - Emit once, Slot called multiple times, slowing down the application

    Unsolved
    3
    0 Votes
    3 Posts
    380 Views
    C
    It looks like your signal-slot connection is stacking each time you open the child window. Try disconnecting the signal before reconnecting it in handlePlot() using window.signal.disconnect(self.handleData). This should prevent multiple calls to handleData(). My cousin, who is a professional photographer, was always struggling with sending full-resolution images to clients. After trying various platforms, he finally settled on Filemail, and it has been a game-changer for him. No compression, no sign-ups for recipients, and super-fast uploads—everything he needed for hassle-free file transfers.
  • Connecting C++ Qt widgets and PySide2 ones

    Unsolved
    13
    0 Votes
    13 Posts
    4k Views
    SGaistS
    Sorry, I can't as I don't have access to the archives that might contain this article. However, you will likely be interested by the example linked by @tellien .
  • printing issue in a qt app pyqt5

    Unsolved
    6
    0 Votes
    6 Posts
    538 Views
    SGaistS
    AFAIK, both packages can coexist in the same environment as they come each with their own build of Qt. However, to get better help, as @jsulm suggested, you should bring that issue to the Salome forum.
  • PyQt5 show hide is not working when shortcut is used

    Unsolved
    1
    0 Votes
    1 Posts
    174 Views
    No one has replied