def __init__( self, parent = None ): super(XKeyValueDialog, self).__init__(parent) # create the interface self._keyEdit = XLineEdit(self) self._keyEdit.setMaximumWidth(80) self._keyEdit.setHint( 'set key' ) self._valueEdit = XLineEdit(self) self._valueEdit.setHint( 'set value' ) hbox = QHBoxLayout() hbox.addWidget(self._keyEdit) hbox.addWidget(self._valueEdit) opts = QDialogButtonBox.Ok | QDialogButtonBox.Cancel buttons = QDialogButtonBox( opts, Qt.Horizontal, self ) vbox = QVBoxLayout() vbox.addLayout(hbox) vbox.addWidget(buttons) # update the look and size self.setLayout(vbox) self.setWindowTitle('Edit Pair') self.setMinimumWidth(350) self.adjustSize() self.setFixedHeight(self.height()) # create connections buttons.accepted.connect( self.accept ) buttons.rejected.connect( self.reject )
def __init__(self, parent): super(XUrlWidget, self).__init__(parent) # define the interface self._urlEdit = XLineEdit(self) self._urlButton = QToolButton(self) self._urlButton.setAutoRaise(True) self._urlButton.setIcon(QIcon(resources.find('img/web.png'))) self._urlButton.setToolTip('Browse Link') self._urlButton.setFocusPolicy(Qt.NoFocus) self._urlEdit.setHint('http://') layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(self._urlEdit) layout.addWidget(self._urlButton) self.setLayout(layout) self.setFocusPolicy(Qt.StrongFocus) # create connections self._urlEdit.textChanged.connect(self.urlChanged) self._urlEdit.textEdited.connect(self.urlEdited) self._urlButton.clicked.connect(self.browse)
def __init__(self, parent): super(XLocationWidget, self).__init__(parent) # define the interface self._locationEdit = XLineEdit(self) self._locationButton = QToolButton(self) self._urlTemplate = 'http://maps.google.com/maps?%(params)s' self._urlQueryKey = 'q' self._locationButton.setAutoRaise(True) self._locationButton.setIcon(QIcon(resources.find('img/map.png'))) self._locationEdit.setHint('no location set') layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(self._locationEdit) layout.addWidget(self._locationButton) self.setLayout(layout) # create connections self._locationEdit.textChanged.connect(self.locationChanged) self._locationEdit.textEdited.connect(self.locationEdited) self._locationButton.clicked.connect(self.browseMaps)
def __init__( self, parent ): super(XLocationWidget, self).__init__(parent) # define the interface self._locationEdit = XLineEdit(self) self._locationButton = QToolButton(self) self._urlTemplate = 'http://maps.google.com/maps?%(params)s' self._urlQueryKey = 'q' self._locationButton.setAutoRaise(True) self._locationButton.setIcon(QIcon(resources.find('img/map.png'))) self._locationEdit.setHint('no location set') layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(self._locationEdit) layout.addWidget(self._locationButton) self.setLayout(layout) # create connections self._locationEdit.textChanged.connect(self.locationChanged) self._locationEdit.textEdited.connect(self.locationEdited) self._locationButton.clicked.connect(self.browseMaps)
def __init__( self, parent ): super(XUrlWidget, self).__init__(parent) # define the interface self._urlEdit = XLineEdit(self) self._urlButton = QToolButton(self) self._urlButton.setAutoRaise(True) self._urlButton.setIcon(QIcon(resources.find('img/web.png'))) self._urlButton.setToolTip('Browse Link') self._urlButton.setFocusPolicy(Qt.NoFocus) self._urlEdit.setHint('http://') layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(self._urlEdit) layout.addWidget(self._urlButton) self.setLayout(layout) self.setFocusPolicy(Qt.StrongFocus) # create connections self._urlEdit.textChanged.connect(self.urlChanged) self._urlEdit.textEdited.connect(self.urlEdited) self._urlButton.clicked.connect(self.browse)
def __init__( self, parent = None ): super(XFilepathEdit, self).__init__( parent ) # define custom properties self._validated = False self._validForeground = QColor(0, 120, 0) self._validBackground = QColor(0, 120, 0, 100) self._invalidForeground = QColor(255, 0, 0) self._invalidBackground = QColor(255, 0, 0, 100) self._normalizePath = False self._filepathMode = XFilepathEdit.Mode.OpenFile self._filepathEdit = XLineEdit(self) self._filepathButton = QToolButton(self) self._filepathTypes = 'All Files (*.*)' # set default properties ico = projexui.resources.find('img/folder.png') self._filepathEdit.setReadOnly(False) self._filepathEdit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self._filepathButton.setText('...') self._filepathButton.setFixedSize(25, 23) self._filepathButton.setAutoRaise(True) self._filepathButton.setIcon(QIcon(ico)) self._filepathEdit.setContextMenuPolicy(Qt.CustomContextMenu) self.setWindowTitle('Load File') self.setAcceptDrops(True) # define the layout layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(self._filepathEdit) layout.addWidget(self._filepathButton) self.setLayout(layout) # create connections self._filepathEdit.installEventFilter(self) self._filepathButton.clicked.connect( self.pickFilepath ) self._filepathEdit.textChanged.connect( self.emitFilepathChanged ) self._filepathEdit.textChanged.connect( self.validateFilepath ) self._filepathEdit.customContextMenuRequested.connect( self.showMenu )
def setLineEdit(self, edit): """ Sets the line edit for this widget. :warning If the inputed edit is NOT an instance of XLineEdit, \ this method will destroy the edit and create a new \ XLineEdit instance. :param edit | <XLineEdit> """ if (edit and not isinstance(edit, XLineEdit)): edit.setParent(None) edit.deleteLater() edit = XLineEdit(self) edit.installEventFilter(self) super(XComboBox, self).setLineEdit(edit)
def setLineEdit( self, edit ): """ Sets the line edit for this widget. :warning If the inputed edit is NOT an instance of XLineEdit, \ this method will destroy the edit and create a new \ XLineEdit instance. :param edit | <XLineEdit> """ if ( edit and not isinstance(edit, XLineEdit) ): edit.setParent(None) edit.deleteLater() edit = XLineEdit(self) edit.installEventFilter(self) super(XComboBox, self).setLineEdit(edit)
def __init__(self, parent, action): super(XSearchActionWidget, self).__init__(parent) # define custom properties self._initialized = False self._triggerText = '' # define the interface self._searchEdit = XLineEdit(self) self._searchEdit.setIcon(QIcon(resources.find('img/search.png'))) self._searchEdit.setHint('enter search') self._searchEdit.setFixedHeight(24) # define the completer self._completer = XTreeWidget(self) self._completer.setHint('No actions were found.') self._completer.setWindowFlags(Qt.Popup) self._completer.setRootIsDecorated(False) self._completer.header().hide() self._completer.setSortingEnabled(True) self._completer.sortByColumn(0, Qt.AscendingOrder) self._completer.installEventFilter(self) self._completer.setFocusProxy(self._searchEdit) self._completer.setShowGrid(False) self._completer.setFrameShape(XTreeWidget.Box) self._completer.setFrameShadow(XTreeWidget.Plain) # match the look for the completer to the menu palette = self._completer.palette() palette.setColor(palette.Base, palette.color(palette.Window)) palette.setColor(palette.Text, palette.color(palette.WindowText)) palette.setColor(palette.WindowText, palette.color(palette.Mid)) self._completer.setPalette(palette) # create the layout layout = QHBoxLayout() layout.setContentsMargins(4, 4, 4, 4) layout.addWidget(self._searchEdit) self.setLayout(layout) # create connections self._searchEdit.textChanged.connect(self.filterOptions) self._completer.itemClicked.connect(self.triggerItem) parent.aboutToShow.connect(self.aboutToShow)
def setEditable( self, state ): """ Sets whether or not this combobox will be editable, updating its \ line edit to an XLineEdit if necessary. :param state | <bool> """ super(XComboBox, self).setEditable(state) if ( state ): edit = self.lineEdit() if ( edit and isinstance(edit, XLineEdit) ): return elif ( edit ): edit.setParent(None) edit.deleteLater() edit = XLineEdit(self) edit.setHint(self.hint()) self.setLineEdit(edit)
def setEditable(self, state): """ Sets whether or not this combobox will be editable, updating its \ line edit to an XLineEdit if necessary. :param state | <bool> """ super(XComboBox, self).setEditable(state) if state: edit = self.lineEdit() if edit and isinstance(edit, XLineEdit): return elif edit: edit.setParent(None) edit.deleteLater() edit = XLineEdit(self) edit.setHint(self.hint()) self.setLineEdit(edit)
def __init__(self, parent=None): super(XComboBox, self).__init__(parent) # define custom properties self._checkable = False self._hint = '' self._separator = ',' # setup the checkable popup widget self._checkablePopup = None # set default properties self.setLineEdit(XLineEdit(self))
def setEditable(self, state): """ Sets whether or not this label should be editable or not. :param state | <bool> """ self._editable = state if state and not self._lineEdit: self.setLineEdit(XLineEdit(self)) elif not state and self._lineEdit: self._lineEdit.close() self._lineEdit.setParent(None) self._lineEdit.deleteLater() self._lineEdit = None
def setQuery(self, query): """ Sets the query instance for this widget to the inputed query. :param query | <orb.Query> || <orb.QueryCompound> """ if hash(query) == hash(self._query): return self._query = query if QueryCompound.typecheck(query): self.uiColumnDDL.hide() self.uiOperatorDDL.hide() # setup the compound editor editor = XLineEdit(self) editor.setReadOnly(True) editor.setText(query.name() + ' %s' % str(query)) editor.setHint(str(query)) self.setEditor(editor) else: self.uiColumnDDL.show() self.uiOperatorDDL.show() text = query.columnName() self.uiColumnDDL.setCurrentSchemaPath(str(text)) self.uiOperatorDDL.blockSignals(True) plug = self.currentPlugin() if plug: op = plug.operator(query.operatorType(), query.value()) index = self.uiOperatorDDL.findText(op) if index != -1: self.uiOperatorDDL.setCurrentIndex(index) self.uiOperatorDDL.blockSignals(False) self.refreshButtons()
def setQuery(self, query): """ Sets the query instance for this widget to the inputed query. :param query | <orb.Query> || <orb.QueryCompound> """ if not query.isNull() and hash(query) == hash(self._query): return self._query = query if QueryCompound.typecheck(query): self.uiColumnDDL.hide() self.uiOperatorDDL.hide() # setup the compound editor editor = XLineEdit(self) editor.setReadOnly(True) editor.setText(query.name() + ' %s' % nativestring(query)) editor.setHint(nativestring(query)) self.setEditor(editor) else: self.uiColumnDDL.show() self.uiOperatorDDL.show() text = query.columnName() self.uiColumnDDL.setCurrentSchemaPath(nativestring(text)) self.uiOperatorDDL.blockSignals(True) plug = self.currentPlugin() if plug: op = plug.operator(query.operatorType(), query.value()) index = self.uiOperatorDDL.findText(op) if index != -1: self.uiOperatorDDL.setCurrentIndex(index) self.uiOperatorDDL.blockSignals(False) self.refreshButtons()
class XFindWidget(QWidget): """ """ __designer_icon__ = resources.find('img/search.png') def __init__(self, parent=None): super(XFindWidget, self).__init__(parent) # define custom properties self._textEdit = None self._webView = None self._lastCursor = QTextCursor() self._lastText = '' self._closeButton = QToolButton(self) self._closeButton.setIcon(QIcon(resources.find('img/close.png'))) self._closeButton.setAutoRaise(True) self._closeButton.setToolTip('Hide the Find Field.') self._searchEdit = XLineEdit(self) self._searchEdit.setHint('search for...') self._previousButton = QToolButton(self) self._previousButton.setIcon(QIcon(resources.find('img/back.png'))) self._previousButton.setAutoRaise(True) self._previousButton.setToolTip('Find Previous') self._nextButton = QToolButton(self) self._nextButton.setIcon(QIcon(resources.find('img/forward.png'))) self._nextButton.setAutoRaise(True) self._nextButton.setToolTip('Find Next') self._caseSensitiveCheckbox = QCheckBox(self) self._caseSensitiveCheckbox.setText('Case Sensitive') self._wholeWordsCheckbox = QCheckBox(self) self._wholeWordsCheckbox.setText('Whole Words Only') self._regexCheckbox = QCheckBox(self) self._regexCheckbox.setText('Use Regex') self._findAction = QAction(self) self._findAction.setText('Find...') self._findAction.setIcon(QIcon(resources.find('img/search.png'))) self._findAction.setToolTip('Find in Text') self._findAction.setShortcut(QKeySequence('Ctrl+F')) self._findAction.setShortcutContext(Qt.WidgetWithChildrenShortcut) # layout the widgets layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self._closeButton) layout.addWidget(self._searchEdit) layout.addWidget(self._previousButton) layout.addWidget(self._nextButton) layout.addWidget(self._caseSensitiveCheckbox) layout.addWidget(self._wholeWordsCheckbox) layout.addWidget(self._regexCheckbox) self.setLayout(layout) # create connections self._findAction.triggered.connect(self.show) self._searchEdit.textChanged.connect(self.findNext) self._closeButton.clicked.connect(self.hide) self._previousButton.clicked.connect(self.findPrev) self._nextButton.clicked.connect(self.findNext) self._caseSensitiveCheckbox.clicked.connect(self.findNext) self._wholeWordsCheckbox.clicked.connect(self.findNext) self._searchEdit.returnPressed.connect(self.findNext) self._regexCheckbox.clicked.connect(self.findNext) def find(self, flags=0): """ Looks throught the text document based on the current criteria. The \ inputed flags will be merged with the generated search flags. :param flags | <QTextDocument.FindFlag> :return <bool> | success """ # check against the web and text views if (not (self._textEdit or self._webView)): fg = QColor('darkRed') bg = QColor('red').lighter(180) palette = self.palette() palette.setColor(palette.Text, fg) palette.setColor(palette.Base, bg) self._searchEdit.setPalette(palette) self._searchEdit.setToolTip('No Text Edit is linked.') return False if (self._caseSensitiveCheckbox.isChecked()): flags |= QTextDocument.FindCaseSensitively if (self._textEdit and self._wholeWordsCheckbox.isChecked()): flags |= QTextDocument.FindWholeWords terms = self._searchEdit.text() if (terms != self._lastText): self._lastCursor = QTextCursor() if (self._regexCheckbox.isChecked()): terms = QRegExp(terms) palette = self.palette() # search on a text edit if (self._textEdit): cursor = self._textEdit.document().find( terms, self._lastCursor, QTextDocument.FindFlags(flags)) found = not cursor.isNull() self._lastCursor = cursor self._textEdit.setTextCursor(cursor) elif (QWebPage): flags = QWebPage.FindFlags(flags) flags |= QWebPage.FindWrapsAroundDocument found = self._webView.findText(terms, flags) self._lastText = self._searchEdit.text() if (not terms or found): fg = palette.color(palette.Text) bg = palette.color(palette.Base) else: fg = QColor('darkRed') bg = QColor('red').lighter(180) palette.setColor(palette.Text, fg) palette.setColor(palette.Base, bg) self._searchEdit.setPalette(palette) return found def findNext(self): """ Looks for the search terms that come up next based on the criteria. :return <bool> | success """ return self.find() def findPrev(self): """ Looks for the search terms that come up last based on the criteria. :return <bool> | success """ return self.find(QTextDocument.FindBackward) def setTextEdit(self, textEdit): """ Sets the text edit that this find widget will use to search. :param textEdit | <QTextEdit> """ if (self._textEdit): self._textEdit.removeAction(self._findAction) self._textEdit = textEdit if (textEdit): textEdit.addAction(self._findAction) def setWebView(self, webView): """ Sets the web view edit that this find widget will use to search. :param webView | <QWebView> """ if (self._webView): self._webView.removeAction(self._findAction) self._webView = webView if (webView): webView.addAction(self._findAction) def show(self): """ Sets this widget visible and then makes the find field have focus. """ super(XFindWidget, self).show() self._searchEdit.setFocus() def textEdit(self): """ Returns the text edit linked with this find widget. :return <QTextEdit> """ return self._textEdit def webView(self): """ Returns the text edit linked with this find widget. :return <QWebView> """ return self._webView
class XKeyValueDialog(QDialog): def __init__( self, parent = None ): super(XKeyValueDialog, self).__init__(parent) # create the interface self._keyEdit = XLineEdit(self) self._keyEdit.setMaximumWidth(80) self._keyEdit.setHint( 'set key' ) self._valueEdit = XLineEdit(self) self._valueEdit.setHint( 'set value' ) hbox = QHBoxLayout() hbox.addWidget(self._keyEdit) hbox.addWidget(self._valueEdit) opts = QDialogButtonBox.Ok | QDialogButtonBox.Cancel buttons = QDialogButtonBox( opts, Qt.Horizontal, self ) vbox = QVBoxLayout() vbox.addLayout(hbox) vbox.addWidget(buttons) # update the look and size self.setLayout(vbox) self.setWindowTitle('Edit Pair') self.setMinimumWidth(350) self.adjustSize() self.setFixedHeight(self.height()) # create connections buttons.accepted.connect( self.accept ) buttons.rejected.connect( self.reject ) def key( self ): """ Returns the current value of the current pair's key. :return <str> """ return nativestring(self._keyEdit.text()) def setKey( self, key ): """ Sets the current value of the current pair's key. :param key | <str> """ self._keyEdit.setText(key) def setValue( self, value ): """ Sets the current value of the current pair's value. :param value | <str> """ self._valueEdit.setText(value) def value( self ): """ Returns the current value of the current pair's value. :return <str> """ return nativestring(self._valueEdit.text()) @staticmethod def edit( key = '', value = '', parent = None ): """ Prompts the user to edit the inputed key/value pairing. :param key | <str> value | <str> parent | <QWidget> :return (<bool> accepted, <str> key, <str> value) """ dlg = XKeyValueDialog(parent) dlg.setKey(key) dlg.setValue(value) if ( dlg.exec_() ): return (True, dlg.key(), dlg.value()) return (False, '', '')
class XSearchActionWidget(QWidget): def __init__(self, parent, action): super(XSearchActionWidget, self).__init__(parent) # define custom properties self._initialized = False self._triggerText = '' # define the interface self._searchEdit = XLineEdit(self) self._searchEdit.setIcon(QIcon(resources.find('img/search.png'))) self._searchEdit.setHint('enter search') self._searchEdit.setFixedHeight(24) # define the completer self._completer = XTreeWidget(self) self._completer.setHint('No actions were found.') self._completer.setWindowFlags(Qt.Popup) self._completer.setRootIsDecorated(False) self._completer.header().hide() self._completer.setSortingEnabled(True) self._completer.sortByColumn(0, Qt.AscendingOrder) self._completer.installEventFilter(self) self._completer.setFocusProxy(self._searchEdit) self._completer.setShowGrid(False) self._completer.setFrameShape(XTreeWidget.Box) self._completer.setFrameShadow(XTreeWidget.Plain) # match the look for the completer to the menu palette = self._completer.palette() palette.setColor(palette.Base, palette.color(palette.Window)) palette.setColor(palette.Text, palette.color(palette.WindowText)) palette.setColor(palette.WindowText, palette.color(palette.Mid)) self._completer.setPalette(palette) # create the layout layout = QHBoxLayout() layout.setContentsMargins(4, 4, 4, 4) layout.addWidget(self._searchEdit) self.setLayout(layout) # create connections self._searchEdit.textChanged.connect(self.filterOptions) self._completer.itemClicked.connect(self.triggerItem) parent.aboutToShow.connect(self.aboutToShow) def aboutToShow(self): """ Processes the search widget when the menu is about to show. """ self.clear() self._searchEdit.setFocus() def addItems(self, menus, processed=None): """ Adds items to the completion tree from the menu. :param menus | [<QMenu>, ..] procesed | [<QAction>, ..] || None """ if processed is None: processed = [] for menu in menus: for action in menu.actions(): # since we can have 1 action in more than 1 submenu, we # will want to make sure we're only adding a unique one # so we don't have duplicates text = nativestring(action.text()) if text in processed or action.isSeparator(): continue processed.append(text) if text and unwrapVariant(action.data()) != 'menu': item = XTreeWidgetItem(self._completer, [text]) item.setFixedHeight(20) item.setIcon(0, action.icon()) item.setToolTip(0, action.toolTip()) item.setData(0, Qt.UserRole, wrapVariant(action)) def clear(self): """ Clears the text from the search edit. """ self._searchEdit.blockSignals(True) self._searchEdit.setText('') self._searchEdit.blockSignals(False) def completer(self): """ Returns the completion widget for this menu. :return <projexui.widgets.xtreewidget.XTreeWidget> """ return self._completer def eventFilter(self, object, event): """ Listens for the key press event from the tree widget to pass along to the line edit. :param object | <QWidget> event | <QEvent> :return <bool> | consumed """ if event.type() == event.KeyPress: if event.key() == Qt.Key_Escape: self._completer.hide() self._completer.setCurrentItem(None) elif event.key() in (Qt.Key_Enter, Qt.Key_Return): tree = self._completer item = tree.currentItem() or tree.itemAt(0, 0) self.triggerItem(item) self._searchEdit.keyPressEvent(event) return False def filterOptions(self, text): """ Filters the searched actions based on the inputed text. :param text | <str> """ if not text: self._completer.hide() self._completer.setCurrentItem(None) return # block the signals self._completer.setUpdatesEnabled(False) self._completer.blockSignals(True) # initialize the actions menu = self.parent() if not self._initialized: self.addItems([menu] + menu.findChildren(QMenu)) self._initialized = True # filter the actions in the search view visible_count = 0 item_count = self._completer.topLevelItemCount() for i in range(item_count): item = self._completer.topLevelItem(i) check = nativestring(item.text(0)).lower() hidden = not nativestring(text).lower() in check item.setHidden(hidden) visible_count += 1 if not hidden else 0 # show the popup widget if it is not visible if not self._completer.isVisible(): point = QPoint(-1, self.height()) width = menu.width() height = menu.height() - self.height() - 1 height = max(height, 22 * min(visible_count, 5)) self._completer.move(self.mapToGlobal(point)) self._completer.resize(width, height) self._completer.show() # restore signals self._completer.setUpdatesEnabled(True) self._completer.blockSignals(False) def searchEdit(self): """ Returns the line edit associated with this widget. :return <projexui.widgets.xlineedit.XLineEdit> """ return self._searchEdit def text(self): """ Returns the text of the item that was triggered. :return <str> """ return self._triggerText def triggerItem(self, item): """ Triggers the item by calling its action's toggled state to display or hide the dock panel. :param item | <QtGui.QTreeWidgetItem> """ if not item: return # emit the trigger action self._triggerText = item.text(0) self._completer.hide() self._completer.setCurrentItem(None) self.parent().hide() # trigger the action unwrapVariant(item.data(0, Qt.UserRole)).trigger()
class XFilepathEdit(QWidget): """ The XFilepathEdit class provides a common interface to prompt the user to select a filepath from the filesystem. It can be configured to load directories, point to a save file path location, or to an open file path location. It can also be setup to color changed based on the validity of the existance of the filepath. == Example == |>>> from projexui.widgets.xfilepathedit import XFilepathEdit |>>> import projexui | |>>> # create the edit |>>> edit = projexui.testWidget(XFilepathEdit) | |>>> # set the filepath |>>> edit.setFilepath('/path/to/file') | |>>> # prompt the user to select the filepath |>>> edit.pickFilepath() | |>>> # enable the coloring validation |>>> edit.setValidated(True) """ __designer_icon__ = projexui.resources.find('img/file.png') Mode = enum('OpenFile', 'SaveFile', 'Path', 'OpenFiles') filepathChanged = qt.Signal(str) def __init__(self, parent=None): super(XFilepathEdit, self).__init__(parent) # define custom properties self._validated = False self._validForeground = QColor(0, 120, 0) self._validBackground = QColor(0, 120, 0, 100) self._invalidForeground = QColor(255, 0, 0) self._invalidBackground = QColor(255, 0, 0, 100) self._normalizePath = False self._filepathMode = XFilepathEdit.Mode.OpenFile self._filepathEdit = XLineEdit(self) self._filepathButton = QToolButton(self) self._filepathTypes = 'All Files (*.*)' # set default properties ico = projexui.resources.find('img/folder.png') self._filepathEdit.setReadOnly(False) self._filepathButton.setText('...') self._filepathButton.setFixedSize(25, 23) self._filepathButton.setAutoRaise(True) self._filepathButton.setIcon(QIcon(ico)) self._filepathEdit.setContextMenuPolicy(Qt.CustomContextMenu) self.setWindowTitle('Load File') self.setAcceptDrops(True) # define the layout layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(self._filepathEdit) layout.addWidget(self._filepathButton) self.setLayout(layout) # create connections self._filepathEdit.installEventFilter(self) self._filepathButton.clicked.connect(self.pickFilepath) self._filepathEdit.textChanged.connect(self.emitFilepathChanged) self._filepathEdit.textChanged.connect(self.validateFilepath) self._filepathEdit.customContextMenuRequested.connect(self.showMenu) def autoRaise(self): """ Returns whether or not the tool button will auto raise. :return <bool> """ return self._filepathButton.autoRaise() @qt.Slot() def clearFilepath(self): """ Clears the filepath contents for this path. """ self.setFilepath('') @qt.Slot() def copyFilepath(self): """ Copies the current filepath contents to the current clipboard. """ clipboard = QApplication.instance().clipboard() clipboard.setText(self.filepath()) clipboard.setText(self.filepath(), clipboard.Selection) def dragEnterEvent(self, event): """ Processes drag enter events. :param event | <QDragEvent> """ if (event.mimeData().hasUrls()): event.acceptProposedAction() def dragMoveEvent(self, event): """ Processes drag move events. :param event | <QDragEvent> """ if (event.mimeData().hasUrls()): event.acceptProposedAction() def dropEvent(self, event): """ Processes drop event. :param event | <QDropEvent> """ if (event.mimeData().hasUrls()): url = event.mimeData().urls()[0] filepath = url.toLocalFile() if (filepath): self.setFilepath(filepath) def emitFilepathChanged(self): """ Emits the filepathChanged signal for this widget if the signals are \ not being blocked. """ if (not self.signalsBlocked()): self.filepathChanged.emit(self.filepath()) def eventFilter(self, object, event): """ Overloads the eventFilter to look for click events on the line edit. :param object | <QObject> event | <QEvent> """ if ( object == self._filepathEdit and \ self._filepathEdit.isReadOnly() and \ event.type() == event.MouseButtonPress and \ event.button() == Qt.LeftButton ): self.pickFilepath() return False def filepath(self, validated=False): """ Returns the filepath for this widget. If the validated flag is set \ then this method will only return if the file or folder actually \ exists for this path. In the case of a SaveFile, only the base folder \ needs to exist on the system, in other modes the actual filepath must \ exist. If not validated, the text will return whatever is currently \ entered. :return <str> """ paths = self.filepaths() if not paths: return '' if not validated or self.isValid(): return paths[0] return '' def filepaths(self): """ Returns a list of the filepaths for this edit. :return [<str>, ..] """ return str(self._filepathEdit.text()).split(os.path.pathsep) def filepathMode(self): """ Returns the filepath mode for this widget. :return <XFilepathEdit.Mode> """ return self._filepathMode def filepathModeText(self): """ Returns the text representation for this filepath mode. :return <str> """ return XFilepathEdit.Mode[self._filepathMode] def filepathTypes(self): """ Returns the filepath types that will be used for this widget. :return <str> """ return self._filepathTypes def hint(self): """ Returns the hint for this filepath. :return <str> """ return self._filepathEdit.hint() def icon(self): """ Returns the icon that is used for this filepath widget. :return <QIcon> """ return self._filepathButton.icon() def invalidBackground(self): """ Returns the invalid background color for this widget. :return <QColor> """ return self._invalidBackground def invalidForeground(self): """ Returns the invalid foreground color for this widget. :return <QColor> """ return self._invalidForeground def isValid(self): """ Returns whether or not the filepath exists on the system. \ In the case of a SaveFile, only the base folder \ needs to exist on the system, in other modes the actual filepath must \ exist. :return <bool> """ check = str(self._filepathEdit.text()).split(os.path.pathsep)[0] if (self.filepathMode() == XFilepathEdit.Mode.SaveFile): check = os.path.dirname(check) return os.path.exists(check) def isValidated(self): """ Set whether or not to validate the filepath as the user is working \ with it. :return <bool> """ return self._validated def isReadOnly(self): """ Returns if the widget is read only for text editing or not. :return <bool> """ return self._filepathEdit.isReadOnly() def normalizePath(self): """ Returns whether or not the path should be normalized for the current operating system. When off, it will be defaulted to forward slashes (/). :return <bool> """ return self._normalizePath def pickFilepath(self): """ Prompts the user to select a filepath from the system based on the \ current filepath mode. """ mode = self.filepathMode() filepath = '' filepaths = [] curr_dir = str(self._filepathEdit.text()) if (not curr_dir): curr_dir = QDir.currentPath() if mode == XFilepathEdit.Mode.SaveFile: filepath = QFileDialog.getSaveFileName(self, self.windowTitle(), curr_dir, self.filepathTypes()) elif mode == XFilepathEdit.Mode.OpenFile: filepath = QFileDialog.getOpenFileName(self, self.windowTitle(), curr_dir, self.filepathTypes()) elif mode == XFilepathEdit.Mode.OpenFiles: filepaths = QFileDialog.getOpenFileNames(self, self.windowTitle(), curr_dir, self.filepathTypes()) else: filepath = QFileDialog.getExistingDirectory( self, self.windowTitle(), curr_dir) if filepath: if type(filepath) == tuple: filepath = filepath[0] self.setFilepath(str(filepath)) elif filepaths: self.setFilepaths(map(str, filepaths)) def setAutoRaise(self, state): """ Sets whether or not the tool button will auto raise. :param state | <bool> """ self._filepathButton.setAutoRaise(state) @qt.Slot(int) def setFilepathMode(self, mode): """ Sets the filepath mode for this widget to the inputed mode. :param mode | <XFilepathEdit.Mode> """ self._filepathMode = mode @qt.Slot(str) def setFilepathModeText(self, text): """ Sets the filepath mode for this widget based on the inputed text. :param text | <str> :return <bool> | success """ try: self.setFilepathMode(XFilepathEdit.Mode[str(text)]) return True except KeyError: return False @qt.Slot(str) def setFilepathTypes(self, filepathTypes): """ Sets the filepath type string that will be used when looking up \ filepaths. :param filepathTypes | <str> """ self._filepathTypes = filepathTypes @qt.Slot(str) def setFilepath(self, filepath): """ Sets the filepath text for this widget to the inputed path. :param filepath | <str> """ if self.normalizePath(): filepath = os.path.normpath(str(filepath)) else: filepath = os.path.normpath(str(filepath)).replace('\\', '/') self._filepathEdit.setText(filepath) def setFilepaths(self, filepaths): """ Sets the list of the filepaths for this widget to the inputed paths. :param filepaths | [<str>, ..] """ self.setFilepath(os.path.pathsep.join(filepaths)) def setHint(self, hint): """ Sets the hint for this filepath. :param hint | <str> """ if self.normalizePath(): filepath = os.path.normpath(str(hint)) else: filepath = os.path.normpath(str(hint)).replace('\\', '/') self._filepathEdit.setHint(hint) def setIcon(self, icon): """ Sets the icon that will be used for this widget's tool button. :param icon | <QIcon> || <str> """ self._filepathButton.setIcon(QIcon(icon)) def setInvalidBackground(self, bg): """ Sets the invalid background color for this widget to the inputed widget. :param bg | <QColor> """ self._invalidBackground = QColor(bg) def setInvalidForeground(self, fg): """ Sets the invalid foreground color for this widget to the inputed widget. :param fg | <QColor> """ self._invalidForeground = QColor(fg) def setNormalizePath(self, state): """ Sets whether or not the path should be normalized for the current operating system. When off, it will be defaulted to forward slashes (/). :param state | <bool> """ self._normalizePath = state @qt.Slot(bool) def setReadOnly(self, state): """ Sets whether or not this filepath widget is readonly in the text edit. :param state | <bool> """ self._filepathEdit.setReadOnly(state) @qt.Slot(bool) def setValidated(self, state): """ Set whether or not to validate the path as the user edits it. :param state | <bool> """ self._validated = state palette = self.palette() # reset the palette to default, revalidate self._filepathEdit.setPalette(palette) self.validate() def setValidBackground(self, bg): """ Sets the valid background color for this widget to the inputed color. :param bg | <QColor> """ self._validBackground = QColor(bg) def setValidForeground(self, fg): """ Sets the valid foreground color for this widget to the inputed color. :param fg | <QColor> """ self._validForeground = QColor(fg) def showMenu(self, pos): """ Popups a menu for this widget. """ menu = QMenu(self) menu.setAttribute(Qt.WA_DeleteOnClose) menu.addAction('Clear').triggered.connect(self.clearFilepath) menu.addSeparator() menu.addAction('Copy Filepath').triggered.connect(self.copyFilepath) menu.exec_(self.mapToGlobal(pos)) def validBackground(self): """ Returns the valid background color for this widget. :return <QColor> """ return self._validBackground def validForeground(self): """ Returns the valid foreground color for this widget. :return <QColor> """ return self._validForeground def validateFilepath(self): """ Alters the color scheme based on the validation settings. """ if (not self.isValidated()): return valid = self.isValid() if (not valid): fg = self.invalidForeground() bg = self.invalidBackground() else: fg = self.validForeground() bg = self.validBackground() palette = self.palette() palette.setColor(palette.Base, bg) palette.setColor(palette.Text, fg) self._filepathEdit.setPalette(palette) # map Qt properties x_autoRaise = qt.Property(bool, autoRaise, setAutoRaise) x_filepathTypes = qt.Property(str, filepathTypes, setFilepathTypes) x_filepath = qt.Property(str, filepath, setFilepath) x_readOnly = qt.Property(bool, isReadOnly, setReadOnly) x_validated = qt.Property(bool, isValidated, setValidated) x_hint = qt.Property(str, hint, setHint) x_icon = qt.Property('QIcon', icon, setIcon) x_normalizePath = qt.Property(bool, normalizePath, setNormalizePath) x_invalidForeground = qt.Property('QColor', invalidForeground, setInvalidForeground) x_invalidBackground = qt.Property('QColor', invalidBackground, setInvalidBackground) x_validForeground = qt.Property('QColor', validForeground, setValidForeground) x_validBackground = qt.Property('QColor', validBackground, setValidBackground) x_filepathModeText = qt.Property(str, filepathModeText, setFilepathModeText)
class XUrlWidget(QWidget): urlChanged = Signal(str) urlEdited = Signal() def __init__( self, parent ): super(XUrlWidget, self).__init__(parent) # define the interface self._urlEdit = XLineEdit(self) self._urlButton = QToolButton(self) self._urlButton.setAutoRaise(True) self._urlButton.setIcon(QIcon(resources.find('img/web.png'))) self._urlButton.setToolTip('Browse Link') self._urlButton.setFocusPolicy(Qt.NoFocus) self._urlEdit.setHint('http://') layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(self._urlEdit) layout.addWidget(self._urlButton) self.setLayout(layout) self.setFocusPolicy(Qt.StrongFocus) # create connections self._urlEdit.textChanged.connect(self.urlChanged) self._urlEdit.textEdited.connect(self.urlEdited) self._urlButton.clicked.connect(self.browse) def blockSignals( self, state ): """ Blocks the signals for this widget and its sub-parts. :param state | <bool> """ super(XUrlWidget, self).blockSignals(state) self._urlEdit.blockSignals(state) self._urlButton.blockSignals(state) def browse( self ): """ Brings up a web browser with the address in a Google map. """ webbrowser.open(self.url()) def hint( self ): """ Returns the hint associated with this widget. :return <str> """ return self._urlEdit.hint() def lineEdit( self ): """ Returns the line edit linked with this widget. :return <XLineEdit> """ return self._urlEdit def setFocus(self): """ Sets the focus for this widget on its line edit. """ self._urlEdit.setFocus() @Slot(str) def setHint( self, hint ): """ Sets the hint associated with this widget. :param hint | <str> """ self._urlEdit.setHint(hint) @Slot(str) def setUrl( self, url ): """ Sets the url for this widget to the inputed url. :param url | <str> """ self._urlEdit.setText(nativestring(url)) def url( self ): """ Returns the current url from the edit. :return <str> """ return nativestring(self._urlEdit.text()) x_hint = Property(str, hint, setHint) x_url = Property(str, url, setUrl)
class XFilepathEdit(QWidget): """ The XFilepathEdit class provides a common interface to prompt the user to select a filepath from the filesystem. It can be configured to load directories, point to a save file path location, or to an open file path location. It can also be setup to color changed based on the validity of the existance of the filepath. == Example == |>>> from projexui.widgets.xfilepathedit import XFilepathEdit |>>> import projexui | |>>> # create the edit |>>> edit = projexui.testWidget(XFilepathEdit) | |>>> # set the filepath |>>> edit.setFilepath('/path/to/file') | |>>> # prompt the user to select the filepath |>>> edit.pickFilepath() | |>>> # enable the coloring validation |>>> edit.setValidated(True) """ __designer_icon__ = projexui.resources.find('img/file.png') Mode = enum('OpenFile', 'SaveFile', 'Path', 'OpenFiles') filepathChanged = qt.Signal(str) def __init__( self, parent = None ): super(XFilepathEdit, self).__init__( parent ) # define custom properties self._validated = False self._validForeground = QColor(0, 120, 0) self._validBackground = QColor(0, 120, 0, 100) self._invalidForeground = QColor(255, 0, 0) self._invalidBackground = QColor(255, 0, 0, 100) self._normalizePath = False self._filepathMode = XFilepathEdit.Mode.OpenFile self._filepathEdit = XLineEdit(self) self._filepathButton = QToolButton(self) self._filepathTypes = 'All Files (*.*)' # set default properties ico = projexui.resources.find('img/folder.png') self._filepathEdit.setReadOnly(False) self._filepathButton.setText('...') self._filepathButton.setFixedSize(25, 23) self._filepathButton.setAutoRaise(True) self._filepathButton.setIcon(QIcon(ico)) self._filepathEdit.setContextMenuPolicy(Qt.CustomContextMenu) self.setWindowTitle('Load File') self.setAcceptDrops(True) # define the layout layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(self._filepathEdit) layout.addWidget(self._filepathButton) self.setLayout(layout) # create connections self._filepathEdit.installEventFilter(self) self._filepathButton.clicked.connect( self.pickFilepath ) self._filepathEdit.textChanged.connect( self.emitFilepathChanged ) self._filepathEdit.textChanged.connect( self.validateFilepath ) self._filepathEdit.customContextMenuRequested.connect( self.showMenu ) def autoRaise( self ): """ Returns whether or not the tool button will auto raise. :return <bool> """ return self._filepathButton.autoRaise() @qt.Slot() def clearFilepath( self ): """ Clears the filepath contents for this path. """ self.setFilepath('') @qt.Slot() def copyFilepath( self ): """ Copies the current filepath contents to the current clipboard. """ clipboard = QApplication.instance().clipboard() clipboard.setText(self.filepath()) clipboard.setText(self.filepath(), clipboard.Selection) def dragEnterEvent( self, event ): """ Processes drag enter events. :param event | <QDragEvent> """ if ( event.mimeData().hasUrls() ): event.acceptProposedAction() def dragMoveEvent( self, event ): """ Processes drag move events. :param event | <QDragEvent> """ if ( event.mimeData().hasUrls() ): event.acceptProposedAction() def dropEvent( self, event ): """ Processes drop event. :param event | <QDropEvent> """ if ( event.mimeData().hasUrls() ): url = event.mimeData().urls()[0] filepath = url.toLocalFile() if ( filepath ): self.setFilepath(filepath) def emitFilepathChanged( self ): """ Emits the filepathChanged signal for this widget if the signals are \ not being blocked. """ if ( not self.signalsBlocked() ): self.filepathChanged.emit(self.filepath()) def eventFilter( self, object, event ): """ Overloads the eventFilter to look for click events on the line edit. :param object | <QObject> event | <QEvent> """ if ( object == self._filepathEdit and \ self._filepathEdit.isReadOnly() and \ event.type() == event.MouseButtonPress and \ event.button() == Qt.LeftButton ): self.pickFilepath() return False def filepath( self, validated = False ): """ Returns the filepath for this widget. If the validated flag is set \ then this method will only return if the file or folder actually \ exists for this path. In the case of a SaveFile, only the base folder \ needs to exist on the system, in other modes the actual filepath must \ exist. If not validated, the text will return whatever is currently \ entered. :return <str> """ paths = self.filepaths() if not paths: return '' if not validated or self.isValid(): return paths[0] return '' def filepaths(self): """ Returns a list of the filepaths for this edit. :return [<str>, ..] """ return str(self._filepathEdit.text()).split(os.path.pathsep) def filepathMode( self ): """ Returns the filepath mode for this widget. :return <XFilepathEdit.Mode> """ return self._filepathMode def filepathModeText( self ): """ Returns the text representation for this filepath mode. :return <str> """ return XFilepathEdit.Mode[self._filepathMode] def filepathTypes( self ): """ Returns the filepath types that will be used for this widget. :return <str> """ return self._filepathTypes def hint( self ): """ Returns the hint for this filepath. :return <str> """ return self._filepathEdit.hint() def icon( self ): """ Returns the icon that is used for this filepath widget. :return <QIcon> """ return self._filepathButton.icon() def invalidBackground( self ): """ Returns the invalid background color for this widget. :return <QColor> """ return self._invalidBackground def invalidForeground( self ): """ Returns the invalid foreground color for this widget. :return <QColor> """ return self._invalidForeground def isValid( self ): """ Returns whether or not the filepath exists on the system. \ In the case of a SaveFile, only the base folder \ needs to exist on the system, in other modes the actual filepath must \ exist. :return <bool> """ check = str(self._filepathEdit.text()).split(os.path.pathsep)[0] if ( self.filepathMode() == XFilepathEdit.Mode.SaveFile ): check = os.path.dirname(check) return os.path.exists(check) def isValidated( self ): """ Set whether or not to validate the filepath as the user is working \ with it. :return <bool> """ return self._validated def isReadOnly( self ): """ Returns if the widget is read only for text editing or not. :return <bool> """ return self._filepathEdit.isReadOnly() def normalizePath(self): """ Returns whether or not the path should be normalized for the current operating system. When off, it will be defaulted to forward slashes (/). :return <bool> """ return self._normalizePath def pickFilepath( self ): """ Prompts the user to select a filepath from the system based on the \ current filepath mode. """ mode = self.filepathMode() filepath = '' filepaths = [] curr_dir = str(self._filepathEdit.text()) if ( not curr_dir ): curr_dir = QDir.currentPath() if mode == XFilepathEdit.Mode.SaveFile: filepath = QFileDialog.getSaveFileName( self, self.windowTitle(), curr_dir, self.filepathTypes() ) elif mode == XFilepathEdit.Mode.OpenFile: filepath = QFileDialog.getOpenFileName( self, self.windowTitle(), curr_dir, self.filepathTypes() ) elif mode == XFilepathEdit.Mode.OpenFiles: filepaths = QFileDialog.getOpenFileNames( self, self.windowTitle(), curr_dir, self.filepathTypes() ) else: filepath = QFileDialog.getExistingDirectory( self, self.windowTitle(), curr_dir ) if filepath: if type(filepath) == tuple: filepath = filepath[0] self.setFilepath(str(filepath)) elif filepaths: self.setFilepaths(map(str, filepaths)) def setAutoRaise( self, state ): """ Sets whether or not the tool button will auto raise. :param state | <bool> """ self._filepathButton.setAutoRaise(state) @qt.Slot(int) def setFilepathMode( self, mode ): """ Sets the filepath mode for this widget to the inputed mode. :param mode | <XFilepathEdit.Mode> """ self._filepathMode = mode @qt.Slot(str) def setFilepathModeText( self, text ): """ Sets the filepath mode for this widget based on the inputed text. :param text | <str> :return <bool> | success """ try: self.setFilepathMode(XFilepathEdit.Mode[str(text)]) return True except KeyError: return False @qt.Slot(str) def setFilepathTypes( self, filepathTypes ): """ Sets the filepath type string that will be used when looking up \ filepaths. :param filepathTypes | <str> """ self._filepathTypes = filepathTypes @qt.Slot(str) def setFilepath(self, filepath): """ Sets the filepath text for this widget to the inputed path. :param filepath | <str> """ if self.normalizePath(): filepath = os.path.normpath(str(filepath)) else: filepath = os.path.normpath(str(filepath)).replace('\\', '/') self._filepathEdit.setText(filepath) def setFilepaths(self, filepaths): """ Sets the list of the filepaths for this widget to the inputed paths. :param filepaths | [<str>, ..] """ self.setFilepath(os.path.pathsep.join(filepaths)) def setHint(self, hint): """ Sets the hint for this filepath. :param hint | <str> """ if self.normalizePath(): filepath = os.path.normpath(str(hint)) else: filepath = os.path.normpath(str(hint)).replace('\\', '/') self._filepathEdit.setHint(hint) def setIcon( self, icon ): """ Sets the icon that will be used for this widget's tool button. :param icon | <QIcon> || <str> """ self._filepathButton.setIcon(QIcon(icon)) def setInvalidBackground( self, bg ): """ Sets the invalid background color for this widget to the inputed widget. :param bg | <QColor> """ self._invalidBackground = QColor(bg) def setInvalidForeground( self, fg ): """ Sets the invalid foreground color for this widget to the inputed widget. :param fg | <QColor> """ self._invalidForeground = QColor(fg) def setNormalizePath(self, state): """ Sets whether or not the path should be normalized for the current operating system. When off, it will be defaulted to forward slashes (/). :param state | <bool> """ self._normalizePath = state @qt.Slot(bool) def setReadOnly( self, state ): """ Sets whether or not this filepath widget is readonly in the text edit. :param state | <bool> """ self._filepathEdit.setReadOnly(state) @qt.Slot(bool) def setValidated( self, state ): """ Set whether or not to validate the path as the user edits it. :param state | <bool> """ self._validated = state palette = self.palette() # reset the palette to default, revalidate self._filepathEdit.setPalette(palette) self.validate() def setValidBackground( self, bg ): """ Sets the valid background color for this widget to the inputed color. :param bg | <QColor> """ self._validBackground = QColor(bg) def setValidForeground( self, fg ): """ Sets the valid foreground color for this widget to the inputed color. :param fg | <QColor> """ self._validForeground = QColor(fg) def showMenu( self, pos ): """ Popups a menu for this widget. """ menu = QMenu(self) menu.setAttribute(Qt.WA_DeleteOnClose) menu.addAction('Clear').triggered.connect(self.clearFilepath) menu.addSeparator() menu.addAction('Copy Filepath').triggered.connect(self.copyFilepath) menu.exec_(self.mapToGlobal(pos)) def validBackground( self ): """ Returns the valid background color for this widget. :return <QColor> """ return self._validBackground def validForeground( self ): """ Returns the valid foreground color for this widget. :return <QColor> """ return self._validForeground def validateFilepath( self ): """ Alters the color scheme based on the validation settings. """ if ( not self.isValidated() ): return valid = self.isValid() if ( not valid ): fg = self.invalidForeground() bg = self.invalidBackground() else: fg = self.validForeground() bg = self.validBackground() palette = self.palette() palette.setColor(palette.Base, bg) palette.setColor(palette.Text, fg) self._filepathEdit.setPalette(palette) # map Qt properties x_autoRaise = qt.Property(bool, autoRaise, setAutoRaise) x_filepathTypes = qt.Property(str, filepathTypes, setFilepathTypes) x_filepath = qt.Property(str, filepath, setFilepath) x_readOnly = qt.Property(bool, isReadOnly, setReadOnly) x_validated = qt.Property(bool, isValidated, setValidated) x_hint = qt.Property(str, hint, setHint) x_icon = qt.Property('QIcon', icon, setIcon) x_normalizePath = qt.Property(bool, normalizePath, setNormalizePath) x_invalidForeground = qt.Property('QColor', invalidForeground, setInvalidForeground) x_invalidBackground = qt.Property('QColor', invalidBackground, setInvalidBackground) x_validForeground = qt.Property('QColor', validForeground, setValidForeground) x_validBackground = qt.Property('QColor', validBackground, setValidBackground) x_filepathModeText = qt.Property(str, filepathModeText, setFilepathModeText)
class XLocationWidget(QWidget): locationChanged = Signal(str) locationEdited = Signal() def __init__( self, parent ): super(XLocationWidget, self).__init__(parent) # define the interface self._locationEdit = XLineEdit(self) self._locationButton = QToolButton(self) self._urlTemplate = 'http://maps.google.com/maps?%(params)s' self._urlQueryKey = 'q' self._locationButton.setAutoRaise(True) self._locationButton.setIcon(QIcon(resources.find('img/map.png'))) self._locationEdit.setHint('no location set') layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(self._locationEdit) layout.addWidget(self._locationButton) self.setLayout(layout) # create connections self._locationEdit.textChanged.connect(self.locationChanged) self._locationEdit.textEdited.connect(self.locationEdited) self._locationButton.clicked.connect(self.browseMaps) def blockSignals( self, state ): """ Blocks the signals for this widget and its sub-parts. :param state | <bool> """ super(XLocationWidget, self).blockSignals(state) self._locationEdit.blockSignals(state) self._locationButton.blockSignals(state) def browseMaps( self ): """ Brings up a web browser with the address in a Google map. """ url = self.urlTemplate() params = urllib.urlencode({self.urlQueryKey(): self.location()}) url = url % {'params': params} webbrowser.open(url) def hint( self ): """ Returns the hint associated with this widget. :return <str> """ return self._locationEdit.hint() def lineEdit( self ): """ Returns the line edit linked with this widget. :return <XLineEdit> """ return self._locationEdit def location( self ): """ Returns the current location from the edit. :return <str> """ return nativestring(self._locationEdit.text()) @Slot(str) def setHint( self, hint ): """ Sets the hint associated with this widget. :param hint | <str> """ self._locationEdit.setHint(hint) @Slot(str) def setLocation( self, location ): """ Sets the location for this widget to the inputed location. :param location | <str> """ self._locationEdit.setText(nativestring(location)) def setUrlQueryKey( self, key ): """ Sets the key for the URL to the inputed key. :param key | <str> """ self._urlQueryKey = nativestring(key) def setUrlTemplate( self, templ ): """ Sets the URL path template that will be used when looking up locations on the web. :param templ | <str> """ self._urlQueryTemplate = nativestring(templ) def urlQueryKey( self ): """ Returns the query key that will be used for this location. :return <str> """ return self._urlQueryKey def urlTemplate( self ): """ Returns the url template that will be used when mapping this location. :return <str> """ return self._urlTemplate x_hint = Property(str, hint, setHint) x_location = Property(str, location, setLocation) x_urlQueryKey = Property(str, urlQueryKey, setUrlQueryKey) x_urlTemplate = Property(str, urlTemplate, setUrlTemplate)
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 setSectionCount(self, count): """ Sets the number of editors that the serial widget should have. :param count | <int> """ # cap the sections at 10 count = max(1, min(count, 10)) # create additional editors while self.layout().count() < count: editor = XLineEdit(self) editor.setFont(self.font()) editor.setReadOnly(self.isReadOnly()) editor.setHint(self.hint()) editor.setAlignment(QtCore.Qt.AlignCenter) editor.installEventFilter(self) editor.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) editor.setMaxLength(self.sectionLength()) editor.returnPressed.connect(self.returnPressed) self.layout().addWidget(editor) # remove unnecessary editors while count < self.layout().count(): widget = self.layout().itemAt(0).widget() widget.close() widget.setParent(None) widget.deleteLater()
def __init__(self, parent=None): super(XFindWidget, self).__init__(parent) # define custom properties self._textEdit = None self._webView = None self._lastCursor = QTextCursor() self._lastText = '' self._closeButton = QToolButton(self) self._closeButton.setIcon(QIcon(resources.find('img/close.png'))) self._closeButton.setAutoRaise(True) self._closeButton.setToolTip('Hide the Find Field.') self._searchEdit = XLineEdit(self) self._searchEdit.setHint('search for...') self._previousButton = QToolButton(self) self._previousButton.setIcon(QIcon(resources.find('img/back.png'))) self._previousButton.setAutoRaise(True) self._previousButton.setToolTip('Find Previous') self._nextButton = QToolButton(self) self._nextButton.setIcon(QIcon(resources.find('img/forward.png'))) self._nextButton.setAutoRaise(True) self._nextButton.setToolTip('Find Next') self._caseSensitiveCheckbox = QCheckBox(self) self._caseSensitiveCheckbox.setText('Case Sensitive') self._wholeWordsCheckbox = QCheckBox(self) self._wholeWordsCheckbox.setText('Whole Words Only') self._regexCheckbox = QCheckBox(self) self._regexCheckbox.setText('Use Regex') self._findAction = QAction(self) self._findAction.setText('Find...') self._findAction.setIcon(QIcon(resources.find('img/search.png'))) self._findAction.setToolTip('Find in Text') self._findAction.setShortcut(QKeySequence('Ctrl+F')) self._findAction.setShortcutContext(Qt.WidgetWithChildrenShortcut) # layout the widgets layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self._closeButton) layout.addWidget(self._searchEdit) layout.addWidget(self._previousButton) layout.addWidget(self._nextButton) layout.addWidget(self._caseSensitiveCheckbox) layout.addWidget(self._wholeWordsCheckbox) layout.addWidget(self._regexCheckbox) self.setLayout(layout) # create connections self._findAction.triggered.connect(self.show) self._searchEdit.textChanged.connect(self.findNext) self._closeButton.clicked.connect(self.hide) self._previousButton.clicked.connect(self.findPrev) self._nextButton.clicked.connect(self.findNext) self._caseSensitiveCheckbox.clicked.connect(self.findNext) self._wholeWordsCheckbox.clicked.connect(self.findNext) self._searchEdit.returnPressed.connect(self.findNext) self._regexCheckbox.clicked.connect(self.findNext)
class XFindWidget(QWidget): """ """ __designer_icon__ = resources.find('img/search.png') def __init__( self, parent = None ): super(XFindWidget, self).__init__( parent ) # define custom properties self._textEdit = None self._webView = None self._lastCursor = QTextCursor() self._lastText = '' self._closeButton = QToolButton(self) self._closeButton.setIcon(QIcon(resources.find('img/close.png'))) self._closeButton.setAutoRaise(True) self._closeButton.setToolTip('Hide the Find Field.') self._searchEdit = XLineEdit(self) self._searchEdit.setHint('search for...') self._previousButton = QToolButton(self) self._previousButton.setIcon(QIcon(resources.find('img/back.png'))) self._previousButton.setAutoRaise(True) self._previousButton.setToolTip('Find Previous') self._nextButton = QToolButton(self) self._nextButton.setIcon(QIcon(resources.find('img/forward.png'))) self._nextButton.setAutoRaise(True) self._nextButton.setToolTip('Find Next') self._caseSensitiveCheckbox = QCheckBox(self) self._caseSensitiveCheckbox.setText('Case Sensitive') self._wholeWordsCheckbox = QCheckBox(self) self._wholeWordsCheckbox.setText('Whole Words Only') self._regexCheckbox = QCheckBox(self) self._regexCheckbox.setText('Use Regex') self._findAction = QAction(self) self._findAction.setText('Find...') self._findAction.setIcon(QIcon(resources.find('img/search.png'))) self._findAction.setToolTip('Find in Text') self._findAction.setShortcut(QKeySequence('Ctrl+F')) self._findAction.setShortcutContext(Qt.WidgetWithChildrenShortcut) # layout the widgets layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget( self._closeButton ) layout.addWidget( self._searchEdit ) layout.addWidget( self._previousButton ) layout.addWidget( self._nextButton ) layout.addWidget( self._caseSensitiveCheckbox ) layout.addWidget( self._wholeWordsCheckbox ) layout.addWidget( self._regexCheckbox ) self.setLayout(layout) # create connections self._findAction.triggered.connect( self.show ) self._searchEdit.textChanged.connect( self.findNext ) self._closeButton.clicked.connect( self.hide ) self._previousButton.clicked.connect( self.findPrev ) self._nextButton.clicked.connect( self.findNext ) self._caseSensitiveCheckbox.clicked.connect( self.findNext ) self._wholeWordsCheckbox.clicked.connect( self.findNext ) self._searchEdit.returnPressed.connect( self.findNext ) self._regexCheckbox.clicked.connect( self.findNext ) def find( self, flags = 0 ): """ Looks throught the text document based on the current criteria. The \ inputed flags will be merged with the generated search flags. :param flags | <QTextDocument.FindFlag> :return <bool> | success """ # check against the web and text views if ( not (self._textEdit or self._webView) ): fg = QColor('darkRed') bg = QColor('red').lighter(180) palette = self.palette() palette.setColor(palette.Text, fg) palette.setColor(palette.Base, bg) self._searchEdit.setPalette(palette) self._searchEdit.setToolTip( 'No Text Edit is linked.' ) return False if ( self._caseSensitiveCheckbox.isChecked() ): flags |= QTextDocument.FindCaseSensitively if ( self._textEdit and self._wholeWordsCheckbox.isChecked() ): flags |= QTextDocument.FindWholeWords terms = self._searchEdit.text() if ( terms != self._lastText ): self._lastCursor = QTextCursor() if ( self._regexCheckbox.isChecked() ): terms = QRegExp(terms) palette = self.palette() # search on a text edit if ( self._textEdit ): cursor = self._textEdit.document().find(terms, self._lastCursor, QTextDocument.FindFlags(flags)) found = not cursor.isNull() self._lastCursor = cursor self._textEdit.setTextCursor(cursor) elif ( QWebPage ): flags = QWebPage.FindFlags(flags) flags |= QWebPage.FindWrapsAroundDocument found = self._webView.findText(terms, flags) self._lastText = self._searchEdit.text() if ( not terms or found ): fg = palette.color(palette.Text) bg = palette.color(palette.Base) else: fg = QColor('darkRed') bg = QColor('red').lighter(180) palette.setColor(palette.Text, fg) palette.setColor(palette.Base, bg) self._searchEdit.setPalette(palette) return found def findNext( self ): """ Looks for the search terms that come up next based on the criteria. :return <bool> | success """ return self.find() def findPrev( self ): """ Looks for the search terms that come up last based on the criteria. :return <bool> | success """ return self.find(QTextDocument.FindBackward) def setTextEdit( self, textEdit ): """ Sets the text edit that this find widget will use to search. :param textEdit | <QTextEdit> """ if ( self._textEdit ): self._textEdit.removeAction(self._findAction) self._textEdit = textEdit if ( textEdit ): textEdit.addAction(self._findAction) def setWebView( self, webView ): """ Sets the web view edit that this find widget will use to search. :param webView | <QWebView> """ if ( self._webView ): self._webView.removeAction(self._findAction) self._webView = webView if ( webView ): webView.addAction(self._findAction) def show( self ): """ Sets this widget visible and then makes the find field have focus. """ super(XFindWidget, self).show() self._searchEdit.setFocus() def textEdit( self ): """ Returns the text edit linked with this find widget. :return <QTextEdit> """ return self._textEdit def webView( self ): """ Returns the text edit linked with this find widget. :return <QWebView> """ return self._webView
class XUrlWidget(QWidget): urlChanged = qt.Signal(str) urlEdited = qt.Signal() def __init__(self, parent): super(XUrlWidget, self).__init__(parent) # define the interface self._urlEdit = XLineEdit(self) self._urlButton = QToolButton(self) self._urlButton.setAutoRaise(True) self._urlButton.setIcon(QIcon(resources.find('img/web.png'))) self._urlButton.setToolTip('Browse Link') self._urlButton.setFocusPolicy(Qt.NoFocus) self._urlEdit.setHint('http://') layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(self._urlEdit) layout.addWidget(self._urlButton) self.setLayout(layout) self.setFocusPolicy(Qt.StrongFocus) # create connections self._urlEdit.textChanged.connect(self.urlChanged) self._urlEdit.textEdited.connect(self.urlEdited) self._urlButton.clicked.connect(self.browse) def blockSignals(self, state): """ Blocks the signals for this widget and its sub-parts. :param state | <bool> """ super(XUrlWidget, self).blockSignals(state) self._urlEdit.blockSignals(state) self._urlButton.blockSignals(state) def browse(self): """ Brings up a web browser with the address in a Google map. """ webbrowser.open(self.url()) def hint(self): """ Returns the hint associated with this widget. :return <str> """ return self._urlEdit.hint() def lineEdit(self): """ Returns the line edit linked with this widget. :return <XLineEdit> """ return self._urlEdit def setFocus(self): """ Sets the focus for this widget on its line edit. """ self._urlEdit.setFocus() @qt.Slot(str) def setHint(self, hint): """ Sets the hint associated with this widget. :param hint | <str> """ self._urlEdit.setHint(hint) @qt.Slot(str) def setUrl(self, url): """ Sets the url for this widget to the inputed url. :param url | <str> """ self._urlEdit.setText(str(url)) def url(self): """ Returns the current url from the edit. :return <str> """ return str(self._urlEdit.text()) x_hint = qt.Property(str, hint, setHint) x_url = qt.Property(str, url, setUrl)
def __init__( self, parent = None ): super(XFindWidget, self).__init__( parent ) # define custom properties self._textEdit = None self._webView = None self._lastCursor = QTextCursor() self._lastText = '' self._closeButton = QToolButton(self) self._closeButton.setIcon(QIcon(resources.find('img/close.png'))) self._closeButton.setAutoRaise(True) self._closeButton.setToolTip('Hide the Find Field.') self._searchEdit = XLineEdit(self) self._searchEdit.setHint('search for...') self._previousButton = QToolButton(self) self._previousButton.setIcon(QIcon(resources.find('img/back.png'))) self._previousButton.setAutoRaise(True) self._previousButton.setToolTip('Find Previous') self._nextButton = QToolButton(self) self._nextButton.setIcon(QIcon(resources.find('img/forward.png'))) self._nextButton.setAutoRaise(True) self._nextButton.setToolTip('Find Next') self._caseSensitiveCheckbox = QCheckBox(self) self._caseSensitiveCheckbox.setText('Case Sensitive') self._wholeWordsCheckbox = QCheckBox(self) self._wholeWordsCheckbox.setText('Whole Words Only') self._regexCheckbox = QCheckBox(self) self._regexCheckbox.setText('Use Regex') self._findAction = QAction(self) self._findAction.setText('Find...') self._findAction.setIcon(QIcon(resources.find('img/search.png'))) self._findAction.setToolTip('Find in Text') self._findAction.setShortcut(QKeySequence('Ctrl+F')) self._findAction.setShortcutContext(Qt.WidgetWithChildrenShortcut) # layout the widgets layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget( self._closeButton ) layout.addWidget( self._searchEdit ) layout.addWidget( self._previousButton ) layout.addWidget( self._nextButton ) layout.addWidget( self._caseSensitiveCheckbox ) layout.addWidget( self._wholeWordsCheckbox ) layout.addWidget( self._regexCheckbox ) self.setLayout(layout) # create connections self._findAction.triggered.connect( self.show ) self._searchEdit.textChanged.connect( self.findNext ) self._closeButton.clicked.connect( self.hide ) self._previousButton.clicked.connect( self.findPrev ) self._nextButton.clicked.connect( self.findNext ) self._caseSensitiveCheckbox.clicked.connect( self.findNext ) self._wholeWordsCheckbox.clicked.connect( self.findNext ) self._searchEdit.returnPressed.connect( self.findNext ) self._regexCheckbox.clicked.connect( self.findNext )
class XLocationWidget(QWidget): locationChanged = qt.Signal(str) locationEdited = qt.Signal() def __init__(self, parent): super(XLocationWidget, self).__init__(parent) # define the interface self._locationEdit = XLineEdit(self) self._locationButton = QToolButton(self) self._urlTemplate = 'http://maps.google.com/maps?%(params)s' self._urlQueryKey = 'q' self._locationButton.setAutoRaise(True) self._locationButton.setIcon(QIcon(resources.find('img/map.png'))) self._locationEdit.setHint('no location set') layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(self._locationEdit) layout.addWidget(self._locationButton) self.setLayout(layout) # create connections self._locationEdit.textChanged.connect(self.locationChanged) self._locationEdit.textEdited.connect(self.locationEdited) self._locationButton.clicked.connect(self.browseMaps) def blockSignals(self, state): """ Blocks the signals for this widget and its sub-parts. :param state | <bool> """ super(XLocationWidget, self).blockSignals(state) self._locationEdit.blockSignals(state) self._locationButton.blockSignals(state) def browseMaps(self): """ Brings up a web browser with the address in a Google map. """ url = self.urlTemplate() params = urllib.urlencode({self.urlQueryKey(): self.location()}) url = url % {'params': params} webbrowser.open(url) def hint(self): """ Returns the hint associated with this widget. :return <str> """ return self._locationEdit.hint() def lineEdit(self): """ Returns the line edit linked with this widget. :return <XLineEdit> """ return self._locationEdit def location(self): """ Returns the current location from the edit. :return <str> """ return str(self._locationEdit.text()) @qt.Slot(str) def setHint(self, hint): """ Sets the hint associated with this widget. :param hint | <str> """ self._locationEdit.setHint(hint) @qt.Slot(str) def setLocation(self, location): """ Sets the location for this widget to the inputed location. :param location | <str> """ self._locationEdit.setText(str(location)) def setUrlQueryKey(self, key): """ Sets the key for the URL to the inputed key. :param key | <str> """ self._urlQueryKey = str(key) def setUrlTemplate(self, templ): """ Sets the URL path template that will be used when looking up locations on the web. :param templ | <str> """ self._urlQueryTemplate = str(templ) def urlQueryKey(self): """ Returns the query key that will be used for this location. :return <str> """ return self._urlQueryKey def urlTemplate(self): """ Returns the url template that will be used when mapping this location. :return <str> """ return self._urlTemplate x_hint = qt.Property(str, hint, setHint) x_location = qt.Property(str, location, setLocation) x_urlQueryKey = qt.Property(str, urlQueryKey, setUrlQueryKey) x_urlTemplate = qt.Property(str, urlTemplate, setUrlTemplate)