def __init__(self, element, model): super(ModelerGraphicItem, self).__init__(None, None) self.model = model self.element = element if isinstance(element, ModelerParameter): icon = QIcon(os.path.dirname(__file__) + '/../images/input.png') self.pixmap = icon.pixmap(20, 20, state=QIcon.On) self.text = element.param.description elif isinstance(element, ModelerOutput): # Output name icon = QIcon(os.path.dirname(__file__) + '/../images/output.png') self.pixmap = icon.pixmap(20, 20, state=QIcon.On) self.text = element.description else: self.text = element.description self.pixmap = element.algorithm.getIcon().pixmap(15, 15) self.arrows = [] self.setFlag(QGraphicsItem.ItemIsMovable, True) self.setFlag(QGraphicsItem.ItemIsSelectable, True) self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True) self.setZValue(1000) if not isinstance(element, ModelerOutput): icon = QIcon(os.path.dirname(__file__) + '/../images/edit.png') pt = QPointF( ModelerGraphicItem.BOX_WIDTH / 2 - FlatButtonGraphicItem.WIDTH / 2, ModelerGraphicItem.BOX_HEIGHT / 2 - FlatButtonGraphicItem.HEIGHT / 2 + 1) self.editButton = FlatButtonGraphicItem(icon, pt, self.editElement) self.editButton.setParentItem(self) icon = QIcon(os.path.dirname(__file__) + '/../images/delete.png') pt = QPointF( ModelerGraphicItem.BOX_WIDTH / 2 - FlatButtonGraphicItem.WIDTH / 2, -ModelerGraphicItem.BOX_HEIGHT / 2 + FlatButtonGraphicItem.HEIGHT / 2 + 1) self.deleteButton = FlatButtonGraphicItem(icon, pt, self.removeElement) self.deleteButton.setParentItem(self) if isinstance(element, Algorithm): alg = element.algorithm if alg.parameters: pt = self.getLinkPointForParameter(-1) pt = QPointF(0, pt.y() + 2) self.inButton = FoldButtonGraphicItem( pt, self.foldInput, self.element.paramsFolded) self.inButton.setParentItem(self) if alg.outputs: pt = self.getLinkPointForOutput(-1) pt = QPointF(0, pt.y() + 2) self.outButton = FoldButtonGraphicItem( pt, self.foldOutput, self.element.outputsFolded) self.outButton.setParentItem(self)
def __init__(self, template, character, parent=None): super(AdvantagesWidget, self).__init__(parent) self.ui = Ui_AdvantagesWidget() self.ui.setupUi(self) self.__character = character self.__storage = template fontMetrics = QFontMetrics(self.font()) textRect = fontMetrics.boundingRect("0") iconGeneral = QIcon(":/items/images/svg/shield.svg") pixmapGeneral = iconGeneral.pixmap(textRect.height(), 10 * textRect.height()) self.ui.label_armorGeneralSign.setPixmap(pixmapGeneral) iconFirearms = QIcon(":/items/images/svg/uzi.svg") pixmapFirearms = iconFirearms.pixmap(textRect.height(), 10 * textRect.height()) self.ui.label_armorFirearmsSign.setPixmap(pixmapFirearms) self.ui.dots_health.setReadOnly(True) self.ui.dots_willpower.setMaximum(Config.TRAIT_WILLPOWER_VALUE_MAX) self.ui.dots_willpower.setReadOnly(True) self.ui.dots_powerstat.setMaximum(Config.TRAIT_POWERSTAT_VALUE_MAX) self.ui.dots_powerstat.setMinimum(Config.TRAIT_POWERSTAT_VALUE_MIN) # Damit später der Wert stimmt muß ich irgendeinen Wert != 1 geben, sonst wird kein Signal gesandt. self.ui.dots_powerstat.setValue(9) self.ui.squares_fuel.columnMax = 10 self.__character.speciesChanged.connect(self.setShapeSize) self.sizeChanged.connect(self.setShapeSize) self.__character.speciesChanged.connect(self.setShapeInitiaitve) self.initiativeChanged.connect(self.setShapeInitiaitve) self.__character.speciesChanged.connect(self.setShapeSpeed) self.speedChanged.connect(self.setShapeSpeed) self.__character.speciesChanged.connect(self.setShapeDefense) self.__character.traits["Attribute"]["Mental"][ "Wits"].valueChanged.connect(self.setShapeDefense) self.__character.traits["Attribute"]["Physical"][ "Dexterity"].valueChanged.connect(self.setShapeDefense) self.__character.speciesChanged.connect(self.setShapeHealth) self.healthChanged.connect(self.setShapeHealth) self.__character.armorChanged.connect(self.updateArmor) self.ui.dots_powerstat.valueChanged.connect( self.__character.setPowerstat) self.__character.powerstatChanged.connect( self.ui.dots_powerstat.setValue) self.__character.powerstatChanged.connect(self.setFuel) self.__character.speciesChanged.connect(self.setFuel) self.__character.speciesChanged.connect(self.renamePowerstatHeading) self.__character.speciesChanged.connect(self.hideSuper)
def __init__(self, element, model): super(ModelerGraphicItem, self).__init__(None, None) self.model = model self.element = element if isinstance(element, ModelerParameter): icon = QIcon(os.path.join(pluginPath, 'images', 'input.png')) self.pixmap = icon.pixmap(20, 20, state=QIcon.On) self.text = element.param.description elif isinstance(element, ModelerOutput): # Output name icon = QIcon(os.path.join(pluginPath, 'images', 'output.png')) self.pixmap = icon.pixmap(20, 20, state=QIcon.On) self.text = element.description else: self.text = element.description self.pixmap = element.algorithm.getIcon().pixmap(15, 15) self.arrows = [] self.setFlag(QGraphicsItem.ItemIsMovable, True) self.setFlag(QGraphicsItem.ItemIsSelectable, True) self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True) self.setZValue(1000) if not isinstance(element, ModelerOutput): icon = QIcon(os.path.join(pluginPath, 'images', 'edit.png')) pt = QPointF(ModelerGraphicItem.BOX_WIDTH / 2 - FlatButtonGraphicItem.WIDTH / 2, ModelerGraphicItem.BOX_HEIGHT / 2 - FlatButtonGraphicItem.HEIGHT / 2 + 1) self.editButton = FlatButtonGraphicItem(icon, pt, self.editElement) self.editButton.setParentItem(self) icon = QIcon(os.path.join(pluginPath, 'images', 'delete.png')) pt = QPointF(ModelerGraphicItem.BOX_WIDTH / 2 - FlatButtonGraphicItem.WIDTH / 2, - ModelerGraphicItem.BOX_HEIGHT / 2 + FlatButtonGraphicItem.HEIGHT / 2 + 1) self.deleteButton = FlatButtonGraphicItem(icon, pt, self.removeElement) self.deleteButton.setParentItem(self) if isinstance(element, Algorithm): alg = element.algorithm if alg.parameters: pt = self.getLinkPointForParameter(-1) pt = QPointF(0, pt.y() + 2) self.inButton = FoldButtonGraphicItem(pt, self.foldInput, self.element.paramsFolded) self.inButton.setParentItem(self) if alg.outputs: pt = self.getLinkPointForOutput(-1) pt = QPointF(0, pt.y() + 2) self.outButton = FoldButtonGraphicItem(pt, self.foldOutput, self.element.outputsFolded) self.outButton.setParentItem(self)
def __init__(self, template, character, parent=None): super(AdvantagesWidget, self).__init__(parent) self.ui = Ui_AdvantagesWidget() self.ui.setupUi(self) self.__character = character self.__storage = template fontMetrics = QFontMetrics(self.font()) textRect = fontMetrics.boundingRect("0") iconGeneral = QIcon(":/items/images/svg/shield.svg") pixmapGeneral = iconGeneral.pixmap(textRect.height(), 10 * textRect.height()) self.ui.label_armorGeneralSign.setPixmap(pixmapGeneral) iconFirearms = QIcon(":/items/images/svg/uzi.svg") pixmapFirearms = iconFirearms.pixmap(textRect.height(), 10 * textRect.height()) self.ui.label_armorFirearmsSign.setPixmap(pixmapFirearms) self.ui.dots_health.setReadOnly( True ) self.ui.dots_willpower.setMaximum( Config.TRAIT_WILLPOWER_VALUE_MAX ) self.ui.dots_willpower.setReadOnly( True ) self.ui.dots_powerstat.setMaximum( Config.TRAIT_POWERSTAT_VALUE_MAX ) self.ui.dots_powerstat.setMinimum( Config.TRAIT_POWERSTAT_VALUE_MIN ) # Damit später der Wert stimmt muß ich irgendeinen Wert != 1 geben, sonst wird kein Signal gesandt. self.ui.dots_powerstat.setValue( 9 ) self.ui.squares_fuel.columnMax = 10 self.__character.speciesChanged.connect(self.setShapeSize) self.sizeChanged.connect(self.setShapeSize) self.__character.speciesChanged.connect(self.setShapeInitiaitve) self.initiativeChanged.connect(self.setShapeInitiaitve) self.__character.speciesChanged.connect(self.setShapeSpeed) self.speedChanged.connect(self.setShapeSpeed) self.__character.speciesChanged.connect(self.setShapeDefense) self.__character.traits["Attribute"]["Mental"]["Wits"].valueChanged.connect(self.setShapeDefense) self.__character.traits["Attribute"]["Physical"]["Dexterity"].valueChanged.connect(self.setShapeDefense) self.__character.speciesChanged.connect(self.setShapeHealth) self.healthChanged.connect(self.setShapeHealth) self.__character.armorChanged.connect(self.updateArmor) self.ui.dots_powerstat.valueChanged.connect(self.__character.setPowerstat) self.__character.powerstatChanged.connect(self.ui.dots_powerstat.setValue) self.__character.powerstatChanged.connect(self.setFuel) self.__character.speciesChanged.connect(self.setFuel) self.__character.speciesChanged.connect(self.renamePowerstatHeading) self.__character.speciesChanged.connect(self.hideSuper)
def __init__(self, icon_path, enabled=True, size_multiplier=0.7, tooltip=None, parent=None, icon_sz=(32, 32)): super(VmIconWidget, self).__init__(parent) self.label_icon = QLabel() if icon_path[0] in ':/': icon = QIcon(icon_path) else: icon = QIcon.fromTheme(icon_path) icon_sz = QSize(row_height * size_multiplier, row_height * size_multiplier) icon_pixmap = icon.pixmap( icon_sz, QIcon.Disabled if not enabled else QIcon.Normal) self.label_icon.setPixmap(icon_pixmap) self.label_icon.setFixedSize(icon_sz) if tooltip != None: self.label_icon.setToolTip(tooltip) layout = QHBoxLayout() layout.addWidget(self.label_icon) layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout)
def load(self, name, size=128, forceCache=False): icon = QIcon() size = int(size) self.pixmap = QPixmap() if not type(name) in (list, tuple): name = [str(name)] if forceCache or self._forceCache: for _name in name: for _size in self.iconSizes: if (QPixmapCache.find('$qt' + str(_name) + str(_size), self.pixmap)): logging.debug('Icon %s returned from cache' % _name) return self.pixmap logging.debug('Getting icon : %s size: %s' % (','.join(name), size)) pix = self.findIcon(name, size) if pix.isNull(): for _size in self.iconSizes: pix = self.findIcon(name, _size) if not pix.isNull(): if size == _size: return pix icon.addPixmap(pix) if icon.isNull(): return self.pixmap return icon.pixmap(QSize(size, size)) return pix
def load(self, name, size = 128, forceCache = False): icon = QIcon() size = int(size) self.pixmap = QPixmap() if not type(name) in (list, tuple): name = [str(name)] if forceCache or self._forceCache: for _name in name: for _size in self.iconSizes: if (QPixmapCache.find('$qt'+str(_name)+str(_size), self.pixmap)): logging.debug('Icon %s returned from cache' % _name) return self.pixmap logging.debug('Getting icon : %s size: %s' % (','.join(name), size)) pix = self.findIcon(name, size) if pix.isNull(): for _size in self.iconSizes: pix = self.findIcon(name, _size) if not pix.isNull(): if size == _size: return pix icon.addPixmap(pix) if icon.isNull(): return self.pixmap return icon.pixmap(QSize(size, size)) return pix
def set_icon(self, item_type, tree_item, index = 0, label = None): base_path = self.controller.datahandler.app_root + "ui/icons/" base_type = item_type.split("/")[0] # item type if item_type == "folder": icon = QIcon(base_path + "folder.png") elif item_type == "folder_opened": icon = QIcon(base_path + "folder_open.png") elif item_type == "n900": icon = QIcon(base_path + "n900_small.png") elif item_type == "size": icon = QIcon(base_path + "calculator.png") elif item_type == "time": icon = QIcon(base_path + "clock.png") elif item_type == "deleted_item": icon = QIcon(base_path + "cancel.png") elif item_type == "deleted_folder": icon = QIcon(base_path + "folder_delete.png") # base type (from mimetype pre /) elif base_type == "text": icon = QIcon(base_path + "document_edit.png") elif base_type == "image": icon = QIcon(base_path + "picture.png") elif base_type == "application": icon = QIcon(base_path + "applications.png") else: icon = QIcon(base_path + "document.png") if tree_item != None: tree_item.setIcon(index, icon) elif label != None: label.setPixmap(icon.pixmap(24,24))
def setIcon(self, icon): super(RecordButton, self).setIcon(icon) on_icon = QIcon(icon) off_icon = QIcon(icon) for size in off_icon.availableSizes(QIcon.Normal, QIcon.On): pixmap = off_icon.pixmap(size, QIcon.Normal, QIcon.Off) off_icon.addPixmap(pixmap, QIcon.Normal, QIcon.On) self.animation_icons = [on_icon, off_icon]
def __init__(self, iconName): if QIcon.hasThemeIcon(iconName): icon = QIcon.fromTheme(iconName) else: icon = QIcon(iconName) size = icon.availableSizes()[0] self.image = icon.pixmap(size).toImage().convertToFormat(QImage.Format_ARGB32) self.image = self.image.rgbSwapped() # otherwise colors are weird :/
def __init__(self, iconName): if QIcon.hasThemeIcon(iconName): icon = QIcon.fromTheme(iconName) else: icon = QIcon(iconName) size = icon.availableSizes()[0] self.image = icon.pixmap(size).toImage().convertToFormat( QImage.Format_ARGB32) self.image = self.image.rgbSwapped( ) # otherwise colors are weird :/
def symbolIcon(symbol): """ Icon for a symbol. @param symbol name of symbol @return QIcon instance; transparent but valid if symbol icon not found """ icon = QIcon(":images/tickers/%s.png" % (symbol.lower(),)) if icon.pixmap(16, 16).isNull(): pixmap = QPixmap(16, 16) pixmap.fill(QColor(0, 0, 0, 0)) icon = QIcon(pixmap) return icon
def symbolIcon(symbol): """ Icon for a symbol. @param symbol name of symbol @return QIcon instance; transparent but valid if symbol icon not found """ icon = QIcon(':images/tickers/%s.png' % (symbol.lower(), )) if icon.pixmap(16, 16).isNull(): pixmap = QPixmap(16, 16) pixmap.fill(QColor(0, 0, 0, 0)) icon = QIcon(pixmap) return icon
def errorAlert(msgText, infoText): icon = QIcon(":/icon_app_error.svg") if msgText is None: msgText = "An unexpected error has occurred" box = QMessageBox() box.setText(msgText) box.setInformativeText(infoText) box.setIconPixmap(icon.pixmap(60, 60)) box.show() if not len(infoText) > 300: box.setFixedSize(420, box.height()) centerOnDesktop(box) return box.exec_()
def errorAlert(msgText, infoText): icon = QIcon(":/icon_app_error.svg") if msgText is None: msgText = "An unexpected error has occurred" box=QMessageBox() box.setText(msgText) box.setInformativeText(infoText) box.setIconPixmap(icon.pixmap(60, 60)) box.show() if not len(infoText) > 300: box.setFixedSize(420, box.height()) centerOnDesktop(box) return box.exec_()
def set_on_icon(self): if self.vm.last_power_state == "Running": icon = QIcon (":/on.png") elif self.vm.last_power_state in ["Paused", "Suspended"]: icon = QIcon (":/paused.png") elif self.vm.last_power_state in ["Transient", "Halting", "Dying"]: icon = QIcon (":/transient.png") else: icon = QIcon (":/off.png") icon_sz = QSize (row_height * 0.5, row_height *0.5) icon_pixmap = icon.pixmap(icon_sz) self.setPixmap (icon_pixmap) self.setFixedSize (icon_sz)
def set_on_icon(self): if self.vm.last_power_state == "Running": icon = QIcon(":/on.png") elif self.vm.last_power_state in ["Paused", "Suspended"]: icon = QIcon(":/paused.png") elif self.vm.last_power_state in ["Transient", "Halting", "Dying"]: icon = QIcon(":/transient.png") else: icon = QIcon(":/off.png") icon_sz = QSize(row_height * 0.5, row_height * 0.5) icon_pixmap = icon.pixmap(icon_sz) self.setPixmap(icon_pixmap) self.setFixedSize(icon_sz)
def paint(self, painter, option, index): """ Draw a button-style on root items """ model = index.model() assert model if not model.parent(index).isValid(): # this is a top-level item. buttonOption = QStyleOptionButton() buttonOption.state = option.state buttonOption.state &= ~QStyle.State_HasFocus buttonOption.rect = option.rect buttonOption.palette = option.palette buttonOption.features = QStyleOptionButton.None self.m_view.style().drawControl(QStyle.CE_PushButton, buttonOption, painter, self.m_view) branchOption = QStyleOption() i = 15 ### hardcoded in qcommonstyle.cpp r = option.rect branchOption.rect = QRect(r.left() + i/2, r.top() + (r.height() - i)/2, i, i) branchOption.palette = option.palette # branchOption.state = QStyle.State_Children if self.m_view.isExpanded(index): branchOption.state |= QStyle.State_Open self.m_view.style().drawPrimitive(QStyle.PE_IndicatorBranch, branchOption, painter, self.m_view) # draw text textrect = QRect(r.left() + i*2, r.top(), r.width() - ((5*i)/2), r.height()) text = self.elidedText(option.fontMetrics, textrect.width(), Qt.ElideMiddle, model.data(index, Qt.DisplayRole).toString()) self.m_view.style().drawItemText(painter, textrect,Qt.AlignLeft|Qt.AlignVCenter, option.palette, self.m_view.isEnabled(), text) icon_variant = index.data(Qt.DecorationRole) icon = QIcon(icon_variant) self.m_view.style().drawItemPixmap( painter, option.rect, Qt.AlignLeft, icon.pixmap(icon.actualSize(QSize(20 ,20))) ) else: QItemDelegate.paint(self, painter, option, index)
def setIcon(self, icon): """Sets the icon to display in the left area. May be: - None or QIcon() - one of 'info', 'warning', 'critical', 'question' - a QStyle.StandardPixmap - a QIcon. """ if icon in standardicons: icon = standardicons[icon] if isinstance(icon, QStyle.StandardPixmap): icon = self.style().standardIcon(icon) if icon is None: icon = QIcon() self._icon = icon self.setPixmap(icon.pixmap(self._iconSize))
def on_iconSelect_clicked(self): """ Signal handler for select icon button. @return None """ item = self.editItem if item: formats = str.join(' ', ['*.%s' % str(fmt) for fmt in QImageReader.supportedImageFormats()]) filename = QFileDialog.getOpenFileName( self, 'Select Symbol Icon', '', 'Images (%s)' % formats) if filename: icon = QIcon(filename) item.setIcon(icon) self.iconPreview.setPixmap(icon.pixmap(32,32)) settings = self.settings settings.setValue('%s/icon' % item.symbol, icon) self.emit(Signals.modified)
def startDrag(self, supportedActions): """ Overwritten function of QTreeWidget. This function creates a QDrag object representing the selected element of this TreeWidget. """ logging.debug(self.__class__.__name__ +": startDrag()") indexes = self.selectedIndexes() if len(indexes) > 0: data = self.model().mimeData(indexes) if not data: return drag = QDrag(self) drag.setMimeData(data) if self.model().data(indexes[0], Qt.DecorationRole).type() == QVariant.Icon: icon = QIcon(self.model().data(indexes[0], Qt.DecorationRole)) drag.setPixmap(icon.pixmap(QSize(50, 50))) drag.setHotSpot(QPoint(drag.pixmap().width()/2, drag.pixmap().height()/2)) # center icon in respect to cursor defaultDropAction = Qt.IgnoreAction drag.exec_(supportedActions, defaultDropAction)
def on_iconSelect_clicked(self): """ Signal handler for select icon button. @return None """ item = self.editItem if item: formats = str.join(' ', [ '*.%s' % str(fmt) for fmt in QImageReader.supportedImageFormats() ]) filename = QFileDialog.getOpenFileName(self, 'Select Symbol Icon', '', 'Images (%s)' % formats) if filename: icon = QIcon(filename) item.setIcon(icon) self.iconPreview.setPixmap(icon.pixmap(32, 32)) settings = self.settings settings.setValue('%s/icon' % item.symbol, icon) self.emit(Signals.modified)
def __init__(self, icon_path, enabled=True, size_multiplier=0.7, tooltip = None, parent=None, icon_sz = (32, 32)): super(VmIconWidget, self).__init__(parent) self.label_icon = QLabel() if icon_path[0] in ':/': icon = QIcon (icon_path) else: icon = QIcon.fromTheme(icon_path) icon_sz = QSize (row_height * size_multiplier, row_height * size_multiplier) icon_pixmap = icon.pixmap(icon_sz, QIcon.Disabled if not enabled else QIcon.Normal) self.label_icon.setPixmap (icon_pixmap) self.label_icon.setFixedSize (icon_sz) if tooltip != None: self.label_icon.setToolTip(tooltip) layout = QHBoxLayout() layout.addWidget(self.label_icon) layout.setContentsMargins(0,0,0,0) self.setLayout(layout)
def _determineIcon(self, iconName, defaultIconName=None): """ Determines the icon identified by the given name. """ icon = None if iconName in self._loadedIcons: icon = self._loadedIcons[iconName] else: registeredIcon = self._iconHandler.getIcon(iconName) if registeredIcon is None: icon = QIcon(_ICON_RESOURCE_PREFIX + iconName + SMALL_ICONFILENAME_SUFFIX) else: icon = QIcon(registeredIcon.smallIconLocalPath) if icon.isNull() and not defaultIconName is None: icon = QIcon(_ICON_RESOURCE_PREFIX + defaultIconName + SMALL_ICONFILENAME_SUFFIX) if icon.pixmap(1, 1).isNull(): icon = None else: self._loadedIcons[iconName] = icon return icon
def paint(self, painter, option, index): style = option.widget.style() style.drawControl(QStyle.CE_ItemViewItem, option, painter) artist, title = [unicode(val) for val in index.data(Qt.DisplayRole).toStringList()] font = QFont(index.data(Qt.FontRole)) icon = QIcon(index.data(Qt.DecorationRole)) painter.setFont(font) rect = option.rect rect.adjust(1, 0, -2, 0) iconSize = self.height - 2 pixmap = icon.pixmap(iconSize, iconSize) left = rect.left() + ((iconSize - pixmap.width()) / 2) top = rect.top()+1 + ((iconSize - pixmap.height()) / 2) painter.drawPixmap(left, top, pixmap) rect.setLeft(rect.left() + iconSize + 2) if self.oneLine: painter.drawText(rect, Qt.AlignBottom, ' - '.join((artist, title))) else: painter.drawText(rect, Qt.AlignTop, title) painter.drawText(rect, Qt.AlignBottom, artist)
def chooseAction(parent, msgText, infoText, doAction, discardAction=None): icon = QIcon(":/icon_app.svg") box=QMessageBox(parent) if parent is not None: box.setWindowFlags(Qt.Sheet) box.setText(msgText) box.setInformativeText(infoText) buttons = QMessageBox.Cancel | QMessageBox.Yes if discardAction is not None: buttons |= QMessageBox.Discard box.setStandardButtons(buttons) button = box.button(QMessageBox.Yes) button.setText(doAction) if discardAction is not None: button = box.button(QMessageBox.Discard) button.setText(discardAction) box.setDefaultButton(QMessageBox.Yes) box.setIconPixmap(icon.pixmap(60, 60)) box.show() centerOnDesktop(box) return box.exec_()
def chooseAction(parent, msgText, infoText, doAction, discardAction=None): icon = QIcon(":/icon_app.svg") box = QMessageBox(parent) if parent is not None: box.setWindowFlags(Qt.Sheet) box.setText(msgText) box.setInformativeText(infoText) buttons = QMessageBox.Cancel | QMessageBox.Yes if discardAction is not None: buttons |= QMessageBox.Discard box.setStandardButtons(buttons) button = box.button(QMessageBox.Yes) button.setText(doAction) if discardAction is not None: button = box.button(QMessageBox.Discard) button.setText(discardAction) box.setDefaultButton(QMessageBox.Yes) box.setIconPixmap(icon.pixmap(60, 60)) box.show() centerOnDesktop(box) return box.exec_()
def get_icon(name, default=None, resample=False): """Return image inside a QIcon object default: default image name or icon resample: if True, manually resample icon pixmaps for usual sizes (16, 24, 32, 48, 96, 128, 256). This is recommended for QMainWindow icons created from SVG images on non-Windows platforms due to a Qt bug (see http://code.google.com/p/spyderlib/issues/detail?id=1314).""" if default is None: icon = QIcon(get_image_path(name)) elif isinstance(default, QIcon): icon_path = get_image_path(name, default=None) icon = default if icon_path is None else QIcon(icon_path) else: icon = QIcon(get_image_path(name, default)) if resample: icon0 = QIcon() for size in (16, 24, 32, 48, 96, 128, 256, 512): icon0.addPixmap(icon.pixmap(size, size)) return icon0 else: return icon
def paint(self, painter, option, index): self.initStyleOption(option, index); icon = QIcon( index.data(ListItemDelegate.IconRole) ) title = index.data(ListItemDelegate.TitleRole).toString() description = index.data(ListItemDelegate.SubtitleRole).toString() #widget = option.widget opt = QStyleOptionViewItemV4( option ); self.initStyleOption(opt, index); if opt.widget != None: style = opt.widget.style() else: style = QApplication.style() widget = opt.widget # highlight selected items if opt.state & QStyle.State_Selected: painter.fillRect(option.rect, option.palette.highlight()); style.drawPrimitive(QStyle.PE_PanelItemViewItem, option, painter, widget) r = option.rect.adjusted(8, 10, 0, 0) style.drawItemPixmap(painter,r,Qt.AlignTop|Qt.AlignLeft, icon.pixmap(30,30)) r = option.rect.adjusted(43, 0, 0, -25) f = painter.font() f.setWeight(QFont.Bold) f.setPointSize(9) painter.setFont(f) painter.setPen(QColor(0,0,0)) style.drawItemText(painter,r,Qt.AlignBottom|Qt.AlignLeft, option.palette, True, title) r = option.rect.adjusted(43, 25, 0, 0) f.setWeight(QFont.Normal) f.setPointSize(8) painter.setFont(f) painter.setPen(QColor(90,90,90)) style.drawItemText(painter,r,Qt.AlignTop|Qt.AlignLeft, option.palette, True, description)
def startDrag(self, supportedActions): """ Overwritten function of QTreeWidget. This function creates a QDrag object representing the selected element of this TreeWidget. """ logging.debug(self.__class__.__name__ + ": startDrag()") indexes = self.selectedIndexes() if len(indexes) > 0: data = self.model().mimeData(indexes) if not data: return drag = QDrag(self) drag.setMimeData(data) if self.model().data(indexes[0], Qt.DecorationRole).type() == QVariant.Icon: icon = QIcon(self.model().data(indexes[0], Qt.DecorationRole)) drag.setPixmap(icon.pixmap(QSize(50, 50))) drag.setHotSpot( QPoint(drag.pixmap().width() / 2, drag.pixmap().height() / 2)) # center icon in respect to cursor defaultDropAction = Qt.IgnoreAction drag.exec_(supportedActions, defaultDropAction)
class MainWindow(QWidget): """ Main window """ def __init__(self, pluginName='undefined', pluginType='dummy', debugMode=False, pluginVersion='1.0.0', pluginIcon=None, pluginDescription='undefined', showMaximized=True): """ Constructor """ super(MainWindow, self).__init__() self.debugMode = debugMode self.bufSdtIn = '' self.clientTmpPath = '' self.pluginName = pluginName self.pluginType = pluginType self.pluginVersion = pluginVersion self.pluginIcon = pluginIcon self.__showMaximized = showMaximized self.isRegistered = False if self.pluginIcon is None: self.pluginIcon = QIcon(':/plugin.png') self.pluginDescription = pluginDescription self.mainPage = None self.settingsPage = None self.TAB_MAIN_PAGE = None self.TAB_SETTINGS_PAGE = None if not self.debugMode: # connect sdtin self.stdClient = ReadStdin(self) self.stdClient.DataIn.connect(self.on_stdinReadyRead) self.stdClient.start() self.aliveClient = ClientAlive(self) self.aliveClient.ClientDead.connect(self.onClientDead) self.aliveClient.start() self.createWidgets() def configure(self, pluginName='undefined', pluginType='dummy', pluginVersion='1.0.0', pluginIcon=None, pluginDescription='undefined', showMaximized=True): """ """ self.pluginName = pluginName self.pluginType = pluginType self.pluginVersion = pluginVersion self.pluginIcon = pluginIcon self.pluginDescription = pluginDescription self.__showMaximized = showMaximized if self.pluginIcon is None: self.pluginIcon = QIcon(':/plugin.png') self.setWindowTitle("%s - %s - %s" % (Settings.instance().readValue(key='Common/name'), self.pluginName, self.pluginVersion)) # register the plugin if not self.debugMode: self.sendMessage(cmd='register') def prepare(self): """ """ Logger.instance().debug("preparing plugin") # convert qicon to base64 pixmapIcon = self.pluginIcon.pixmap(64, 64, mode=QIcon.Normal, state=QIcon.Off) byteArray = QByteArray() buffer = QBuffer(byteArray) buffer.open(QIODevice.WriteOnly) pixmapIcon.save(buffer, "png", quality=100) iconBase64 = byteArray.toBase64().data() Logger.instance().debug("icon converted to base64") self.sendMessage(cmd='configure', data=str(iconBase64, 'utf8'), more={"description": self.pluginDescription}) def createWidgets(self): """ Create all widgets """ self.setWindowIcon(QIcon(':/plugin.png')) self.mainTab = QTabWidget() self.aboutPage = AboutPage(parent=self) self.debugPage = DebugPage(parent=self) self.mainTab.addTab(self.aboutPage, "About") self.mainTab.addTab(self.debugPage, "Debug") mainLayout = QVBoxLayout() mainLayout.addWidget(self.mainTab) self.setLayout(mainLayout) self.setWindowTitle("%s - %s - %s" % (Settings.instance().readValue(key='Common/name'), self.pluginName, self.pluginVersion)) flags = Qt.WindowFlags() if not self.debugMode: flags |= Qt.WindowStaysOnTopHint self.setWindowFlags(flags) def debug(self): """ Return debug page """ return self.debugPage def about(self): """ Return about page """ return self.aboutPage def main(self): """ Return main page """ return self.mainPage def settings(self): """ Return about page """ return self.settingsPage def closeEvent(self, event): """ On window close event """ if not self.debugMode: self.hide() event.ignore() def addMainPage(self, pageName, widget): """ Add the main page to the tabwidget """ self.mainPage = widget if self.settingsPage is not None: self.settingsPage.ReloadSettings.connect( self.mainPage.onReloadSettings) self.mainTab.addTab(widget, pageName) self.TAB_MAIN_PAGE = self.mainTab.indexOf(widget) def addSettingsPage(self, widget): """ Add the settings page to the tabwidget """ self.settingsPage = widget self.mainTab.addTab(widget, "Settings") self.TAB_SETTINGS_PAGE = self.mainTab.indexOf(widget) def updateAboutPage(self, text): """ Update the about text """ self.aboutPage.updateAbout(text=text) def onClientDead(self): """" On client terminattion, no more keepalive received from the client """ self.stdClient.terminate() self.stdClient.wait() self.aliveClient.terminate() self.aliveClient.wait() QApplication.quit() def on_stdinReadyRead(self, data): """ On data in STD in """ try: self.bufSdtIn += data pdus = self.bufSdtIn.split("\n\n") for pdu in pdus[:-1]: try: datagramDecoded = base64.b64decode(pdu) if sys.version_info > (3, ): # python 3 support messageJson = json.loads(str(datagramDecoded, "utf8")) else: messageJson = json.loads(datagramDecoded) except Exception as e: self.debugPage.addLogError(txt="decode: %s" % e) else: self.onPluginMessage(msg=messageJson) self.bufSdtIn = pdus[-1] except Exception as e: self.debugPage.addLogError(txt=e) def onPluginMessage(self, msg): """ On message received from the client """ try: if not self.isRegistered and msg['cmd'] == 'registered': Logger.instance().debug("plugin registered") self.clientTmpPath = msg['tmp-path'] self.debugPage.addLogSuccess( txt="plugin registered [Type=%s]" % self.pluginType) self.isRegistered = True self.prepare() elif msg['cmd'] == 'keepalive': self.aliveClient.lastTimestamp = time.time() Logger.instance().debug("keepalive received") elif msg['cmd'] == 'run': data = None #read data if msg['in-data']: # read the file f = open("%s/%s" % (self.clientTmpPath, msg['data-id']), 'r') all = f.read() f.close() dataJson = json.loads(all) # delete them os.remove("%s/%s" % (self.clientTmpPath, msg['data-id'])) self.__onPluginRun(data=dataJson) elif msg['cmd'] == 'open-main': if self.mainPage is None: return if self.TAB_MAIN_PAGE is not None: self.mainTab.setCurrentIndex(self.TAB_MAIN_PAGE) self.__showWindows() if msg['in-data']: # read the file f = open("%s/%s" % (self.clientTmpPath, msg['data-id']), 'r') all = f.read() f.close() dataJson = json.loads(all) self.mainPage.insertData(data=dataJson) # delete them os.remove("%s/%s" % (self.clientTmpPath, msg['data-id'])) else: pass except Exception as e: self.debugPage.addLogError(txt="error: %s" % e) self.mainTab.setCurrentIndex(TAB_DEBUG_PAGE) self.__showWindows() def __showWindows(self): """" """ if self.__showMaximized: self.showMaximized() else: self.show() def __onPluginRun(self, data): """ Function to reimplement """ try: self.onPluginRun(data=data) self.sendMessage(cmd="success") except Exception as e: self.sendMessage(cmd="error", more={"msg": "%s" % e}) def onPluginRun(self, data): """ """ pass def sendMessage(self, cmd, data='', more={}): """ Send a message to the client """ inData = False msg = {'cmd': cmd} # save data to temp area idFile = '' if len(data): try: idFile = "%s" % uuid.uuid4() pluginDataFile = '%s/%s' % (self.clientTmpPath, idFile) with open(pluginDataFile, mode='w') as myfile: myfile.write(json.dumps(data)) inData = True except Exception as e: print("unable to write data file from plugin: %s" % e) Logger.instance().error( "unable to write data file from plugin: %s" % e) self.debug().addLogError("internal error on send message") msg.update({'in-data': inData}) # add data parameters if inData: msg.update({'data-id': idFile}) # add more params msg.update(more) # adding reference msg.update({ 'id': self.pluginName, 'name': self.pluginName, 'type': self.pluginType }) Logger.instance().debug("%s" % msg) # encode message and send to stdout datagram = json.dumps(msg) datagramEncoded = base64.b64encode(bytes(datagram, "utf8")) print(str(datagramEncoded, "utf8")) sys.stdout.flush()
class GraphicsIconItem(QGraphicsItem): """ A graphics item displaying an :class:`QIcon`. """ def __init__(self, parent=None, icon=None, iconSize=None, **kwargs): QGraphicsItem.__init__(self, parent, **kwargs) self.setFlag(QGraphicsItem.ItemUsesExtendedStyleOption, True) if icon is None: icon = QIcon() if iconSize is None: style = QApplication.instance().style() size = style.pixelMetric(style.PM_LargeIconSize) iconSize = QSize(size, size) self.__transformationMode = Qt.SmoothTransformation self.__iconSize = QSize(iconSize) self.__icon = QIcon(icon) def setIcon(self, icon): """ Set the icon (:class:`QIcon`). """ if self.__icon != icon: self.__icon = QIcon(icon) self.update() def icon(self): """ Return the icon (:class:`QIcon`). """ return QIcon(self.__icon) def setIconSize(self, size): """ Set the icon (and this item's) size (:class:`QSize`). """ if self.__iconSize != size: self.prepareGeometryChange() self.__iconSize = QSize(size) self.update() def iconSize(self): """ Return the icon size (:class:`QSize`). """ return QSize(self.__iconSize) def setTransformationMode(self, mode): """ Set pixmap transformation mode. (`Qt.SmoothTransformation` or `Qt.FastTransformation`). """ if self.__transformationMode != mode: self.__transformationMode = mode self.update() def transformationMode(self): """ Return the pixmap transformation mode. """ return self.__transformationMode def boundingRect(self): return QRectF(0, 0, self.__iconSize.width(), self.__iconSize.height()) def paint(self, painter, option, widget=None): if not self.__icon.isNull(): if option.state & QStyle.State_Selected: mode = QIcon.Selected elif option.state & QStyle.State_Enabled: mode = QIcon.Normal elif option.state & QStyle.State_Active: mode = QIcon.Active else: mode = QIcon.Disabled transform = self.sceneTransform() if widget is not None: # 'widget' is the QGraphicsView.viewport() view = widget.parent() if isinstance(view, QGraphicsView): # Combine the scene transform with the view transform. view_transform = view.transform() transform = view_transform * view_transform lod = option.levelOfDetailFromTransform(transform) w, h = self.__iconSize.width(), self.__iconSize.height() target = QRectF(0, 0, w, h) source = QRectF(0, 0, w * lod, w * lod).toRect() # The actual size of the requested pixmap can be smaller. size = self.__icon.actualSize(source.size(), mode=mode) source.setSize(size) pixmap = self.__icon.pixmap(source.size(), mode=mode) painter.setRenderHint( QPainter.SmoothPixmapTransform, self.__transformationMode == Qt.SmoothTransformation ) painter.drawPixmap(target, pixmap, QRectF(source))
class CanvasView(QGraphicsView): """Canvas View handles the zooming. """ def __init__(self, *args): QGraphicsView.__init__(self, *args) self.setAlignment(Qt.AlignTop | Qt.AlignLeft) self.__backgroundIcon = QIcon() self.__autoScroll = False self.__autoScrollMargin = 16 self.__autoScrollTimer = QTimer(self) self.__autoScrollTimer.timeout.connect(self.__autoScrollAdvance) def setScene(self, scene): QGraphicsView.setScene(self, scene) self._ensureSceneRect(scene) def _ensureSceneRect(self, scene): r = scene.addRect(QRectF(0, 0, 400, 400)) scene.sceneRect() scene.removeItem(r) def setAutoScrollMargin(self, margin): self.__autoScrollMargin = margin def autoScrollMargin(self): return self.__autoScrollMargin def setAutoScroll(self, enable): self.__autoScroll = enable def autoScroll(self): return self.__autoScroll def mousePressEvent(self, event): QGraphicsView.mousePressEvent(self, event) def mouseMoveEvent(self, event): if event.buttons() & Qt.LeftButton: if not self.__autoScrollTimer.isActive() and \ self.__shouldAutoScroll(event.pos()): self.__startAutoScroll() QGraphicsView.mouseMoveEvent(self, event) def mouseReleaseEvent(self, event): if event.button() & Qt.LeftButton: self.__stopAutoScroll() return QGraphicsView.mouseReleaseEvent(self, event) def __shouldAutoScroll(self, pos): if self.__autoScroll: margin = self.__autoScrollMargin viewrect = self.contentsRect() rect = viewrect.adjusted(margin, margin, -margin, -margin) # only do auto scroll when on the viewport's margins return not rect.contains(pos) and viewrect.contains(pos) else: return False def __startAutoScroll(self): self.__autoScrollTimer.start(10) log.debug("Auto scroll timer started") def __stopAutoScroll(self): if self.__autoScrollTimer.isActive(): self.__autoScrollTimer.stop() log.debug("Auto scroll timer stopped") def __autoScrollAdvance(self): """Advance the auto scroll """ pos = QCursor.pos() pos = self.mapFromGlobal(pos) margin = self.__autoScrollMargin vvalue = self.verticalScrollBar().value() hvalue = self.horizontalScrollBar().value() vrect = QRect(0, 0, self.width(), self.height()) # What should be the speed advance = 10 # We only do auto scroll if the mouse is inside the view. if vrect.contains(pos): if pos.x() < vrect.left() + margin: self.horizontalScrollBar().setValue(hvalue - advance) if pos.y() < vrect.top() + margin: self.verticalScrollBar().setValue(vvalue - advance) if pos.x() > vrect.right() - margin: self.horizontalScrollBar().setValue(hvalue + advance) if pos.y() > vrect.bottom() - margin: self.verticalScrollBar().setValue(vvalue + advance) if self.verticalScrollBar().value() == vvalue and \ self.horizontalScrollBar().value() == hvalue: self.__stopAutoScroll() else: self.__stopAutoScroll() log.debug("Auto scroll advance") def setBackgroundIcon(self, icon): if not isinstance(icon, QIcon): raise TypeError("A QIcon expected.") if self.__backgroundIcon != icon: self.__backgroundIcon = icon self.viewport().update() def backgroundIcon(self): return QIcon(self.__backgroundIcon) def drawBackground(self, painter, rect): QGraphicsView.drawBackground(self, painter, rect) if not self.__backgroundIcon.isNull(): painter.setClipRect(rect) vrect = QRect(QPoint(0, 0), self.viewport().size()) vrect = self.mapToScene(vrect).boundingRect() pm = self.__backgroundIcon.pixmap(vrect.size().toSize().boundedTo( QSize(200, 200))) pmrect = QRect(QPoint(0, 0), pm.size()) pmrect.moveCenter(vrect.center().toPoint()) if rect.toRect().intersects(pmrect): painter.drawPixmap(pmrect, pm)
class GraphicsIconItem(QGraphicsItem): """ A graphics item displaying an :class:`QIcon`. """ def __init__(self, parent=None, icon=None, iconSize=None, **kwargs): QGraphicsItem.__init__(self, parent, **kwargs) self.setFlag(QGraphicsItem.ItemUsesExtendedStyleOption, True) if icon is None: icon = QIcon() if iconSize is None: style = QApplication.instance().style() size = style.pixelMetric(style.PM_LargeIconSize) iconSize = QSize(size, size) self.__transformationMode = Qt.SmoothTransformation self.__iconSize = QSize(iconSize) self.__icon = QIcon(icon) def setIcon(self, icon): """ Set the icon (:class:`QIcon`). """ if self.__icon != icon: self.__icon = QIcon(icon) self.update() def icon(self): """ Return the icon (:class:`QIcon`). """ return QIcon(self.__icon) def setIconSize(self, size): """ Set the icon (and this item's) size (:class:`QSize`). """ if self.__iconSize != size: self.prepareGeometryChange() self.__iconSize = QSize(size) self.update() def iconSize(self): """ Return the icon size (:class:`QSize`). """ return QSize(self.__iconSize) def setTransformationMode(self, mode): """ Set pixmap transformation mode. (`Qt.SmoothTransformation` or `Qt.FastTransformation`). """ if self.__transformationMode != mode: self.__transformationMode = mode self.update() def transformationMode(self): """ Return the pixmap transformation mode. """ return self.__transformationMode def boundingRect(self): return QRectF(0, 0, self.__iconSize.width(), self.__iconSize.height()) def paint(self, painter, option, widget=None): if not self.__icon.isNull(): if option.state & QStyle.State_Selected: mode = QIcon.Selected elif option.state & QStyle.State_Enabled: mode = QIcon.Normal elif option.state & QStyle.State_Active: mode = QIcon.Active else: mode = QIcon.Disabled transform = self.sceneTransform() if widget is not None: # 'widget' is the QGraphicsView.viewport() view = widget.parent() if isinstance(view, QGraphicsView): # Combine the scene transform with the view transform. view_transform = view.transform() transform = view_transform * view_transform lod = option.levelOfDetailFromTransform(transform) w, h = self.__iconSize.width(), self.__iconSize.height() target = QRectF(0, 0, w, h) source = QRectF(0, 0, w * lod, w * lod).toRect() # The actual size of the requested pixmap can be smaller. size = self.__icon.actualSize(source.size(), mode=mode) source.setSize(size) pixmap = self.__icon.pixmap(source.size(), mode=mode) painter.setRenderHint( QPainter.SmoothPixmapTransform, self.__transformationMode == Qt.SmoothTransformation) painter.drawPixmap(target, pixmap, QRectF(source))
class Dialog(QDialog): """A Dialog with basic layout features: a main widget, an icon or pixmap, a separator, buttons (provided by a QDialogButtonBox) """ def __init__(self, parent=None, message="", title="", icon=None, iconSize=QSize(64, 64), pixmap=None, separator=True, buttonOrientation=Qt.Horizontal, buttons=('ok', 'cancel'), help=None, **kwargs): """Initializes the dialog. parent = a parent widget or None. The following keyword arguments are recognized: - message: the text to display in the message label - title: the window title - icon or pixmap: shown in the left area - iconSize: size of the icon in the left (QSize, default: 64x64) - separator: draw a separator line or not (default: True) - buttonOrientation: Qt.Horizontal (default) or Qt.Vertical - buttons: which buttons to use (default: Ok, Cancel) - help: function to call when a help button is clicked. Other keyword arguments are passed to QDialog. """ super(Dialog, self).__init__(parent, **kwargs) self._icon = QIcon() self._separatorWidget = Separator() self._mainWidget = QWidget() self._pixmap = QPixmap() self._pixmapLabel = QLabel(self) self._messageLabel = QLabel(self) self._buttonBox = b = QDialogButtonBox(self) b.accepted.connect(self.accept) b.rejected.connect(self.reject) layout = QGridLayout() layout.setSpacing(10) self.setLayout(layout) # handle keyword args self._buttonOrientation = buttonOrientation self._iconSize = iconSize self._separator = separator if title: self.setWindowTitle(title) self.setMessage(message) if icon: self.setIcon(icon) elif pixmap: self.setPixmap(pixmap) b.helpRequested.connect(help or self.helpRequest) self.setStandardButtons(buttons) self.reLayout() def helpRequest(self): """Called when a help button is clicked.""" pass def setButtonOrientation(self, orientation): """Sets the button orientation. Qt.Horizontal (default) puts the buttons at the bottom of the dialog in a horizonzal row, Qt.Vertical puts the buttons at the right in a vertical column. """ if orientation != self._buttonOrientation: self._buttonOrientation = orientation self._buttonBox.setOrientation(orientation) self.reLayout() def buttonOrientation(self): """Returns the button orientation.""" return self._buttonOrientation def setIcon(self, icon): """Sets the icon to display in the left area. May be: - None or QIcon() - one of 'info', 'warning', 'critical', 'question' - a QStyle.StandardPixmap - a QIcon. """ if icon in standardicons: icon = standardicons[icon] if isinstance(icon, QStyle.StandardPixmap): icon = self.style().standardIcon(icon) if icon is None: icon = QIcon() self._icon = icon self.setPixmap(icon.pixmap(self._iconSize)) def icon(self): """Returns the currently set icon as a QIcon.""" return self._icon def setIconSize(self, size): """Sets the icon size (QSize or int).""" if isinstance(size, int): size = QSize(size, size) changed = size != self._iconSize self._iconSize = size if changed and not self._icon.isNull(): self.setPixmap(self._icon.pixmap(size)) def iconSize(self): """Returns the icon size (QSize).""" return self._iconSize def setPixmap(self, pixmap): """Sets the pixmap to display in the left area.""" changed = self._pixmap.isNull() != pixmap.isNull() self._pixmap = pixmap self._pixmapLabel.setPixmap(pixmap) if not pixmap.isNull(): self._pixmapLabel.setFixedSize(pixmap.size()) if changed: self.reLayout() def pixmap(self): """Returns the currently set pixmap.""" return self._pixmap def setMessage(self, text): """Sets the main text in the dialog.""" self._messageLabel.setText(text) def message(self): """Returns the main text.""" return self._messageLabel.text() def messageLabel(self): """Returns the QLabel displaying the message text.""" return self._messageLabel def buttonBox(self): """Returns our QDialogButtonBox instance.""" return self._buttonBox def setStandardButtons(self, buttons): """Convenience method to set standard buttons in the button box. Accepts a sequence of string names from the standardbuttons constant, or a QDialogButtonBox.StandardButtons value. """ if isinstance(buttons, (set, tuple, list)): buttons = functools.reduce(operator.or_, map(standardbuttons.get, buttons), QDialogButtonBox.StandardButtons()) self._buttonBox.setStandardButtons(buttons) def button(self, button): """Returns the given button. May be a QDialogButtonBox.StandardButton or a key from standardbuttons. """ if button in standardbuttons: button = standardbuttons[button] return self._buttonBox.button(button) def setSeparator(self, enabled): """Sets whether to show a line between contents and buttons.""" changed = self._separator != enabled self._separator = enabled if changed: self.reLayout() def hasSeparator(self): """Returns whether a separator line is shown.""" return self._separator def setMainWidget(self, widget): """Sets the specified widget as our main widget.""" old = self._mainWidget if old: old.setParent(None) self._mainWidget = widget self.reLayout() def mainWidget(self): """Returns the current main widget (an empty QWidget by default).""" return self._mainWidget def reLayout(self): """(Internal) Lays out all items in this dialog.""" layout = self.layout() while layout.takeAt(0): pass if not self._pixmap.isNull(): col = 1 layout.addWidget(self._pixmapLabel, 0, 0, 2, 1) else: layout.setColumnStretch(1, 0) col = 0 layout.setColumnStretch(col, 1) self._pixmapLabel.setVisible(not self._pixmap.isNull()) layout.addWidget(self._messageLabel, 0, col) layout.addWidget(self._mainWidget, 1, col) if self._buttonOrientation == Qt.Horizontal: if self._separator: layout.addWidget(self._separatorWidget, 2, 0, 1, col + 1) layout.addWidget(self._buttonBox, 3, 0, 1, col + 1) else: if self._separator: layout.addWidget(self._separatorWidget, 0, col + 1, 2, 1) layout.addWidget(self._buttonBox, 0, col + 2, 2, 1) self._separatorWidget.setVisible(self._separator)
class MessageWidget(QWidget): """ A widget displaying a simple message to the user. This is an alternative to a full QMessageBox intended for inline modeless messages. [[icon] {Message text} (Ok) (Cancel)] """ #: Emitted when a button with the AcceptRole is clicked accepted = Signal() #: Emitted when a button with the RejectRole is clicked rejected = Signal() #: Emitted when a button with the HelpRole is clicked helpRequested = Signal() #: Emitted when a button is clicked clicked = Signal(QAbstractButton) class StandardButton(enum.IntEnum): NoButton, Ok, Close, Help = 0x0, 0x1, 0x2, 0x4 NoButton, Ok, Close, Help = list(StandardButton) class ButtonRole(enum.IntEnum): InvalidRole, AcceptRole, RejectRole, HelpRole = 0, 1, 2, 3 InvalidRole, AcceptRole, RejectRole, HelpRole = list(ButtonRole) _Button = namedtuple("_Button", ["button", "role", "stdbutton"]) def __init__(self, parent=None, icon=QIcon(), text="", wordWrap=False, textFormat=Qt.AutoText, standardButtons=NoButton, **kwargs): super().__init__(parent, **kwargs) self.__text = text self.__icon = QIcon() self.__wordWrap = wordWrap self.__standardButtons = MessageWidget.NoButton self.__buttons = [] layout = QHBoxLayout() layout.setContentsMargins(8, 0, 8, 0) self.__iconlabel = QLabel(objectName="icon-label") self.__iconlabel.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.__textlabel = QLabel(objectName="text-label", text=text, wordWrap=wordWrap, textFormat=textFormat) if sys.platform == "darwin": self.__textlabel.setAttribute(Qt.WA_MacSmallSize) layout.addWidget(self.__iconlabel) layout.addWidget(self.__textlabel) self.setLayout(layout) self.setIcon(icon) self.setStandardButtons(standardButtons) def setText(self, text): """ Set the current message text. :type message: str """ if self.__text != text: self.__text = text self.__textlabel.setText(text) def text(self): """ Return the current message text. :rtype: str """ return self.__text def setIcon(self, icon): """ Set the message icon. :type icon: QIcon | QPixmap | QString | QStyle.StandardPixmap """ if isinstance(icon, QStyle.StandardPixmap): icon = self.style().standardIcon(icon) else: icon = QIcon(icon) if self.__icon != icon: self.__icon = QIcon(icon) if not self.__icon.isNull(): size = self.style().pixelMetric( QStyle.PM_SmallIconSize, None, self) pm = self.__icon.pixmap(QSize(size, size)) else: pm = QPixmap() self.__iconlabel.setPixmap(pm) self.__iconlabel.setVisible(not pm.isNull()) def icon(self): """ Return the current icon. :rtype: QIcon """ return QIcon(self.__icon) def setWordWrap(self, wordWrap): """ Set the message text wrap property :type wordWrap: bool """ if self.__wordWrap != wordWrap: self.__wordWrap = wordWrap self.__textlabel.setWordWrap(wordWrap) def wordWrap(self): """ Return the message text wrap property. :rtype: bool """ return self.__wordWrap def setTextFormat(self, textFormat): """ Set message text format :type textFormat: Qt.TextFormat """ self.__textlabel.setTextFormat(textFormat) def textFormat(self): """ Return the message text format. :rtype: Qt.TextFormat """ return self.__textlabel.textFormat() def changeEvent(self, event): # reimplemented if event.type() == 177: # QEvent.MacSizeChange: ... super().changeEvent(event) def setStandardButtons(self, buttons): for button in MessageWidget.StandardButton: existing = self.button(button) if button & buttons and existing is None: self.addButton(button) elif existing is not None: self.removeButton(existing) def standardButtons(self): return functools.reduce( operator.ior, (slot.stdbutton for slot in self.__buttons if slot.stdbutton is not None), MessageWidget.NoButton) def addButton(self, button, *rolearg): """ addButton(QAbstractButton, ButtonRole) addButton(str, ButtonRole) addButton(StandardButton) Add and return a button """ stdbutton = None if isinstance(button, QAbstractButton): if len(rolearg) != 1: raise TypeError("Wrong number of arguments for " "addButton(QAbstractButton, role)") role = rolearg[0] elif isinstance(button, MessageWidget.StandardButton): if len(rolearg) != 0: raise TypeError("Wrong number of arguments for " "addButton(StandardButton)") stdbutton = button if button == MessageWidget.Ok: role = MessageWidget.AcceptRole button = QPushButton("Ok", default=False, autoDefault=False) elif button == MessageWidget.Close: role = MessageWidget.RejectRole # button = QPushButton( # default=False, autoDefault=False, flat=True, # icon=QIcon(self.style().standardIcon( # QStyle.SP_TitleBarCloseButton))) button = SimpleButton( icon=QIcon(self.style().standardIcon( QStyle.SP_TitleBarCloseButton))) elif button == MessageWidget.Help: role = MessageWidget.HelpRole button = QPushButton("Help", default=False, autoDefault=False) elif isinstance(button, str): if len(rolearg) != 1: raise TypeError("Wrong number of arguments for " "addButton(str, ButtonRole)") role = rolearg[0] button = QPushButton(button, default=False, autoDefault=False) if sys.platform == "darwin": button.setAttribute(Qt.WA_MacSmallSize) self.__buttons.append(MessageWidget._Button(button, role, stdbutton)) button.clicked.connect(self.__button_clicked) self.__relayout() return button def removeButton(self, button): """ Remove a `button`. :type button: QAbstractButton """ slot = [s for s in self.__buttons if s.button is button] if slot: slot = slot[0] self.__buttons.remove(slot) self.layout().removeWidget(slot.button) slot.button.setParent(None) def buttonRole(self, button): """ Return the ButtonRole for button :type button: QAbsstractButton """ for slot in self.__buttons: if slot.button is button: return slot.role else: return MessageWidget.InvalidRole def button(self, standardButton): """ Return the button for the StandardButton. :type standardButton: StandardButton """ for slot in self.__buttons: if slot.stdbutton == standardButton: return slot.button else: return None def __button_clicked(self): button = self.sender() role = self.buttonRole(button) self.clicked.emit(button) if role == MessageWidget.AcceptRole: self.accepted.emit() self.close() elif role == MessageWidget.RejectRole: self.rejected.emit() self.close() elif role == MessageWidget.HelpRole: self.helpRequested.emit() def __relayout(self): for slot in self.__buttons: self.layout().removeWidget(slot.button) order = { MessageOverlayWidget.HelpRole: 0, MessageOverlayWidget.AcceptRole: 2, MessageOverlayWidget.RejectRole: 3, } orderd = sorted(self.__buttons, key=lambda slot: order.get(slot.role, -1)) prev = self.__textlabel for slot in orderd: self.layout().addWidget(slot.button) QWidget.setTabOrder(prev, slot.button)
class CanvasView(QGraphicsView): """Canvas View handles the zooming. """ def __init__(self, *args): QGraphicsView.__init__(self, *args) self.setAlignment(Qt.AlignTop | Qt.AlignLeft) self.__backgroundIcon = QIcon() self.__autoScroll = False self.__autoScrollMargin = 16 self.__autoScrollTimer = QTimer(self) self.__autoScrollTimer.timeout.connect(self.__autoScrollAdvance) def setScene(self, scene): QGraphicsView.setScene(self, scene) self._ensureSceneRect(scene) def _ensureSceneRect(self, scene): r = scene.addRect(QRectF(0, 0, 400, 400)) scene.sceneRect() scene.removeItem(r) def setAutoScrollMargin(self, margin): self.__autoScrollMargin = margin def autoScrollMargin(self): return self.__autoScrollMargin def setAutoScroll(self, enable): self.__autoScroll = enable def autoScroll(self): return self.__autoScroll def mousePressEvent(self, event): QGraphicsView.mousePressEvent(self, event) def mouseMoveEvent(self, event): if event.buttons() & Qt.LeftButton: if not self.__autoScrollTimer.isActive() and \ self.__shouldAutoScroll(event.pos()): self.__startAutoScroll() QGraphicsView.mouseMoveEvent(self, event) def mouseReleaseEvent(self, event): if event.button() & Qt.LeftButton: self.__stopAutoScroll() return QGraphicsView.mouseReleaseEvent(self, event) def __shouldAutoScroll(self, pos): if self.__autoScroll: margin = self.__autoScrollMargin viewrect = self.contentsRect() rect = viewrect.adjusted(margin, margin, -margin, -margin) # only do auto scroll when on the viewport's margins return not rect.contains(pos) and viewrect.contains(pos) else: return False def __startAutoScroll(self): self.__autoScrollTimer.start(10) log.debug("Auto scroll timer started") def __stopAutoScroll(self): if self.__autoScrollTimer.isActive(): self.__autoScrollTimer.stop() log.debug("Auto scroll timer stopped") def __autoScrollAdvance(self): """Advance the auto scroll """ pos = QCursor.pos() pos = self.mapFromGlobal(pos) margin = self.__autoScrollMargin vvalue = self.verticalScrollBar().value() hvalue = self.horizontalScrollBar().value() vrect = QRect(0, 0, self.width(), self.height()) # What should be the speed advance = 10 # We only do auto scroll if the mouse is inside the view. if vrect.contains(pos): if pos.x() < vrect.left() + margin: self.horizontalScrollBar().setValue(hvalue - advance) if pos.y() < vrect.top() + margin: self.verticalScrollBar().setValue(vvalue - advance) if pos.x() > vrect.right() - margin: self.horizontalScrollBar().setValue(hvalue + advance) if pos.y() > vrect.bottom() - margin: self.verticalScrollBar().setValue(vvalue + advance) if self.verticalScrollBar().value() == vvalue and \ self.horizontalScrollBar().value() == hvalue: self.__stopAutoScroll() else: self.__stopAutoScroll() log.debug("Auto scroll advance") def setBackgroundIcon(self, icon): if not isinstance(icon, QIcon): raise TypeError("A QIcon expected.") if self.__backgroundIcon != icon: self.__backgroundIcon = icon self.viewport().update() def backgroundIcon(self): return QIcon(self.__backgroundIcon) def drawBackground(self, painter, rect): QGraphicsView.drawBackground(self, painter, rect) if not self.__backgroundIcon.isNull(): painter.setClipRect(rect) vrect = QRect(QPoint(0, 0), self.viewport().size()) vrect = self.mapToScene(vrect).boundingRect() pm = self.__backgroundIcon.pixmap( vrect.size().toSize().boundedTo(QSize(200, 200)) ) pmrect = QRect(QPoint(0, 0), pm.size()) pmrect.moveCenter(vrect.center().toPoint()) if rect.toRect().intersects(pmrect): painter.drawPixmap(pmrect, pm)
class Dialog(QDialog): """A Dialog with basic layout features: a main widget, an icon or pixmap, a separator, buttons (provided by a QDialogButtonBox) """ def __init__(self, parent = None, message = "", title = "", icon = None, iconSize = QSize(64, 64), pixmap = None, separator = True, buttonOrientation = Qt.Horizontal, buttons = ('ok', 'cancel'), help = None, **kwargs): """Initializes the dialog. parent = a parent widget or None. The following keyword arguments are recognized: - message: the text to display in the message label - title: the window title - icon or pixmap: shown in the left area - iconSize: size of the icon in the left (QSize, default: 64x64) - separator: draw a separator line or not (default: True) - buttonOrientation: Qt.Horizontal (default) or Qt.Vertical - buttons: which buttons to use (default: Ok, Cancel) - help: function to call when a help button is clicked. Other keyword arguments are passed to QDialog. """ super(Dialog, self).__init__(parent, **kwargs) self._icon = QIcon() self._separatorWidget = Separator() self._mainWidget = QWidget() self._pixmap = QPixmap() self._pixmapLabel = QLabel(self) self._messageLabel = QLabel(self) self._buttonBox = b = QDialogButtonBox(self) b.accepted.connect(self.accept) b.rejected.connect(self.reject) layout = QGridLayout() layout.setSpacing(10) self.setLayout(layout) # handle keyword args self._buttonOrientation = buttonOrientation self._iconSize = iconSize self._separator = separator if title: self.setWindowTitle(title) self.setMessage(message) if icon: self.setIcon(icon) elif pixmap: self.setPixmap(pixmap) b.helpRequested.connect(help or self.helpRequest) self.setStandardButtons(buttons) self.reLayout() def helpRequest(self): """Called when a help button is clicked.""" pass def setButtonOrientation(self, orientation): """Sets the button orientation. Qt.Horizontal (default) puts the buttons at the bottom of the dialog in a horizontal row, Qt.Vertical puts the buttons at the right in a vertical column. """ if orientation != self._buttonOrientation: self._buttonOrientation = orientation self._buttonBox.setOrientation(orientation) self.reLayout() def buttonOrientation(self): """Returns the button orientation.""" return self._buttonOrientation def setIcon(self, icon): """Sets the icon to display in the left area. May be: - None or QIcon() - one of 'info', 'warning', 'critical', 'question' - a QStyle.StandardPixmap - a QIcon. """ if icon in standardicons: icon = standardicons[icon] if isinstance(icon, QStyle.StandardPixmap): icon = self.style().standardIcon(icon) if icon is None: icon = QIcon() self._icon = icon self.setPixmap(icon.pixmap(self._iconSize)) def icon(self): """Returns the currently set icon as a QIcon.""" return self._icon def setIconSize(self, size): """Sets the icon size (QSize or int).""" if isinstance(size, int): size = QSize(size, size) changed = size != self._iconSize self._iconSize = size if changed and not self._icon.isNull(): self.setPixmap(self._icon.pixmap(size)) def iconSize(self): """Returns the icon size (QSize).""" return self._iconSize def setPixmap(self, pixmap): """Sets the pixmap to display in the left area.""" changed = self._pixmap.isNull() != pixmap.isNull() self._pixmap = pixmap self._pixmapLabel.setPixmap(pixmap) if not pixmap.isNull(): self._pixmapLabel.setFixedSize(pixmap.size()) if changed: self.reLayout() def pixmap(self): """Returns the currently set pixmap.""" return self._pixmap def setMessage(self, text): """Sets the main text in the dialog.""" self._messageLabel.setText(text) def message(self): """Returns the main text.""" return self._messageLabel.text() def messageLabel(self): """Returns the QLabel displaying the message text.""" return self._messageLabel def buttonBox(self): """Returns our QDialogButtonBox instance.""" return self._buttonBox def setStandardButtons(self, buttons): """Convenience method to set standard buttons in the button box. Accepts a sequence of string names from the standardbuttons constant, or a QDialogButtonBox.StandardButtons value. """ if isinstance(buttons, (set, tuple, list)): buttons = functools.reduce(operator.or_, map(standardbuttons.get, buttons), QDialogButtonBox.StandardButtons()) self._buttonBox.setStandardButtons(buttons) def button(self, button): """Returns the given button. May be a QDialogButtonBox.StandardButton or a key from standardbuttons. """ if button in standardbuttons: button = standardbuttons[button] return self._buttonBox.button(button) def setSeparator(self, enabled): """Sets whether to show a line between contents and buttons.""" changed = self._separator != enabled self._separator = enabled if changed: self.reLayout() def hasSeparator(self): """Returns whether a separator line is shown.""" return self._separator def setMainWidget(self, widget): """Sets the specified widget as our main widget.""" old = self._mainWidget if old: old.setParent(None) self._mainWidget = widget self.reLayout() def mainWidget(self): """Returns the current main widget (an empty QWidget by default).""" return self._mainWidget def reLayout(self): """(Internal) Lays out all items in this dialog.""" layout = self.layout() while layout.takeAt(0): pass if not self._pixmap.isNull(): col = 1 layout.addWidget(self._pixmapLabel, 0, 0, 2, 1) else: layout.setColumnStretch(1, 0) col = 0 layout.setColumnStretch(col, 1) self._pixmapLabel.setVisible(not self._pixmap.isNull()) layout.addWidget(self._messageLabel, 0, col) layout.addWidget(self._mainWidget, 1, col) if self._buttonOrientation == Qt.Horizontal: if self._separator: layout.addWidget(self._separatorWidget, 2, 0, 1, col+1) layout.addWidget(self._buttonBox, 3, 0, 1, col+1) else: if self._separator: layout.addWidget(self._separatorWidget, 0, col+1, 2, 1) layout.addWidget(self._buttonBox, 0, col+2, 2, 1) self._separatorWidget.setVisible(self._separator)