diff --git a/ai_diffusion/client.py b/ai_diffusion/client.py index 574a6d37a..13b6ff332 100644 --- a/ai_diffusion/client.py +++ b/ai_diffusion/client.py @@ -2,7 +2,7 @@ from abc import ABC, abstractmethod from enum import Enum from typing import Any, AsyncGenerator, Iterable, NamedTuple -from PyQt5.QtCore import QObject, pyqtSignal +from PyQt6.QtCore import QObject, pyqtSignal from .api import WorkflowInput from .image import ImageCollection diff --git a/ai_diffusion/connection.py b/ai_diffusion/connection.py index 73fd0485f..d5be049b4 100644 --- a/ai_diffusion/connection.py +++ b/ai_diffusion/connection.py @@ -1,7 +1,7 @@ from __future__ import annotations from enum import Enum -from PyQt5.QtCore import QObject, pyqtSignal, QUrl -from PyQt5.QtGui import QDesktopServices +from PyQt6.QtCore import QObject, pyqtSignal, QUrl +from PyQt6.QtGui import QDesktopServices import asyncio from .client import Client, ClientMessage, ClientEvent, DeviceInfo, SharedWorkflow, MissingResources diff --git a/ai_diffusion/control.py b/ai_diffusion/control.py index d88de3f3d..e64ebac67 100644 --- a/ai_diffusion/control.py +++ b/ai_diffusion/control.py @@ -1,5 +1,5 @@ from __future__ import annotations -from PyQt5.QtCore import QObject, pyqtSignal, QUuid, Qt +from PyQt6.QtCore import QObject, pyqtSignal, QUuid, Qt from typing import Any, NamedTuple from pathlib import Path import json diff --git a/ai_diffusion/custom_workflow.py b/ai_diffusion/custom_workflow.py index 596655993..1f7bb62a3 100644 --- a/ai_diffusion/custom_workflow.py +++ b/ai_diffusion/custom_workflow.py @@ -7,8 +7,8 @@ from dataclasses import dataclass from typing import Any, Awaitable, Callable, NamedTuple, Literal, TYPE_CHECKING from pathlib import Path -from PyQt5.QtCore import Qt, QObject, QUuid, QAbstractListModel, QSortFilterProxyModel, QModelIndex -from PyQt5.QtCore import QMetaObject, QTimer, pyqtSignal +from PyQt6.QtCore import Qt, QObject, QUuid, QAbstractListModel, QSortFilterProxyModel, QModelIndex +from PyQt6.QtCore import QMetaObject, QTimer, pyqtSignal from .api import WorkflowInput from .client import TextOutput, ClientOutput diff --git a/ai_diffusion/document.py b/ai_diffusion/document.py index f26b7fec4..7fb29e0d2 100644 --- a/ai_diffusion/document.py +++ b/ai_diffusion/document.py @@ -4,7 +4,7 @@ from weakref import WeakValueDictionary import krita from krita import Krita -from PyQt5.QtCore import QObject, QUuid, QByteArray, QTimer, pyqtSignal +from PyQt6.QtCore import QObject, QUuid, QByteArray, QTimer, pyqtSignal from .image import Extent, Bounds, Mask, Image from .layer import Layer, LayerManager, LayerType diff --git a/ai_diffusion/eventloop.py b/ai_diffusion/eventloop.py index a8ff3ffd0..8e3afcb53 100644 --- a/ai_diffusion/eventloop.py +++ b/ai_diffusion/eventloop.py @@ -1,7 +1,7 @@ import asyncio import threading from typing import Callable -from PyQt5.QtCore import QTimer +from PyQt6.QtCore import QTimer _loop = asyncio.new_event_loop() _timer = QTimer() diff --git a/ai_diffusion/extension.py b/ai_diffusion/extension.py index ba4c32013..cfcaaa0aa 100644 --- a/ai_diffusion/extension.py +++ b/ai_diffusion/extension.py @@ -1,7 +1,7 @@ import sys from pathlib import Path from typing import Callable -from PyQt5.QtWidgets import QAction +from PyQt6.QtGui import QAction from krita import Extension, Krita, DockWidgetFactory, DockWidgetFactoryBase, Window # type: ignore from . import eventloop, __version__ @@ -79,5 +79,5 @@ def createActions(self, window): Krita.instance().addExtension(AIToolsExtension(Krita.instance())) Krita.instance().addDockWidgetFactory( - DockWidgetFactory("imageDiffusion", DockWidgetFactoryBase.DockRight, ImageDiffusionWidget) # type: ignore + DockWidgetFactory("imageDiffusion", DockWidgetFactoryBase.DockPosition.DockRight, ImageDiffusionWidget) # type: ignore ) diff --git a/ai_diffusion/files.py b/ai_diffusion/files.py index 9bedc2a91..51bed38e4 100644 --- a/ai_diffusion/files.py +++ b/ai_diffusion/files.py @@ -5,8 +5,8 @@ from dataclasses import dataclass, asdict from pathlib import Path from typing import Any, NamedTuple, Sequence, cast -from PyQt5.QtCore import QAbstractListModel, QSortFilterProxyModel, QModelIndex, Qt -from PyQt5.QtGui import QIcon +from PyQt6.QtCore import QAbstractListModel, QSortFilterProxyModel, QModelIndex, Qt +from PyQt6.QtGui import QIcon from .util import encode_json, read_json_with_comments, user_data_dir, client_logger as log diff --git a/ai_diffusion/image.py b/ai_diffusion/image.py index c5eabd7ba..4b295c79b 100644 --- a/ai_diffusion/image.py +++ b/ai_diffusion/image.py @@ -1,9 +1,9 @@ from __future__ import annotations from enum import Enum from math import sqrt -from PyQt5.QtGui import QImage, QImageWriter, QImageReader, QPixmap, QIcon, QPainter, QColorSpace -from PyQt5.QtGui import qRgba, qRed, qGreen, qBlue, qAlpha, qGray -from PyQt5.QtCore import Qt, QByteArray, QBuffer, QRect, QSize, QFile, QIODevice +from PyQt6.QtGui import QImage, QImageWriter, QImageReader, QPixmap, QIcon, QPainter, QColorSpace +from PyQt6.QtGui import qRgba, qRed, qGreen, qBlue, qAlpha, qGray +from PyQt6.QtCore import Qt, QByteArray, QBuffer, QRect, QSize, QFile, QIODevice from typing import Callable, Iterable, SupportsIndex, Tuple, NamedTuple, Union, Optional from itertools import product from pathlib import Path @@ -484,11 +484,11 @@ def data(self): return buffer else: ptr = ensure(self._qimage.constBits(), "Accessing data of invalid image") - return QByteArray(ptr.asstring(self._qimage.byteCount())) + return QByteArray(ptr.asstring(self._qimage.sizeInBytes())) @property def size(self): # in bytes - return self._qimage.byteCount() + return self._qimage.sizeInBytes() def to_array(self): import numpy as np diff --git a/ai_diffusion/jobs.py b/ai_diffusion/jobs.py index b8c375377..38a9b89db 100644 --- a/ai_diffusion/jobs.py +++ b/ai_diffusion/jobs.py @@ -4,7 +4,7 @@ from datetime import datetime from enum import Enum, Flag from typing import Any, NamedTuple, TYPE_CHECKING -from PyQt5.QtCore import QObject, pyqtSignal +from PyQt6.QtCore import QObject, pyqtSignal from .image import Bounds, ImageCollection from .settings import settings diff --git a/ai_diffusion/layer.py b/ai_diffusion/layer.py index 836299da3..f2bf791dc 100644 --- a/ai_diffusion/layer.py +++ b/ai_diffusion/layer.py @@ -2,8 +2,8 @@ from contextlib import contextmanager, nullcontext from enum import Enum import krita -from PyQt5.QtCore import QObject, QUuid, QByteArray, QTimer, pyqtSignal -from PyQt5.QtGui import QImage +from PyQt6.QtCore import QObject, QUuid, QByteArray, QTimer, pyqtSignal +from PyQt6.QtGui import QImage from .image import Extent, Bounds, Image, ImageCollection from .util import acquire_elements, ensure, maybe, client_logger as log diff --git a/ai_diffusion/model.py b/ai_diffusion/model.py index 0031f1cae..e26c58aec 100644 --- a/ai_diffusion/model.py +++ b/ai_diffusion/model.py @@ -8,8 +8,8 @@ from tempfile import TemporaryDirectory import time from typing import Any, NamedTuple -from PyQt5.QtCore import QObject, QUuid, pyqtSignal, Qt -from PyQt5.QtGui import QPainter, QColor, QBrush +from PyQt6.QtCore import QObject, QUuid, pyqtSignal, Qt +from PyQt6.QtGui import QPainter, QColor, QBrush import uuid from . import eventloop, workflow, util diff --git a/ai_diffusion/network.py b/ai_diffusion/network.py index 432d8fe0a..51b245031 100644 --- a/ai_diffusion/network.py +++ b/ai_diffusion/network.py @@ -6,8 +6,8 @@ from datetime import datetime from pathlib import Path from typing import NamedTuple -from PyQt5.QtCore import QByteArray, QUrl, QFile, QBuffer -from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply, QSslError +from PyQt6.QtCore import QByteArray, QUrl, QFile, QBuffer +from PyQt6.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply, QSslError from .localization import translate as _ from .util import client_logger as log @@ -35,7 +35,7 @@ def __str__(self): @staticmethod def from_reply(reply: QNetworkReply): - code: QNetworkReply.NetworkError = reply.error() # type: ignore (bug in PyQt5-stubs) + code: QNetworkReply.NetworkError = reply.error() # type: ignore (bug in PyQt6-stubs) url = reply.url().toString() status = reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute) if reply.isReadable(): @@ -96,7 +96,7 @@ def http( self._cleanup() request = QNetworkRequest(QUrl(url)) - request.setAttribute(QNetworkRequest.FollowRedirectsAttribute, True) + request.setAttribute(QNetworkRequest.Attribute.RedirectPolicyAttribute, True) request.setRawHeader(b"ngrok-skip-browser-warning", b"69420") if bearer: request.setRawHeader(b"Authorization", f"Bearer {bearer}".encode("utf-8")) @@ -146,7 +146,7 @@ async def upload(self, url: str, data: QByteArray | bytes, sha256: str | None = assert isinstance(data, QByteArray) request = QNetworkRequest(QUrl(url)) - request.setAttribute(QNetworkRequest.Attribute.FollowRedirectsAttribute, True) + request.setAttribute(QNetworkRequest.Attribute.RedirectPolicyAttribute, True) if sha256: request.setRawHeader(b"x-amz-checksum-sha256", sha256.encode("utf-8")) request.setHeader( @@ -173,7 +173,7 @@ async def upload(self, url: str, data: QByteArray | bytes, sha256: str | None = def download(self, url: str): self._cleanup() request = QNetworkRequest(QUrl(url)) - request.setAttribute(QNetworkRequest.Attribute.FollowRedirectsAttribute, True) + request.setAttribute(QNetworkRequest.Attribute.RedirectPolicyAttribute, True) reply = self._net.get(request) assert reply is not None, f"Network request for {url} failed: reply is None" @@ -201,7 +201,7 @@ def _upload_progress(self, bytes_sent: int, bytes_total: int): def _finished(self, reply: QNetworkReply): future = None try: - code = reply.error() # type: ignore (bug in PyQt5-stubs) + code = reply.error() # type: ignore (bug in PyQt6-stubs) tracker = self._requests[reply] future = tracker.future if future.cancelled(): @@ -274,13 +274,13 @@ def final(self): async def _try_download(network: QNetworkAccessManager, url: str, path: Path): out_file = QFile(str(path) + ".part") - if not out_file.open(QFile.ReadWrite | QFile.Append): # type: ignore + if not out_file.open(QFile.OpenModeFlag.ReadWrite | QFile.OpenModeFlag.Append): # type: ignore raise Exception( _("Error during download: could not open {path} for writing", path=out_file.fileName()) ) request = QNetworkRequest(QUrl(_map_host(url))) - request.setAttribute(QNetworkRequest.FollowRedirectsAttribute, True) + request.setAttribute(QNetworkRequest.Attribute.RedirectPolicyAttribute, True) if out_file.size() > 0: log.info(f"Found {path}.part, resuming download from {out_file.size()} bytes") request.setRawHeader(b"Range", f"bytes={out_file.size()}-".encode("utf-8")) @@ -302,7 +302,7 @@ def handle_finished(): out_file.close() if finished_future.cancelled(): return # operation was cancelled, discard result - if reply.error() == QNetworkReply.NetworkError.NoError: # type: ignore (bug in PyQt5-stubs) + if reply.error() == QNetworkReply.NetworkError.NoError: # type: ignore (bug in PyQt6-stubs) finished_future.set_result(path) elif reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 416: # 416 = Range Not Satisfiable diff --git a/ai_diffusion/persistence.py b/ai_diffusion/persistence.py index 5438521bf..f319837c9 100644 --- a/ai_diffusion/persistence.py +++ b/ai_diffusion/persistence.py @@ -5,9 +5,9 @@ from enum import Enum from typing import Any from time import time -from PyQt5.QtCore import QObject, QByteArray -from PyQt5.QtGui import QImageReader -from PyQt5.QtWidgets import QMessageBox +from PyQt6.QtCore import QObject, QByteArray +from PyQt6.QtGui import QImageReader +from PyQt6.QtWidgets import QMessageBox from .api import InpaintMode, FillMode from .image import ImageCollection diff --git a/ai_diffusion/pose.py b/ai_diffusion/pose.py index d1b153eee..9f4ff985c 100644 --- a/ai_diffusion/pose.py +++ b/ai_diffusion/pose.py @@ -1,7 +1,7 @@ from functools import reduce import operator from typing import Dict, List, NamedTuple, Optional -from PyQt5.QtCore import QPointF +from PyQt6.QtCore import QPointF from .image import Extent from .util import batched diff --git a/ai_diffusion/properties.py b/ai_diffusion/properties.py index 00902e9e5..6122f9a41 100644 --- a/ai_diffusion/properties.py +++ b/ai_diffusion/properties.py @@ -2,8 +2,8 @@ from enum import Enum from typing import Any, NamedTuple, Sequence, TypeVar, Generic -from PyQt5.QtCore import QObject, QMetaObject, QUuid, pyqtBoundSignal -from PyQt5.QtWidgets import QComboBox +from PyQt6.QtCore import QObject, QMetaObject, QUuid, pyqtBoundSignal +from PyQt6.QtWidgets import QComboBox T = TypeVar("T") diff --git a/ai_diffusion/region.py b/ai_diffusion/region.py index 1cd39ef1e..d3dcd0b51 100644 --- a/ai_diffusion/region.py +++ b/ai_diffusion/region.py @@ -1,6 +1,6 @@ from __future__ import annotations from enum import Enum -from PyQt5.QtCore import QObject, QUuid, pyqtSignal +from PyQt6.QtCore import QObject, QUuid, pyqtSignal from . import eventloop, model, workflow from .api import ConditioningInput, RegionInput diff --git a/ai_diffusion/root.py b/ai_diffusion/root.py index ecc2000f4..1a69bbadd 100644 --- a/ai_diffusion/root.py +++ b/ai_diffusion/root.py @@ -1,7 +1,7 @@ from __future__ import annotations from dataclasses import dataclass from typing import Callable -from PyQt5.QtCore import QObject, pyqtSignal +from PyQt6.QtCore import QObject, pyqtSignal from .connection import Connection, ConnectionState from .client import ClientMessage diff --git a/ai_diffusion/server.py b/ai_diffusion/server.py index 04e6779a4..d1088f00e 100644 --- a/ai_diffusion/server.py +++ b/ai_diffusion/server.py @@ -8,7 +8,7 @@ import os import time from typing import Callable, NamedTuple, Optional, Union -from PyQt5.QtNetwork import QNetworkAccessManager +from PyQt6.QtNetwork import QNetworkAccessManager from .settings import settings, ServerBackend from . import eventloop, resources diff --git a/ai_diffusion/settings.py b/ai_diffusion/settings.py index f35fee942..9cd468f88 100644 --- a/ai_diffusion/settings.py +++ b/ai_diffusion/settings.py @@ -5,7 +5,7 @@ from enum import Enum from pathlib import Path from typing import NamedTuple, Optional, Any -from PyQt5.QtCore import QObject, pyqtSignal +from PyQt6.QtCore import QObject, pyqtSignal from .util import is_macos, is_windows, user_data_dir, client_logger as log from .util import encode_json, read_json_with_comments diff --git a/ai_diffusion/style.py b/ai_diffusion/style.py index 955f94a72..6567d61d4 100644 --- a/ai_diffusion/style.py +++ b/ai_diffusion/style.py @@ -4,7 +4,7 @@ from typing import Iterable, NamedTuple import json from pathlib import Path -from PyQt5.QtCore import QObject, pyqtSignal +from PyQt6.QtCore import QObject, pyqtSignal from .api import CheckpointInput, LoraInput from .settings import Setting, settings diff --git a/ai_diffusion/ui/animation.py b/ai_diffusion/ui/animation.py index 5d96796cd..f771ca7e8 100644 --- a/ai_diffusion/ui/animation.py +++ b/ai_diffusion/ui/animation.py @@ -1,6 +1,6 @@ from __future__ import annotations -from PyQt5.QtCore import Qt, QMetaObject -from PyQt5.QtWidgets import ( +from PyQt6.QtCore import Qt, QMetaObject +from PyQt6.QtWidgets import ( QWidget, QVBoxLayout, QHBoxLayout, @@ -102,12 +102,12 @@ def __init__(self): self.target_layer = QComboBox(self) self.target_layer.setMinimumContentsLength(20) self.target_layer.setSizeAdjustPolicy( - QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLength + QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon ) layout.addWidget(self.target_layer) self.preview_area = QLabel(self) - self.preview_area.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) + self.preview_area.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) self.preview_area.setAlignment( Qt.AlignmentFlag(Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignLeft) ) diff --git a/ai_diffusion/ui/autocomplete.py b/ai_diffusion/ui/autocomplete.py index 2b6534a93..91109dbe4 100644 --- a/ai_diffusion/ui/autocomplete.py +++ b/ai_diffusion/ui/autocomplete.py @@ -3,9 +3,9 @@ import csv from typing import cast -from PyQt5.QtWidgets import QApplication, QCompleter, QPlainTextEdit, QStyledItemDelegate, QStyle -from PyQt5.QtGui import QFont, QPalette, QPen, QColor, QFontMetrics, QTextCursor -from PyQt5.QtCore import Qt, QStringListModel, QSize, QRect, QAbstractProxyModel +from PyQt6.QtWidgets import QApplication, QCompleter, QPlainTextEdit, QStyledItemDelegate, QStyle +from PyQt6.QtGui import QFont, QPalette, QPen, QColor, QFontMetrics, QTextCursor +from PyQt6.QtCore import Qt, QStringListModel, QSize, QRect, QAbstractProxyModel from ..root import root from ..settings import settings diff --git a/ai_diffusion/ui/control.py b/ai_diffusion/ui/control.py index 4feab95fa..e667c5b6f 100644 --- a/ai_diffusion/ui/control.py +++ b/ai_diffusion/ui/control.py @@ -1,9 +1,9 @@ from __future__ import annotations -from PyQt5.QtGui import QResizeEvent -from PyQt5.QtWidgets import QWidget, QLabel, QSlider, QToolButton, QCheckBox -from PyQt5.QtWidgets import QComboBox, QHBoxLayout, QVBoxLayout, QGridLayout, QFrame -from PyQt5.QtCore import Qt, QMetaObject, pyqtSignal +from PyQt6.QtGui import QResizeEvent +from PyQt6.QtWidgets import QWidget, QLabel, QSlider, QToolButton, QCheckBox +from PyQt6.QtWidgets import QComboBox, QHBoxLayout, QVBoxLayout, QGridLayout, QFrame +from PyQt6.QtCore import Qt, QMetaObject, pyqtSignal from ..resources import ControlMode from ..properties import Binding, bind, bind_combo, bind_toggle diff --git a/ai_diffusion/ui/custom_workflow.py b/ai_diffusion/ui/custom_workflow.py index 33b071e84..7c0b3f0b0 100644 --- a/ai_diffusion/ui/custom_workflow.py +++ b/ai_diffusion/ui/custom_workflow.py @@ -3,12 +3,12 @@ from typing import Any, Callable from krita import Krita -from PyQt5.QtCore import Qt, pyqtSignal, QMetaObject, QUuid, QUrl, QPoint, QSize -from PyQt5.QtGui import QFontMetrics, QIcon, QDesktopServices, QPalette -from PyQt5.QtWidgets import QComboBox, QFileDialog, QFrame, QGridLayout, QHBoxLayout, QMenu -from PyQt5.QtWidgets import QLabel, QLineEdit, QListWidgetItem, QMessageBox, QSpinBox, QAction -from PyQt5.QtWidgets import QToolButton, QVBoxLayout, QWidget, QSlider, QDoubleSpinBox -from PyQt5.QtWidgets import QScrollArea, QTextEdit, QSplitter +from PyQt6.QtCore import Qt, pyqtSignal, QMetaObject, QUuid, QUrl, QPoint, QSize +from PyQt6.QtGui import QFontMetrics, QIcon, QDesktopServices, QPalette, QAction +from PyQt6.QtWidgets import QComboBox, QFileDialog, QFrame, QGridLayout, QHBoxLayout, QMenu +from PyQt6.QtWidgets import QLabel, QLineEdit, QListWidgetItem, QMessageBox, QSpinBox +from PyQt6.QtWidgets import QToolButton, QVBoxLayout, QWidget, QSlider, QDoubleSpinBox +from PyQt6.QtWidgets import QScrollArea, QTextEdit, QSplitter from ..custom_workflow import CustomParam, ParamKind, SortedWorkflows, WorkflowSource from ..custom_workflow import CustomGenerationMode diff --git a/ai_diffusion/ui/diffusion.py b/ai_diffusion/ui/diffusion.py index f13a9fca8..429b7e1a6 100644 --- a/ai_diffusion/ui/diffusion.py +++ b/ai_diffusion/ui/diffusion.py @@ -1,7 +1,7 @@ from __future__ import annotations -from PyQt5.QtCore import Qt -from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QStackedWidget -from PyQt5.QtWidgets import QCheckBox +from PyQt6.QtCore import Qt +from PyQt6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QStackedWidget +from PyQt6.QtWidgets import QCheckBox from krita import Krita, DockWidget import krita diff --git a/ai_diffusion/ui/generation.py b/ai_diffusion/ui/generation.py index f57ce27e5..5769786bb 100644 --- a/ai_diffusion/ui/generation.py +++ b/ai_diffusion/ui/generation.py @@ -1,13 +1,13 @@ from __future__ import annotations from textwrap import wrap as wrap_text from typing import cast -from PyQt5.QtCore import Qt, QEvent, QMetaObject, QSize, QPoint, QTimer, QUuid, pyqtSignal -from PyQt5.QtCore import QItemSelectionModel -from PyQt5.QtGui import QGuiApplication, QMouseEvent, QKeyEvent, QKeySequence -from PyQt5.QtGui import QPalette, QColor, QIcon -from PyQt5.QtWidgets import QAction, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QProgressBar -from PyQt5.QtWidgets import QListWidget, QListWidgetItem, QListView, QSizePolicy -from PyQt5.QtWidgets import QComboBox, QCheckBox, QMenu, QMessageBox, QToolButton +from PyQt6.QtCore import Qt, QEvent, QMetaObject, QSize, QPoint, QTimer, QUuid, pyqtSignal +from PyQt6.QtCore import QItemSelectionModel +from PyQt6.QtGui import QGuiApplication, QMouseEvent, QKeyEvent, QKeySequence +from PyQt6.QtGui import QPalette, QColor, QIcon, QAction +from PyQt6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QProgressBar +from PyQt6.QtWidgets import QListWidget, QListWidgetItem, QListView, QSizePolicy +from PyQt6.QtWidgets import QComboBox, QCheckBox, QMenu, QMessageBox, QToolButton from ..properties import Binding, Bind, bind, bind_combo, bind_toggle from ..image import Bounds, Extent, Image @@ -54,13 +54,13 @@ def __init__(self, parent: QWidget | None): self._model = root.active_model self._connections = [] - self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) - self.setResizeMode(QListView.Adjust) + self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) + self.setResizeMode(QListView.ResizeMode.Adjust) self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff) - self.setFlow(QListView.LeftToRight) - self.setViewMode(QListWidget.IconMode) + self.setFlow(QListView.Flow.LeftToRight) + self.setViewMode(QListWidget.ViewMode.IconMode) self.setIconSize(theme.screen_scale(self, QSize(self._thumb_size, self._thumb_size))) - self.setFrameStyle(QListWidget.NoFrame) + self.setFrameStyle(QListWidget.Shape.NoFrame) self.setStyleSheet(self._list_css) self.setSelectionMode(QListWidget.SelectionMode.ExtendedSelection) self.setDragEnabled(False) @@ -260,7 +260,7 @@ def update_apply_button(self): rect = self.visualItemRect(selected[0]) font = self._apply_button.fontMetrics() context_visible = rect.width() >= 0.6 * self.iconSize().width() - apply_text_visible = font.width(_("Apply")) < 0.35 * rect.width() + apply_text_visible = font.horizontalAdvance(_("Apply")) < 0.35 * rect.width() apply_pos = QPoint(rect.left() + 3, rect.bottom() - self._apply_button.height() - 2) if context_visible: cw = self._context_button.width() @@ -542,7 +542,7 @@ def ctx_icon(name): ) self.context_combo.setMinimumContentsLength(20) self.context_combo.setSizeAdjustPolicy( - QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLength + QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon ) self.context_combo.currentIndexChanged.connect(self.set_context) diff --git a/ai_diffusion/ui/interval_slider.py b/ai_diffusion/ui/interval_slider.py index b27a4ada7..790d41b8d 100644 --- a/ai_diffusion/ui/interval_slider.py +++ b/ai_diffusion/ui/interval_slider.py @@ -14,11 +14,11 @@ from typing import Tuple -from PyQt5.QtCore import pyqtSignal as Signal +from PyQt6.QtCore import pyqtSignal as Signal -from PyQt5.QtWidgets import QWidget, QStyleOptionSlider, QSizePolicy, QStyle, QSlider -from PyQt5.QtGui import QPainter, QMouseEvent, QPalette, QBrush -from PyQt5.QtCore import QRect, Qt, QSize +from PyQt6.QtWidgets import QWidget, QStyleOptionSlider, QSizePolicy, QStyle, QSlider +from PyQt6.QtGui import QPainter, QMouseEvent, QPalette, QBrush +from PyQt6.QtCore import QRect, Qt, QSize # Based on idea and in part the code from diff --git a/ai_diffusion/ui/live.py b/ai_diffusion/ui/live.py index 4b8f40db2..c3d06c65d 100644 --- a/ai_diffusion/ui/live.py +++ b/ai_diffusion/ui/live.py @@ -1,6 +1,6 @@ from __future__ import annotations -from PyQt5.QtCore import QMetaObject, Qt -from PyQt5.QtWidgets import ( +from PyQt6.QtCore import QMetaObject, Qt +from PyQt6.QtWidgets import ( QWidget, QVBoxLayout, QHBoxLayout, diff --git a/ai_diffusion/ui/region.py b/ai_diffusion/ui/region.py index 0a7032f7c..3c3917ee2 100644 --- a/ai_diffusion/ui/region.py +++ b/ai_diffusion/ui/region.py @@ -1,7 +1,7 @@ from __future__ import annotations from enum import Enum -from PyQt5.QtWidgets import QWidget, QLabel, QToolButton, QHBoxLayout, QVBoxLayout, QFrame, QMenu -from PyQt5.QtGui import ( +from PyQt6.QtWidgets import QWidget, QLabel, QToolButton, QHBoxLayout, QVBoxLayout, QFrame, QMenu +from PyQt6.QtGui import ( QGuiApplication, QMouseEvent, QResizeEvent, @@ -11,7 +11,7 @@ QIcon, QFontMetrics, ) -from PyQt5.QtCore import QObject, QEvent, Qt, QMetaObject, QSize, pyqtSignal +from PyQt6.QtCore import QObject, QEvent, Qt, QMetaObject, QSize, pyqtSignal from ..root import root from ..client import Client diff --git a/ai_diffusion/ui/server.py b/ai_diffusion/ui/server.py index c035e647c..91f8a2f43 100644 --- a/ai_diffusion/ui/server.py +++ b/ai_diffusion/ui/server.py @@ -2,9 +2,9 @@ from enum import Enum from pathlib import Path from typing import Optional -from PyQt5.QtCore import Qt, QUrl, pyqtSignal -from PyQt5.QtGui import QDesktopServices -from PyQt5.QtWidgets import ( +from PyQt6.QtCore import Qt, QUrl, pyqtSignal +from PyQt6.QtGui import QDesktopServices +from PyQt6.QtWidgets import ( QWidget, QCheckBox, QComboBox, @@ -292,7 +292,7 @@ def __init__(self, srv: Server, parent=None): self._manage_button = QToolButton(self) self._manage_button.setText(_("Manage")) - self._manage_button.setPopupMode(QToolButton.InstantPopup) + self._manage_button.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup) self._manage_button.setMinimumWidth(150) menu = QMenu(self) @@ -334,7 +334,7 @@ def __init__(self, srv: Server, parent=None): scroll = QScrollArea(self) scroll.setWidget(package_list) scroll.setWidgetResizable(True) - scroll.setFrameStyle(QFrame.NoFrame) + scroll.setFrameStyle(QFrame.Shape.NoFrame) scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff) layout.addWidget(scroll, 1) diff --git a/ai_diffusion/ui/settings.py b/ai_diffusion/ui/settings.py index c1bfd6225..81d1b2577 100644 --- a/ai_diffusion/ui/settings.py +++ b/ai_diffusion/ui/settings.py @@ -2,7 +2,7 @@ from krita import Krita from typing import Optional -from PyQt5.QtWidgets import ( +from PyQt6.QtWidgets import ( QVBoxLayout, QHBoxLayout, QDialog, @@ -20,8 +20,8 @@ QMessageBox, QCheckBox, ) -from PyQt5.QtCore import Qt, QMetaObject, QSize, QUrl, pyqtSignal -from PyQt5.QtGui import QDesktopServices, QGuiApplication, QCursor, QFontMetrics +from PyQt6.QtCore import Qt, QMetaObject, QSize, QUrl, pyqtSignal +from PyQt6.QtGui import QDesktopServices, QGuiApplication, QCursor, QFontMetrics from ..client import Client, User, MissingResources from ..cloud_client import CloudClient diff --git a/ai_diffusion/ui/settings_widgets.py b/ai_diffusion/ui/settings_widgets.py index 9ae1efadd..bbc14c146 100644 --- a/ai_diffusion/ui/settings_widgets.py +++ b/ai_diffusion/ui/settings_widgets.py @@ -2,7 +2,7 @@ from enum import Enum from typing import Any -from PyQt5.QtWidgets import ( +from PyQt6.QtWidgets import ( QVBoxLayout, QHBoxLayout, QCheckBox, @@ -17,8 +17,8 @@ QScrollArea, QFrame, ) -from PyQt5.QtCore import Qt, QAbstractItemModel, QSize, pyqtSignal -from PyQt5.QtGui import QIcon +from PyQt6.QtCore import Qt, QAbstractItemModel, QSize, pyqtSignal +from PyQt6.QtGui import QIcon from ..localization import translate as _ from ..settings import Setting, settings @@ -69,7 +69,7 @@ def __init__(self, setting: Setting, parent=None): super().__init__(parent) self._key_label = QLabel(f"{setting.name}
{setting.desc}") - self._key_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) + self._key_label.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred) self._checkbox: QCheckBox | None = None self._widget: QWidget | None = None @@ -441,7 +441,7 @@ def __init__(self, title: str): scroll = QScrollArea(self) scroll.setWidget(inner) scroll.setWidgetResizable(True) - scroll.setFrameStyle(QFrame.NoFrame) + scroll.setFrameStyle(QFrame.Shape.NoFrame) scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff) frame_layout.addWidget(scroll) diff --git a/ai_diffusion/ui/style.py b/ai_diffusion/ui/style.py index 50595d465..a95ea6576 100644 --- a/ai_diffusion/ui/style.py +++ b/ai_diffusion/ui/style.py @@ -2,7 +2,7 @@ from typing import Optional, cast from pathlib import Path -from PyQt5.QtWidgets import ( +from PyQt6.QtWidgets import ( QVBoxLayout, QHBoxLayout, QPushButton, @@ -18,8 +18,8 @@ QMessageBox, QLineEdit, ) -from PyQt5.QtCore import Qt, QUrl, pyqtSignal -from PyQt5.QtGui import QDesktopServices, QPalette, QColor +from PyQt6.QtCore import Qt, QUrl, pyqtSignal +from PyQt6.QtGui import QDesktopServices, QPalette, QColor from krita import Krita from ..client import resolve_arch @@ -599,7 +599,7 @@ def __init__(self, server: Server): frame_layout.addLayout(builtin_layout) frame = QFrame(self) - frame.setFrameStyle(QFrame.StyledPanel) + frame.setFrameStyle(QFrame.Shape.StyledPanel) frame.setLineWidth(1) frame.setLayout(frame_layout) self._layout.addWidget(frame) diff --git a/ai_diffusion/ui/switch.py b/ai_diffusion/ui/switch.py index 59d73d596..89e146869 100644 --- a/ai_diffusion/ui/switch.py +++ b/ai_diffusion/ui/switch.py @@ -2,16 +2,16 @@ from https://stackoverflow.com/a/51825815 """ -from PyQt5.QtCore import QPropertyAnimation, QSize, Qt, pyqtProperty # type: ignore -from PyQt5.QtGui import QPainter -from PyQt5.QtWidgets import QAbstractButton, QSizePolicy +from PyQt6.QtCore import QPropertyAnimation, QSize, Qt, pyqtProperty # type: ignore +from PyQt6.QtGui import QPainter +from PyQt6.QtWidgets import QAbstractButton, QSizePolicy class SwitchWidget(QAbstractButton): def __init__(self, parent=None): super().__init__(parent=parent) self.setCheckable(True) - self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) + self.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed) self._thumb_radius = self.fontMetrics().height() // 2 self._track_radius = self._thumb_radius + 2 @@ -69,7 +69,7 @@ def resizeEvent(self, a0): def paintEvent(self, e): p = QPainter(self) - p.setRenderHint(QPainter.Antialiasing, True) + p.setRenderHint(QPainter.RenderHint.Antialiasing, True) p.setPen(Qt.PenStyle.NoPen) track_opacity = self._track_opacity thumb_opacity = 1.0 diff --git a/ai_diffusion/ui/theme.py b/ai_diffusion/ui/theme.py index e7dbda4dd..3f4fedff3 100644 --- a/ai_diffusion/ui/theme.py +++ b/ai_diffusion/ui/theme.py @@ -1,7 +1,7 @@ from __future__ import annotations -from PyQt5.QtCore import Qt, QObject, QSize -from PyQt5.QtGui import QGuiApplication, QPalette, QIcon, QPixmap, QFontMetrics -from PyQt5.QtWidgets import QVBoxLayout, QLabel, QWidget +from PyQt6.QtCore import Qt, QObject, QSize +from PyQt6.QtGui import QGuiApplication, QPalette, QIcon, QPixmap, QFontMetrics +from PyQt6.QtWidgets import QVBoxLayout, QLabel, QWidget from pathlib import Path from ..files import FileFormat @@ -21,7 +21,7 @@ highlight = "#8df" if is_dark else "#357" progress_alt = "#a16207" if is_dark else "#ca8a04" active = _palette.color(QPalette.ColorRole.Highlight).name() -line = _palette.color(QPalette.ColorRole.Background).darker(120).name() +line = _palette.color(QPalette.ColorRole.Window).darker(120).name() line_base = _palette.color(QPalette.ColorRole.Base).darker(120).name() flat_combo_stylesheet = f""" diff --git a/ai_diffusion/ui/upscale.py b/ai_diffusion/ui/upscale.py index c9b8c7e47..7883a4f39 100644 --- a/ai_diffusion/ui/upscale.py +++ b/ai_diffusion/ui/upscale.py @@ -1,6 +1,6 @@ -from PyQt5.QtCore import Qt, QMetaObject, QEvent, pyqtSignal -from PyQt5.QtGui import QCursor -from PyQt5.QtWidgets import ( +from PyQt6.QtCore import Qt, QMetaObject, QEvent, pyqtSignal +from PyQt6.QtGui import QCursor +from PyQt6.QtWidgets import ( QWidget, QVBoxLayout, QHBoxLayout, diff --git a/ai_diffusion/ui/widget.py b/ai_diffusion/ui/widget.py index 942eeb771..ac86c86c3 100644 --- a/ai_diffusion/ui/widget.py +++ b/ai_diffusion/ui/widget.py @@ -1,8 +1,9 @@ from __future__ import annotations from typing import Any, Callable, cast -from PyQt5.QtWidgets import ( - QAction, +from PyQt6.QtGui import QAction + +from PyQt6.QtWidgets import ( QSlider, QWidget, QPlainTextEdit, @@ -22,7 +23,7 @@ QFrame, QScrollBar, ) -from PyQt5.QtGui import ( +from PyQt6.QtGui import ( QCloseEvent, QDesktopServices, QGuiApplication, @@ -35,7 +36,7 @@ QPaintEvent, QKeySequence, ) -from PyQt5.QtCore import Qt, QMetaObject, QSize, pyqtSignal, QEvent, QUrl +from PyQt6.QtCore import Qt, QMetaObject, QSize, pyqtSignal, QEvent, QUrl from krita import Krita from ..style import Style, Styles @@ -272,7 +273,7 @@ def _update(self): def sizeHint(self) -> QSize: original = super().sizeHint() - width = original.height() * 0.75 + self.fontMetrics().width(" 99 ") + 20 + width = original.height() * 0.75 + self.fontMetrics().horizontalAdvance(" 99 ") + 20 return QSize(int(width), original.height()) def paintEvent(self, a0): @@ -719,7 +720,7 @@ def __init__(self, parent): self.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly) self.setMenu(menu) - self.setPopupMode(QToolButton.InstantPopup) + self.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup) self.setToolTip( _("Switch between workspaces: image generation, upscaling, live preview and animation.") ) @@ -771,7 +772,7 @@ def operation(self, value: str): def minimumSizeHint(self): fm = self.fontMetrics() - return QSize(fm.width(self._operation) + 40, 12 + int(1.3 * fm.height())) + return QSize(fm.horizontalAdvance(self._operation) + 40, 12 + int(1.3 * fm.height())) def enterEvent(self, a0: QEvent | None): if client := root.connection.client_if_connected: @@ -796,7 +797,7 @@ def mouseReleaseEvent(self, e: QMouseEvent | None): def paintEvent(self, a0: QPaintEvent | None) -> None: opt = QStyleOption() opt.initFrom(self) - opt.state |= QStyle.StateFlag.State_Sunken if self.isDown() else 0 + opt.state |= QStyle.StateFlag.State_Sunken if self.isDown() else QStyle.StateFlag.State_None painter = QPainter(self) fm = self.fontMetrics() style = ensure(self.style()) @@ -807,9 +808,9 @@ def paintEvent(self, a0: QPaintEvent | None) -> None: ) rect = self.rect() pixmap = self.icon().pixmap(int(fm.height() * 1.3)) - is_hover = int(opt.state) & QStyle.StateFlag.State_MouseOver + is_hover = opt.state & QStyle.StateFlag.State_MouseOver element = QStyle.PrimitiveElement.PE_PanelButtonCommand - content_width = fm.width(self._operation) + 5 + pixmap.width() + content_width = fm.horizontalAdvance(self._operation) + 5 + pixmap.width() content_rect = rect.adjusted(int(0.5 * (rect.width() - content_width)), 0, 0, 0) style.drawPrimitive(element, opt, painter, self) style.drawItemPixmap(painter, content_rect, align, pixmap) @@ -996,7 +997,7 @@ def _paint_tool_drop_down(widget: QToolButton, text: str | None = None): rect = widget.rect() pixmap = widget.icon().pixmap(int(rect.height() * 0.75)) element = QStyle.PrimitiveElement.PE_Widget - if int(opt.state) & QStyle.StateFlag.State_MouseOver: + if opt.state & QStyle.StateFlag.State_MouseOver: element = QStyle.PrimitiveElement.PE_PanelButtonCommand style.drawPrimitive(element, opt, painter, widget) style.drawItemPixmap(painter, rect.adjusted(4, 0, 0, 0), align, pixmap) diff --git a/ai_diffusion/updates.py b/ai_diffusion/updates.py index 44f72e8e2..6911c02d2 100644 --- a/ai_diffusion/updates.py +++ b/ai_diffusion/updates.py @@ -6,7 +6,7 @@ from pathlib import Path from tempfile import TemporaryDirectory from typing import NamedTuple -from PyQt5.QtCore import QObject, pyqtSignal +from PyQt6.QtCore import QObject, pyqtSignal from . import __version__, eventloop from .network import RequestManager diff --git a/ai_diffusion/util.py b/ai_diffusion/util.py index 7542f6924..f6723ec3f 100644 --- a/ai_diffusion/util.py +++ b/ai_diffusion/util.py @@ -15,8 +15,8 @@ import statistics import zipfile from typing import Any, Callable, Iterable, Optional, Sequence, TypeVar -from PyQt5 import sip -from PyQt5.QtCore import QObject, QStandardPaths +from PyQt6 import sip +from PyQt6.QtCore import QObject, QStandardPaths T = TypeVar("T") R = TypeVar("R") @@ -35,11 +35,11 @@ def _get_user_data_dir(): dir.mkdir(exist_ok=True) return dir try: - dir = Path(QStandardPaths.writableLocation(QStandardPaths.AppDataLocation)) + dir = Path(QStandardPaths.writableLocation(QStandardPaths.StandardLocation.AppDataLocation)) if dir.exists() and "krita" in dir.name.lower(): dir = dir / "ai_diffusion" else: - dir = Path(QStandardPaths.writableLocation(QStandardPaths.GenericDataLocation)) + dir = Path(QStandardPaths.writableLocation(QStandardPaths.StandardLocation.GenericDataLocation)) dir = dir / "krita-ai-diffusion" dir.mkdir(exist_ok=True) return dir diff --git a/tests/conftest.py b/tests/conftest.py index 3e664c69c..1fe0a4ed8 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,7 +4,7 @@ import subprocess import dotenv from pathlib import Path -from PyQt5.QtCore import QCoreApplication +from PyQt6.QtCore import QCoreApplication sys.path.append(str(Path(__file__).parent.parent)) from ai_diffusion import eventloop, network, util diff --git a/tests/test_api.py b/tests/test_api.py index 56d6f8605..3012a405a 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1,4 +1,4 @@ -from PyQt5.QtCore import Qt +from PyQt6.QtCore import Qt from ai_diffusion.api import ( WorkflowInput, diff --git a/tests/test_custom_workflow.py b/tests/test_custom_workflow.py index bf79394a4..0ff53f482 100644 --- a/tests/test_custom_workflow.py +++ b/tests/test_custom_workflow.py @@ -2,7 +2,7 @@ import pytest from copy import copy from pathlib import Path -from PyQt5.QtCore import Qt +from PyQt6.QtCore import Qt from ai_diffusion.api import CustomWorkflowInput, ImageInput, WorkflowInput from ai_diffusion.client import Client, ClientModels, CheckpointInfo, TextOutput diff --git a/tests/test_files.py b/tests/test_files.py index 18a0d94b2..42803d19f 100644 --- a/tests/test_files.py +++ b/tests/test_files.py @@ -1,6 +1,6 @@ from pathlib import Path -from PyQt5.QtCore import Qt, QModelIndex -from PyQt5.QtGui import QIcon +from PyQt6.QtCore import Qt, QModelIndex +from PyQt6.QtGui import QIcon from ai_diffusion.files import File, FileCollection, FileSource, FileFilter diff --git a/tests/test_image.py b/tests/test_image.py index 839368e34..23691fec8 100644 --- a/tests/test_image.py +++ b/tests/test_image.py @@ -1,7 +1,7 @@ import pytest import numpy as np -from PyQt5.QtGui import QImage, qRgba -from PyQt5.QtCore import Qt, QByteArray +from PyQt6.QtGui import QImage, qRgba +from PyQt6.QtCore import Qt, QByteArray from PIL import Image as PILImage from ai_diffusion.image import Mask, Bounds, Extent, Image, ImageCollection from .config import image_dir, result_dir, reference_dir @@ -109,8 +109,8 @@ def test_image_from_packed_bytes(): @pytest.mark.skip("Benchmark") def test_image_compress_speed(): - from PyQt5.QtGui import QImageWriter - from PyQt5.QtCore import QBuffer, QByteArray, QFile, QIODevice + from PyQt6.QtGui import QImageWriter + from PyQt6.QtCore import QBuffer, QByteArray, QFile, QIODevice from timeit import default_timer img = Image.load("tests/images/beach_1536x1024.webp") diff --git a/tests/test_properties.py b/tests/test_properties.py index 78dbc9ef0..9c16e05a4 100644 --- a/tests/test_properties.py +++ b/tests/test_properties.py @@ -1,6 +1,6 @@ from enum import Enum import pytest -from PyQt5.QtCore import QObject, pyqtSignal +from PyQt6.QtCore import QObject, pyqtSignal from ai_diffusion.properties import Property, ObservableProperties, bind, serialize, deserialize diff --git a/tests/test_server.py b/tests/test_server.py index e7d1d38e1..d59064e64 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -1,6 +1,6 @@ from pathlib import Path from tempfile import TemporaryDirectory -from PyQt5.QtNetwork import QNetworkAccessManager +from PyQt6.QtNetwork import QNetworkAccessManager import asyncio import pytest import shutil diff --git a/tests/test_updates.py b/tests/test_updates.py index e540a9624..a802d2ceb 100644 --- a/tests/test_updates.py +++ b/tests/test_updates.py @@ -2,7 +2,7 @@ import pytest from aiohttp import ClientSession from pathlib import Path -from PyQt5.QtCore import pyqtBoundSignal +from PyQt6.QtCore import pyqtBoundSignal from ai_diffusion.util import ZipFile from ai_diffusion.updates import AutoUpdate, UpdateState