Skip to content

Qt for Python

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

3.2k Topics 14.3k Posts
  • 0 Votes
    2 Posts
    59 Views
    jsulmJ

    @markleo

    Qt itself is always compiled even if you use PySide. So, the only difference is the one between compiled C++ code and interpreted Python code, but that has nothing to do with Qt. You should rather check which libraries you need and whether those are available in PySide. Most of the Qt libraries are available in PySide as far as I know. PyKDE is not part of Qt, you should consider ask them.
  • 0 Votes
    2 Posts
    46 Views
    SGaistS

    Hi,

    Are you thinking about something like the Qt Graphs module ?
    The KDE project also has quite a lot of additional libraries.

  • 0 Votes
    1 Posts
    48 Views
    No one has replied
  • 0 Votes
    2 Posts
    39 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 ?
  • 0 Votes
    3 Posts
    75 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
    139 Views
    B

    @ctismer
    Thanks for fixing the problem.

  • simplest mvc pattern in pyside6

    Unsolved
    2
    0 Votes
    2 Posts
    153 Views
    SGaistS

    Hi,

    Did you already took a look at Qt's model view implementation ?

  • 0 Votes
    6 Posts
    176 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()

  • Could not update timestamps for skipped samples.

    Unsolved
    6
    0 Votes
    6 Posts
    126 Views
    SGaistS

    You don't need to be an expert :-)
    You can simply go to the bug reporting system and check there if there's already something about it.

    If not, open a new ticket providing your example and full system information so it is easier to reproduce. Provide the findings you made about the error message and how it can be dealt with.

    If a report already exist, you can check whether it contains all the information required. If not, add yours. You can also vote for it.

    That would already be a good help to improve Qt.

    You are not required to implement a solution, but if you want to take a shot at it, then just try. It's one way to learn and get better at the subject.

    We all started and tried at some point, that's also how you learn :-)

  • QSystemTrayIcon bug for computer system!!!

    Unsolved
    2
    0 Votes
    2 Posts
    51 Views
    jsulmJ

    @LuoMeng This is not the right place to request bug fixes.
    File a bug report here: https://bugreports.qt.io/secure/Dashboard.jspa

  • How to Keep PyQt6 Window Always on Top on macOS

    Unsolved
    4
    0 Votes
    4 Posts
    166 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
    54 Views
    No one has replied
  • PYQT TABLE WIDGET ABILITES

    Unsolved
    3
    0 Votes
    3 Posts
    73 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
    1
    0 Votes
    1 Posts
    47 Views
    No one has replied
  • 0 Votes
    2 Posts
    63 Views
    F

    You can try to specify QwtSeriesStore as <custom-type name /> with generate="no" and see what happens. But maybe wrapping is better.

  • 0 Votes
    2 Posts
    129 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
    1k Views
    F

    For the record, there is https://bugreports.qt.io/browse/PYSIDE-2713 . Contributions for this would be very welcome.

  • Cannot pip install pyside6_ds?

    Unsolved
    1
    0 Votes
    1 Posts
    79 Views
    No one has replied
  • 0 Votes
    1 Posts
    63 Views
    No one has replied
  • Why does PySide6 need glibc 2.39 since 6.8.1 on aarch64?

    Unsolved
    2
    0 Votes
    2 Posts
    103 Views
    SGaistS

    Hi and welcome to devnet,

    If memory serves well, Ubuntu is used to build Qt for ARM. It has that more recent version of glibc.