Skip to content

Commit

Permalink
feat(widgets): add GraphicsAnchorLayout / GraphicsGridLayout / Graphi…
Browse files Browse the repository at this point in the history
…csLinearLayout
  • Loading branch information
phil65 committed Aug 25, 2020
1 parent 9a75bde commit c0e75ed
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 0 deletions.
6 changes: 6 additions & 0 deletions prettyqt/widgets/__init__.py
Expand Up @@ -26,6 +26,9 @@
from .graphicstextitem import GraphicsTextItem
from .graphicslayoutitem import GraphicsLayoutItem
from .graphicslayout import GraphicsLayout
from .graphicsgridlayout import GraphicsGridLayout
from .graphicslinearlayout import GraphicsLinearLayout
from .graphicsanchorlayout import GraphicsAnchorLayout
from .graphicswidget import GraphicsWidget
from .graphicsproxywidget import GraphicsProxyWidget
from .graphicslineitem import GraphicsLineItem
Expand Down Expand Up @@ -164,6 +167,9 @@ def app():
"GraphicsTextItem",
"GraphicsLayoutItem",
"GraphicsLayout",
"GraphicsGridLayout",
"GraphicsAnchorLayout",
"GraphicsLinearLayout",
"GraphicsWidget",
"GraphicsProxyWidget",
"GraphicsLineItem",
Expand Down
74 changes: 74 additions & 0 deletions prettyqt/widgets/graphicsanchorlayout.py
@@ -0,0 +1,74 @@
from qtpy import QtWidgets, QtCore

from prettyqt import widgets
from prettyqt.utils import bidict

ANCHORS = bidict(
left=QtCore.Qt.AnchorLeft,
horizontal_center=QtCore.Qt.AnchorHorizontalCenter,
right=QtCore.Qt.AnchorRight,
top=QtCore.Qt.AnchorTop,
vertical_center=QtCore.Qt.AnchorVerticalCenter,
bottom=QtCore.Qt.AnchorBottom,
)

CORNERS = bidict(
top_left=QtCore.Qt.TopLeftCorner,
top_right=QtCore.Qt.TopRightCorner,
bottom_left=QtCore.Qt.BottomLeftCorner,
bottom_right=QtCore.Qt.BottomRightCorner,
)

QtWidgets.QGraphicsAnchorLayout.__bases__ = (widgets.GraphicsLayout,)


class GraphicsAnchorLayout(QtWidgets.QGraphicsAnchorLayout):
def add_anchor(
self,
first_item: QtWidgets.QGraphicsLayoutItem,
first_edge: str,
second_item: QtWidgets.QGraphicsLayoutItem,
second_edge: str,
):
self.addAnchor(first_item, ANCHORS[first_edge], second_item, ANCHORS[second_edge])

def get_anchor(
self,
first_item: QtWidgets.QGraphicsLayoutItem,
first_edge: str,
second_item: QtWidgets.QGraphicsLayoutItem,
second_edge: str,
):
return self.anchor(
first_item, ANCHORS[first_edge], second_item, ANCHORS[second_edge]
)

def add_anchors(
self,
first_item: QtWidgets.QGraphicsLayoutItem,
second_item: QtWidgets.QGraphicsLayoutItem,
orientation: str,
):
if orientation == "horizontal":
orientation = QtCore.Qt.Horizontal
elif orientation == "vertical":
orientation = QtCore.Qt.Vertical
else:
raise ValueError()
self.addAnchors(first_item, second_item, orientation)

def add_corner_anchors(
self,
first_item: QtWidgets.QGraphicsLayoutItem,
first_corner: str,
second_item: QtWidgets.QGraphicsLayoutItem,
second_corner: str,
):
self.addCornerAnchors(
first_item, CORNERS[first_corner], second_item, CORNERS[second_corner]
)


if __name__ == "__main__":
app = widgets.app()
layout = GraphicsAnchorLayout()
98 changes: 98 additions & 0 deletions prettyqt/widgets/graphicsgridlayout.py
@@ -0,0 +1,98 @@
# -*- coding: utf-8 -*-

from typing import Tuple, Optional

from qtpy import QtWidgets

from prettyqt import widgets, constants
from prettyqt.utils import bidict


ALIGNMENTS = bidict(
left=constants.ALIGN_LEFT,
right=constants.ALIGN_RIGHT,
top=constants.ALIGN_TOP,
bottom=constants.ALIGN_BOTTOM,
top_left=constants.ALIGN_TOP_LEFT,
top_right=constants.ALIGN_TOP_RIGHT,
bottom_left=constants.ALIGN_BOTTOM_LEFT,
bottom_right=constants.ALIGN_BOTTOM_RIGHT,
center=constants.ALIGN_CENTER,
)

QtWidgets.QGraphicsGridLayout.__bases__ = (widgets.GraphicsLayout,)


class GraphicsGridLayout(QtWidgets.QGraphicsGridLayout):
def __getitem__(
self, idx: Tuple[int, int]
) -> Optional[QtWidgets.QGraphicsLayoutItem]:
return self.itemAt(*idx)

def __setitem__(self, idx, value):
row, col = idx
rowspan = row.stop - row.start + 1 if isinstance(row, slice) else 1
colspan = col.stop - col.start + 1 if isinstance(col, slice) else 1
rowstart = row.start if isinstance(row, slice) else row
colstart = col.start if isinstance(col, slice) else col
self.add(value, rowstart, colstart, rowspan, colspan)

def serialize_fields(self):
items = []
positions = []
for row in self.rowCount():
for col in self.columnCount():
item = self.itemAt(row, col)
if item is not None:
items.append(item)
positions.append((row, col))
return dict(widgets=widgets, positions=positions)

def __setstate__(self, state):
self.__init__()
for i, (item, pos) in enumerate(zip(state["widgets"], state["positions"])):
x, y, w, h = pos
self[x : x + w - 1, y : y + h - 1] = item

def __iter__(self):
return iter(self[i] for i in range(self.count()) if self[i] is not None)

def __add__(self, other):
if isinstance(other, (tuple, list)):
for i, control in enumerate(other):
self[self.rowCount(), i] = other
else:
self[self.rowCount(), 0 : self.columnCount() - 1] = other
return self

def add(self, item, rowstart, colstart, rowspan=1, colspan=1):
if isinstance(item, QtWidgets.QWidget):
self.addWidget(item, rowstart, colstart, rowspan, colspan)
elif isinstance(item, QtWidgets.QLayout):
self.addLayout(item, rowstart, colstart, rowspan, colspan)
else:
self.addItem(item, rowstart, colstart, rowspan, colspan)

def append(self, item):
self[self.rowCount(), 0 : self.columnCount() - 1] = item

def set_column_alignment(self, column: int, alignment: str):
self.setColumnAlignment(column, ALIGNMENTS[alignment])

def set_row_alignment(self, row: int, alignment: str):
self.setRowAlignment(row, ALIGNMENTS[alignment])


if __name__ == "__main__":
app = widgets.app()
layout = GraphicsGridLayout()
layout[1, 5:6] = widgets.RadioButton("1 2 3 jk jkjl j kföldsjfköj")
layout[3:5, 7:8] = widgets.RadioButton("2")
layout[3:5, 1:4] = widgets.RadioButton("3")
layout += widgets.RadioButton("3")
layout += widgets.RadioButton("4")
widget = widgets.Widget()
widget.set_layout(layout)
print(layout)
widget.show()
app.exec_()
28 changes: 28 additions & 0 deletions prettyqt/widgets/graphicslinearlayout.py
@@ -0,0 +1,28 @@
from qtpy import QtWidgets
from prettyqt import widgets


QtWidgets.QGraphicsLinearLayout.__bases__ = (widgets.GraphicsLayout,)


class GraphicsLinearLayout(QtWidgets.QGraphicsLinearLayout):
def serialize_fields(self):
return dict(items=self.get_children())

def __setstate__(self, state):
self.__init__()
for i, (item, pos) in enumerate(zip(state["widgets"], state["positions"])):
x, y = pos
self[x, y] = item

def __iter__(self):
return iter(self[i] for i in range(self.count()))

def __add__(self, other):
self[self.count()] = other
return self


if __name__ == "__main__":
app = widgets.app()
layout = GraphicsLinearLayout()

0 comments on commit c0e75ed

Please sign in to comment.