Skip to content

Qt for Python

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

3.3k Topics 14.6k Posts
  • How to set the QGraphicsDropShadowEffect on the drop down menu of a QComboBox?

    Moved Unsolved
    6
    0 Votes
    6 Posts
    513 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
    498 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
    178 Views
    No one has replied
  • PyQt TableWidget abilities

    Unsolved qt for python python pyside pyside2
    3
    0 Votes
    3 Posts
    429 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
    179 Views
    No one has replied
  • 0 Votes
    2 Posts
    297 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
    172 Views
    No one has replied
  • using qt designer to connect a widget to a method

    Unsolved
    4
    0 Votes
    4 Posts
    390 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
    454 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
    689 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
    718 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
    400 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
    567 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
    212 Views
    No one has replied
  • how to include page1.ui file in mainwindow.ui file

    Solved
    6
    0 Votes
    6 Posts
    624 Views
    JonBJ
    @abiabi Because Qt Designer/Creator is not particularly Python-oriented. The accepted solution from @eyllanesc is the way to go, as with his other Python posts.
  • shiboken6/pyside6 with poetry under msys2

    Unsolved
    3
    0 Votes
    3 Posts
    473 Views
    R
    Hello @Jaime02 , Hum I am using poetry and as it is showed in the project, there is no specified version (so it takes the latest if available). It works perfectly out of the poetry world yes for sure, but not in poetry one...
  • Qt Creator randomly won't update .py file with changes from .ui file

    Unsolved pyside
    2
    0 Votes
    2 Posts
    374 Views
    JonBJ
    @BGrimaud If you delete the ui_...py file and resave does that recreate it, and reflect new changes? Do you have the option to try a newer version of Creator?