{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Dynamic grid layout\n\nExample for dynamically changing the content of a grid layout.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from itomUi import (\n ItomUi,\n) # import the base class ItomUi from the module itomUi in the itom-packages subfolder\nfrom itom import ui\n\n\n\nclass DynamicGridLayout(ItomUi):\n\n LOAD_FROM_UI = \"\"\n\n def __init__(self):\n \"\"\"Constructor.\n \"\"\"\n\n # call constructor of ItomUi like it would be the constructor of the class itom.ui:\n ItomUi.__init__(self, \"dynamicGridLayout.ui\", ui.TYPEWINDOW)\n\n # the spacing between each item of the layout is a property\n self.layout[\"spacing\"] = 7\n\n # contents margins is left, top, right, bottom\n self.layout.call(\"setContentsMargins\", 30, 15, 20, 5)\n\n self.gui.comboAddWidget.call(\n \"addItems\",\n [\n self.LOAD_FROM_UI,\n ]\n + ui.availableWidgets(),\n )\n\n self._update()\n\n @property\n def layout(self):\n \"\"\"The reference to the grid layout.\"\"\"\n return self.gui.gridLayout\n\n @property\n def rowCount(self):\n \"\"\"Returns number of rows in the grid layout.\"\"\"\n return self.layout.call(\"rowCount\")\n\n @property\n def columnCount(self):\n \"\"\"Returns number of column in the grid layout.\"\"\"\n return self.layout.call(\"columnCount\")\n\n @ItomUi.autoslot(\"\")\n def on_btnAddWidget_clicked(self):\n rowFrom = self.gui.spinAddRowFrom[\"value\"]\n colFrom = self.gui.spinAddColFrom[\"value\"]\n rowSpan = self.gui.spinAddRowSpan[\"value\"]\n colSpan = self.gui.spinAddColSpan[\"value\"]\n widget = self.gui.comboAddWidget[\"currentText\"]\n\n if widget == self.LOAD_FROM_UI:\n filename = ui.getOpenFileName(\"UI File\", filters=\"UI Files (*.ui)\", parent=self.gui)\n\n if filename is not None:\n self.layout.call(\n \"addItemToGridFromUiFile\",\n filename,\n f\"_{rowFrom}_{colFrom}\",\n rowFrom,\n colFrom,\n rowSpan,\n colSpan,\n )\n else:\n self.layout.call(\n \"addItemToGrid\",\n widget,\n f\"item_{rowFrom}_{colFrom}\",\n rowFrom,\n colFrom,\n rowSpan,\n colSpan,\n )\n\n self._update()\n\n @ItomUi.autoslot(\"\")\n def on_btnRemoveWidget_clicked(self):\n row = self.gui.spinRemoveRow[\"value\"]\n column = self.gui.spinRemoveColumn[\"value\"]\n\n try:\n self.layout.call(\"removeItemFromGrid\", row, column)\n except RuntimeError as ex:\n ui.msgCritical(\"Error\", str(ex), parent=self.gui)\n\n self._update()\n\n @ItomUi.autoslot(\"\")\n def on_btnInfo_clicked(self):\n text = f\"Current grid size: {self.rowCount} rows x {self.columnCount} columns.\"\n text += \"\\n\\n\"\n\n for r in range(self.rowCount):\n for c in range(self.columnCount):\n try:\n item = self.layout.call(\"itemAtPosition\", r, c)\n except RuntimeError:\n item = \"-\"\n text += f\"Row {r}, col {c}: {item}\\n\"\n\n ui.msgInformation(\"Grid Content\", text, parent=self.gui)\n\n @ItomUi.autoslot(\"\")\n def on_btnColStretch_clicked(self):\n\n if self.rowCount * self.columnCount <= 0:\n return\n\n stretchs = [str(self.layout.call(\"columnStretch\", idx)) for idx in range(self.columnCount)]\n\n text, valid = ui.getText(\n \"Stretch\",\n f\"Indicate a comma-separated list of stretch \" f\"factors for up to {self.columnCount} columns\",\n \",\".join(stretchs),\n )\n\n if valid:\n stretchs = text.split(\",\")\n\n if len(stretchs) > self.columnCount:\n ui.msgCritical(\n \"Wrong input\",\n f\"Stretchs must be a comma separated list of \" f\"integers (max. {self.columnCount} entries)\",\n parent=self.gui,\n )\n return\n\n for idx in range(len(stretchs)):\n try:\n val = int(stretchs[idx])\n except ValueError:\n ui.msgCiritcal(\n \"Wrong input\",\n f\"Value '{stretchs[idx]}' is no integer number\",\n parent=self.gui,\n )\n return\n\n self.layout.call(\"setColumnStretch\", idx, val)\n\n @ItomUi.autoslot(\"\")\n def on_btnRowStretch_clicked(self):\n\n if self.rowCount * self.columnCount <= 0:\n return\n\n stretchs = [str(self.layout.call(\"rowStretch\", idx)) for idx in range(self.rowCount)]\n\n text, valid = ui.getText(\n \"Stretch\",\n f\"Indicate a comma-separated list of stretch \" f\"factors for up to {self.rowCount} columns\",\n \",\".join(stretchs),\n )\n\n if valid:\n stretchs = text.split(\",\")\n\n if len(stretchs) > self.rowCount:\n ui.msgCritical(\n \"Wrong input\",\n f\"Stretchs must be a comma separated list of \" f\"integers (max. {self.rowCount} entries)\",\n parent=self.gui,\n )\n return\n\n for idx in range(len(stretchs)):\n try:\n val = int(stretchs[idx])\n except ValueError:\n ui.msgCiritcal(\n \"Wrong input\",\n f\"Value '{stretchs[idx]}' is no integer number\",\n parent=self.gui,\n )\n return\n\n self.layout.call(\"setRowStretch\", idx, val)\n\n def _update(self):\n self.gui.btnRemoveWidget[\"enabled\"] = (self.rowCount * self.columnCount) > 0\n self.gui.btnColStretch[\"enabled\"] = (self.rowCount * self.columnCount) > 0\n self.gui.btnRowStretch[\"enabled\"] = (self.rowCount * self.columnCount) > 0\n self.gui.lblCaption[\"text\"] = (\n f\"Grid Layout (Current grid size: \" f\"{self.rowCount} rows x {self.columnCount} columns)\"\n )\n\n\nif __name__ == \"__main__\":\n # create a first instance of AutoConnectExample and the gui\n win1 = DynamicGridLayout()\n win1.gui.show() # show the gui" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 0 }