def __init__(self, parent): super(XWalkthroughWidget, self).__init__(parent) # setup the properties self.setAutoFillBackground(True) self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) self.setFocusPolicy(QtCore.Qt.StrongFocus) self.setMouseTracking(True) # install the event filter parent.installEventFilter(self) # define child widgets self._direction = QtGui.QBoxLayout.TopToBottom self._slideshow = XStackedWidget(self) self._previousButton = XWalkthroughButton('Previous', self) self._nextButton = XWalkthroughButton('Finish', self) self._previousButton.hide() self.resize(parent.size()) # setup look for the widget clr = QtGui.QColor('black') clr.setAlpha(120) palette = self.palette() palette.setColor(palette.Window, clr) palette.setColor(palette.WindowText, QtGui.QColor('white')) self.setPalette(palette) # create connections self._slideshow.currentChanged.connect(self.updateUi) self._previousButton.clicked.connect(self.goBack) self._nextButton.clicked.connect(self.goForward)
def paintEvent(self, event): super(XMdiSubWindow, self).paintEvent(event) palette = self.palette() # draw the title with XPainter(self) as painter: painter.setRenderHint(QtGui.QPainter.Antialiasing) painter.setPen(self.titleBarBorder()) painter.setBrush(self.titleBarBackground()) painter.drawRect(0, 0, self.width(), 29) grad = QtGui.QLinearGradient() grad.setColorAt(0, QtGui.QColor(255, 255, 255, 30)) grad.setColorAt(1, QtGui.QColor(0, 0, 0, 28)) grad.setStart(0, 0) grad.setFinalStop(0, 30) painter.setPen(QtCore.Qt.NoPen) painter.setBrush(grad) painter.drawRect(0, 0, self.width(), 30) # draw the text painter.setFont(self.titleBarFont()) bg = self.titleBarBackground() painter.setPen(bg.lighter(110)) painter.drawText(45, 1, self.width(), 30, QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter, self.windowTitle()) painter.setPen(self.titleBarForeground()) painter.drawText(45, 0, self.width(), 30, QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter, self.windowTitle())
def setupSplash(self, pixmap, align=None, color='white', cls=None): """ Sets up a splash screen for the application for the given pixmap. :param pixmap | <QtGui.QPixmap> align | <QtCore.Qt.Alignment> color | <QtGui.QColor> cls | <subclass of QtGui.QSplashScreen> :return <QtGui.QSplashScreen> """ if cls is None: cls = XLoggerSplashScreen if align is None: align = QtCore.Qt.AlignLeft | QtCore.Qt.AlignBottom color = QtGui.QColor('white') pixmap = QtGui.QPixmap(pixmap) screen = cls(splash) screen.setTextColor(color) screen.setTextAlignment(align) screen.show() self.processEvents() self._splash = screen return screen
def paintEvent(self, event): """ Overloads the paint even to render this button. """ if self.isHoverable() and self.icon().isNull(): return # initialize the painter painter = QtGui.QStylePainter() painter.begin(self) try: option = QtGui.QStyleOptionToolButton() self.initStyleOption(option) # generate the scaling and rotating factors x_scale = 1 y_scale = 1 if self.flipHorizontal(): x_scale = -1 if self.flipVertical(): y_scale = -1 center = self.rect().center() painter.translate(center.x(), center.y()) painter.rotate(self.angle()) painter.scale(x_scale, y_scale) painter.translate(-center.x(), -center.y()) painter.drawComplexControl(QtGui.QStyle.CC_ToolButton, option) finally: painter.end()
def addToGroup(self, item): """ Adds the inputed item to this group. :param item | <QtGui.QGraphicsItem> """ effect = QtGui.QGraphicsDropShadowEffect(self.scene()) effect.setColor(QtGui.QColor('black')) effect.setOffset(0, 0) effect.setBlurRadius(40) item.setGraphicsEffect(effect) item.setParentItem(self) super(XWalkthroughGraphic, self).addToGroup(item)
def addSlide(self, slide): """ Adds a new slide to the widget. :param slide | <XWalkthroughSlide> :return <QtGui.QGraphicsView> """ # create the scene scene = XWalkthroughScene(self) scene.setReferenceWidget(self.parent()) scene.load(slide) # create the view view = QtGui.QGraphicsView(self) view.setCacheMode(view.CacheBackground) view.setScene(scene) view.setStyleSheet('background: transparent') view.setFrameShape(view.NoFrame) view.setInteractive(False) view.setFocusPolicy(QtCore.Qt.NoFocus) view.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents) view.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft) view.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) view.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) # add the slide self._slideshow.addWidget(view) self.updateUi() return view
def __init__(self, text, parent=None): super(XWalkthroughButton, self).__init__(text, parent) font = self.font() font.setBold(True) self.setFont(font) palette = self.palette() palette.setColor(palette.Highlight, QtGui.QColor('#3EBDFF')) palette.setColor(palette.HighlightedText, QtGui.QColor('white')) palette.setColor(palette.Button, QtGui.QColor('#4070FF')) palette.setColor(palette.ButtonText, QtGui.QColor('white')) self.setPalette(palette) self.setFont(font) self.setFixedSize(150, 30)
def adaptSize(self, text, rect, wordWrap=False, minimum=0.1): metrics = QtGui.QFontMetrics(self) # don't use the word wrap information if not wordWrap: factor = rect.width() / max(float(metrics.width(text)), 1) if factor < 1: new_size = self.pointSizeF() * factor if new_size < minimum: new_size = minimum self.setPointSizeF(new_size) # otherwise, loop through it else: fit = False flags = QtCore.Qt.TextWordWrap | QtCore.Qt.AlignLeft for i in range(10): bound = metrics.boundingRect(rect, flags, text) if bound.width() < rect.width() and \ bound.height() < rect.height(): break break_it = False new_size = self.pointSizeF() - 0.25 if new_size < minimum: new_size = minimum break_it = True self.setPointSizeF(new_size) if break_it: break
def leaveEvent(self, event): if self.isHoverable(): super(XToolButton, self).setIcon(QtGui.QIcon()) if self.isShadowed() or self.isColored(): self.updateUi() else: super(XToolButton, self).leaveEvent(event)
def update(self, enabled=None): """ Updates this item based on the interface. """ if enabled is None: enabled = self.checkState(0) == QtCore.Qt.Checked elif not enabled or self._element.get('enabled', 'True') != 'True': self.setCheckState(0, QtCore.Qt.Unchecked) else: self.setCheckState(0, QtCore.Qt.Checked) if enabled: self.setForeground(0, QtGui.QBrush()) else: self.setForeground(0, QtGui.QBrush(QtGui.QColor('lightGray'))) for child in self.children(): child.update(enabled)
def __init__(self, parent): super(XDropZoneWidget, self).__init__(parent) self._filter = None parent.installEventFilter(self) self.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents) self.setLayout(QtGui.QGridLayout()) self.lower() self.hide()
def addPixmap(self, pixmap): """ Adds a pixmap to this graphics item. :param pixmap | <QtGui.QPixmap> """ # add the item to the group item = QtGui.QGraphicsPixmapItem(pixmap) self.addToGroup(item) return item
def exec_(window, data): """ Executes the startup data for the given main window. This method needs to be called in conjunction with the setup method. :sa setup :param window | <QWidget> data | { <str> key: <variant> value, .. } :return <int> err """ import_qt(globals()) if 'splash' in data: data['splash'].finish(window) if not window.parent(): window.setAttribute(QtCore.Qt.WA_DeleteOnClose) if 'app' in data: # setup application information data['app'].setPalette(window.palette()) data['app'].setWindowIcon(window.windowIcon()) # create the tray menu if not window.windowIcon().isNull(): menu = QtGui.QMenu(window) action = menu.addAction('Quit') action.triggered.connect(window.close) # create the tray icon tray_icon = QtGui.QSystemTrayIcon(window) tray_icon.setObjectName('trayIcon') tray_icon.setIcon(window.windowIcon()) tray_icon.setContextMenu(menu) tray_icon.setToolTip(data['app'].applicationName()) tray_icon.show() window.destroyed.connect(tray_icon.deleteLater) return data['app'].exec_() return 0
def setShadowed(self, state): self._shadowed = state if state: self._colored = False effect = QtGui.QGraphicsDropShadowEffect(self) effect.setColor(QtGui.QColor(0, 0, 0, 0)) effect.setOffset(0, 0) effect.setBlurRadius(self.shadowRadius()) self.setGraphicsEffect(effect) if self.isClickable(): self.setStyleSheet(CLICKABLE_SHEET) else: self.setStyleSheet(UNCLICKABLE_SHEET) self.updateUi() else: self.setStyleSheet('') self.setGraphicsEffect(None) self.blink(False)
def exec_(self): """ Runs the main application for this instance and returns the success value. :return <int> """ # create the tray icon if self.autoCreateTrayIcon() and not self.trayIcon(): try: window = self.topLevelWindows()[0] except IndexError: pass else: # create the menu menu = QtGui.QMenu(window) if self.applicationName(): act = menu.addAction('Quit {0}'.format( self.applicationName())) else: act = menu.addAction('Quit') act.triggered.connect(self.quit) # create the tray icon icon = QtGui.QSystemTrayIcon() icon.setIcon(self.windowIcon()) icon.setObjectName('trayIcon') icon.setContextMenu(menu) icon.setToolTip(self.applicationName()) icon.show() self._trayIcon = icon result = super(XApplication, self).exec_() # save the settings before exiting self.saveSettings() return result
def paintEvent(self, event): with XPainter(self) as painter: if self.isHovered(): alpha = 120 else: alpha = 30 x = 0 y = 0 w = self.width() - 1 h = self.height() - 1 clr = QtGui.QColor(self.background()) clr.setAlpha(alpha) brush = QtGui.QBrush(clr) painter.setPen(self.foreground()) painter.setBrush(brush) painter.drawRect(x, y, w, h) painter.drawText(x, y, w, h, QtCore.Qt.AlignCenter | QtCore.Qt.TextWordWrap, self.text())
def updateUi(self): if not self.isClickable(): return effect = self.graphicsEffect() if isinstance(effect, QtGui.QGraphicsDropShadowEffect): palette = self.palette() transparent = QtGui.QColor(0, 0, 0, 0) clr = palette.color(palette.Shadow) show = self.isChecked() and self.isEnabled() effect.setColor(transparent if not show else clr) elif isinstance(effect, QtGui.QGraphicsColorizeEffect): effect.setStrength(1 if self.isChecked() else 0)
def addText(self, text, width=None): """ Adds a simple text item to this group. :param text | <str> maximumWidth | <float> || None maximumHeight | <float> || None """ item = QtGui.QGraphicsTextItem() font = item.font() font.setFamily('Arial') font.setPointSize(12) item.setFont(font) item.setHtml(text) item.setDefaultTextColor(QtGui.QColor('white')) self.addToGroup(item) item.graphicsEffect().setBlurRadius(8) if width: item.setTextWidth(width) return item
def __init__(self, parent, element): super(XScaffoldElementItem, self).__init__(parent) # define custom properties self._element = element # setup properties self.setFixedHeight(20) self.setText(0, element.get('name', '')) self.update(element.get('enabled', 'True') == 'True') # setup the icon for this item folder_ico = QtGui.QIcon(projexui.resources.find('img/folder.png')) file_ico = QtGui.QIcon(projexui.resources.find('img/file.png')) if element.tag == 'folder': self.setIcon(0, folder_ico) else: self.setIcon(0, file_ico) # create sub-items for xchild in element: XScaffoldElementItem(self, xchild) self.setExpanded(element.get('expand', 'True') == 'True')
def timerEvent(self, event): effect = self.graphicsEffect() if not (effect and self.isBlinking()): self.killTimer(event.timerId()) elif isinstance(effect, QtGui.QGraphicsDropShadowEffect): palette = self.palette() transparent = QtGui.QColor(0, 0, 0, 0) clr = palette.color(palette.Shadow) if effect.color() == transparent: effect.setColor(clr) else: effect.setColor(transparent) elif isinstance(effect, QtGui.QGraphicsColorizeEffect): effect.setStrength(int(not effect.strength()))
def __init__(self, parent=None): super(XSerialEdit, self).__init__(parent) # define custom properties self._sectionLength = 5 self._readOnly = False self._editorHandlingBlocked = False # set standard values layout = QtGui.QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(4) self.setLayout(layout) self.setSectionCount(4) self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
def restoreValue(self, xelem): """ Stores the value for the inptued instance to the given xml element. :param xelem | <xml.etree.Element> :return <variant> """ typ = xelem.get('type') if typ == 'color': return QtGui.QColor(xelem.text) elif typ == 'point': return QtCore.QPoint(*map(int, xelem.text.split(','))) elif typ == 'pointf': return QtCore.QPointF(*map(float, xelem.text.split(','))) elif typ == 'rect': return QtCore.QRectF(*map(int, xelem.text.split(','))) elif typ == 'rectf': return QtCore.QRectF(*map(float, xelem.text.split(','))) elif typ == 'bytea': return QtCore.QByteArray(cPickle.loads(xelem.text)) elif typ == 'pickle': return cPickle.loads(xelem.text) elif typ == 'xml': return xelem[0] elif typ in ('str', 'unicode'): return xelem.text else: try: return eval('{0}({1})'.format(typ, xelem.text)) except: return None
def setColored(self, state): self._colored = state if state: self._shadowed = False palette = self.palette() effect = QtGui.QGraphicsColorizeEffect(self) effect.setStrength(0) effect.setColor(palette.color(palette.Highlight)) self.setGraphicsEffect(effect) if self.isClickable(): self.setStyleSheet(CLICKABLE_SHEET) else: self.setStyleSheet(UNCLICKABLE_SHEET) self.updateUi() else: self.setStyleSheet('') self.setGraphicsEffect(None) self.blink(False)
def drawForeground(self, painter, rect, showGrid, showColumns, showRows): """ Draws the grid on the inputed painter :param painter | <QPainter> rect | <QRect> showGrid | <bool> showColumns | <bool> showRows | <bool> """ painter.save() center = self.buildData('center') radius = self.buildData('radius') / 2.0 palette = QtGui.QApplication.palette() pen = QtGui.QPen(palette.color(palette.Text)) pen.setWidthF(0.75) painter.setBrush(palette.color(palette.Base)) painter.setPen(pen) painter.setRenderHint(painter.Antialiasing) painter.drawEllipse(center, radius, radius) painter.restore()
def setTheme(self, theme): if theme == XCodeHighlighter.Theme.Default: # create the default keyword format form = QtGui.QTextCharFormat() form.setForeground(QtGui.QColor('blue')) self._formats[XCodeHighlighter.Style.Keyword] = form # create the default comment format form = QtGui.QTextCharFormat() form.setForeground(QtGui.QColor('green')) self._formats[XCodeHighlighter.Style.Comment] = form # create the default string format form = QtGui.QTextCharFormat() form.setForeground(QtGui.QColor('brown')) self._formats[XCodeHighlighter.Style.String] = form # create the class format form = QtGui.QTextCharFormat() form.setForeground(QtGui.QColor('darkMagenta')) form.setFontWeight(QtGui.QFont.Bold) self._formats[XCodeHighlighter.Style.Class] = form # create the function format form = QtGui.QTextCharFormat() form.setForeground(QtGui.QColor('darkMagenta')) form.setFontWeight(QtGui.QFont.Bold) self._formats[XCodeHighlighter.Style.Function] = form elif theme == XCodeHighlighter.Theme.Dark: opts = [] opts.append((self.Style.Keyword, '#2da4ff', False)) opts.append((self.Style.String, 'orange', False)) opts.append((self.Style.Comment, '#10ff00', False)) opts.append((self.Style.Class, '#f7ffc1', True)) opts.append((self.Style.Function, '#f7ffc1', True)) for style, clr, bold in opts: form = QtGui.QTextCharFormat() form.setForeground(QtGui.QColor(clr)) if bold: form.setFontWeight(QtGui.QFont.Bold) self._formats[style] = form
def setup(applicationName, applicationType=None, style='plastique', splash='', splashType=None, splashTextColor='white', splashTextAlign=None, theme=''): """ Wrapper system for the QApplication creation process to handle all proper pre-application setup. This method will verify that there is no application running, creating one if necessary. If no application is created, a None value is returned - signaling that there is already an app running. If you need to specify your own QApplication subclass, you can do so through the applicationType parameter. :note This method should always be used with the exec_ method to handle the post setup process. :param applicationName | <str> applicationType | <subclass of QApplication> || None style | <str> || <QStyle> | style to use for the new app splash | <str> | filepath to use for a splash screen splashType | <subclass of QSplashScreen> || None splashTextColor | <str> || <QColor> splashTextAlign | <Qt.Alignment> :usage |import projexui | |def main(argv): | # initialize the application | data = projexui.setup() | | # do some initialization code | window = MyWindow() | window.show() | | # execute the application | projexui.exec_(window, data) :return { <str> key: <variant> value, .. } """ import_qt(globals()) output = {} # check to see if there is a qapplication running if not QtGui.QApplication.instance(): # make sure we have a valid QApplication type if applicationType is None: applicationType = QtGui.QApplication app = applicationType([applicationName]) app.setApplicationName(applicationName) app.setQuitOnLastWindowClosed(True) stylize(app, style=style, theme=theme) # utilized with the projexui.config.xschemeconfig app.setProperty('useScheme', wrapVariant(True)) output['app'] = app # create a new splash screen if desired if splash: if not splashType: splashType = XLoggerSplashScreen pixmap = QtGui.QPixmap(splash) screen = splashType(pixmap) if splashTextAlign is None: splashTextAlign = QtCore.Qt.AlignLeft | QtCore.Qt.AlignBottom screen.setTextColor(QtGui.QColor(splashTextColor)) screen.setTextAlignment(splashTextAlign) screen.show() QtGui.QApplication.instance().processEvents() output['splash'] = screen return output
def showEvent(self, event): super(XToolButton, self).showEvent(event) if self.isHoverable(): super(XToolButton, self).setIcon(QtGui.QIcon())
def _updateFrame(self): """ Sets the icon for this button to the frame at the given number. """ self.setIcon(QtGui.QIcon(self._movie.currentPixmap()))
def __init__(self, scaffold, parent=None): super(XScaffoldPropertiesPage, self).__init__(parent) # setup the scaffolding options self._scaffold = scaffold self.setTitle('Properties') self.setSubTitle('Setup scaffold properties') if scaffold.uifile(): projexui.loadUi(__file__, self, scaffold.uifile()) else: layout = QtGui.QFormLayout() for prop in scaffold.properties(): # define the text text = prop.label if prop.required: text += '*' text += ':' # create a checkbox if prop.type == 'bool': widget = QtGui.QCheckBox(self) widget.setProperty('propertyName', wrapVariant(prop.name)) widget.setText(text.strip(':')) layout.addRow(None, widget) # create a float elif prop.type == 'int': lbl = QtGui.QLabel(text, self) widget = QtGui.QSpinBox(self) widget.setProperty('propertyName', wrapVariant(prop.name)) layout.addRow(lbl, widget) # create a double elif prop.type == 'float': lbl = QtGui.QLabel(text, self) widget = QtGui.QDoubleSpinBox(self) widget.setProperty('propertyName', wrapVariant(prop.name)) layout.addRow(lbl, widget) # create a text edit elif prop.type == 'text': lbl = QtGui.QLabel(text, self) widget = XTextEdit(self) widget.setProperty('propertyName', wrapVariant(prop.name)) layout.addRow(lbl, widget) # create a filepath elif prop.type == 'file': lbl = QtGui.QLabel(text, self) widget = XFilepathEdit(self) # create an icon elif prop.type == 'icon': widget = XIconButton(self) layout.addRow(lbl, widget) # create a line edit else: lbl = QtGui.QLabel(text, self) if prop.choices: widget = XComboBox(self) widget.setProperty('dataType', 'string') widget.addItems([''] + prop.choices) else: widget = XLineEdit(self) if prop.regex: regexp = QtCore.QRegExp(prop.regex) validator = QtGui.QRegExpValidator(regexp, widget) widget.setValidator(validator) widget.setProperty('propertyName', wrapVariant(prop.name)) layout.addRow(lbl, widget) self.setLayout(layout) for prop, widget in self.propertyWidgetMap().items(): if prop.default is not None: try: widget.setHint(prop.default) except AttributeError: projexui.setWidgetValue(widget, prop.default)
def __init__(self, parent, windowFlags=0): windowFlags = QtCore.Qt.WindowFlags(windowFlags) super(XMdiSubWindow, self).__init__(parent, windowFlags) # define custom properties palette = self.palette() font = self.font() font.setBold(True) font.setPointSize(font.pointSize() + 2) self._titleBarFont = font self._titleBarBackground = palette.color(palette.Button) self._titleBarForeground = palette.color(palette.ButtonText) self._titleBarBorder = QtGui.QColor('black') # create the drop shadow effect eff = QtGui.QGraphicsDropShadowEffect(self) eff.setOffset(0, 0) eff.setBlurRadius(40) eff.setColor(palette.color(palette.Shadow)) self.setGraphicsEffect(eff) # create the control buttons self._sysmenuBtn = XToolButton(self) self._sysmenuBtn.setIcon(self.windowIcon()) self._sysmenuBtn.setPalette(palette) self._sysmenuBtn.setAutoRaise(True) self._sysmenuBtn.setFixedSize(QtCore.QSize(22, 22)) self._sysmenuBtn.move(4, 4) self._sysmenuBtn.show() palette.setColor(palette.Shadow, QtGui.QColor('yellow')) self._minimizeBtn = XToolButton(self) self._minimizeBtn.setIcon( QtGui.QIcon(resources.find('img/mdiarea/minimize.png'))) self._minimizeBtn.setPalette(palette) self._minimizeBtn.setShadowed(True) self._minimizeBtn.setShadowRadius(10) self._minimizeBtn.setFixedSize(QtCore.QSize(22, 22)) self._minimizeBtn.show() palette.setColor(palette.Shadow, QtGui.QColor('orange')) self._maximizeBtn = XToolButton(self) self._maximizeBtn.setIcon( QtGui.QIcon(resources.find('img/mdiarea/maximize.png'))) self._maximizeBtn.setPalette(palette) self._maximizeBtn.setShadowed(True) self._maximizeBtn.setShadowRadius(10) self._maximizeBtn.setFixedSize(QtCore.QSize(22, 22)) self._maximizeBtn.show() palette.setColor(palette.Shadow, QtGui.QColor('red')) self._closeBtn = XToolButton(self) self._closeBtn.setIcon( QtGui.QIcon(resources.find('img/mdiarea/close.png'))) self._closeBtn.setPalette(palette) self._closeBtn.setShadowed(True) self._closeBtn.setShadowRadius(10) self._closeBtn.setFixedSize(QtCore.QSize(22, 22)) self._closeBtn.show() # create connections self._sysmenuBtn.clicked.connect(self.showSystemMenu) self._minimizeBtn.clicked.connect(self.toggleMinimized) self._maximizeBtn.clicked.connect(self.toggleMaximized) self._closeBtn.clicked.connect(self.close)