Я пытаюсь создать полупрозрачный QWidget произвольной формы, используя QPainterPath, который рисует фигуру с помощью QBrush, а затем границы вокруг нее с помощью QPen. Пока я получаю нужную форму, граница моего окна отклоняется на 1 пиксель вправо:
[img]https:/ /i.sstatic.net/TOXNI5Jj.png[/img]
Надеюсь, фотография сможет передать мою точку зрения. Слева вы можете увидеть темное пятно, которое показывает, что пиксели кнопки и границы перекрываются по сравнению с правым. Я не уверен, связано ли это с моими расчетами в коде или с внутренним ограничением способа отрисовки окна?
import functools as _functools
import typing as _t
from Qt import (
QtCore as _QtCore,
QtGui as _QtGui,
QtWidgets as _QtWidgets,
)
class MyWindow(_QtWidgets.QWidget):
_MAX_WIDTH = 600
_CLOSE_BUTTON_SIZE: _t.ClassVar[_t.Tuple[int, int]] = (15, 15)
_CLOSE_BUTTON_TOOLTIP: _t.ClassVar[str] = "Close"
_BORDER_WIDTH = 15.0
def __init__(self):
super().__init__(parent=None)
self._tip_palette = _QtWidgets.QToolTip.palette()
self._setup_ui()
self._setup_connections()
# TODO: Remove after testing.
self._setup_pdb()
self.setAttribute(_QtCore.Qt.WA_TranslucentBackground)
self.setWindowFlag(_QtCore.Qt.FramelessWindowHint)
self.setAttribute(_QtCore.Qt.WA_DeleteOnClose)
self.setWindowFlag(_QtCore.Qt.ToolTip)
self.allow_close(True)
self.resize(1000, 500)
self._window_shape_path = self._get_window_shape_path()
def set_message(self, text: str) -> None:
self._message_label.setText(text)
def allow_close(self, allow: bool):
self._close_t_button.setHidden(not allow)
def _get_window_shape_path(self) -> _QtGui.QPainterPath:
shape_size = _QtCore.QSizeF(self.geometry().size())
center_offset = self._BORDER_WIDTH/2
origin = _QtCore.QPointF(center_offset, center_offset)
bottom_left = _QtCore.QPointF(origin.x(), shape_size.height() - center_offset)
bottom_right = _QtCore.QPointF(shape_size.width() - center_offset, bottom_left.y())
top_right = _QtCore.QPointF(bottom_right.x(), origin.y())
shape_path = _QtGui.QPainterPath()
shape_path.moveTo(origin)
shape_path.lineTo(bottom_left)
shape_path.lineTo(bottom_right)
shape_path.lineTo(top_right)
shape_path.lineTo(origin)
return shape_path
def paintEvent(self, event: _QtGui.QPaintEvent) -> None:
painter = _QtGui.QPainter(self)
brush = self._tip_palette.background()
pen = _QtGui.QPen()
pen.setColor(_QtCore.Qt.red)
pen.setWidthF(self._BORDER_WIDTH)
painter.setBrush(brush)
painter.setPen(pen)
painter.drawPath(self._window_shape_path)
def _setup_ui(self):
self._message_label = _QtWidgets.QLabel()
self._message_label.setWordWrap(True)
self._message_label.setForegroundRole(self._tip_palette.ToolTipText)
self._button = _QtWidgets.QPushButton()
self._close_t_button = _QtWidgets.QToolButton()
self._close_t_button.setIcon(
_QtWidgets.QApplication.style().standardIcon(
_QtWidgets.QStyle.SP_TitleBarCloseButton
)
)
self._close_t_button.setToolTip(self._CLOSE_BUTTON_TOOLTIP)
self._close_t_button.setFixedSize(*self._CLOSE_BUTTON_SIZE)
self._main_layout = _QtWidgets.QVBoxLayout()
self._main_layout.addWidget(
self._close_t_button, alignment=_QtCore.Qt.AlignRight
)
self._main_layout.addWidget(self._message_label)
self._main_layout.addWidget(self._button)
self.setLayout(self._main_layout)
self.setMaximumWidth(self._MAX_WIDTH)
self._message_label.setMaximumWidth(
self.maximumWidth() - self._main_layout.contentsMargins().right()
)
def _setup_connections(self):
self._close_t_button.clicked.connect(_functools.partial(self.close))
def _setup_pdb(self):
self._pdb_shortcut = _QtWidgets.QShortcut(_QtGui.QKeySequence("Ctrl+p"), self)
self._pdb_shortcut.activated.connect(self._launch_pdb)
def _launch_pdb(self):
import pdb
pdb.set_trace()
if __name__ == "__main__":
import sys as _sys
app = _QtWidgets.QApplication([])
widget = MyWindow()
widget.show()
_sys.exit(app.exec_())
Подробнее здесь: https://stackoverflow.com/questions/792 ... -my-window
Почему моя граница QPainterPath отклоняется на 1 пиксель справа от моего окна? ⇐ Python
Программы на Python
1732689710
Anonymous
Я пытаюсь создать полупрозрачный QWidget произвольной формы, используя QPainterPath, который рисует фигуру с помощью QBrush, а затем границы вокруг нее с помощью QPen. Пока я получаю нужную форму, граница моего окна отклоняется на 1 пиксель вправо:
[img]https:/ /i.sstatic.net/TOXNI5Jj.png[/img]
Надеюсь, фотография сможет передать мою точку зрения. Слева вы можете увидеть темное пятно, которое показывает, что пиксели кнопки и границы перекрываются по сравнению с правым. Я не уверен, связано ли это с моими расчетами в коде или с внутренним ограничением способа отрисовки окна?
import functools as _functools
import typing as _t
from Qt import (
QtCore as _QtCore,
QtGui as _QtGui,
QtWidgets as _QtWidgets,
)
class MyWindow(_QtWidgets.QWidget):
_MAX_WIDTH = 600
_CLOSE_BUTTON_SIZE: _t.ClassVar[_t.Tuple[int, int]] = (15, 15)
_CLOSE_BUTTON_TOOLTIP: _t.ClassVar[str] = "Close"
_BORDER_WIDTH = 15.0
def __init__(self):
super().__init__(parent=None)
self._tip_palette = _QtWidgets.QToolTip.palette()
self._setup_ui()
self._setup_connections()
# TODO: Remove after testing.
self._setup_pdb()
self.setAttribute(_QtCore.Qt.WA_TranslucentBackground)
self.setWindowFlag(_QtCore.Qt.FramelessWindowHint)
self.setAttribute(_QtCore.Qt.WA_DeleteOnClose)
self.setWindowFlag(_QtCore.Qt.ToolTip)
self.allow_close(True)
self.resize(1000, 500)
self._window_shape_path = self._get_window_shape_path()
def set_message(self, text: str) -> None:
self._message_label.setText(text)
def allow_close(self, allow: bool):
self._close_t_button.setHidden(not allow)
def _get_window_shape_path(self) -> _QtGui.QPainterPath:
shape_size = _QtCore.QSizeF(self.geometry().size())
center_offset = self._BORDER_WIDTH/2
origin = _QtCore.QPointF(center_offset, center_offset)
bottom_left = _QtCore.QPointF(origin.x(), shape_size.height() - center_offset)
bottom_right = _QtCore.QPointF(shape_size.width() - center_offset, bottom_left.y())
top_right = _QtCore.QPointF(bottom_right.x(), origin.y())
shape_path = _QtGui.QPainterPath()
shape_path.moveTo(origin)
shape_path.lineTo(bottom_left)
shape_path.lineTo(bottom_right)
shape_path.lineTo(top_right)
shape_path.lineTo(origin)
return shape_path
def paintEvent(self, event: _QtGui.QPaintEvent) -> None:
painter = _QtGui.QPainter(self)
brush = self._tip_palette.background()
pen = _QtGui.QPen()
pen.setColor(_QtCore.Qt.red)
pen.setWidthF(self._BORDER_WIDTH)
painter.setBrush(brush)
painter.setPen(pen)
painter.drawPath(self._window_shape_path)
def _setup_ui(self):
self._message_label = _QtWidgets.QLabel()
self._message_label.setWordWrap(True)
self._message_label.setForegroundRole(self._tip_palette.ToolTipText)
self._button = _QtWidgets.QPushButton()
self._close_t_button = _QtWidgets.QToolButton()
self._close_t_button.setIcon(
_QtWidgets.QApplication.style().standardIcon(
_QtWidgets.QStyle.SP_TitleBarCloseButton
)
)
self._close_t_button.setToolTip(self._CLOSE_BUTTON_TOOLTIP)
self._close_t_button.setFixedSize(*self._CLOSE_BUTTON_SIZE)
self._main_layout = _QtWidgets.QVBoxLayout()
self._main_layout.addWidget(
self._close_t_button, alignment=_QtCore.Qt.AlignRight
)
self._main_layout.addWidget(self._message_label)
self._main_layout.addWidget(self._button)
self.setLayout(self._main_layout)
self.setMaximumWidth(self._MAX_WIDTH)
self._message_label.setMaximumWidth(
self.maximumWidth() - self._main_layout.contentsMargins().right()
)
def _setup_connections(self):
self._close_t_button.clicked.connect(_functools.partial(self.close))
def _setup_pdb(self):
self._pdb_shortcut = _QtWidgets.QShortcut(_QtGui.QKeySequence("Ctrl+p"), self)
self._pdb_shortcut.activated.connect(self._launch_pdb)
def _launch_pdb(self):
import pdb
pdb.set_trace()
if __name__ == "__main__":
import sys as _sys
app = _QtWidgets.QApplication([])
widget = MyWindow()
widget.show()
_sys.exit(app.exec_())
Подробнее здесь: [url]https://stackoverflow.com/questions/79229194/why-is-my-qpainterpath-border-off-by-1-pixel-on-the-right-of-my-window[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия