File size: 4,436 Bytes
4189926 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | from os import path
from PIL import Image
from urllib.parse import urlparse, unquote
from PyQt5 import QtCore
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
QApplication,
QMainWindow,
QHBoxLayout,
QVBoxLayout,
QGridLayout,
QPushButton,
QRadioButton,
QButtonGroup,
QSlider,
QLabel,
QFrame,
QComboBox,
QCheckBox,
QWidget,
QSizePolicy,
QMessageBox,
)
from PyQt5.QtCore import QSize
from PyQt5.QtGui import QPixmap, QDesktopServices, QDragEnterEvent, QDropEvent
class LabeledSlider(QWidget):
"""A simple QSlider and QLabel combo for displaying the slider value;
it holds both an _int_ and _float_ representation of the slider value
for convenience, the value to display is determined by the
_use_float_value_ initialization argument.
"""
valueChanged = QtCore.pyqtSignal(int, float)
def __init__(self, use_float_value=False):
super().__init__()
self.use_float_value = use_float_value
self._label = QLabel("0")
if use_float_value:
self._label.setText("0.00")
self._slider = QSlider(orientation=Qt.Orientation.Horizontal)
self._slider.setMaximum(20)
self._slider.setMinimum(0)
self._slider.setValue(0)
self._slider.setTickInterval(1)
self._slider.setSingleStep(1)
self._slider.valueChanged.connect(self.onSliderChanged)
hlayout = QHBoxLayout()
hlayout.addWidget(self._slider)
hlayout.addWidget(self._label)
self.setLayout(hlayout)
def onSliderChanged(self, value):
if self.use_float_value:
self._label.setText("%.2f" % (value / 20.0))
else:
self._label.setText("%d" % (value))
self.valueChanged.emit(value, value / 20.0)
def setValue(self, value):
if self.use_float_value:
self._slider.setValue(int(value * 20))
else:
self._slider.setValue(value)
def getValue(self):
if self.use_float_value:
return self._slider.value() / 20.0
else:
return self._slider.value()
class ImageLabel(QLabel):
"""A simple QLabel widget for displaying an image; the label image
can be updated either by calling the _show_image()_ method or by
dragging an image into the widget area if the label is set to
accept drag and drop, which is set to _False_ by default.
"""
changed = QtCore.pyqtSignal()
def __init__(self, text: str, width=512, height=512):
super().__init__(text)
self.setAlignment(Qt.AlignCenter)
self.resize(width, height)
self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)
self.sizeHint = QSize(width, height)
self.width = width
self.height = height
self.setAcceptDrops(False)
def show_image(self, pixmap: QPixmap = None):
"""Updates the widget pixamp"""
if pixmap == None or pixmap.isNull():
return
self.current_pixmap = pixmap
self.changed.emit()
# Resize the pixmap to the widget dimensions
image_width = self.current_pixmap.width()
image_height = self.current_pixmap.height()
if image_width > self.width or image_height > self.height:
new_width = self.width if image_width > self.width else image_width
new_height = self.height if image_height > self.height else image_height
self.setPixmap(
self.current_pixmap.scaled(
new_width,
new_height,
Qt.KeepAspectRatio,
)
)
else:
self.setPixmap(self.current_pixmap)
def dragEnterEvent(self, event: QDragEnterEvent):
if event.mimeData().hasFormat("text/plain"):
event.acceptProposedAction()
def dropEvent(self, event: QDropEvent):
event.acceptProposedAction()
self.path = unquote(urlparse(event.mimeData().text()).path)
pixmap = QPixmap(self.path)
self.show_image(pixmap)
self.update()
# Test the widget
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
window = QMainWindow()
window.resize(640, 480)
window.layout().addWidget(LabeledSlider(True))
window.layout().addWidget(ImageLabel("Hello world!", 128, 128))
window.show()
app.exec()
|