2021-06-17 10:34:23 +12:00
|
|
|
import io
|
2021-02-10 23:48:25 +13:00
|
|
|
import os
|
2021-06-18 10:17:01 +12:00
|
|
|
from logging import getLogger
|
2021-10-11 09:08:31 +13:00
|
|
|
from typing import Callable, Tuple
|
2021-02-10 23:48:25 +13:00
|
|
|
|
2021-08-26 06:25:10 +12:00
|
|
|
import PIL
|
2021-06-17 10:34:23 +12:00
|
|
|
from PIL import Image
|
2021-10-10 00:33:54 +13:00
|
|
|
from PyQt5.QtCore import Qt, QCoreApplication, QRect, QSize, QPoint, pyqtSignal
|
2021-10-09 09:02:11 +13:00
|
|
|
from PyQt5.QtGui import QMovie, QPixmap, QFontMetrics
|
2021-04-29 23:20:20 +12:00
|
|
|
from PyQt5.QtWidgets import QLayout, QStyle, QSizePolicy, QLabel, QFileDialog, QHBoxLayout, QWidget, QPushButton, \
|
2021-10-12 06:09:20 +13:00
|
|
|
QStyleOptionTab, QStylePainter, QTabBar, QLineEdit, QToolButton, QTabWidget
|
2021-03-10 04:52:51 +13:00
|
|
|
from qtawesome import icon
|
2021-02-10 23:48:25 +13:00
|
|
|
|
2021-08-24 02:55:21 +12:00
|
|
|
from rare import resources_path, cache_dir
|
2021-08-23 08:22:17 +12:00
|
|
|
from rare.utils.qt_requests import QtRequestManager
|
2021-04-28 03:40:10 +12:00
|
|
|
|
2021-06-18 10:17:01 +12:00
|
|
|
logger = getLogger("ExtraWidgets")
|
2021-04-28 03:40:10 +12:00
|
|
|
|
2021-02-10 23:48:25 +13:00
|
|
|
|
|
|
|
class FlowLayout(QLayout):
|
|
|
|
def __init__(self, parent=None, margin=-1, hspacing=-1, vspacing=-1):
|
|
|
|
super(FlowLayout, self).__init__(parent)
|
|
|
|
self._hspacing = hspacing
|
|
|
|
self._vspacing = vspacing
|
|
|
|
self._items = []
|
|
|
|
self.setContentsMargins(margin, margin, margin, margin)
|
|
|
|
|
|
|
|
def __del__(self):
|
|
|
|
del self._items[:]
|
|
|
|
|
|
|
|
def addItem(self, item):
|
|
|
|
self._items.append(item)
|
|
|
|
|
|
|
|
def horizontalSpacing(self):
|
|
|
|
if self._hspacing >= 0:
|
|
|
|
return self._hspacing
|
|
|
|
else:
|
|
|
|
return self.smartSpacing(
|
|
|
|
QStyle.PM_LayoutHorizontalSpacing)
|
|
|
|
|
|
|
|
def verticalSpacing(self):
|
|
|
|
if self._vspacing >= 0:
|
|
|
|
return self._vspacing
|
|
|
|
else:
|
|
|
|
return self.smartSpacing(
|
|
|
|
QStyle.PM_LayoutVerticalSpacing)
|
|
|
|
|
|
|
|
def count(self):
|
|
|
|
return len(self._items)
|
|
|
|
|
|
|
|
def itemAt(self, index):
|
|
|
|
if 0 <= index < len(self._items):
|
|
|
|
return self._items[index]
|
|
|
|
|
|
|
|
def takeAt(self, index):
|
|
|
|
if 0 <= index < len(self._items):
|
|
|
|
return self._items.pop(index)
|
|
|
|
|
|
|
|
def expandingDirections(self):
|
|
|
|
return Qt.Orientations(0)
|
|
|
|
|
|
|
|
def hasHeightForWidth(self):
|
|
|
|
return True
|
|
|
|
|
|
|
|
def heightForWidth(self, width):
|
|
|
|
return self.doLayout(QRect(0, 0, width, 0), True)
|
|
|
|
|
|
|
|
def setGeometry(self, rect):
|
|
|
|
super(FlowLayout, self).setGeometry(rect)
|
|
|
|
self.doLayout(rect, False)
|
|
|
|
|
|
|
|
def sizeHint(self):
|
|
|
|
return self.minimumSize()
|
|
|
|
|
|
|
|
def minimumSize(self):
|
|
|
|
size = QSize()
|
|
|
|
for item in self._items:
|
|
|
|
size = size.expandedTo(item.minimumSize())
|
|
|
|
left, top, right, bottom = self.getContentsMargins()
|
|
|
|
size += QSize(left + right, top + bottom)
|
|
|
|
return size
|
|
|
|
|
|
|
|
def doLayout(self, rect, testonly):
|
|
|
|
left, top, right, bottom = self.getContentsMargins()
|
|
|
|
effective = rect.adjusted(+left, +top, -right, -bottom)
|
|
|
|
x = effective.x()
|
|
|
|
y = effective.y()
|
|
|
|
lineheight = 0
|
|
|
|
for item in self._items:
|
|
|
|
widget = item.widget()
|
2021-08-31 01:14:40 +12:00
|
|
|
if not widget.isVisible():
|
|
|
|
continue
|
2021-02-10 23:48:25 +13:00
|
|
|
hspace = self.horizontalSpacing()
|
|
|
|
if hspace == -1:
|
|
|
|
hspace = widget.style().layoutSpacing(
|
|
|
|
QSizePolicy.PushButton,
|
|
|
|
QSizePolicy.PushButton, Qt.Horizontal)
|
|
|
|
vspace = self.verticalSpacing()
|
|
|
|
if vspace == -1:
|
|
|
|
vspace = widget.style().layoutSpacing(
|
|
|
|
QSizePolicy.PushButton,
|
|
|
|
QSizePolicy.PushButton, Qt.Vertical)
|
|
|
|
nextX = x + item.sizeHint().width() + hspace
|
|
|
|
if nextX - hspace > effective.right() and lineheight > 0:
|
|
|
|
x = effective.x()
|
|
|
|
y = y + lineheight + vspace
|
|
|
|
nextX = x + item.sizeHint().width() + hspace
|
|
|
|
lineheight = 0
|
|
|
|
if not testonly:
|
|
|
|
item.setGeometry(
|
|
|
|
QRect(QPoint(x, y), item.sizeHint()))
|
|
|
|
x = nextX
|
|
|
|
lineheight = max(lineheight, item.sizeHint().height())
|
|
|
|
return y + lineheight - rect.y() + bottom
|
|
|
|
|
|
|
|
def smartSpacing(self, pm):
|
|
|
|
parent = self.parent()
|
|
|
|
if parent is None:
|
|
|
|
return -1
|
|
|
|
elif parent.isWidgetType():
|
|
|
|
return parent.style().pixelMetric(pm, None, parent)
|
|
|
|
else:
|
|
|
|
return parent.spacing()
|
|
|
|
|
|
|
|
|
2021-10-10 00:33:54 +13:00
|
|
|
class IndicatorLineEdit(QWidget):
|
|
|
|
textChanged = pyqtSignal(str)
|
|
|
|
is_valid = False
|
|
|
|
|
2021-04-30 04:05:04 +12:00
|
|
|
def __init__(self,
|
|
|
|
text: str = "",
|
2021-10-10 00:33:54 +13:00
|
|
|
ph_text: str = "",
|
2021-10-11 09:08:31 +13:00
|
|
|
edit_func: Callable[[str], Tuple[bool, str]] = None,
|
2021-10-10 00:33:54 +13:00
|
|
|
save_func: Callable[[str], None] = None,
|
|
|
|
horiz_policy: QSizePolicy = QSizePolicy.Expanding,
|
|
|
|
parent=None):
|
|
|
|
super(IndicatorLineEdit, self).__init__(parent=parent)
|
|
|
|
self.setObjectName("IndicatorTextEdit")
|
|
|
|
self.layout = QHBoxLayout(self)
|
|
|
|
self.layout.setObjectName("layout")
|
|
|
|
self.layout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
self.line_edit = QLineEdit(self)
|
|
|
|
self.line_edit.setObjectName("line_edit")
|
|
|
|
self.line_edit.setPlaceholderText(ph_text)
|
|
|
|
self.line_edit.setSizePolicy(horiz_policy, QSizePolicy.Fixed)
|
|
|
|
self.layout.addWidget(self.line_edit)
|
|
|
|
if edit_func is not None:
|
|
|
|
self.indicator_label = QLabel()
|
|
|
|
self.indicator_label.setPixmap(icon("ei.info-circle", color="gray").pixmap(16, 16))
|
|
|
|
self.indicator_label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
|
|
|
|
self.layout.addWidget(self.indicator_label)
|
|
|
|
|
|
|
|
if not ph_text:
|
|
|
|
_translate = QCoreApplication.translate
|
|
|
|
self.line_edit.setPlaceholderText(_translate("PathEdit", "Default"))
|
|
|
|
|
|
|
|
if text:
|
|
|
|
self.line_edit.setText(text)
|
2021-04-28 03:40:10 +12:00
|
|
|
|
2021-05-02 08:15:42 +12:00
|
|
|
self.edit_func = edit_func
|
|
|
|
self.save_func = save_func
|
2021-10-10 00:33:54 +13:00
|
|
|
self.line_edit.textChanged.connect(self.__edit)
|
|
|
|
if self.edit_func is None:
|
|
|
|
self.line_edit.textChanged.connect(self.__save)
|
|
|
|
|
|
|
|
def text(self) -> str:
|
|
|
|
return self.line_edit.text()
|
|
|
|
|
|
|
|
def setText(self, text: str):
|
|
|
|
self.line_edit.setText(text)
|
|
|
|
|
|
|
|
def __indicator(self, res):
|
|
|
|
color = "green" if res else "red"
|
|
|
|
self.indicator_label.setPixmap(icon("ei.info-circle", color=color).pixmap(16, 16))
|
|
|
|
|
|
|
|
def __edit(self, text):
|
2021-05-02 08:15:42 +12:00
|
|
|
if self.edit_func is not None:
|
2021-10-10 00:33:54 +13:00
|
|
|
self.line_edit.blockSignals(True)
|
|
|
|
self.is_valid, text = self.edit_func(text)
|
|
|
|
self.line_edit.setText(text)
|
|
|
|
self.line_edit.blockSignals(False)
|
|
|
|
self.__indicator(self.is_valid)
|
|
|
|
self.textChanged.emit(text)
|
|
|
|
if self.is_valid:
|
|
|
|
self.__save(text)
|
2021-09-09 08:08:41 +12:00
|
|
|
|
2021-10-10 00:33:54 +13:00
|
|
|
def __save(self, text):
|
|
|
|
if self.save_func is not None:
|
|
|
|
self.save_func(text)
|
2021-02-10 23:48:25 +13:00
|
|
|
|
|
|
|
|
2021-10-10 00:33:54 +13:00
|
|
|
class PathEdit(IndicatorLineEdit):
|
|
|
|
def __init__(self,
|
|
|
|
text: str = "",
|
|
|
|
file_type: QFileDialog.FileType = QFileDialog.AnyFile,
|
|
|
|
type_filter: str = "",
|
|
|
|
name_filter: str = "",
|
|
|
|
ph_text: str = "",
|
2021-10-11 09:08:31 +13:00
|
|
|
edit_func: Callable[[str], Tuple[bool, str]] = None,
|
2021-10-10 00:33:54 +13:00
|
|
|
save_func: Callable[[str], None] = None,
|
|
|
|
horiz_policy: QSizePolicy = QSizePolicy.Expanding,
|
|
|
|
parent=None):
|
|
|
|
super(PathEdit, self).__init__(text=text, ph_text=ph_text,
|
|
|
|
edit_func=edit_func, save_func=save_func,
|
|
|
|
horiz_policy=horiz_policy, parent=parent)
|
|
|
|
self.setObjectName("PathEdit")
|
2021-10-10 02:39:35 +13:00
|
|
|
self.line_edit.setMinimumSize(QSize(300, 0))
|
2021-10-10 00:33:54 +13:00
|
|
|
self.path_select = QToolButton(self)
|
|
|
|
self.path_select.setObjectName("path_select")
|
|
|
|
self.layout.addWidget(self.path_select)
|
|
|
|
|
|
|
|
_translate = QCoreApplication.translate
|
|
|
|
self.path_select.setText(_translate("PathEdit", "Browse..."))
|
2021-05-21 11:47:03 +12:00
|
|
|
|
2021-10-10 00:33:54 +13:00
|
|
|
self.type_filter = type_filter
|
|
|
|
self.name_filter = name_filter
|
|
|
|
self.file_type = file_type
|
2021-05-02 08:15:42 +12:00
|
|
|
|
2021-10-10 00:33:54 +13:00
|
|
|
self.path_select.clicked.connect(self.__set_path)
|
|
|
|
|
|
|
|
def __set_path(self):
|
|
|
|
dlg_path = self.line_edit.text()
|
2021-04-30 04:05:04 +12:00
|
|
|
if not dlg_path:
|
|
|
|
dlg_path = os.path.expanduser("~/")
|
2021-05-30 03:24:33 +12:00
|
|
|
dlg = QFileDialog(self, self.tr("Choose path"), dlg_path)
|
2021-04-30 04:05:04 +12:00
|
|
|
dlg.setFileMode(self.file_type)
|
|
|
|
if self.type_filter:
|
|
|
|
dlg.setFilter([self.type_filter])
|
2021-04-28 03:40:10 +12:00
|
|
|
if self.name_filter:
|
|
|
|
dlg.setNameFilter(self.name_filter)
|
2021-02-10 23:48:25 +13:00
|
|
|
if dlg.exec_():
|
|
|
|
names = dlg.selectedFiles()
|
2021-10-10 00:33:54 +13:00
|
|
|
self.line_edit.setText(names[0])
|
2021-02-28 03:54:26 +13:00
|
|
|
|
|
|
|
|
|
|
|
class SideTabBar(QTabBar):
|
2021-10-10 00:33:54 +13:00
|
|
|
def __init__(self, parent=None):
|
|
|
|
super(SideTabBar, self).__init__(parent=parent)
|
|
|
|
self.setObjectName("side_tab_bar")
|
2021-10-09 09:02:11 +13:00
|
|
|
self.fm = QFontMetrics(self.font())
|
2021-02-28 03:54:26 +13:00
|
|
|
|
|
|
|
def tabSizeHint(self, index):
|
|
|
|
# width = QTabBar.tabSizeHint(self, index).width()
|
2021-10-09 09:02:11 +13:00
|
|
|
return QSize(200, self.fm.height() + 18)
|
2021-02-28 03:54:26 +13:00
|
|
|
|
|
|
|
def paintEvent(self, event):
|
|
|
|
painter = QStylePainter(self)
|
|
|
|
opt = QStyleOptionTab()
|
|
|
|
|
|
|
|
for i in range(self.count()):
|
|
|
|
self.initStyleOption(opt, i)
|
|
|
|
painter.drawControl(QStyle.CE_TabBarTabShape, opt)
|
|
|
|
painter.save()
|
|
|
|
|
|
|
|
s = opt.rect.size()
|
|
|
|
s.transpose()
|
|
|
|
r = QRect(QPoint(), s)
|
|
|
|
r.moveCenter(opt.rect.center())
|
|
|
|
opt.rect = r
|
|
|
|
|
|
|
|
c = self.tabRect(i).center()
|
|
|
|
painter.translate(c)
|
|
|
|
painter.rotate(90)
|
|
|
|
painter.translate(-c)
|
2021-10-10 00:33:54 +13:00
|
|
|
painter.drawControl(QStyle.CE_TabBarTabLabel, opt)
|
2021-02-28 03:54:26 +13:00
|
|
|
painter.restore()
|
2021-02-28 05:20:56 +13:00
|
|
|
|
2021-03-10 04:52:51 +13:00
|
|
|
|
2021-10-12 06:09:20 +13:00
|
|
|
class SideTabWidget(QTabWidget):
|
|
|
|
back_clicked = pyqtSignal()
|
|
|
|
|
|
|
|
def __init__(self, show_back: bool = False, parent=None):
|
|
|
|
super(SideTabWidget, self).__init__(parent=parent)
|
|
|
|
self.setTabBar(SideTabBar())
|
|
|
|
self.setTabPosition(QTabWidget.West)
|
|
|
|
if show_back:
|
|
|
|
self.addTab(QWidget(), icon("mdi.keyboard-backspace"), self.tr("Back"))
|
|
|
|
self.tabBarClicked.connect(self.back_func)
|
|
|
|
|
|
|
|
def back_func(self, tab):
|
|
|
|
# shortcut for tab == 0
|
|
|
|
if not tab:
|
|
|
|
self.back_clicked.emit()
|
|
|
|
|
|
|
|
|
2021-02-28 05:20:56 +13:00
|
|
|
class WaitingSpinner(QLabel):
|
|
|
|
def __init__(self):
|
|
|
|
super(WaitingSpinner, self).__init__()
|
|
|
|
self.setStyleSheet("""
|
|
|
|
margin-left: auto;
|
|
|
|
margin-right: auto;
|
|
|
|
""")
|
2021-06-01 07:43:50 +12:00
|
|
|
self.movie = QMovie(os.path.join(resources_path, "images", "loader.gif"))
|
2021-02-28 05:20:56 +13:00
|
|
|
self.setMovie(self.movie)
|
|
|
|
self.movie.start()
|
2021-03-09 05:20:28 +13:00
|
|
|
|
|
|
|
|
2021-03-10 04:52:51 +13:00
|
|
|
class SelectViewWidget(QWidget):
|
|
|
|
toggled = pyqtSignal()
|
2021-03-09 05:20:28 +13:00
|
|
|
|
2021-03-10 04:52:51 +13:00
|
|
|
def __init__(self, icon_view: bool):
|
|
|
|
super(SelectViewWidget, self).__init__()
|
|
|
|
self.icon_view = icon_view
|
2021-03-10 06:13:04 +13:00
|
|
|
self.setStyleSheet("""QPushButton{border: none; background-color: transparent}""")
|
2021-03-10 04:52:51 +13:00
|
|
|
self.icon_view_button = QPushButton()
|
|
|
|
self.list_view = QPushButton()
|
|
|
|
if icon_view:
|
2021-03-26 02:15:18 +13:00
|
|
|
self.icon_view_button.setIcon(icon("mdi.view-grid-outline", color="orange"))
|
2021-08-29 06:03:25 +12:00
|
|
|
self.list_view.setIcon(icon("fa5s.list"))
|
2021-03-10 04:52:51 +13:00
|
|
|
else:
|
2021-08-29 06:03:25 +12:00
|
|
|
self.icon_view_button.setIcon(icon("mdi.view-grid-outline"))
|
2021-03-10 04:52:51 +13:00
|
|
|
self.list_view.setIcon(icon("fa5s.list", color="orange"))
|
2021-03-09 05:20:28 +13:00
|
|
|
|
2021-03-10 04:52:51 +13:00
|
|
|
self.icon_view_button.clicked.connect(self.icon)
|
|
|
|
self.list_view.clicked.connect(self.list)
|
|
|
|
|
|
|
|
self.layout = QHBoxLayout()
|
|
|
|
self.layout.addWidget(self.icon_view_button)
|
|
|
|
self.layout.addWidget(self.list_view)
|
|
|
|
|
|
|
|
self.setLayout(self.layout)
|
|
|
|
|
|
|
|
def isChecked(self):
|
|
|
|
return self.icon_view
|
2021-03-09 05:20:28 +13:00
|
|
|
|
2021-03-10 04:52:51 +13:00
|
|
|
def icon(self):
|
|
|
|
self.icon_view_button.setIcon(icon("mdi.view-grid-outline", color="orange"))
|
2021-08-29 06:03:25 +12:00
|
|
|
self.list_view.setIcon(icon("fa5s.list"))
|
2021-03-10 04:52:51 +13:00
|
|
|
self.icon_view = False
|
|
|
|
self.toggled.emit()
|
2021-03-09 05:20:28 +13:00
|
|
|
|
2021-03-10 04:52:51 +13:00
|
|
|
def list(self):
|
2021-08-29 06:03:25 +12:00
|
|
|
self.icon_view_button.setIcon(icon("mdi.view-grid-outline"))
|
2021-03-10 04:52:51 +13:00
|
|
|
self.list_view.setIcon(icon("fa5s.list", color="orange"))
|
|
|
|
self.icon_view = True
|
|
|
|
self.toggled.emit()
|
2021-06-11 00:13:28 +12:00
|
|
|
|
|
|
|
|
|
|
|
class ImageLabel(QLabel):
|
2021-10-10 00:33:54 +13:00
|
|
|
image = None
|
|
|
|
img_size = None
|
|
|
|
name = str()
|
2021-06-11 00:13:28 +12:00
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
super(ImageLabel, self).__init__()
|
2021-08-08 10:49:27 +12:00
|
|
|
self.path = cache_dir
|
2021-08-08 09:42:40 +12:00
|
|
|
self.manager = QtRequestManager("bytes")
|
2021-06-11 00:13:28 +12:00
|
|
|
|
2021-09-13 07:19:51 +12:00
|
|
|
def update_image(self, url, name="", size: tuple = (240, 320)):
|
2021-06-11 00:13:28 +12:00
|
|
|
self.setFixedSize(*size)
|
|
|
|
self.img_size = size
|
|
|
|
self.name = name
|
|
|
|
for c in r'<>?":|\/* ':
|
|
|
|
self.name = self.name.replace(c, "")
|
2021-06-11 22:56:25 +12:00
|
|
|
if self.img_size[0] > self.img_size[1]:
|
|
|
|
name_extension = "wide"
|
|
|
|
else:
|
|
|
|
name_extension = "tall"
|
|
|
|
self.name = f"{self.name}_{name_extension}.png"
|
|
|
|
if not os.path.exists(os.path.join(self.path, self.name)):
|
2021-08-23 08:22:17 +12:00
|
|
|
self.manager.get(url, self.image_ready)
|
2021-08-08 09:42:40 +12:00
|
|
|
# self.request.finished.connect(self.image_ready)
|
2021-06-11 00:13:28 +12:00
|
|
|
else:
|
|
|
|
self.show_image()
|
|
|
|
|
2021-08-08 09:42:40 +12:00
|
|
|
def image_ready(self, data):
|
2021-09-13 07:19:51 +12:00
|
|
|
self.setPixmap(QPixmap())
|
2021-08-26 06:25:10 +12:00
|
|
|
try:
|
|
|
|
image: Image.Image = Image.open(io.BytesIO(data))
|
|
|
|
except PIL.UnidentifiedImageError:
|
|
|
|
return
|
2021-09-13 07:19:51 +12:00
|
|
|
image = image.resize((self.img_size[:2]))
|
2021-08-08 09:42:40 +12:00
|
|
|
byte_array = io.BytesIO()
|
|
|
|
image.save(byte_array, format="PNG")
|
|
|
|
# pixmap = QPixmap.fromImage(ImageQt(image))
|
|
|
|
pixmap = QPixmap()
|
|
|
|
pixmap.loadFromData(byte_array.getvalue())
|
|
|
|
# pixmap = QPixmap.fromImage(ImageQt.ImageQt(image))
|
2021-09-13 07:19:51 +12:00
|
|
|
pixmap = pixmap.scaled(*self.img_size[:2], Qt.KeepAspectRatioByExpanding)
|
2021-08-08 09:42:40 +12:00
|
|
|
self.setPixmap(pixmap)
|
2021-06-11 00:13:28 +12:00
|
|
|
|
|
|
|
def show_image(self):
|
2021-06-11 22:56:25 +12:00
|
|
|
self.image = QPixmap(os.path.join(self.path, self.name)).scaled(*self.img_size,
|
2021-06-21 08:22:36 +12:00
|
|
|
transformMode=Qt.SmoothTransformation)
|
2021-06-11 00:13:28 +12:00
|
|
|
self.setPixmap(self.image)
|
2021-06-21 08:22:36 +12:00
|
|
|
|
|
|
|
|
|
|
|
class ButtonLineEdit(QLineEdit):
|
|
|
|
buttonClicked = pyqtSignal()
|
|
|
|
|
|
|
|
def __init__(self, icon_name, placeholder_text: str, parent=None):
|
|
|
|
super(ButtonLineEdit, self).__init__(parent)
|
|
|
|
|
|
|
|
self.button = QToolButton(self)
|
|
|
|
self.button.setIcon(icon(icon_name, color="white"))
|
|
|
|
self.button.setStyleSheet('border: 0px; padding: 0px;')
|
|
|
|
self.button.setCursor(Qt.ArrowCursor)
|
|
|
|
self.button.clicked.connect(self.buttonClicked.emit)
|
2021-06-30 10:38:42 +12:00
|
|
|
self.setPlaceholderText(placeholder_text)
|
2021-06-21 08:22:36 +12:00
|
|
|
frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
|
|
|
|
buttonSize = self.button.sizeHint()
|
|
|
|
|
|
|
|
self.setStyleSheet('QLineEdit {padding-right: %dpx; }' % (buttonSize.width() + frameWidth + 1))
|
|
|
|
self.setMinimumSize(max(self.minimumSizeHint().width(), buttonSize.width() + frameWidth * 2 + 2),
|
|
|
|
max(self.minimumSizeHint().height(), buttonSize.height() + frameWidth * 2 + 2))
|
|
|
|
|
|
|
|
def resizeEvent(self, event):
|
|
|
|
buttonSize = self.button.sizeHint()
|
|
|
|
frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
|
|
|
|
self.button.move(self.rect().right() - frameWidth - buttonSize.width(),
|
|
|
|
(self.rect().bottom() - buttonSize.height() + 1) / 2)
|
|
|
|
super(ButtonLineEdit, self).resizeEvent(event)
|