class Window(QWidget): def __init__(self): QWidget.__init__(self) layout = QHBoxLayout(self) self.button = QToolButton(self) self.button.setPopupMode(QToolButton.MenuButtonPopup) self.button.setMenu(QMenu(self.button)) self.textBox = QTextBrowser(self) action = QWidgetAction(self.button) action.setDefaultWidget(self.textBox) self.button.menu().addAction(action) layout.addWidget(self.button)
def addToolbarPopup(toolbar, text = None, icon_name = None, icon_file = None, actions = [], popup_mode = QToolButton.InstantPopup, toolbutton_style=Qt.ToolButtonTextBesideIcon): button = QToolButton() button.setToolButtonStyle(toolbutton_style) button.setDefaultAction(QAction(button)) if text: button.defaultAction().setText(text) button.defaultAction().setIconText(text) button.setPopupMode(popup_mode) button.setMenu(QMenu()) if icon_name: button.defaultAction().setIcon(QIcon.fromTheme(icon_name)) if icon_file: button.defaultAction().setIcon(QIcon(icon_file)) for action in actions: button.menu().addAction(action) toolbar.addWidget(button) return button
def addToolbarPopup(toolbar, text=None, icon_name=None, icon_file=None, actions=[], popup_mode=QToolButton.InstantPopup, toolbutton_style=Qt.ToolButtonTextBesideIcon): button = QToolButton() button.setToolButtonStyle(toolbutton_style) button.setDefaultAction(QAction(button)) if text: button.defaultAction().setText(text) button.defaultAction().setIconText(text) button.setPopupMode(popup_mode) button.setMenu(QMenu()) if icon_name: button.defaultAction().setIcon(QIcon.fromTheme(icon_name)) if icon_file: button.defaultAction().setIcon(QIcon(icon_file)) for action in actions: button.menu().addAction(action) toolbar.addWidget(button) return button
class MainWindow(QMainWindow): InsertTextButton = 10 def __init__(self): super(MainWindow, self).__init__() self.createActions() self.createMenus() self.createToolBox() self.scene = DiagramScene(self.itemMenu) self.scene.setSceneRect(QRectF(0, 0, 5000, 5000)) self.scene.itemInserted.connect(self.itemInserted) self.scene.textInserted.connect(self.textInserted) self.scene.itemSelected.connect(self.itemSelected) self.createToolbars() layout = QHBoxLayout() layout.addWidget(self.toolBox) self.view = QGraphicsView(self.scene) layout.addWidget(self.view) self.widget = QWidget() self.widget.setLayout(layout) self.setCentralWidget(self.widget) self.setWindowTitle("Diagramscene") def backgroundButtonGroupClicked(self, button): buttons = self.backgroundButtonGroup.buttons() for myButton in buttons: if myButton != button: button.setChecked(False) text = button.text() if text == "Blue Grid": self.scene.setBackgroundBrush(QBrush(QPixmap(':/images/background1.png'))) elif text == "White Grid": self.scene.setBackgroundBrush(QBrush(QPixmap(':/images/background2.png'))) elif text == "Gray Grid": self.scene.setBackgroundBrush(QBrush(QPixmap(':/images/background3.png'))) else: self.scene.setBackgroundBrush(QBrush(QPixmap(':/images/background4.png'))) self.scene.update() self.view.update() def buttonGroupClicked(self, id): buttons = self.buttonGroup.buttons() for button in buttons: if self.buttonGroup.button(id) != button: button.setChecked(False) if id == self.InsertTextButton: self.scene.setMode(DiagramScene.InsertText) else: self.scene.setItemType(id) self.scene.setMode(DiagramScene.InsertItem) def deleteItem(self): for item in self.scene.selectedItems(): if isinstance(item, DiagramItem): item.removeArrows() self.scene.removeItem(item) def pointerGroupClicked(self, i): self.scene.setMode(self.pointerTypeGroup.checkedId()) def bringToFront(self): if not self.scene.selectedItems(): return selectedItem = self.scene.selectedItems()[0] overlapItems = selectedItem.collidingItems() zValue = 0 for item in overlapItems: if (item.zValue() >= zValue and isinstance(item, DiagramItem)): zValue = item.zValue() + 0.1 selectedItem.setZValue(zValue) def sendToBack(self): if not self.scene.selectedItems(): return selectedItem = self.scene.selectedItems()[0] overlapItems = selectedItem.collidingItems() zValue = 0 for item in overlapItems: if (item.zValue() <= zValue and isinstance(item, DiagramItem)): zValue = item.zValue() - 0.1 selectedItem.setZValue(zValue) def itemInserted(self, item): self.pointerTypeGroup.button(DiagramScene.MoveItem).setChecked(True) self.scene.setMode(self.pointerTypeGroup.checkedId()) self.buttonGroup.button(item.diagramType).setChecked(False) def textInserted(self, item): self.buttonGroup.button(self.InsertTextButton).setChecked(False)# self.scene.setMode(self.pointerTypeGroup.checkedId()) def currentFontChanged(self, font): self.handleFontChange() def fontSizeChanged(self, font): self.handleFontChange() def sceneScaleChanged(self, scale): newScale = float(scale[:scale.index("%")]) / 100.0 oldMatrix = self.view.transform() self.view.resetTransform() self.view.translate(oldMatrix.dx(), oldMatrix.dy()) self.view.scale(newScale, newScale) def textColorChanged(self): self.textAction = self.sender() self.fontColorToolButton.setIcon( self.createColorToolButtonIcon(':/images/textpointer.png', QColor(self.textAction.data()))) self.textButtonTriggered() def itemColorChanged(self): self.fillAction = self.sender() self.fillColorToolButton.setIcon( self.createColorToolButtonIcon( ':/images/floodfill.png', QColor(self.fillAction.data()))) self.fillButtonTriggered() def lineColorChanged(self): self.lineAction = self.sender() self.lineColorToolButton.setIcon( self.createColorToolButtonIcon(':/images/linecolor.png', QColor(self.lineAction.data()))) self.lineButtonTriggered() def textButtonTriggered(self): self.scene.setTextColor(QColor(self.textAction.data())) def fillButtonTriggered(self): self.scene.setItemColor(QColor(self.fillAction.data())) def lineButtonTriggered(self): self.scene.setLineColor(QColor(self.lineAction.data())) def handleFontChange(self): font = self.fontCombo.currentFont() font.setPointSize(int(self.fontSizeCombo.currentText())) if self.boldAction.isChecked(): font.setWeight(QFont.Bold) else: font.setWeight(QFont.Normal) font.setItalic(self.italicAction.isChecked()) font.setUnderline(self.underlineAction.isChecked()) self.scene.setFont(font) def itemSelected(self, item): font = item.font() color = item.defaultTextColor() self.fontCombo.setCurrentFont(font) self.fontSizeCombo.setEditText(str(font.pointSize())) self.boldAction.setChecked(font.weight() == QFont.Bold) self.italicAction.setChecked(font.italic()) self.underlineAction.setChecked(font.underline()) def about(self): QMessageBox.about(self, "About Diagram Scene", "The <b>Diagram Scene</b> example shows use of the graphics framework.") def createToolBox(self): self.buttonGroup = QButtonGroup() self.buttonGroup.setExclusive(False) self.buttonGroup.buttonClicked[int].connect(self.buttonGroupClicked) layout = QGridLayout() layout.addWidget(self.createCellWidget("Conditional", DiagramItem.Conditional), 0, 0) layout.addWidget(self.createCellWidget("Process", DiagramItem.Step), 0, 1) layout.addWidget(self.createCellWidget("Input/Output", DiagramItem.Io), 1, 0) textButton = QToolButton() textButton.setCheckable(True) self.buttonGroup.addButton(textButton, self.InsertTextButton) textButton.setIcon(QIcon(QPixmap(':/images/textpointer.png').scaled(30, 30))) textButton.setIconSize(QSize(50, 50)) textLayout = QGridLayout() textLayout.addWidget(textButton, 0, 0, Qt.AlignHCenter) textLayout.addWidget(QLabel("Text"), 1, 0, Qt.AlignCenter) textWidget = QWidget() textWidget.setLayout(textLayout) layout.addWidget(textWidget, 1, 1) layout.setRowStretch(3, 10) layout.setColumnStretch(2, 10) itemWidget = QWidget() itemWidget.setLayout(layout) self.backgroundButtonGroup = QButtonGroup() self.backgroundButtonGroup.buttonClicked.connect(self.backgroundButtonGroupClicked) backgroundLayout = QGridLayout() backgroundLayout.addWidget(self.createBackgroundCellWidget("Blue Grid", ':/images/background1.png'), 0, 0) backgroundLayout.addWidget(self.createBackgroundCellWidget("White Grid", ':/images/background2.png'), 0, 1) backgroundLayout.addWidget(self.createBackgroundCellWidget("Gray Grid", ':/images/background3.png'), 1, 0) backgroundLayout.addWidget(self.createBackgroundCellWidget("No Grid", ':/images/background4.png'), 1, 1) backgroundLayout.setRowStretch(2, 10) backgroundLayout.setColumnStretch(2, 10) backgroundWidget = QWidget() backgroundWidget.setLayout(backgroundLayout) self.toolBox = QToolBox() self.toolBox.setSizePolicy(QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Ignored)) self.toolBox.setMinimumWidth(itemWidget.sizeHint().width()) self.toolBox.addItem(itemWidget, "Basic Flowchart Shapes") self.toolBox.addItem(backgroundWidget, "Backgrounds") def createActions(self): self.toFrontAction = QAction( QIcon(':/images/bringtofront.png'), "Bring to &Front", self, shortcut="Ctrl+F", statusTip="Bring item to front", triggered=self.bringToFront) self.sendBackAction = QAction( QIcon(':/images/sendtoback.png'), "Send to &Back", self, shortcut="Ctrl+B", statusTip="Send item to back", triggered=self.sendToBack) self.deleteAction = QAction(QIcon(':/images/delete.png'), "&Delete", self, shortcut="Delete", statusTip="Delete item from diagram", triggered=self.deleteItem) self.exitAction = QAction("E&xit", self, shortcut="Ctrl+X", statusTip="Quit Scenediagram example", triggered=self.close) self.boldAction = QAction(QIcon(':/images/bold.png'), "Bold", self, checkable=True, shortcut="Ctrl+B", triggered=self.handleFontChange) self.italicAction = QAction(QIcon(':/images/italic.png'), "Italic", self, checkable=True, shortcut="Ctrl+I", triggered=self.handleFontChange) self.underlineAction = QAction( QIcon(':/images/underline.png'), "Underline", self, checkable=True, shortcut="Ctrl+U", triggered=self.handleFontChange) self.aboutAction = QAction("A&bout", self, shortcut="Ctrl+B", triggered=self.about) def createMenus(self): self.fileMenu = self.menuBar().addMenu("&File") self.fileMenu.addAction(self.exitAction) self.itemMenu = self.menuBar().addMenu("&Item") self.itemMenu.addAction(self.deleteAction) self.itemMenu.addSeparator() self.itemMenu.addAction(self.toFrontAction) self.itemMenu.addAction(self.sendBackAction) self.aboutMenu = self.menuBar().addMenu("&Help") self.aboutMenu.addAction(self.aboutAction) def createToolbars(self): self.editToolBar = self.addToolBar("Edit") self.editToolBar.addAction(self.deleteAction) self.editToolBar.addAction(self.toFrontAction) self.editToolBar.addAction(self.sendBackAction) self.fontCombo = QFontComboBox() self.fontCombo.currentFontChanged.connect(self.currentFontChanged) self.fontSizeCombo = QComboBox() self.fontSizeCombo.setEditable(True) for i in range(8, 30, 2): self.fontSizeCombo.addItem(str(i)) validator = QIntValidator(2, 64, self) self.fontSizeCombo.setValidator(validator) self.fontSizeCombo.currentIndexChanged.connect(self.fontSizeChanged) self.fontColorToolButton = QToolButton() self.fontColorToolButton.setPopupMode(QToolButton.MenuButtonPopup) self.fontColorToolButton.setMenu( self.createColorMenu(self.textColorChanged, Qt.black)) self.textAction = self.fontColorToolButton.menu().defaultAction() self.fontColorToolButton.setIcon( self.createColorToolButtonIcon(':/images/textpointer.png', Qt.black)) self.fontColorToolButton.setAutoFillBackground(True) self.fontColorToolButton.clicked.connect(self.textButtonTriggered) self.fillColorToolButton = QToolButton() self.fillColorToolButton.setPopupMode(QToolButton.MenuButtonPopup) self.fillColorToolButton.setMenu( self.createColorMenu(self.itemColorChanged, Qt.white)) self.fillAction = self.fillColorToolButton.menu().defaultAction() self.fillColorToolButton.setIcon( self.createColorToolButtonIcon(':/images/floodfill.png', Qt.white)) self.fillColorToolButton.clicked.connect(self.fillButtonTriggered) self.lineColorToolButton = QToolButton() self.lineColorToolButton.setPopupMode(QToolButton.MenuButtonPopup) self.lineColorToolButton.setMenu( self.createColorMenu(self.lineColorChanged, Qt.black)) self.lineAction = self.lineColorToolButton.menu().defaultAction() self.lineColorToolButton.setIcon( self.createColorToolButtonIcon(':/images/linecolor.png', Qt.black)) self.lineColorToolButton.clicked.connect(self.lineButtonTriggered) self.textToolBar = self.addToolBar("Font") self.textToolBar.addWidget(self.fontCombo) self.textToolBar.addWidget(self.fontSizeCombo) self.textToolBar.addAction(self.boldAction) self.textToolBar.addAction(self.italicAction) self.textToolBar.addAction(self.underlineAction) self.colorToolBar = self.addToolBar("Color") self.colorToolBar.addWidget(self.fontColorToolButton) self.colorToolBar.addWidget(self.fillColorToolButton) self.colorToolBar.addWidget(self.lineColorToolButton) pointerButton = QToolButton() pointerButton.setCheckable(True) pointerButton.setChecked(True) pointerButton.setIcon(QIcon(':/images/pointer.png')) linePointerButton = QToolButton() linePointerButton.setCheckable(True) linePointerButton.setIcon(QIcon(':/images/linepointer.png')) self.pointerTypeGroup = QButtonGroup() self.pointerTypeGroup.addButton(pointerButton, DiagramScene.MoveItem) self.pointerTypeGroup.addButton(linePointerButton, DiagramScene.InsertLine) self.pointerTypeGroup.buttonClicked[int].connect(self.pointerGroupClicked) self.sceneScaleCombo = QComboBox() self.sceneScaleCombo.addItems(["50%", "75%", "100%", "125%", "150%"]) self.sceneScaleCombo.setCurrentIndex(2) self.sceneScaleCombo.currentIndexChanged[str].connect(self.sceneScaleChanged) self.pointerToolbar = self.addToolBar("Pointer type") self.pointerToolbar.addWidget(pointerButton) self.pointerToolbar.addWidget(linePointerButton) self.pointerToolbar.addWidget(self.sceneScaleCombo) def createBackgroundCellWidget(self, text, image): button = QToolButton() button.setText(text) button.setIcon(QIcon(image)) button.setIconSize(QSize(50, 50)) button.setCheckable(True) self.backgroundButtonGroup.addButton(button) layout = QGridLayout() layout.addWidget(button, 0, 0, Qt.AlignHCenter) layout.addWidget(QLabel(text), 1, 0, Qt.AlignCenter) widget = QWidget() widget.setLayout(layout) return widget def createCellWidget(self, text, diagramType): item = DiagramItem(diagramType, self.itemMenu) icon = QIcon(item.image()) button = QToolButton() button.setIcon(icon) button.setIconSize(QSize(50, 50)) button.setCheckable(True) self.buttonGroup.addButton(button, diagramType) layout = QGridLayout() layout.addWidget(button, 0, 0, Qt.AlignHCenter) layout.addWidget(QLabel(text), 1, 0, Qt.AlignCenter) widget = QWidget() widget.setLayout(layout) return widget def createColorMenu(self, slot, defaultColor): colors = [Qt.black, Qt.white, Qt.red, Qt.blue, Qt.yellow] names = ["black", "white", "red", "blue", "yellow"] colorMenu = QMenu(self) for color, name in zip(colors, names): action = QAction(self.createColorIcon(color), name, self, triggered=slot) action.setData(QColor(color)) colorMenu.addAction(action) if color == defaultColor: colorMenu.setDefaultAction(action) return colorMenu def createColorToolButtonIcon(self, imageFile, color): pixmap = QPixmap(50, 80) pixmap.fill(Qt.transparent) painter = QPainter(pixmap) image = QPixmap(imageFile) target = QRect(0, 0, 50, 60) source = QRect(0, 0, 42, 42) painter.fillRect(QRect(0, 60, 50, 80), color) painter.drawPixmap(target, image, source) painter.end() return QIcon(pixmap) def createColorIcon(self, color): pixmap = QPixmap(20, 20) painter = QPainter(pixmap) painter.setPen(Qt.NoPen) painter.fillRect(QRect(0, 0, 20, 20), color) painter.end() return QIcon(pixmap)
class QToolsMenuToolWindowArea(QToolWindowArea): """ Handles the tabbar and decides where the menu button should be displayed. """ def __init__(self, manager, parent): super(QToolsMenuToolWindowArea, self).__init__(manager, parent) self.tabBar().currentChanged.connect(self.onCurrentChanged) self.setMovable(True) self.menuButton = QToolButton(self) self.menuButton.setObjectName("QuickAccessButton") self.menuButton.setPopupMode(QToolButton.InstantPopup) self.menuButton.setVisible(False) self.menuButton.setIcon( QIcon("./QToolWindowManager/resources/general_corner_menu.ico")) customTabFrame = QToolsMenuWindowSingleTabAreaFrame(manager, self) self.menuButton.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) # self.addAction ( ) customTabFrame.layout.addWidget( self.menuButton, 0, 1, QtCore.Qt.AlignVCenter | QtCore.Qt.AlignRight) self.tabFrame = customTabFrame self.tabFrame.hide() self.tabFrame.installEventFilter(self) self.tabFrame.caption.installEventFilter(self) self.tabBar().installEventFilter(self) def adjustDragVisuals(self): currentIdx = self.tabBar().currentIndex() if currentIdx >= 0: focusTarget = self.setupMenu(currentIdx) self.menuButton.setFocusProxy(focusTarget) self.tabBar().setFocusProxy(focusTarget) customTabFrame = cast(self.tabFrame, QToolsMenuWindowSingleTabAreaFrame) floatingWrapper = self.manager.isFloatingWrapper( self.parentWidget()) # print ( "[QToolsMenuToolWindowArea] adjustDragVisuals isFloatingWrapper %s %s" % ( floatingWrapper, self.parentWidget () ), self ) if self.tabBar().count() > 1: self.setCornerWidget(self.menuButton) elif self.tabBar().count() == 1: customTabFrame.layout.addWidget( self.menuButton, 0, 1, QtCore.Qt.AlignVCenter | QtCore.Qt.AlignRight) # If we are floating we can hide the caption because we already # have the titlebar in Sandbox wrapper to show the title if customTabFrame != None: if floatingWrapper: customTabFrame.caption.hide() else: customTabFrame.caption.show() self.updateMenuButtonVisibility() super().adjustDragVisuals() def shouldShowSingleTabFrame(self): if not self.manager.config.setdefault(QTWM_SINGLE_TAB_FRAME, True): return False if self.count() == 1: return True return False def event(self, e): # TODO: SandboxEvent # if e.type() == SandboxEvent.Command: return super().event(e) def onCurrentChanged(self, index): if index < 0 or self.tabBar().count() == 1: return focusTarget = self.setupMenu(index) self.menuButton.setFocusProxy(focusTarget) self.tabBar().setFocusProxy(focusTarget) customTabFrame = cast(self.tabFrame, QToolsMenuWindowSingleTabAreaFrame) if self.tabBar().count() > 1: self.setCornerWidget(self.menuButton) elif self.tabBar().count() == 1: customTabFrame.layout.addWidget( self.menuButton, 0, 1, QtCore.Qt.AlignVCenter | QtCore.Qt.AlignRight) self.updateMenuButtonVisibility() def findIPaneInTabChildren(self, tabIndex): result = [None, None] widgetAtIndex = self.widget(tabIndex) paneProxy = cast(widgetAtIndex, QBaseTabPane) pane = cast(widgetAtIndex, IPane) if paneProxy != None: result[0] = paneProxy.pane result[1] = paneProxy return result elif pane != None: result[0] = pane result[1] = widgetAtIndex return result for obj in widgetAtIndex.children(): ppaneProxy = cast(obj, QBaseTabPane) ppane = cast(obj, IPane) result[1] = cast(obj, QWidget) if ppaneProxy != None: result[0] = ppaneProxy.pane result[1] = ppaneProxy break elif ppane != None: result[0] = ppane break return result def setupMenu(self, currentIndex): foundParents = self.findIPaneInTabChildren(currentIndex) ownerWidget = foundParents[1] pane = foundParents[0] self.setCornerWidget(None) focusTarget = ownerWidget menuToAttach = None if pane != None: menuToAttach = pane.getPaneMenu() focusTarget = pane.getWidget() self.menuButton.setMenu(menuToAttach) return focusTarget def updateMenuButtonVisibility(self): if self.menuButton == None: return if self.menuButton.menu(): self.menuButton.setVisible(True) else: self.menuButton.setVisible(False) def createDefaultMenu(self): helpMenu = QMenu() menuItem = helpMenu.addMenu("Help") # menuItem.addAction() return helpMenu
class MainWindow(QMainWindow): InsertTextButton = 10 def __init__(self): super(MainWindow, self).__init__() self.createActions() self.createMenus() self.createToolBox() self.scene = DiagramScene(self.itemMenu) self.scene.setSceneRect(QRectF(0, 0, 5000, 5000)) self.scene.itemInserted.connect(self.itemInserted) self.scene.textInserted.connect(self.textInserted) self.scene.itemSelected.connect(self.itemSelected) self.createToolbars() layout = QHBoxLayout() layout.addWidget(self.toolBox) self.view = QGraphicsView(self.scene) layout.addWidget(self.view) self.widget = QWidget() self.widget.setLayout(layout) self.setCentralWidget(self.widget) self.setWindowTitle("Diagramscene") def backgroundButtonGroupClicked(self, button): buttons = self.backgroundButtonGroup.buttons() for myButton in buttons: if myButton != button: button.setChecked(False) text = button.text() if text == "Blue Grid": self.scene.setBackgroundBrush(QBrush(QPixmap(':/images/background1.png'))) elif text == "White Grid": self.scene.setBackgroundBrush(QBrush(QPixmap(':/images/background2.png'))) elif text == "Gray Grid": self.scene.setBackgroundBrush(QBrush(QPixmap(':/images/background3.png'))) else: self.scene.setBackgroundBrush(QBrush(QPixmap(':/images/background4.png'))) self.scene.update() self.view.update() def buttonGroupClicked(self, id): buttons = self.buttonGroup.buttons() for button in buttons: if self.buttonGroup.button(id) != button: button.setChecked(False) if id == self.InsertTextButton: self.scene.setMode(DiagramScene.InsertText) else: self.scene.setItemType(id) self.scene.setMode(DiagramScene.InsertItem) def deleteItem(self): for item in self.scene.selectedItems(): if isinstance(item, DiagramItem): item.removeArrows() self.scene.removeItem(item) def pointerGroupClicked(self, i): self.scene.setMode(self.pointerTypeGroup.checkedId()) def bringToFront(self): if not self.scene.selectedItems(): return selectedItem = self.scene.selectedItems()[0] overlapItems = selectedItem.collidingItems() zValue = 0 for item in overlapItems: if (item.zValue() >= zValue and isinstance(item, DiagramItem)): zValue = item.zValue() + 0.1 selectedItem.setZValue(zValue) def sendToBack(self): if not self.scene.selectedItems(): return selectedItem = self.scene.selectedItems()[0] overlapItems = selectedItem.collidingItems() zValue = 0 for item in overlapItems: if (item.zValue() <= zValue and isinstance(item, DiagramItem)): zValue = item.zValue() - 0.1 selectedItem.setZValue(zValue) def itemInserted(self, item): self.pointerTypeGroup.button(DiagramScene.MoveItem).setChecked(True) self.scene.setMode(self.pointerTypeGroup.checkedId()) self.buttonGroup.button(item.diagramType).setChecked(False) def textInserted(self, item): self.buttonGroup.button(self.InsertTextButton).setChecked(False) self.scene.setMode(self.pointerTypeGroup.checkedId()) def currentFontChanged(self, font): self.handleFontChange() def fontSizeChanged(self, font): self.handleFontChange() def sceneScaleChanged(self, scale): newScale = scale.left(scale.indexOf("%")).toDouble()[0] / 100.0 oldMatrix = self.view.matrix() self.view.resetMatrix() self.view.translate(oldMatrix.dx(), oldMatrix.dy()) self.view.scale(newScale, newScale) def textColorChanged(self): self.textAction = self.sender() self.fontColorToolButton.setIcon( self.createColorToolButtonIcon(':/images/textpointer.png', QColor(self.textAction.data()))) self.textButtonTriggered() def itemColorChanged(self): self.fillAction = self.sender() self.fillColorToolButton.setIcon( self.createColorToolButtonIcon( ':/images/floodfill.png', QColor(self.fillAction.data()))) self.fillButtonTriggered() def lineColorChanged(self): self.lineAction = self.sender() self.lineColorToolButton.setIcon( self.createColorToolButtonIcon(':/images/linecolor.png', QColor(self.lineAction.data()))) self.lineButtonTriggered() def textButtonTriggered(self): self.scene.setTextColor(QColor(self.textAction.data())) def fillButtonTriggered(self): self.scene.setItemColor(QColor(self.fillAction.data())) def lineButtonTriggered(self): self.scene.setLineColor(QColor(self.lineAction.data())) def handleFontChange(self): font = self.fontCombo.currentFont() font.setPointSize(self.fontSizeCombo.currentText().toInt()[0]) if self.boldAction.isChecked(): font.setWeight(QFont.Bold) else: font.setWeight(QFont.Normal) font.setItalic(self.italicAction.isChecked()) font.setUnderline(self.underlineAction.isChecked()) self.scene.setFont(font) def itemSelected(self, item): font = item.font() color = item.defaultTextColor() self.fontCombo.setCurrentFont(font) self.fontSizeCombo.setEditText(str(font.pointSize())) self.boldAction.setChecked(font.weight() == QFont.Bold) self.italicAction.setChecked(font.italic()) self.underlineAction.setChecked(font.underline()) def about(self): QMessageBox.about(self, "About Diagram Scene", "The <b>Diagram Scene</b> example shows use of the graphics framework.") def createToolBox(self): self.buttonGroup = QButtonGroup() self.buttonGroup.setExclusive(False) self.buttonGroup.buttonClicked[int].connect(self.buttonGroupClicked) layout = QGridLayout() layout.addWidget(self.createCellWidget("Conditional", DiagramItem.Conditional), 0, 0) layout.addWidget(self.createCellWidget("Process", DiagramItem.Step), 0, 1) layout.addWidget(self.createCellWidget("Input/Output", DiagramItem.Io), 1, 0) textButton = QToolButton() textButton.setCheckable(True) self.buttonGroup.addButton(textButton, self.InsertTextButton) textButton.setIcon(QIcon(QPixmap(':/images/textpointer.png').scaled(30, 30))) textButton.setIconSize(QSize(50, 50)) textLayout = QGridLayout() textLayout.addWidget(textButton, 0, 0, Qt.AlignHCenter) textLayout.addWidget(QLabel("Text"), 1, 0, Qt.AlignCenter) textWidget = QWidget() textWidget.setLayout(textLayout) layout.addWidget(textWidget, 1, 1) layout.setRowStretch(3, 10) layout.setColumnStretch(2, 10) itemWidget = QWidget() itemWidget.setLayout(layout) self.backgroundButtonGroup = QButtonGroup() self.backgroundButtonGroup.buttonClicked.connect(self.backgroundButtonGroupClicked) backgroundLayout = QGridLayout() backgroundLayout.addWidget(self.createBackgroundCellWidget("Blue Grid", ':/images/background1.png'), 0, 0) backgroundLayout.addWidget(self.createBackgroundCellWidget("White Grid", ':/images/background2.png'), 0, 1) backgroundLayout.addWidget(self.createBackgroundCellWidget("Gray Grid", ':/images/background3.png'), 1, 0) backgroundLayout.addWidget(self.createBackgroundCellWidget("No Grid", ':/images/background4.png'), 1, 1) backgroundLayout.setRowStretch(2, 10) backgroundLayout.setColumnStretch(2, 10) backgroundWidget = QWidget() backgroundWidget.setLayout(backgroundLayout) self.toolBox = QToolBox() self.toolBox.setSizePolicy(QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Ignored)) self.toolBox.setMinimumWidth(itemWidget.sizeHint().width()) self.toolBox.addItem(itemWidget, "Basic Flowchart Shapes") self.toolBox.addItem(backgroundWidget, "Backgrounds") def createActions(self): self.toFrontAction = QAction( QIcon(':/images/bringtofront.png'), "Bring to &Front", self, shortcut="Ctrl+F", statusTip="Bring item to front", triggered=self.bringToFront) self.sendBackAction = QAction( QIcon(':/images/sendtoback.png'), "Send to &Back", self, shortcut="Ctrl+B", statusTip="Send item to back", triggered=self.sendToBack) self.deleteAction = QAction(QIcon(':/images/delete.png'), "&Delete", self, shortcut="Delete", statusTip="Delete item from diagram", triggered=self.deleteItem) self.exitAction = QAction("E&xit", self, shortcut="Ctrl+X", statusTip="Quit Scenediagram example", triggered=self.close) self.boldAction = QAction(QIcon(':/images/bold.png'), "Bold", self, checkable=True, shortcut="Ctrl+B", triggered=self.handleFontChange) self.italicAction = QAction(QIcon(':/images/italic.png'), "Italic", self, checkable=True, shortcut="Ctrl+I", triggered=self.handleFontChange) self.underlineAction = QAction( QIcon(':/images/underline.png'), "Underline", self, checkable=True, shortcut="Ctrl+U", triggered=self.handleFontChange) self.aboutAction = QAction("A&bout", self, shortcut="Ctrl+B", triggered=self.about) def createMenus(self): self.fileMenu = self.menuBar().addMenu("&File") self.fileMenu.addAction(self.exitAction) self.itemMenu = self.menuBar().addMenu("&Item") self.itemMenu.addAction(self.deleteAction) self.itemMenu.addSeparator() self.itemMenu.addAction(self.toFrontAction) self.itemMenu.addAction(self.sendBackAction) self.aboutMenu = self.menuBar().addMenu("&Help") self.aboutMenu.addAction(self.aboutAction) def createToolbars(self): self.editToolBar = self.addToolBar("Edit") self.editToolBar.addAction(self.deleteAction) self.editToolBar.addAction(self.toFrontAction) self.editToolBar.addAction(self.sendBackAction) self.fontCombo = QFontComboBox() self.fontCombo.currentFontChanged.connect(self.currentFontChanged) self.fontSizeCombo = QComboBox() self.fontSizeCombo.setEditable(True) for i in range(8, 30, 2): self.fontSizeCombo.addItem(str(i)) validator = QIntValidator(2, 64, self) self.fontSizeCombo.setValidator(validator) self.fontSizeCombo.currentIndexChanged.connect(self.fontSizeChanged) self.fontColorToolButton = QToolButton() self.fontColorToolButton.setPopupMode(QToolButton.MenuButtonPopup) self.fontColorToolButton.setMenu( self.createColorMenu(self.textColorChanged, Qt.black)) self.textAction = self.fontColorToolButton.menu().defaultAction() self.fontColorToolButton.setIcon( self.createColorToolButtonIcon(':/images/textpointer.png', Qt.black)) self.fontColorToolButton.setAutoFillBackground(True) self.fontColorToolButton.clicked.connect(self.textButtonTriggered) self.fillColorToolButton = QToolButton() self.fillColorToolButton.setPopupMode(QToolButton.MenuButtonPopup) self.fillColorToolButton.setMenu( self.createColorMenu(self.itemColorChanged, Qt.white)) self.fillAction = self.fillColorToolButton.menu().defaultAction() self.fillColorToolButton.setIcon( self.createColorToolButtonIcon(':/images/floodfill.png', Qt.white)) self.fillColorToolButton.clicked.connect(self.fillButtonTriggered) self.lineColorToolButton = QToolButton() self.lineColorToolButton.setPopupMode(QToolButton.MenuButtonPopup) self.lineColorToolButton.setMenu( self.createColorMenu(self.lineColorChanged, Qt.black)) self.lineAction = self.lineColorToolButton.menu().defaultAction() self.lineColorToolButton.setIcon( self.createColorToolButtonIcon(':/images/linecolor.png', Qt.black)) self.lineColorToolButton.clicked.connect(self.lineButtonTriggered) self.textToolBar = self.addToolBar("Font") self.textToolBar.addWidget(self.fontCombo) self.textToolBar.addWidget(self.fontSizeCombo) self.textToolBar.addAction(self.boldAction) self.textToolBar.addAction(self.italicAction) self.textToolBar.addAction(self.underlineAction) self.colorToolBar = self.addToolBar("Color") self.colorToolBar.addWidget(self.fontColorToolButton) self.colorToolBar.addWidget(self.fillColorToolButton) self.colorToolBar.addWidget(self.lineColorToolButton) pointerButton = QToolButton() pointerButton.setCheckable(True) pointerButton.setChecked(True) pointerButton.setIcon(QIcon(':/images/pointer.png')) linePointerButton = QToolButton() linePointerButton.setCheckable(True) linePointerButton.setIcon(QIcon(':/images/linepointer.png')) self.pointerTypeGroup = QButtonGroup() self.pointerTypeGroup.addButton(pointerButton, DiagramScene.MoveItem) self.pointerTypeGroup.addButton(linePointerButton, DiagramScene.InsertLine) self.pointerTypeGroup.buttonClicked[int].connect(self.pointerGroupClicked) self.sceneScaleCombo = QComboBox() self.sceneScaleCombo.addItems(["50%", "75%", "100%", "125%", "150%"]) self.sceneScaleCombo.setCurrentIndex(2) self.sceneScaleCombo.currentIndexChanged[str].connect(self.sceneScaleChanged) self.pointerToolbar = self.addToolBar("Pointer type") self.pointerToolbar.addWidget(pointerButton) self.pointerToolbar.addWidget(linePointerButton) self.pointerToolbar.addWidget(self.sceneScaleCombo) def createBackgroundCellWidget(self, text, image): button = QToolButton() button.setText(text) button.setIcon(QIcon(image)) button.setIconSize(QSize(50, 50)) button.setCheckable(True) self.backgroundButtonGroup.addButton(button) layout = QGridLayout() layout.addWidget(button, 0, 0, Qt.AlignHCenter) layout.addWidget(QLabel(text), 1, 0, Qt.AlignCenter) widget = QWidget() widget.setLayout(layout) return widget def createCellWidget(self, text, diagramType): item = DiagramItem(diagramType, self.itemMenu) icon = QIcon(item.image()) button = QToolButton() button.setIcon(icon) button.setIconSize(QSize(50, 50)) button.setCheckable(True) self.buttonGroup.addButton(button, diagramType) layout = QGridLayout() layout.addWidget(button, 0, 0, Qt.AlignHCenter) layout.addWidget(QLabel(text), 1, 0, Qt.AlignCenter) widget = QWidget() widget.setLayout(layout) return widget def createColorMenu(self, slot, defaultColor): colors = [Qt.black, Qt.white, Qt.red, Qt.blue, Qt.yellow] names = ["black", "white", "red", "blue", "yellow"] colorMenu = QMenu(self) for color, name in zip(colors, names): action = QAction(self.createColorIcon(color), name, self, triggered=slot) action.setData(QColor(color)) colorMenu.addAction(action) if color == defaultColor: colorMenu.setDefaultAction(action) return colorMenu def createColorToolButtonIcon(self, imageFile, color): pixmap = QPixmap(50, 80) pixmap.fill(Qt.transparent) painter = QPainter(pixmap) image = QPixmap(imageFile) target = QRect(0, 0, 50, 60) source = QRect(0, 0, 42, 42) painter.fillRect(QRect(0, 60, 50, 80), color) painter.drawPixmap(target, image, source) painter.end() return QIcon(pixmap) def createColorIcon(self, color): pixmap = QPixmap(20, 20) painter = QPainter(pixmap) painter.setPen(Qt.NoPen) painter.fillRect(QRect(0, 0, 20, 20), color) painter.end() return QIcon(pixmap)
class QCopycanvas: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'QCopycanvas_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = self.tr(u'&QCopycanvas') self.toolbar = self.iface.addToolBar(u'QCopycanvas') self.toolbar.setObjectName(u'QCopycanvas') self.toolButton = QToolButton() self.toolButton.setMenu(QMenu()) self.toolButton.setPopupMode(QToolButton.MenuButtonPopup) self.toolbar.addWidget(self.toolButton) # Check if plugin was started the first time in current QGIS session # Must be set in initGui() to survive plugin reloads self.first_start = None # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('QCopycanvas', message) def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, shortcut=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if shortcut is not None: action.setShortcut(QKeySequence(shortcut)) #if add_to_toolbar: # Adds plugin icon to Plugins toolbar # self.iface.addToolBarIcon(action) if add_to_menu: self.iface.addPluginToMenu(self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/QCopycanvas/icon.png' self.mainButton = self.add_action(icon_path, text=self.tr(u'Copy Map Canvas'), shortcut="Ctrl+Space", callback=self.run, parent=self.iface.mainWindow()) # will be set False in run() self.first_start = True self.with_legend_btn = QAction(QIcon(''), "Copy Map Canvas with Legend", self.iface.mainWindow()) self.with_legend_btn.setText("Copy Map Canvas with Legend") self.with_legend_btn.triggered.connect(self.with_legend_btn_run) menu = self.toolButton.menu() menu.addAction(self.mainButton) menu.addAction(self.with_legend_btn) self.toolButton.setDefaultAction(self.mainButton) def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginMenu(self.tr(u'&QCopycanvas'), action) self.iface.removeToolBarIcon(action) def get_group_layers(self, group): for child in group.children(): if isinstance(child, QgsLayerTreeGroup): self.get_group_layers(child) elif child.isVisible(): self.checked_layers.append(child.name()) def with_legend_btn_run(self): project = QgsProject.instance() self.checked_layers = [] root = project.layerTreeRoot() for child in root.children(): if child.isVisible() and isinstance(child, QgsLayerTreeLayer): self.checked_layers.append(child.name()) if child.isVisible() and isinstance(child, QgsLayerTreeGroup): self.get_group_layers(child) layersToAdd = [ layer for layer in project.mapLayers().values() if layer.name() in sorted(self.checked_layers, reverse=False) ] layers_names_length = [ len(layer.name()) for layer in project.mapLayers().values() if layer.name() in sorted(self.checked_layers, reverse=False) ] maxlen = max(layers_names_length) root = QgsLayerTree() for layer in layersToAdd: root.addLayer(layer) model = QgsLayerTreeModel(root) lenlen = model.rowCount() view = QgsLayerTreeView() view.setModel(model) view.setFixedHeight(lenlen * 20) view.setFixedWidth(maxlen * 10) legendIm = QImage(QWidget.grab(view)) legendpath = self.plugin_dir + "\\legend.png" legendIm.save(legendpath) legendIm = Image.open(legendpath) #legendIm = legendIm.imageData() legendWidth, legendHeight = legendIm.size main_image = QImage(QWidget.grab(self.iface.mapCanvas())) mainpath = self.plugin_dir + "\\main.png" main_image.save(mainpath) main_image = Image.open(mainpath).convert("RGBA") width, height = main_image.size d = ImageDraw.Draw(main_image) font = ImageFont.truetype("arial.ttf", 16) d.text(((width / 2.5) + len(project.title()), 10), project.title(), fill='black', font=font) if abs(height - width) < 150: sq_fit_size = legendWidth height = legendHeight else: sq_fit_size = width if width > sq_fit_size and height > sq_fit_size: if width > height: height = int((sq_fit_size / width) * height) width = sq_fit_size else: width = int((sq_fit_size / height) * width) height = sq_fit_size main_image = main_image.resize((width, height)) main_image.paste(legendIm, (max(width - legendWidth, 0), height - legendHeight)) finalpath = self.plugin_dir + "\\main.png" main_image.save(finalpath) QApplication.clipboard().setImage(QImage(finalpath)) self.iface.messageBar().pushMessage( 'QCopycanvas', 'Copied map canvas to clipboard with legend', level=Qgis.Success, duration=2) def run(self): """Run method that performs all the real work""" # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started QApplication.clipboard().setImage( QImage(QWidget.grab(self.iface.mapCanvas()))) self.iface.messageBar().pushMessage('QCopycanvas', 'Copied map canvas to clipboard', level=Qgis.Success, duration=2)
class TableWidget(QFrame): def __init__(self, parent): super(TableWidget, self).__init__(parent) self.m_frame = QFrame(self) self.m_frame.setFrameShape(QFrame.Panel) self.m_frame.setFrameShadow(QFrame.Plain) horizontalLayout = QHBoxLayout(self.m_frame) horizontalLayout.setContentsMargins(0, 0, 0, 0) horizontalLayout.setSpacing(0) self.m_table = QTableView(self.m_frame) self.m_table.setStatusTip("") self.m_table.setLayoutDirection(Qt.LeftToRight) self.m_table.setFrameShape(QFrame.NoFrame) self.m_table.setFrameShadow(QFrame.Plain) self.m_table.setSelectionBehavior(QAbstractItemView.SelectRows) horizontalLayout.addWidget(self.m_table) self.m_line = QFrame(self.m_frame) self.m_line.setFrameShadow(QFrame.Plain) self.m_line.setFrameShape(QFrame.VLine) horizontalLayout.addWidget(self.m_line) self.m_toolBtnFrame = QFrame(self.m_frame) self.m_toolBtnFrame.setLayoutDirection(Qt.RightToLeft) self.m_toolBtnFrame.setFrameShape(QFrame.NoFrame) self.m_toolBtnFrame.setFrameShadow(QFrame.Plain) self.m_verticalLayout = QVBoxLayout(self.m_toolBtnFrame) self.m_verticalLayout.setContentsMargins(1, 1, 1, 1) self.m_verticalLayout.setSpacing(1) self.m_addBtn = QToolButton(self.m_toolBtnFrame) icon = QIcon() icon.addPixmap(QPixmap(":/icons/plus.png"), QIcon.Normal, QIcon.Off) self.m_addBtn.setIcon(icon) self.m_addBtn.setAutoRaise(True) self.m_addBtn.setArrowType(Qt.NoArrow) self.m_verticalLayout.addWidget(self.m_addBtn) self.m_deleteBtn = QToolButton(self.m_toolBtnFrame) icon1 = QIcon() icon1.addPixmap(QPixmap(":/icons/minus.png"), QIcon.Normal, QIcon.Off) self.m_deleteBtn.setIcon(icon1) self.m_deleteBtn.setAutoRaise(True) self.m_verticalLayout.addWidget(self.m_deleteBtn) self.m_clearAllBtn = QToolButton(self.m_toolBtnFrame) icon1 = QIcon() icon1.addPixmap(QPixmap(":/icons/clear.png"), QIcon.Normal, QIcon.Off) self.m_clearAllBtn.setIcon(icon1) self.m_clearAllBtn.setAutoRaise(True) self.m_verticalLayout.addWidget(self.m_clearAllBtn) self.m_clearAllBtn.setVisible(False) self.m_browseBtn = QToolButton(self.m_toolBtnFrame) icon1 = QIcon() icon1.addPixmap(QPixmap(":/icons/local.png"), QIcon.Normal, QIcon.Off) self.m_browseBtn.setIcon(icon1) self.m_browseBtn.setAutoRaise(True) self.m_verticalLayout.addWidget(self.m_browseBtn) self.m_browseBtn.setVisible(False) self.m_editBtn = QToolButton(self.m_toolBtnFrame) icon1 = QIcon() icon1.addPixmap(QPixmap(":/icons/edit.png"), QIcon.Normal, QIcon.Off) self.m_editBtn.setIcon(icon1) self.m_editBtn.setAutoRaise(True) self.m_verticalLayout.addWidget(self.m_editBtn) self.m_editBtn.setVisible(False) self.m_pdfBtn = QToolButton(self.m_toolBtnFrame) icon1 = QIcon() icon1.addPixmap(QPixmap(":/icons/pdf.png"), QIcon.Normal, QIcon.Off) self.m_pdfBtn.setIcon(icon1) self.m_pdfBtn.setAutoRaise(True) self.m_verticalLayout.addWidget(self.m_pdfBtn) self.m_pdfBtn.setVisible(False) self.m_pdfBtn.setToolTip("Generate PDF report") self.m_htmlBtn = QToolButton(self.m_toolBtnFrame) icon1 = QIcon() icon1.addPixmap(QPixmap(":/icons/html.png"), QIcon.Normal, QIcon.Off) self.m_htmlBtn.setIcon(icon1) self.m_htmlBtn.setAutoRaise(True) self.m_verticalLayout.addWidget(self.m_htmlBtn) self.m_htmlBtn.setVisible(False) self.m_htmlBtn.setToolTip("Generate HTML report") self.m_textBtn = QToolButton(self.m_toolBtnFrame) icon1 = QIcon() icon1.addPixmap(QPixmap(":/icons/text.png"), QIcon.Normal, QIcon.Off) self.m_textBtn.setIcon(icon1) self.m_textBtn.setAutoRaise(True) self.m_verticalLayout.addWidget(self.m_textBtn) self.m_textBtn.setVisible(False) self.m_textBtn.setToolTip("Generate report in text format") spacerItem = QSpacerItem(20, 10, QSizePolicy.Minimum, QSizePolicy.Expanding) self.m_verticalLayout.addItem(spacerItem) horizontalLayout.addWidget(self.m_toolBtnFrame) mainLayout = QHBoxLayout() mainLayout.setContentsMargins(0, 0, 0, 0) mainLayout.addWidget(self.m_frame) self.setLayout(mainLayout) def addActionToAddBtn(self, action): menu = self.m_addBtn.menu() if menu is None: self.m_addBtn.setMenu(QMenu()) self.m_addBtn.setPopupMode(QToolButton.MenuButtonPopup) menu = self.m_addBtn.menu() menu.addAction(action) def showClearAll(self, show): self.m_clearAllBtn.setVisible(show) def showBrowse(self, show): self.m_browseBtn.setVisible(show) def showEdit(self, show): self.m_editBtn.setVisible(show) def showPdfBtn(self, show): self.m_pdfBtn.setVisible(show) def showHtmlBtn(self, show): self.m_htmlBtn.setVisible(show) def showTextBtn(self, show): self.m_textBtn.setVisible(show) def showAddBtn(self, show): self.m_addBtn.setVisible(show) def showDeleteBtn(self, show): self.m_deleteBtn.setVisible(show) def showBtns(self, show): self.m_toolBtnFrame.setVisible(show) def model(self): return self.m_table.model() def setModel(self, model): self.m_table.setModel(model) if self.m_table.selectionModel() is not None: self.m_table.selectionModel().selectionChanged.connect( self.updateDeleteBtnState) self.updateDeleteBtnState() self.m_table.selectionModel().selectionChanged.connect( self.updateEditBtnState) self.updateEditBtnState() self.m_table.selectionModel().selectionChanged.connect( self.updatePdfBtnState) self.updatePdfBtnState() self.m_table.selectionModel().selectionChanged.connect( self.updateHtmlBtnState) self.updateHtmlBtnState() self.m_table.selectionModel().selectionChanged.connect( self.updateTextBtnState) self.updateTextBtnState() def updateDeleteBtnState(self): enable = self.m_table.selectionModel().hasSelection() self.m_deleteBtn.setEnabled(enable) def updateEditBtnState(self): enable = self.m_table.selectionModel().hasSelection() self.m_editBtn.setEnabled(enable) def updateHtmlBtnState(self): enable = self.m_table.selectionModel().hasSelection() self.m_htmlBtn.setEnabled(enable) def updatePdfBtnState(self): enable = self.m_table.selectionModel().hasSelection() self.m_pdfBtn.setEnabled(enable) def updateTextBtnState(self): enable = self.m_table.selectionModel().hasSelection() self.m_textBtn.setEnabled(enable) def addBtn(self): return self.m_addBtn def deleteBtn(self): return self.m_deleteBtn def clearAllBtn(self): return self.m_clearAllBtn def browseBtn(self): return self.m_browseBtn def editBtn(self): return self.m_editBtn def pdfBtn(self): return self.m_pdfBtn def htmlBtn(self): return self.m_htmlBtn def textBtn(self): return self.m_textBtn def table(self): return self.m_table
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.createActions() self.createMenus() self.createToolBox() self.createStatusBar() self.scene = ITGScene(self.itemMenu) self.scene.setSceneRect(QRectF(0, 0, 5000, 5000)) self.scene.itemInserted.connect(self.itemInserted) self.scene.itemSelected.connect(self.itemSelected) # ================================================================ # THIS IS THE PROBLEM SECTION # THIS CAUSES TypeError: native Qt signal is not callable # To reproduce the error, run the program, click on one of the # shapes, then click on the scene area # ================================================================ self.scene.selectionChanged.connect(self.print_item_info) # this one doesn't work self.createToolbars() layout = QHBoxLayout() layout.addWidget(self.toolBox) self.view = QGraphicsView(self.scene) # view and scene established together layout.addWidget(self.view) self.widget = QWidget() self.widget.setLayout(layout) self.setCentralWidget(self.widget) self.setWindowTitle("ITG: Illegitimate Template Generator") #@pyqtSlot() # Adding this does not change the error def print_item_info(self): for item in self.scene.selectedItems(): print(item) def buttonGroupClicked(self, id): buttons = self.buttonGroup.buttons() for button in buttons: if self.buttonGroup.button(id) != button: button.setChecked(False) self.scene.setItemType(id) self.scene.setMode(ITGScene.InsertItem) self.updateStatusBar() def deleteItem(self): for item in self.scene.selectedItems(): self.scene.removeItem(item) def pointerGroupClicked(self, i): self.scene.setMode(self.pointerTypeGroup.checkedId()) self.updateStatusBar() def bringToFront(self): if not self.scene.selectedItems(): return selectedItem = self.scene.selectedItems()[0] overlapItems = selectedItem.collidingItems() zValue = 0 for item in overlapItems: if (item.zValue() >= zValue and isinstance(item, ITGItem)): zValue = item.zValue() + 0.1 selectedItem.setZValue(zValue) def sendToBack(self): if not self.scene.selectedItems(): return selectedItem = self.scene.selectedItems()[0] overlapItems = selectedItem.collidingItems() zValue = 0 for item in overlapItems: if (item.zValue() <= zValue and isinstance(item, ITGItem)): zValue = item.zValue() - 0.1 selectedItem.setZValue(zValue) def itemInserted(self, item): self.pointerTypeGroup.button(ITGScene.MoveItem).setChecked(True) self.scene.setMode(self.pointerTypeGroup.checkedId()) self.updateStatusBar() self.buttonGroup.button(item.ITGType).setChecked(False) def sceneScaleChanged(self, scale): newScale = scale.left(scale.indexOf("%")).toDouble()[0] / 100.0 oldMatrix = self.view.matrix() self.view.resetMatrix() self.view.translate(oldMatrix.dx(), oldMatrix.dy()) self.view.scale(newScale, newScale) def itemColorChanged(self): self.fillAction = self.sender() self.fillColorToolButton.setIcon( self.createColorToolButtonIcon( ':/images/floodfill.png', QColor(self.fillAction.data()))) self.fillButtonTriggered() def fillButtonTriggered(self): self.scene.setItemColor(QColor(self.fillAction.data())) def itemSelected(self, item): font = item.font() color = item.defaultTextColor() self.fontCombo.setCurrentFont(font) self.fontSizeCombo.setEditText(str(font.pointSize())) self.boldAction.setChecked(font.weight() == QFont.Bold) self.italicAction.setChecked(font.italic()) self.underlineAction.setChecked(font.underline()) def about(self): QMessageBox.about(self, "About ITG Scene", "The <b>ITG Scene</b> example shows use of the graphics framework.") def createToolBox(self): self.buttonGroup = QButtonGroup() self.buttonGroup.setExclusive(False) self.buttonGroup.buttonClicked[int].connect(self.buttonGroupClicked) layout = QGridLayout() layout.addWidget(self.createCellWidget("Diamond", ITGItem.Diamond), 0, 0) layout.addWidget(self.createCellWidget("Square", ITGItem.Square), 0, 1) layout.addWidget(self.createCellWidget("Parallelogram", ITGItem.Parallelogram), 1, 0) layout.setRowStretch(3, 10) layout.setColumnStretch(2, 10) itemWidget = QWidget() itemWidget.setLayout(layout) self.backgroundButtonGroup = QButtonGroup() self.toolBox = QToolBox() self.toolBox.setSizePolicy(QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Ignored)) self.toolBox.setMinimumWidth(itemWidget.sizeHint().width()) self.toolBox.addItem(itemWidget, "Basic Components") def createActions(self): self.toFrontAction = QAction( QIcon(':/images/bringtofront.png'), "Bring to &Front", self, shortcut="Ctrl+F", statusTip="Bring item to front", triggered=self.bringToFront) self.sendBackAction = QAction( QIcon(':/images/sendtoback.png'), "Send to &Back", self, shortcut="Ctrl+B", statusTip="Send item to back", triggered=self.sendToBack) self.deleteAction = QAction(QIcon(':/images/delete.png'), "&Delete", self, shortcut="Delete", statusTip="Delete item from ITG", triggered=self.deleteItem) self.exitAction = QAction("E&xit", self, shortcut="Ctrl+X", statusTip="Quit SceneITG example", triggered=self.close) self.aboutAction = QAction("A&bout", self, shortcut="Ctrl+B", triggered=self.about) def createMenus(self): self.fileMenu = self.menuBar().addMenu("&File") self.fileMenu.addAction(self.exitAction) self.itemMenu = self.menuBar().addMenu("&Item") self.itemMenu.addAction(self.deleteAction) self.itemMenu.addSeparator() self.itemMenu.addAction(self.toFrontAction) self.itemMenu.addAction(self.sendBackAction) self.aboutMenu = self.menuBar().addMenu("&Help") self.aboutMenu.addAction(self.aboutAction) def createToolbars(self): self.editToolBar = self.addToolBar("Edit") self.editToolBar.addAction(self.deleteAction) self.editToolBar.addAction(self.toFrontAction) self.editToolBar.addAction(self.sendBackAction) self.fillColorToolButton = QToolButton() self.fillColorToolButton.setPopupMode(QToolButton.MenuButtonPopup) self.fillColorToolButton.setMenu( self.createColorMenu(self.itemColorChanged, Qt.red)) self.fillAction = self.fillColorToolButton.menu().defaultAction() self.fillColorToolButton.setIcon( self.createColorToolButtonIcon(':/images/floodfill.png', Qt.red)) self.fillColorToolButton.clicked.connect(self.fillButtonTriggered) self.colorToolBar = self.addToolBar("Color") self.colorToolBar.addWidget(self.fillColorToolButton) pointerButton = QToolButton() pointerButton.setCheckable(True) pointerButton.setChecked(True) pointerButton.setIcon(QIcon(':/images/pointer.png')) self.pointerTypeGroup = QButtonGroup() self.pointerTypeGroup.addButton(pointerButton, ITGScene.MoveItem) self.pointerTypeGroup.buttonClicked[int].connect(self.pointerGroupClicked) self.sceneScaleCombo = QComboBox() self.sceneScaleCombo.addItems(["50%", "75%", "100%", "125%", "150%"]) self.sceneScaleCombo.setCurrentIndex(2) self.sceneScaleCombo.currentIndexChanged[str].connect(self.sceneScaleChanged) self.pointerToolbar = self.addToolBar("Pointer type") self.pointerToolbar.addWidget(pointerButton) self.pointerToolbar.addWidget(self.sceneScaleCombo) def createBackgroundCellWidget(self, text, image): button = QToolButton() button.setText(text) button.setIcon(QIcon(image)) button.setIconSize(QSize(50, 50)) button.setCheckable(True) self.backgroundButtonGroup.addButton(button) layout = QGridLayout() layout.addWidget(button, 0, 0, Qt.AlignHCenter) layout.addWidget(QLabel(text), 1, 0, Qt.AlignCenter) widget = QWidget() widget.setLayout(layout) return widget def createCellWidget(self, text, ITGType): item = ITGItem(ITGType, self.itemMenu) icon = QIcon(item.image()) button = QToolButton() button.setIcon(icon) button.setIconSize(QSize(50, 50)) button.setCheckable(True) self.buttonGroup.addButton(button, ITGType) layout = QGridLayout() layout.addWidget(button, 0, 0, Qt.AlignHCenter) layout.addWidget(QLabel(text), 1, 0, Qt.AlignCenter) widget = QWidget() widget.setLayout(layout) return widget def createColorMenu(self, slot, defaultColor): colors = [Qt.black, Qt.white, Qt.red, Qt.blue, Qt.yellow] names = ["black", "white", "red", "blue", "yellow"] colorMenu = QMenu(self) for color, name in zip(colors, names): action = QAction(self.createColorIcon(color), name, self, triggered=slot) action.setData(QColor(color)) colorMenu.addAction(action) if color == defaultColor: colorMenu.setDefaultAction(action) return colorMenu def createColorToolButtonIcon(self, imageFile, color): pixmap = QPixmap(50, 80) pixmap.fill(Qt.transparent) painter = QPainter(pixmap) image = QPixmap(imageFile) target = QRect(0, 0, 50, 60) source = QRect(0, 0, 42, 42) painter.fillRect(QRect(0, 60, 50, 80), color) painter.drawPixmap(target, image, source) painter.end() return QIcon(pixmap) def createColorIcon(self, color): pixmap = QPixmap(20, 20) painter = QPainter(pixmap) painter.setPen(Qt.NoPen) painter.fillRect(QRect(0, 0, 20, 20), color) painter.end() return QIcon(pixmap) def createStatusBar(self): self.sbar = self.statusBar() self.lbl_mode = QLabel('Mode: not set') self.sbar.addPermanentWidget(self.lbl_mode) self.lbl_selection = QLabel('Sel: none') self.sbar.addPermanentWidget(self.lbl_selection) def updateStatusBar(self): self.lbl_mode.setText('Mode: ' + self.scene.getMode()) #! This section is not working!!! if len(self.scene.selectedItems()) == 0: self.lbl_selection.setText('Sel: none') elif len(self.scene.selectedItems()) == 1: self.lbl_selection.setText('Sel: ' + self.scene.selectedItems()[0].get_ITGType_as_str()) elif len(self.scene.selectedItems()) > 1: self.lbl_selection.setText('Sel: <multiple>')
class PrintTools: """QGIS Plugin Implementation.""" def __init__(self, iface): # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( self.plugin_dir, 'i18n', 'PrintFragment_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = u'PrintMap' def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" self.toolButton = QToolButton() self.toolButton.setMenu(QMenu()) self.toolButton.setPopupMode(QToolButton.MenuButtonPopup) self.toolButton.setAutoRaise(True) self.toolBtnAdd = self.iface.addToolBarWidget(self.toolButton) self.fragment_action = QAction(QIcon(os.path.join( self.plugin_dir, 'tools/fragmentPrint', 'icon.png')), u"Create layout with fragment map", self.iface.mainWindow()) self.iface.addPluginToMenu(u"&PrintMap", self.fragment_action) m = self.toolButton.menu() m.addAction(self.fragment_action) self.toolButton.setDefaultAction(self.fragment_action) self.fragment_action.triggered.connect(self.run_fragmentPrint) self.compPrint_action = QAction(QIcon(os.path.join( self.plugin_dir, 'tools/comp_print', 'icon.png')), u"Create multipage layout", self.iface.mainWindow()) self.iface.addPluginToMenu(u"&PrintMap", self.compPrint_action) m = self.toolButton.menu() m.addAction(self.compPrint_action) self.compPrint_action.triggered.connect(self.run_compPrint) self.legend_action = QAction(QIcon(os.path.join( self.plugin_dir, 'tools/userLegend', 'icon.png')), u"Add custom legend to Layout", self.iface.mainWindow()) self.iface.addPluginToMenu(u"&PrintMap", self.legend_action) m = self.toolButton.menu() m.addAction(self.legend_action) self.legend_action.triggered.connect(self.run_userLegend) def unload(self): self.iface.unregisterMainWindowAction(self.fragment_action) self.iface.removePluginMenu(u"&PrintMap", self.fragment_action) self.iface.removeToolBarIcon(self.fragment_action) self.iface.unregisterMainWindowAction(self.compPrint_action) self.iface.removePluginMenu(u"&PrintMap", self.compPrint_action) self.iface.removeToolBarIcon(self.compPrint_action) self.iface.unregisterMainWindowAction(self.legend_action) self.iface.removePluginMenu(u"&PrintMap", self.legend_action) self.iface.removeToolBarIcon(self.legend_action) self.iface.removeToolBarIcon(self.toolBtnAdd) def run_fragmentPrint(self): self.toolButton.setDefaultAction(self.fragment_action) FragmentPrint(self.iface).run() def run_compPrint(self): self.toolButton.setDefaultAction(self.compPrint_action) CompPrint(self.iface).run() def run_userLegend(self): UserLegend(self.iface).run()
class DxvkWidget(QWidget): dxvk_settings = { "fps": (False, "Fps"), "gpuload": (False, "GPU usage"), "memory": (False, "Used Memory"), "devinfo": (False, "Device info"), "version": (False, "DXVK version"), "api": (False, "D3D Level of application") } def __init__(self, core: LegendaryCore): super(DxvkWidget, self).__init__() self.core = core self.name = "default" self.layout = QVBoxLayout() self.child_layout = QHBoxLayout() self.title = QLabel("dxvk settings") self.show_dxvk = QCheckBox("Show Dxvk HUD") self.more_settings = QToolButton() dxvk_hud = self.core.lgd.config.get(f"{self.name}.env", "DXVK_HUD", fallback="") self.more_settings.setDisabled(not dxvk_hud == "") if dxvk_hud: for s in dxvk_hud.split(","): y = list(self.dxvk_settings[s]) y[0] = True self.dxvk_settings[s] = tuple(y) self.more_settings.setPopupMode(QToolButton.InstantPopup) self.more_settings.setMenu(QMenu()) self.more_settings.setText("More DXVK settings") action = QWidgetAction(self) self.more_settings_widget = DxvkMoreSettingsWidget( self.dxvk_settings, self.core) action.setDefaultWidget(self.more_settings_widget) self.more_settings.menu().addAction(action) self.show_dxvk.stateChanged.connect(self.update_dxvk_active) self.show_dxvk.setChecked(not dxvk_hud == "") self.layout.addWidget(self.title) self.child_layout.addWidget(self.show_dxvk) self.child_layout.addWidget(self.more_settings) self.layout.addLayout(self.child_layout) self.setLayout(self.layout) def update_settings(self, app_name): self.name = app_name dxvk_hud = self.core.lgd.config.get(f"{self.name}.env", "DXVK_HUD", fallback="") self.more_settings.setDisabled(not dxvk_hud == "") if dxvk_hud: for s in dxvk_hud.split(","): y = list(self.dxvk_settings[s]) y[0] = True self.dxvk_settings[s] = tuple(y) else: self.show_dxvk.setChecked(False) def update_dxvk_active(self): if self.show_dxvk.isChecked(): if not f"{self.name}.env" in self.core.lgd.config.sections(): self.core.lgd.config[f"{self.name}.env"] = {} self.more_settings.setDisabled(False) self.more_settings_widget.settings = { "fps": (True, "Fps"), "gpuload": (True, "GPU usage"), "memory": (False, "Used Memory"), "devinfo": (False, "Device info"), "version": (False, "DXVK version"), "api": (False, "D3D Level of application") } self.core.lgd.config[f"{self.name}.env"][ "DXVK_HUD"] = "fps,gpuload" for w in self.more_settings_widget.widgets: if w.tag == "fps" or w.tag == "gpuload": w.setChecked(True) else: w.setChecked(False) else: self.more_settings.setDisabled(True) if not self.core.lgd.config.get( f"{self.name}.env", "DXVK_HUD", fallback="") == "": self.core.lgd.config.remove_option(f"{self.name}.env", "DXVK_HUD") if not self.core.lgd.config[f"{self.name}.env"]: self.core.lgd.config.remove_section(f"{self.name}.env") print("Remove Section DXVK_HUD") self.core.lgd.save_config()
class QRectangleCreator: def __init__(self, iface): self.iface = iface self.plugin_dir = os.path.dirname(__file__) locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'qrectanglecreator_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) self.actions = [] self.menu = self.tr(u'&QRectangleCreator') self.toolsToolbar = self.iface.addToolBar(u'QRectangle Creator') self.toolsToolbar.setObjectName(u'QRectangle Creator') self.settingsDlg = SettingsDialog() self.settingsDlg.width.valueChanged.connect(self.settingsChanged) self.settingsDlg.height.valueChanged.connect(self.settingsChanged) self.settingsDlg.angle.valueChanged.connect(self.settingsChanged) self.first_start = None def tr(self, message): return QCoreApplication.translate('QRectangleCreator', message) def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None, checkable=False, checked=False, shortcut=None): icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolsToolbar.addAction(action) if add_to_menu: self.iface.addPluginToMenu(self.menu, action) if checkable: action.setCheckable(True) if checked: action.setChecked(1) if shortcut: action.setShortcut(shortcut) self.actions.append(action) return action def initGui(self): icon_path = ':/plugins/QRectangleCreator/icons/' #LoginButton self.mainButton = QToolButton() self.mainButton.setIcon(QIcon(icon_path + 'addRectangle.png')) self.mainButton.setPopupMode(QToolButton.MenuButtonPopup) self.mainButton.clicked.connect(self.run) self.mainButton.setToolTip('Add Rectangle') self.mainButton.setEnabled(True) self.mainButton.setCheckable(True) self.mainButton.setMenu(QMenu()) self.toolsToolbar.addWidget(self.mainButton) #SettingsButton self.SettingsButton = self.add_action(icon_path + 'addRectangle.png', text=self.tr(u'Settings'), callback=self.settings, parent=self.iface.mainWindow(), add_to_menu=False, enabled_flag=False, add_to_toolbar=False) m = self.mainButton.menu() m.addAction(self.SettingsButton) self.first_start = True def unload(self): for action in self.actions: self.iface.removePluginMenu(self.tr(u'&QRectangleCreator'), action) self.iface.removeToolBarIcon(action) def run(self): if self.first_start == True: self.first_start = False if self.mainButton.isChecked() == 1: self.drawingObject = StartDrawing(self.iface.mapCanvas(), self.iface) self.drawingObject.setConfiguration( self.settingsDlg.width.value(), self.settingsDlg.height.value(), self.settingsDlg.angle.value()) self.iface.mapCanvas().setMapTool(self.drawingObject) self.SettingsButton.setEnabled(True) else: self.iface.mapCanvas().unsetMapTool(self.drawingObject) self.drawingObject.reset() self.SettingsButton.setEnabled(False) def settings(self): self.settingsDlg.show() current_width = self.settingsDlg.width.value() current_height = self.settingsDlg.height.value() current_angle = self.settingsDlg.angle.value() if self.settingsDlg.exec_() != 1: self.settingsDlg.width.setValue(current_width) self.settingsDlg.height.setValue(current_height) self.settingsDlg.angle.setValue(current_angle) def settingsChanged(self): self.drawingObject.setConfiguration(self.settingsDlg.width.value(), self.settingsDlg.height.value(), self.settingsDlg.angle.value())
class ParametersWidget(QWidget): communicator = None parameter_control_widgets = [] dirty = False def __init__(self, communicator, parent=None): super(ParametersWidget, self).__init__(parent) self.communicator = communicator self.settings = QtCore.QSettings( os.path.join(qApp.applicationDirPath(), 'parameter_profiles.ini'), QtCore.QSettings.IniFormat ) ### # Parameter groups ### scroll_widget = QWidget() group_widgets_layout = QHBoxLayout(scroll_widget) last_group = None curr_group_widget = None for param in Parameters.get_sorted_parameters(): if param.startswith('_'): continue group, param_name = param.split('_', 1) if group != last_group: if last_group is not None: curr_group_widget.layout().addStretch() last_group = group curr_group_widget = QGroupBox(group) group_layout = QVBoxLayout() curr_group_widget.setLayout(group_layout) group_layout.setContentsMargins(5, 5, 5, 5) group_layout.setSpacing(3) group_widgets_layout.addWidget(curr_group_widget) param_widget = ParameterControlWidget(param_name, getattr(Parameters, param)) param_widget.setParameterTypeName(param) param_widget.editingFinished.connect(self.parameter_changed) #param_widget.setContentsMargins(0, 0, 0, 0) curr_group_widget.layout().addWidget(param_widget) self.parameter_control_widgets.append(param_widget) curr_group_widget.layout().addStretch() del last_group, curr_group_widget ### # Buttons ### self.profile_button = QToolButton() self.profile_button.setArrowType(Qt.DownArrow) self.profile_button.setMenu(QMenu()) self.profile_button.setPopupMode(QToolButton.MenuButtonPopup) self.profile_button.setToolButtonStyle(Qt.ToolButtonTextOnly) self.profile_button.clicked.connect(self.save_profile) self.profile_button.triggered.connect(self.change_profile) get_parameters_button = QPushButton('Fetch parameters') get_parameters_button.clicked.connect(self.fetch_parameters) self.send_parameters_button = QPushButton('Send parameters') self.send_parameters_button.clicked.connect(self.send_parameters) button_layout = QHBoxLayout() button_layout.addStretch() button_layout.addWidget(self.profile_button) button_layout.addWidget(get_parameters_button) button_layout.addWidget(self.send_parameters_button) ### # Main layout ### scroll_area = HorizontalScrollArea() scroll_area.setWidget(scroll_widget) main_layout = QVBoxLayout() main_layout.setContentsMargins(0, 0, 0, 0) main_layout.addWidget(scroll_area) main_layout.addLayout(button_layout) self.setLayout(main_layout) self.rebuild_profile_menu() self.change_profile(self.profile_button.menu().defaultAction()) @pyqtSlot() def fetch_parameters(self): # TODO block UI for param, id in Parameters.list(): msg = GetParameterMessage() msg.parameter = id self.communicator.send_message(ProxyMessage(msg)) @pyqtSlot() def send_parameters(self): # TODO return @pyqtSlot(QAction) def change_profile(self, action): """ @type action: QtGui.QAction """ profile_uuid = action.data() if profile_uuid is None: return if self.dirty: msg_box = QMessageBox() msg_box.setText('The current profile has unsaved changes') msg_box.setInformativeText('Should the changes be saved in the current profile?') msg_box.setStandardButtons(QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel) msg_box.setDefaultButton(QMessageBox.Save) r = msg_box.exec() if r == QMessageBox.Cancel: return elif r == QMessageBox.Save: self.save_profile() self.active_profile = action self.set_dirty(False) if profile_uuid == 'new_profile': text = QInputDialog.getText(self, 'New profile', 'Name:') if not text: return profile_uuid = "{" + str(uuid.uuid4()) + "}" self.settings.beginGroup(profile_uuid) self.settings.setValue('profileName', text) self.settings.beginGroup('parameters') for le in self.parameter_control_widgets: self.settings.setValue(le.parameterTypeName(), le.value()) self.settings.endGroup() self.settings.endGroup() self.rebuild_profile_menu() for action in self.profile_button.menu().actions(): if action.data() == profile_uuid: self.change_profile(action) return else: self.profile_button.setText('Profile: ' + action.text()) readonly = profile_uuid == 'read_only' self.send_parameters_button.setDisabled(readonly) for le in self.parameter_control_widgets: le.setReadOnly(readonly) le.setValue(0) if profile_uuid.startswith('{'): profile_uuid = "{" + str(uuid.UUID(profile_uuid)) + "}" self.settings.beginGroup(profile_uuid) self.settings.beginGroup('parameters') for le in self.parameter_control_widgets: le.setValue(int(self.settings.value(le.parameterTypeName(), 0))) self.settings.endGroup() self.settings.endGroup() def rebuild_profile_menu(self): menu = self.profile_button.menu() menu.clear() read_only_action = QAction('Read-only', menu) read_only_action.setData('read_only') menu.addAction(read_only_action) menu.addSeparator() for le in self.settings.childGroups(): action = QAction(self.settings.value(le + '/profileName')[0], menu) action.setData(le) menu.addAction(action) menu.addSeparator() new_profile_action = QAction("New profile", menu) new_profile_action.setData('new_profile') menu.addAction(new_profile_action) menu.setDefaultAction(read_only_action) def save_profile(self): if self.dirty and self.active_profile.data().startswith('{'): self.settings.beginGroup(self.active_profile.data()) self.settings.beginGroup('parameters') for le in self.parameter_control_widgets: self.settings.setValue(le.parameterTypeName(), le.value()) self.settings.endGroup() self.settings.endGroup() self.set_dirty(False) def set_dirty(self, dirty): self.dirty = dirty if self.dirty: self.profile_button.setText('Profile: ' + self.active_profile.text() + '*') else: self.profile_button.setText('Profile: ' + self.active_profile.text()) @pyqtSlot(QWidget) def parameter_changed(self, widget): if self.active_profile.data() == 'read_only': return print("Test") # TODO msg self.set_dirty(True) def update_parameter(self, parameter, parameter_value): for widget in self.parameter_control_widgets: if widget.parameter_type_id == parameter: widget.setValue(parameter_value) break
class APIS: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) QSettings().setValue("APIS/plugin_dir", self.plugin_dir) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'APIS_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = tr(u'&APIS') self.toolbar = self.iface.addToolBar(u'APIS') self.toolbar.setObjectName(u'APIS') self.dbm = None self.apisLayer = None self.areDialogsInit = False self.areDialogsActive = False self.imageMappingMode = False self.imageMappingDlg = None self.siteMappingDlg = None self.searchDlg = None self.openDialogButtons = None self.imageMappingActionBtn = None self.siteMappingActionBtn = None self.searchActionBtn = None # Require configStatus on startup and Settings self.configStatus, self.settings = ApisPluginSettings() # Create APIS Image Registry self.imageRegistry = ApisImageRegistry(self.plugin_dir, self.iface) self.imageRegistry.loaded.connect(self.enableApis) if self.configStatus: self.imageRegistry.setupSettings() self.imageRegistry.setupRegistry() # Create the src (after translation) and keep reference self.settingsDlg = APISSettings(self.iface, self.imageRegistry, self.iface.mainWindow()) def enableApis(self): #QMessageBox.warning(None, self.tr(u"ApisEnabled"), u"ImageRegistry is now loaded!") if (self.configStatus and self.imageRegistry.registryIsLoaded()): self.dbm = ApisDbManager(self.settings.value("APIS/database_file")) self.apisLayer = ApisLayerManager(self.plugin_dir, self.iface, self.dbm) self.initDialogs() if self.openDialogButtons is not None: self.activateDialogs(True) else: QMessageBox.warning( None, self.tr(u"Konfiguration"), u"{0}, {1}".format(self.configStatus, self.settings)) if self.openDialogButtons is not None: self.activateDialogs(False) def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, checkable=False, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if checkable: action.setCheckable(checkable) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToDatabaseMenu(self.menu, action) self.actions.append(action) return action def initDialogs(self): self.filmDlg = APISFilm(self.iface, self.dbm, self.imageRegistry, self.apisLayer, self.iface.mainWindow()) self.imageMappingDlg = None self.siteMappingDlg = None self.searchDlg = None self.areDialogsInit = True self.areDialogsActive = True def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" # Settings Dialog if self.configStatus and self.imageRegistry.registryIsLoaded(): icon_path = os.path.join(self.plugin_dir, 'ui', 'icons', 'settings.png') else: icon_path = os.path.join(self.plugin_dir, 'ui', 'icons', 'settings_alert.png') self.openSettingsButton = self.add_action( icon_path, text=tr(u'APIS Einstellungen'), callback=self.openSettingsDialog, parent=self.iface.mainWindow()) self.openDialogButtons = [] self.apisLayerActionsGroup = QActionGroup(self.iface.mainWindow()) self.uiLayerTBtn = QToolButton() self.uiLayerTBtn.setMenu(QMenu()) self.uiLayerTBtn.setPopupMode(QToolButton.MenuButtonPopup) self.uiLayerTBtnAction = self.toolbar.addWidget(self.uiLayerTBtn) # (Re)Load Apis Layers icon_path = os.path.join(self.plugin_dir, 'ui', 'icons', 'layer.png') self.openDialogButtons.append( self.add_action(icon_path, text=self.tr(u'Alle Layer'), callback=partial(self.loadApisLayerTree, "all"), enabled_flag=self.configStatus and self.imageRegistry.registryIsLoaded(), add_to_toolbar=False, add_to_menu=False, parent=self.iface.mainWindow())) self.apisLayerActionsGroup.addAction(self.openDialogButtons[0]) m = self.uiLayerTBtn.menu() m.addAction(self.openDialogButtons[0]) self.uiLayerTBtn.setDefaultAction(self.openDialogButtons[0]) m.addSeparator() icon_path = os.path.join(self.plugin_dir, 'ui', 'icons', 'site.png') self.openDialogButtons.append( self.add_action(icon_path, text=self.tr(u'Funde Layer'), callback=partial(self.loadApisLayerTree, "site"), enabled_flag=self.configStatus and self.imageRegistry.registryIsLoaded(), add_to_toolbar=False, add_to_menu=False, parent=self.iface.mainWindow())) self.apisLayerActionsGroup.addAction(self.openDialogButtons[1]) m.addAction(self.openDialogButtons[1]) icon_path = os.path.join(self.plugin_dir, 'ui', 'icons', 'images.png') self.openDialogButtons.append( self.add_action(icon_path, text=self.tr(u'Luftbild Layer'), callback=partial(self.loadApisLayerTree, "image"), enabled_flag=self.configStatus and self.imageRegistry.registryIsLoaded(), add_to_toolbar=False, add_to_menu=False, parent=self.iface.mainWindow())) self.apisLayerActionsGroup.addAction(self.openDialogButtons[2]) m.addAction(self.openDialogButtons[2]) m.addSeparator() icon_path = os.path.join(self.plugin_dir, 'ui', 'icons', 'layer.png') self.openDialogButtons.append( self.add_action(icon_path, text=self.tr(u'Gemeindegrenzen'), callback=partial(self.loadApisLayerTree, "municipalborders"), enabled_flag=self.configStatus and self.imageRegistry.registryIsLoaded(), add_to_toolbar=False, add_to_menu=False, parent=self.iface.mainWindow())) self.apisLayerActionsGroup.addAction(self.openDialogButtons[3]) m.addAction(self.openDialogButtons[3]) icon_path = os.path.join(self.plugin_dir, 'ui', 'icons', 'layer.png') self.openDialogButtons.append( self.add_action(icon_path, text=self.tr(u'Staatsgrenzen'), callback=partial(self.loadApisLayerTree, "nationalborders"), enabled_flag=self.configStatus and self.imageRegistry.registryIsLoaded(), add_to_toolbar=False, add_to_menu=False, parent=self.iface.mainWindow())) self.apisLayerActionsGroup.addAction(self.openDialogButtons[4]) m.addAction(self.openDialogButtons[4]) m.addSeparator() icon_path = os.path.join(self.plugin_dir, 'ui', 'icons', 'layer.png') self.openDialogButtons.append( self.add_action(icon_path, text=self.tr(u'ÖK50 Layer'), callback=partial(self.loadApisLayerTree, "oek50"), enabled_flag=self.configStatus and self.imageRegistry.registryIsLoaded(), add_to_toolbar=False, add_to_menu=False, parent=self.iface.mainWindow())) self.apisLayerActionsGroup.addAction(self.openDialogButtons[5]) m.addAction(self.openDialogButtons[5]) #dbM = self.iface.databaseMenu() #QMessageBox.information(None,"menu", "{}".format(",".join(dbM.children()))) #self.iface.addPluginToDatabaseMenu( # self.menu, # m) #self.toolbar.addActions(self.apisLayerActionsGroup.actions()) # Film Dialog icon_path = os.path.join(self.plugin_dir, 'ui', 'icons', 'film.png') self.openDialogButtons.append( self.add_action(icon_path, text=tr(u'APIS Film'), callback=self.openFilmDialog, enabled_flag=self.configStatus and self.imageRegistry.registryIsLoaded(), parent=self.iface.mainWindow())) # Image Mapping Dialog icon_path = os.path.join(self.plugin_dir, 'ui', 'icons', 'mapping_vertical.png') self.imageMappingActionBtn = self.add_action( icon_path, text=self.tr(u'Bilder kartieren'), callback=self.toggleImageMappingDialog, enabled_flag=self.configStatus and self.imageRegistry.registryIsLoaded(), parent=self.iface.mainWindow(), checkable=True) self.openDialogButtons.append(self.imageMappingActionBtn) # Site Mapping Dialog icon_path = os.path.join(self.plugin_dir, 'ui', 'icons', 'site.png') self.siteMappingActionBtn = self.add_action( icon_path, text=self.tr(u'Fundorte kartieren'), callback=self.toggleSiteMappingDialog, enabled_flag=self.configStatus and self.imageRegistry.registryIsLoaded() and self.settings.value("APIS/disable_site_and_findspot", "0") != "1", parent=self.iface.mainWindow(), checkable=True) self.openDialogButtons.append(self.siteMappingActionBtn) # Search Dialog icon_path = os.path.join(self.plugin_dir, 'ui', 'icons', 'search.png') self.searchActionBtn = self.add_action( icon_path, text=self.tr(u'APIS Suche'), callback=self.toggleSearchDialg, enabled_flag=self.configStatus and self.imageRegistry.registryIsLoaded(), parent=self.iface.mainWindow(), checkable=True) self.openDialogButtons.append(self.searchActionBtn) def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginDatabaseMenu(tr(u'&APIS'), action) self.iface.removeToolBarIcon(action) # remove the toolbar del self.toolbar # ToDo: disconnect DB def run(self): """Run method that performs all the real work""" # show the src self.dlg.show() # Run the src event loop result = self.dlg.exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. pass def openSettingsDialog(self): """Run method that performs all the real work""" # show the src self.configStatus, self.settings = ApisPluginSettings() if self.configStatus: if not self.imageRegistry.registryIsSetup(): self.imageRegistry.setupSettings() if not self.imageRegistry.registryIsLoaded(): self.imageRegistry.setupRegistry() self.settingsDlg.uiUpdateImageRegistryBtn.setEnabled(True) if self.dbm and self.settings: self.settingsDlg.setDbm(self.dbm) self.settingsDlg.setSettings(self.settings) self.settingsDlg.uiEditSystemTableBtn.setEnabled(True) self.settingsDlg.uiSystemTableCombo.setEnabled(True) else: self.settingsDlg.uiEditSystemTableBtn.setEnabled(False) self.settingsDlg.uiSystemTableCombo.setEnabled(False) else: self.settingsDlg.uiUpdateImageRegistryBtn.setEnabled(False) self.settingsDlg.uiEditSystemTableBtn.setEnabled(False) self.settingsDlg.uiSystemTableCombo.setEnabled(False) self.settingsDlg.updateSysTablesCombo() self.settingsDlg.show() # Run the src event loop if self.settingsDlg.exec_(): # See if OK was pressed self.configStatus, self.settings = ApisPluginSettings() if self.configStatus: if not self.imageRegistry.registryIsSetup(): self.imageRegistry.setupSettings() if not self.imageRegistry.registryIsLoaded(): self.imageRegistry.setupRegistry() self.enableApis() else: pass def loadApisLayerTree(self, layerGroup): #QMessageBox.information(None, "Apis Layer", layerGroup) if self.apisLayer and self.apisLayer.isLoaded: if layerGroup == "all": self.apisLayer.loadDefaultLayerTree() elif layerGroup == "oek50": self.apisLayer.loadOEK50Layers() else: VersionToCome() def openFilmDialog(self): """Run method that performs all the real work""" # show the src self.filmDlg.show() # Run the src event loop result = self.filmDlg.exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. pass def toggleImageMappingDialog(self): if not self.imageMappingDlg: self.imageMappingDlg = APISImageMapping(self.iface, self.dbm, self.apisLayer) self.imageMappingDlg.visibilityChanged.connect( self.imageMappingActionBtn.setChecked) self.imageMappingDlg.visibilityChanged.connect( self.checkEnableForSettingsDialog) #if self.imageMappingDlg.isVisible(): if self.imageMappingActionBtn and self.imageMappingActionBtn.isChecked( ): self.imageMappingDlg.show() self.imageMappingMode = True else: #TODO Check Mapping State !!! self.imageMappingDlg.hide() self.imageMappingMode = False def toggleSiteMappingDialog(self): if not self.siteMappingDlg: self.siteMappingDlg = APISSiteMapping(self.iface, self.dbm, self.imageRegistry, self.apisLayer) self.siteMappingDlg.visibilityChanged.connect( self.siteMappingActionBtn.setChecked) self.siteMappingDlg.visibilityChanged.connect( self.checkEnableForSettingsDialog) if self.siteMappingActionBtn and self.siteMappingActionBtn.isChecked(): self.siteMappingDlg.show() else: self.siteMappingDlg.hide() def toggleSearchDialg(self): if not self.searchDlg: self.searchDlg = APISSearch(self.iface, self.dbm, self.imageRegistry, self.apisLayer, self.iface.mainWindow()) #self.searchDlg = APISSearch(self.iface) self.searchDlg.visibilityChanged.connect( self.searchActionBtn.setChecked) self.searchDlg.visibilityChanged.connect( self.checkEnableForSettingsDialog) if self.searchActionBtn and self.searchActionBtn.isChecked(): self.searchDlg.show() else: self.searchDlg.hide() def checkEnableForSettingsDialog(self): if (self.searchDlg and self.searchDlg.isVisible()) or ( self.siteMappingDlg and self.siteMappingDlg.isVisible()) or ( self.imageMappingDlg and self.imageMappingDlg.isVisible()): self.openSettingsButton.setEnabled(False) else: self.openSettingsButton.setEnabled(True) def activateDialogs(self, value): """ iterate through openDialogButtons and set them VALUE :param value: :return: """ for action in self.openDialogButtons: if action is self.siteMappingActionBtn: if self.configStatus: if self.settings.value("APIS/disable_site_and_findspot", "0") != "1": action.setEnabled(value) else: action.setEnabled(False) else: action.setEnabled(value) self.areDialogsActive = value # Change Settings Icon if required if self.configStatus and self.imageRegistry.registryIsLoaded(): icon_path = os.path.join(self.plugin_dir, 'ui', 'icons', 'settings.png') else: icon_path = os.path.join(self.plugin_dir, 'ui', 'icons', 'settings_alert.png') self.openSettingsButton.setIcon(QIcon(icon_path)) if self.imageMappingActionBtn and self.imageMappingActionBtn.isChecked( ): self.imageMappingActionBtn.trigger() if self.siteMappingActionBtn and self.siteMappingActionBtn.isChecked(): self.siteMappingActionBtn.trigger() if self.searchActionBtn and self.searchActionBtn.isChecked(): self.searchActionBtn.trigger() # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('APIS', message)
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.createActions() self.createMenus() self.createToolBox() self.createStatusBar() self.scene = ITGScene(self.itemMenu) self.scene.setSceneRect(QRectF(0, 0, 5000, 5000)) self.scene.itemInserted.connect(self.itemInserted) self.scene.itemSelected.connect(self.itemSelected) # ================================================================ # THIS IS THE PROBLEM SECTION # THIS CAUSES TypeError: native Qt signal is not callable # To reproduce the error, run the program, click on one of the # shapes, then click on the scene area # ================================================================ self.scene.selectionChanged.connect( self.print_item_info) # this one doesn't work self.createToolbars() layout = QHBoxLayout() layout.addWidget(self.toolBox) self.view = QGraphicsView( self.scene) # view and scene established together layout.addWidget(self.view) self.widget = QWidget() self.widget.setLayout(layout) self.setCentralWidget(self.widget) self.setWindowTitle("ITG: Illegitimate Template Generator") #@pyqtSlot() # Adding this does not change the error def print_item_info(self): for item in self.scene.selectedItems(): print(item) def buttonGroupClicked(self, id): buttons = self.buttonGroup.buttons() for button in buttons: if self.buttonGroup.button(id) != button: button.setChecked(False) self.scene.setItemType(id) self.scene.setMode(ITGScene.InsertItem) self.updateStatusBar() def deleteItem(self): for item in self.scene.selectedItems(): self.scene.removeItem(item) def pointerGroupClicked(self, i): self.scene.setMode(self.pointerTypeGroup.checkedId()) self.updateStatusBar() def bringToFront(self): if not self.scene.selectedItems(): return selectedItem = self.scene.selectedItems()[0] overlapItems = selectedItem.collidingItems() zValue = 0 for item in overlapItems: if (item.zValue() >= zValue and isinstance(item, ITGItem)): zValue = item.zValue() + 0.1 selectedItem.setZValue(zValue) def sendToBack(self): if not self.scene.selectedItems(): return selectedItem = self.scene.selectedItems()[0] overlapItems = selectedItem.collidingItems() zValue = 0 for item in overlapItems: if (item.zValue() <= zValue and isinstance(item, ITGItem)): zValue = item.zValue() - 0.1 selectedItem.setZValue(zValue) def itemInserted(self, item): self.pointerTypeGroup.button(ITGScene.MoveItem).setChecked(True) self.scene.setMode(self.pointerTypeGroup.checkedId()) self.updateStatusBar() self.buttonGroup.button(item.ITGType).setChecked(False) def sceneScaleChanged(self, scale): newScale = scale.left(scale.indexOf("%")).toDouble()[0] / 100.0 oldMatrix = self.view.matrix() self.view.resetMatrix() self.view.translate(oldMatrix.dx(), oldMatrix.dy()) self.view.scale(newScale, newScale) def itemColorChanged(self): self.fillAction = self.sender() self.fillColorToolButton.setIcon( self.createColorToolButtonIcon(':/images/floodfill.png', QColor(self.fillAction.data()))) self.fillButtonTriggered() def fillButtonTriggered(self): self.scene.setItemColor(QColor(self.fillAction.data())) def itemSelected(self, item): font = item.font() color = item.defaultTextColor() self.fontCombo.setCurrentFont(font) self.fontSizeCombo.setEditText(str(font.pointSize())) self.boldAction.setChecked(font.weight() == QFont.Bold) self.italicAction.setChecked(font.italic()) self.underlineAction.setChecked(font.underline()) def about(self): QMessageBox.about( self, "About ITG Scene", "The <b>ITG Scene</b> example shows use of the graphics framework." ) def createToolBox(self): self.buttonGroup = QButtonGroup() self.buttonGroup.setExclusive(False) self.buttonGroup.buttonClicked[int].connect(self.buttonGroupClicked) layout = QGridLayout() layout.addWidget(self.createCellWidget("Diamond", ITGItem.Diamond), 0, 0) layout.addWidget(self.createCellWidget("Square", ITGItem.Square), 0, 1) layout.addWidget( self.createCellWidget("Parallelogram", ITGItem.Parallelogram), 1, 0) layout.setRowStretch(3, 10) layout.setColumnStretch(2, 10) itemWidget = QWidget() itemWidget.setLayout(layout) self.backgroundButtonGroup = QButtonGroup() self.toolBox = QToolBox() self.toolBox.setSizePolicy( QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Ignored)) self.toolBox.setMinimumWidth(itemWidget.sizeHint().width()) self.toolBox.addItem(itemWidget, "Basic Components") def createActions(self): self.toFrontAction = QAction(QIcon(':/images/bringtofront.png'), "Bring to &Front", self, shortcut="Ctrl+F", statusTip="Bring item to front", triggered=self.bringToFront) self.sendBackAction = QAction(QIcon(':/images/sendtoback.png'), "Send to &Back", self, shortcut="Ctrl+B", statusTip="Send item to back", triggered=self.sendToBack) self.deleteAction = QAction(QIcon(':/images/delete.png'), "&Delete", self, shortcut="Delete", statusTip="Delete item from ITG", triggered=self.deleteItem) self.exitAction = QAction("E&xit", self, shortcut="Ctrl+X", statusTip="Quit SceneITG example", triggered=self.close) self.aboutAction = QAction("A&bout", self, shortcut="Ctrl+B", triggered=self.about) def createMenus(self): self.fileMenu = self.menuBar().addMenu("&File") self.fileMenu.addAction(self.exitAction) self.itemMenu = self.menuBar().addMenu("&Item") self.itemMenu.addAction(self.deleteAction) self.itemMenu.addSeparator() self.itemMenu.addAction(self.toFrontAction) self.itemMenu.addAction(self.sendBackAction) self.aboutMenu = self.menuBar().addMenu("&Help") self.aboutMenu.addAction(self.aboutAction) def createToolbars(self): self.editToolBar = self.addToolBar("Edit") self.editToolBar.addAction(self.deleteAction) self.editToolBar.addAction(self.toFrontAction) self.editToolBar.addAction(self.sendBackAction) self.fillColorToolButton = QToolButton() self.fillColorToolButton.setPopupMode(QToolButton.MenuButtonPopup) self.fillColorToolButton.setMenu( self.createColorMenu(self.itemColorChanged, Qt.red)) self.fillAction = self.fillColorToolButton.menu().defaultAction() self.fillColorToolButton.setIcon( self.createColorToolButtonIcon(':/images/floodfill.png', Qt.red)) self.fillColorToolButton.clicked.connect(self.fillButtonTriggered) self.colorToolBar = self.addToolBar("Color") self.colorToolBar.addWidget(self.fillColorToolButton) pointerButton = QToolButton() pointerButton.setCheckable(True) pointerButton.setChecked(True) pointerButton.setIcon(QIcon(':/images/pointer.png')) self.pointerTypeGroup = QButtonGroup() self.pointerTypeGroup.addButton(pointerButton, ITGScene.MoveItem) self.pointerTypeGroup.buttonClicked[int].connect( self.pointerGroupClicked) self.sceneScaleCombo = QComboBox() self.sceneScaleCombo.addItems(["50%", "75%", "100%", "125%", "150%"]) self.sceneScaleCombo.setCurrentIndex(2) self.sceneScaleCombo.currentIndexChanged[str].connect( self.sceneScaleChanged) self.pointerToolbar = self.addToolBar("Pointer type") self.pointerToolbar.addWidget(pointerButton) self.pointerToolbar.addWidget(self.sceneScaleCombo) def createBackgroundCellWidget(self, text, image): button = QToolButton() button.setText(text) button.setIcon(QIcon(image)) button.setIconSize(QSize(50, 50)) button.setCheckable(True) self.backgroundButtonGroup.addButton(button) layout = QGridLayout() layout.addWidget(button, 0, 0, Qt.AlignHCenter) layout.addWidget(QLabel(text), 1, 0, Qt.AlignCenter) widget = QWidget() widget.setLayout(layout) return widget def createCellWidget(self, text, ITGType): item = ITGItem(ITGType, self.itemMenu) icon = QIcon(item.image()) button = QToolButton() button.setIcon(icon) button.setIconSize(QSize(50, 50)) button.setCheckable(True) self.buttonGroup.addButton(button, ITGType) layout = QGridLayout() layout.addWidget(button, 0, 0, Qt.AlignHCenter) layout.addWidget(QLabel(text), 1, 0, Qt.AlignCenter) widget = QWidget() widget.setLayout(layout) return widget def createColorMenu(self, slot, defaultColor): colors = [Qt.black, Qt.white, Qt.red, Qt.blue, Qt.yellow] names = ["black", "white", "red", "blue", "yellow"] colorMenu = QMenu(self) for color, name in zip(colors, names): action = QAction(self.createColorIcon(color), name, self, triggered=slot) action.setData(QColor(color)) colorMenu.addAction(action) if color == defaultColor: colorMenu.setDefaultAction(action) return colorMenu def createColorToolButtonIcon(self, imageFile, color): pixmap = QPixmap(50, 80) pixmap.fill(Qt.transparent) painter = QPainter(pixmap) image = QPixmap(imageFile) target = QRect(0, 0, 50, 60) source = QRect(0, 0, 42, 42) painter.fillRect(QRect(0, 60, 50, 80), color) painter.drawPixmap(target, image, source) painter.end() return QIcon(pixmap) def createColorIcon(self, color): pixmap = QPixmap(20, 20) painter = QPainter(pixmap) painter.setPen(Qt.NoPen) painter.fillRect(QRect(0, 0, 20, 20), color) painter.end() return QIcon(pixmap) def createStatusBar(self): self.sbar = self.statusBar() self.lbl_mode = QLabel('Mode: not set') self.sbar.addPermanentWidget(self.lbl_mode) self.lbl_selection = QLabel('Sel: none') self.sbar.addPermanentWidget(self.lbl_selection) def updateStatusBar(self): self.lbl_mode.setText('Mode: ' + self.scene.getMode()) #! This section is not working!!! if len(self.scene.selectedItems()) == 0: self.lbl_selection.setText('Sel: none') elif len(self.scene.selectedItems()) == 1: self.lbl_selection.setText( 'Sel: ' + self.scene.selectedItems()[0].get_ITGType_as_str()) elif len(self.scene.selectedItems()) > 1: self.lbl_selection.setText('Sel: <multiple>')
class MainWindow(QMainWindow): InsertTextButton = 10 items = {-2: "source", -3: "channel", -4: "sink"} def __init__(self): import _diagramscene_rc super(MainWindow, self).__init__() self.config_manipulations = FlumeConfig(self) properties_generator.dump_props() self.create_actions() self.create_menus() self.create_tool_box() self.clicked_button_id = 0 self.scene = DiagramScene(self.item_menu) self.scene.setSceneRect(QRectF(0, 0, 5000, 5000)) self.scene.itemInserted.connect(self.item_inserted) self.scene.textInserted.connect(self.text_inserted) self.scene.itemSelected.connect(self.item_selected) self.create_tool_bars() # self.scene.enable_grid() layout = QHBoxLayout() layout.addWidget(self.tool_box) self.view = QGraphicsView(self.scene) self.view.centerOn(0, 0) layout.addWidget(self.view) self.widget = QWidget() self.widget.setLayout(layout) self.setCentralWidget(self.widget) self.setWindowTitle("The Flume Illustrator") # noinspection PyAttributeOutsideInit,PyArgumentList def create_actions(self): self.to_front_action = QAction(QIcon(':/images/bringtofront.png'), "Bring to &Front", self, shortcut="Ctrl+F", statusTip="Bring item to front", triggered=self.bring_to_front) self.send_back_action = QAction(QIcon(':/images/sendtoback.png'), "Send to &Back", self, shortcut="Ctrl+B", statusTip="Send item to back", triggered=self.send_to_back) self.bold_action = QAction(QIcon(':/images/bold.png'), "Bold", self, checkable=True, shortcut="Ctrl+B", triggered=self.handle_font_change) self.italic_action = QAction(QIcon(':/images/italic.png'), "Italic", self, checkable=True, shortcut="Ctrl+I", triggered=self.handle_font_change) self.underline_action = QAction(QIcon(':/images/underline.png'), "Underline", self, checkable=True, shortcut="Ctrl+U", triggered=self.handle_font_change) self.delete_action = QAction(QIcon(':/images/delete.png'), "Delete", self, shortcut="Delete", statusTip='Delete item from diagram', triggered=self.delete_item) self.exit_action = QAction("Exit", self, shortcut="Ctrl+X", statusTip="Quit program", triggered=self.close) self.about_action = QAction("About", self, shortcut="Ctrl+B", triggered=self.about) self.load_config_action = QAction("Load", self, shortcut="Ctrl+O", statusTip="Load config file", triggered=self.config_manipulations.load_config) self.enable_grid_action = QAction("Enable grid", self, checkable=True, triggered=self.enable_grid) # noinspection PyAttributeOutsideInit def create_menus(self): self.file_menu = self.menuBar().addMenu("File") self.file_menu.addAction(self.load_config_action) self.file_menu.addAction(self.exit_action) self.item_menu = self.menuBar().addMenu("Item") self.item_menu.addAction(self.delete_action) self.item_menu.addSeparator() self.item_menu.addAction(self.to_front_action) self.item_menu.addAction(self.send_back_action) self.about_menu = self.menuBar().addMenu("Help") self.about_menu.addAction(self.about_action) # noinspection PyAttributeOutsideInit,PyUnresolvedReferences def create_tool_box(self): self.button_group = QButtonGroup() self.button_group.setExclusive(False) self.button_group.buttonClicked[int].connect(self.button_group_clicked) layout = QGridLayout() layout.addWidget(self.create_cell_widget("Source", "source"), 0, 0) layout.addWidget(self.create_cell_widget("Channel", "channel"), 0, 1) layout.addWidget(self.create_cell_widget("Sink", "sink"), 1, 0) text_button = QToolButton() text_button.setCheckable(True) self.button_group.addButton(text_button, self.InsertTextButton) text_button.setIcon(QIcon(QPixmap(':/images/textpointer.png').scaled(30, 30))) text_button.setIconSize(QSize(50, 50)) text_layout = QGridLayout() text_layout.addWidget(text_button, 0, 0, Qt.AlignHCenter) text_layout.addWidget(QLabel("Text"), 1, 0, Qt.AlignCenter) text_widget = QWidget() text_widget.setLayout(text_layout) layout.addWidget(text_widget, 1, 1) layout.setRowStretch(3, 10) layout.setColumnStretch(2, 10) item_widget = QWidget() item_widget.setLayout(layout) self.tool_box = QToolBox() self.tool_box.setSizePolicy(QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Ignored)) self.tool_box.setMinimumWidth(item_widget.sizeHint().width()) self.tool_box.addItem(item_widget, "Basic Flume Items") # noinspection PyAttributeOutsideInit,PyUnresolvedReferences def create_tool_bars(self): self.edit_tool_bar = self.addToolBar("Edit") self.edit_tool_bar.addAction(self.delete_action) self.edit_tool_bar.addAction(self.to_front_action) self.edit_tool_bar.addAction(self.send_back_action) self.edit_tool_bar.addAction(self.enable_grid_action) self.font_combo = QFontComboBox() self.font_combo.currentFontChanged.connect(self.current_font_changed) self.font_size_combo = QComboBox() self.font_size_combo.setEditable(True) for i in range(8, 30, 2): self.font_size_combo.addItem(str(i)) validator = QIntValidator(2, 64, self) self.font_size_combo.setValidator(validator) self.font_size_combo.currentIndexChanged.connect(self.font_size_changed) self.font_color_tool_button = QToolButton() self.font_color_tool_button.setPopupMode(QToolButton.MenuButtonPopup) self.font_color_tool_button.setMenu( self.create_color_menu(self.text_color_changed, Qt.black)) self.text_action = self.font_color_tool_button.menu().defaultAction() self.font_color_tool_button.setIcon( self.create_color_tool_button_icon(':/images/textpointer.png', Qt.black)) self.font_color_tool_button.setAutoFillBackground(True) self.font_color_tool_button.clicked.connect(self.text_button_triggered) self.fill_color_tool_button = QToolButton() self.fill_color_tool_button.setPopupMode(QToolButton.MenuButtonPopup) self.fill_color_tool_button.setMenu( self.create_color_menu(self.item_color_changed, Qt.white)) self.fillAction = self.fill_color_tool_button.menu().defaultAction() self.fill_color_tool_button.setIcon( self.create_color_tool_button_icon(':/images/floodfill.png', Qt.white)) self.fill_color_tool_button.clicked.connect(self.fill_button_triggered) self.line_color_tool_button = QToolButton() self.line_color_tool_button.setPopupMode(QToolButton.MenuButtonPopup) self.line_color_tool_button.setMenu( self.create_color_menu(self.line_color_changed, Qt.black)) self.lineAction = self.line_color_tool_button.menu().defaultAction() self.line_color_tool_button.setIcon( self.create_color_tool_button_icon(':/images/linecolor.png', Qt.black)) self.line_color_tool_button.clicked.connect(self.line_button_triggered) self.text_tool_bar = self.addToolBar("Font") self.text_tool_bar.addWidget(self.font_combo) self.text_tool_bar.addWidget(self.font_size_combo) self.text_tool_bar.addAction(self.bold_action) self.text_tool_bar.addAction(self.italic_action) self.text_tool_bar.addAction(self.underline_action) self.color_tool_bar = self.addToolBar("Color") self.color_tool_bar.addWidget(self.font_color_tool_button) self.color_tool_bar.addWidget(self.fill_color_tool_button) self.color_tool_bar.addWidget(self.line_color_tool_button) self.loading_tool_bar = self.addToolBar("Load") self.loading_tool_bar.addAction(self.load_config_action) pointer_button = QToolButton() pointer_button.setCheckable(True) pointer_button.setChecked(True) pointer_button.setIcon(QIcon(":/images/pointer.png")) line_pointer_button = QToolButton() line_pointer_button.setCheckable(True) line_pointer_button.setIcon(QIcon(":/images/linepointer.png")) self.pointer_type_group = QButtonGroup() self.pointer_type_group.addButton(pointer_button, DiagramScene.MoveItem) self.pointer_type_group.addButton(line_pointer_button, DiagramScene.InsertLine) self.pointer_type_group.buttonClicked[int].connect(self.pointer_group_clicked) self.scene_scale_combo = QComboBox() self.scene_scale_combo.addItems(["50%", "75%", "100%", "125%", "150%"]) self.scene_scale_combo.setCurrentIndex(2) self.scene_scale_combo.currentIndexChanged[str].connect(self.scene_scale_changed) self.pointer_tool_bar = self.addToolBar("Pointer type") self.pointer_tool_bar.addWidget(pointer_button) self.pointer_tool_bar.addWidget(line_pointer_button) self.pointer_tool_bar.addWidget(self.scene_scale_combo) def button_group_clicked(self, button_id): buttons = self.button_group.buttons() self.clicked_button_id = button_id for button in buttons: if self.button_group.button(button_id) != button: button.setChecked(False) if button_id == self.InsertTextButton: self.scene.set_mode(DiagramScene.InsertText) else: self.scene.set_item_type(self.items[button_id]) self.scene.set_mode(DiagramScene.InsertItem) def delete_item(self): for item in self.scene.selectedItems(): if isinstance(item, FlumeDiagramItem): item.remove_arrows() self.scene.removeItem(item) # noinspection PyTypeChecker,PyCallByClass def about(self): # noinspection PyArgumentList QMessageBox.about(self, "About Flume Illustrator", "The Flume illustrator shows config-file details") def pointer_group_clicked(self): self.scene.set_mode(self.pointer_type_group.checkedId()) def bring_to_front(self): if not self.scene.selectedItems(): return selected_item = self.scene.selectedItems()[0] overlap_items = selected_item.collidingItems() z_value = 0 for item in overlap_items: if item.zValue() >= z_value and isinstance(item, FlumeDiagramItem): z_value = item.zValue() + 0.1 selected_item.setZValue(z_value) def send_to_back(self): if not self.scene.selectedItems(): return selected_item = self.scene.selectedItems()[0] overlap_items = selected_item.collidingItems() z_value = 0 for item in overlap_items: if item.zValue() <= z_value and isinstance(item, FlumeDiagramItem): z_value = item.zValue() - 0.1 selected_item.setZValue(z_value) def scene_scale_changed(self, scale): new_scale = float(scale[:scale.index("%")]) / 100 old_transform = self.view.transform() self.view.resetTransform() self.view.translate(old_transform.dx(), old_transform.dy()) self.view.scale(new_scale, new_scale) def item_inserted(self, diagram_type): self.pointer_type_group.button(DiagramScene.MoveItem).setChecked(True) self.scene.set_mode(self.scene.DefaultMode) self.button_group.button(self.clicked_button_id).setChecked(False) def text_inserted(self, item): self.button_group.button(self.InsertTextButton).setChecked(False) self.scene.set_mode(self.pointer_type_group.checkedId()) def current_font_changed(self, font): self.handle_font_change() def font_size_changed(self, font=None): self.handle_font_change() def text_color_changed(self): self.text_action = self.sender() self.font_color_tool_button.setIcon( self.create_color_tool_button_icon(':/images/textpointer.png', QColor(self.text_action.data()))) self.text_button_triggered() def item_color_changed(self): self.fillAction = self.sender() self.fill_color_tool_button.setIcon( self.create_color_tool_button_icon(':/images/floodfill.png', QColor(self.fillAction.data()))) self.fill_button_triggered() def line_color_changed(self): self.lineAction = self.sender() self.line_color_tool_button.setIcon( self.create_color_tool_button_icon(':/images/linecolor.png', QColor(self.lineAction.data()))) self.line_button_triggered() def text_button_triggered(self): self.scene.set_text_color(QColor(self.text_action.data())) def fill_button_triggered(self): self.scene.set_item_color(QColor(self.fillAction.data())) def line_button_triggered(self): self.scene.set_line_color(QColor(self.lineAction.data())) def handle_font_change(self): font = self.font_combo.currentFont() font.setPointSize(int(self.font_size_combo.currentText())) if self.bold_action.isChecked(): font.setWeight(QFont.Bold) else: font.setWeight(QFont.Normal) font.setItalic(self.italic_action.isChecked()) font.setUnderline(self.underline_action.isChecked()) self.scene.setFont(font) def item_selected(self, item): font = item.font() self.font_combo.setCurrentFont(font) self.font_size_combo.setEditText(str(font.pointSize())) self.bold_action.setChecked(font.weight() == QFont.Bold) self.italic_action.setChecked(font.italic()) self.underline_action.setChecked(font.underline()) def create_cell_widget(self, text, diagram_type): item = FlumeObject(diagram_type, "") icon = QIcon(item.pictogram.image()) button = QToolButton() button.setIcon(icon) button.setIconSize(QSize(50, 50)) button.setCheckable(True) self.button_group.addButton(button) # , diagram_type layout = QGridLayout() layout.addWidget(button, 0, 0, Qt.AlignHCenter) layout.addWidget(QLabel(text), 1, 0, Qt.AlignHCenter) widget = QWidget() widget.setLayout(layout) return widget # noinspection PyArgumentList def create_color_menu(self, slot, default_color): colors = [Qt.black, Qt.white, Qt.red, Qt.blue, Qt.yellow] names = ["black", "white", "red", "blue", "yellow"] color_menu = QMenu(self) for color, name in zip(colors, names): action = QAction(self.create_color_icon(color), name, self, triggered=slot) action.setData(QColor(color)) color_menu.addAction(action) if color == default_color: color_menu.setDefaultAction(action) return color_menu @staticmethod def create_color_tool_button_icon(image_file, color): pixmap = QPixmap(50, 80) pixmap.fill(Qt.transparent) painter = QPainter(pixmap) image = QPixmap(image_file) target = QRect(0, 0, 50, 60) source = QRect(0, 0, 42, 42) painter.fillRect(QRect(0, 60, 50, 80), color) painter.drawPixmap(target, image, source) painter.end() return QIcon(pixmap) @staticmethod def create_color_icon(color): pixmap = QPixmap(20, 20) painter = QPainter(pixmap) painter.setPen(Qt.NoPen) painter.fillRect(QRect(0, 0, 20, 20), color) painter.end() return QIcon(pixmap) def enable_grid(self): if self.enable_grid_action.isChecked(): color = Qt.black else: color = Qt.white for i in range(50): for j in range(50): self.scene.addEllipse(i * 100, j * 100, 2, 2, QPen(color))