def filterRegExpChanged(self): syntax_nr = self.filterSyntaxComboBox.currentData() pattern = self.filterPatternLineEdit.text() if syntax_nr == WILDCARD: pattern = QRegularExpression.wildcardToRegularExpression(pattern) elif syntax_nr == FIXED_STRING: pattern = QRegularExpression.escape(pattern) regExp = QRegularExpression(pattern) if not self.filterCaseSensitivityCheckBox.isChecked(): options = regExp.patternOptions() options |= QRegularExpression.CaseInsensitiveOption regExp.setPatternOptions(options) self.proxyModel.setFilterRegularExpression(regExp)
def apply_filter(self, text=None): """filter table to only show tests matching text""" if text is None: text = self.filter.text() if text: text = text.replace("(", "\(") text = text.replace(")", "\)") m = QRegularExpression(text) m.setPatternOptions(QRegularExpression.CaseInsensitiveOption) if m.isValid(): m.optimize() filter = lambda row_num: m.match( self.table.item(row_num, 0).text()).hasMatch() else: return else: filter = lambda row: True for i in range(0, self.table.rowCount()): self.table.setRowHidden(i, not filter(i))
def setupTabs(self): """ Setup the various tabs in the AddressWidget. """ groups = ["ABC", "DEF", "GHI", "JKL", "MNO", "PQR", "STU", "VW", "XYZ"] for group in groups: proxyModel = QSortFilterProxyModel(self) proxyModel.setSourceModel(self.tableModel) proxyModel.setDynamicSortFilter(True) tableView = QTableView() tableView.setModel(proxyModel) tableView.setSortingEnabled(True) tableView.setSelectionBehavior(QAbstractItemView.SelectRows) tableView.horizontalHeader().setStretchLastSection(True) tableView.verticalHeader().hide() tableView.setEditTriggers(QAbstractItemView.NoEditTriggers) tableView.setSelectionMode(QAbstractItemView.SingleSelection) # This here be the magic: we use the group name (e.g. "ABC") to # build the regex for the QSortFilterProxyModel for the group's # tab. The regex will end up looking like "^[ABC].*", only # allowing this tab to display items where the name starts with # "A", "B", or "C". Notice that we set it to be case-insensitive. re = QRegularExpression("^[{}].*".format(group)) assert re.isValid() re.setPatternOptions(QRegularExpression.CaseInsensitiveOption) proxyModel.setFilterRegularExpression(re) proxyModel.setFilterKeyColumn(0) # Filter on the "name" column proxyModel.sort(0, Qt.AscendingOrder) # This prevents an application crash (see: http://www.qtcentre.org/threads/58874-QListView-SelectionModel-selectionChanged-Crash) viewselectionmodel = tableView.selectionModel() tableView.selectionModel().selectionChanged.connect( self.selectionChanged) self.addTab(tableView, group)
def __init__(self, document=None): super().__init__(document) palette = QApplication.instance().palette("QTextEdit") # SQL Syntax highlighter rules # dict: pattern, font, color, minimal (not greedy) # TODO : What about dark mode ? self.highlighting_patterns = [ { # Keywords # \b allows to perform a "whole words only" "pattern": "|".join(("\\b%s\\b" % keyword for keyword in VqlSyntaxHighlighter.sql_keywords)), "font": QFont.Bold, "color": palette.color(QPalette.Highlight), # default: Qt.darkBlue "case_insensitive": True, }, { # Strings simple quotes '...' "pattern": r"\'.*\'", "color": Qt.red, "minimal": True, # Need to stop match as soon as possible }, { # Strings double quotes: "..." "pattern": r"\".*\"", "color": Qt.red, "minimal": True, # Need to stop match as soon as possible }, { # Numbers "pattern": r"\\b[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?\\b", "color": Qt.darkGreen, }, { # Comments "pattern": r"--[^\n]*", "color": Qt.gray, }, ] self.highlighting_rules = list() for pattern in self.highlighting_patterns: t_format = QTextCharFormat() font = pattern.get("font", None) if font: t_format.setFontWeight(font) color = pattern.get("color", None) if color: t_format.setForeground(color) regex = QRegularExpression(pattern["pattern"]) if pattern.get("minimal", False): # The greediness of the quantifiers is inverted: *, +, ?, {m,n}, etc. # become lazy, while their lazy versions (*?, +?, ??, {m,n}?, etc.) # become greedy. # https://doc.qt.io/Qt-5/qregularexpression.html#setPatternOptions regex.setPatternOptions( QRegularExpression.InvertedGreedinessOption) if pattern.get("case_insensitive", False): # NOTE: Deletes previous pattern options # Not serious in practice, this only concerns the keywords regex.setPatternOptions( QRegularExpression.CaseInsensitiveOption) self.highlighting_rules.append((regex, t_format))
class TypeChecker: def __init__(self, parent=None): self.bool_exp = QRegularExpression('^(true)|(false)$') assert self.bool_exp.isValid() self.bool_exp.setPatternOptions(QRegularExpression.CaseInsensitiveOption) self.byteArray_exp = QRegularExpression(r'^[\x00-\xff]*$') assert self.byteArray_exp.isValid() self.char_exp = QRegularExpression('^.$') assert self.char_exp.isValid() pattern = r'^[+-]?\d+$' self.int_exp = QRegularExpression(pattern) assert self.int_exp.isValid() pattern = r'^\(([0-9]*),([0-9]*),([0-9]*),([0-9]*)\)$' self.color_exp = QRegularExpression(pattern) assert self.color_exp.isValid() pattern = r'^\((-?[0-9]*),(-?[0-9]*)\)$' self.point_exp = QRegularExpression(pattern) assert self.point_exp.isValid() pattern = r'^\((-?[0-9]*),(-?[0-9]*),(-?[0-9]*),(-?[0-9]*)\)$' self.rect_exp = QRegularExpression(pattern) assert self.rect_exp.isValid() self.size_exp = QRegularExpression(self.point_exp) date_pattern = '([0-9]{,4})-([0-9]{,2})-([0-9]{,2})' self.date_exp = QRegularExpression('^{}$'.format(date_pattern)) assert self.date_exp.isValid() time_pattern = '([0-9]{,2}):([0-9]{,2}):([0-9]{,2})' self.time_exp = QRegularExpression('^{}$'.format(time_pattern)) assert self.time_exp.isValid() pattern = '^{}T{}$'.format(date_pattern, time_pattern) self.dateTime_exp = QRegularExpression(pattern) assert self.dateTime_exp.isValid() def type_from_text(self, text): if self.bool_exp.match(text).hasMatch(): return bool if self.int_exp.match(text).hasMatch(): return int return None def create_validator(self, value, parent): if isinstance(value, bool): return QRegularExpressionValidator(self.bool_exp, parent) if isinstance(value, float): return QDoubleValidator(parent) if isinstance(value, int): return QIntValidator(parent) if isinstance(value, QByteArray): return QRegularExpressionValidator(self.byteArray_exp, parent) if isinstance(value, QColor): return QRegularExpressionValidator(self.color_exp, parent) if isinstance(value, QDate): return QRegularExpressionValidator(self.date_exp, parent) if isinstance(value, QDateTime): return QRegularExpressionValidator(self.dateTime_exp, parent) if isinstance(value, QTime): return QRegularExpressionValidator(self.time_exp, parent) if isinstance(value, QPoint): return QRegularExpressionValidator(self.point_exp, parent) if isinstance(value, QRect): return QRegularExpressionValidator(self.rect_exp, parent) if isinstance(value, QSize): return QRegularExpressionValidator(self.size_exp, parent) return None def from_string(self, text, original_value): if isinstance(original_value, QColor): match = self.color_exp.match(text) return QColor(min(int(match.captured(1)), 255), min(int(match.captured(2)), 255), min(int(match.captured(3)), 255), min(int(match.captured(4)), 255)) if isinstance(original_value, QDate): value = QDate.fromString(text, Qt.ISODate) return value if value.isValid() else None if isinstance(original_value, QDateTime): value = QDateTime.fromString(text, Qt.ISODate) return value if value.isValid() else None if isinstance(original_value, QTime): value = QTime.fromString(text, Qt.ISODate) return value if value.isValid() else None if isinstance(original_value, QPoint): match = self.point_exp.match(text) return QPoint(int(match.captured(1)), int(match.captured(2))) if isinstance(original_value, QRect): match = self.rect_exp.match(text) return QRect(int(match.captured(1)), int(match.captured(2)), int(match.captured(3)), int(match.captured(4))) if isinstance(original_value, QSize): match = self.size_exp.match(text) return QSize(int(match.captured(1)), int(match.captured(2))) if isinstance(original_value, list): return text.split(',') return type(original_value)(text)