def init_ui(self): self.setWindowTitle("About") self.setFixedSize(550, 190) layout = QVBoxLayout() about_text = QLabel( "Here it is. In your hands you have music generator using neural network." "\nWith enough midi files you can create basically any kind of song." "\nFor more details and instruction visit our github by clicking this link: ", self) about_text.move(10, 20) link = QLabel() link.setText( '''<a href='https://github.com/Bananasis/PytonMusic-Inc.'>PytonMusic-Inc</a>''' ) link.setOpenExternalLinks(True) link.setAlignment(Qt.AlignCenter) authors_text = QLabel( "by: Dominika Szydło, Patryk Majewski, Ivan Feofilaktov and Gabriel Wechta." ) layout.addWidget(about_text) layout.addWidget(link) layout.addWidget(authors_text) main_widget = QWidget() main_widget.setLayout(layout) main_widget.adjustSize() # self.about_text.adjustSize() self.setCentralWidget(main_widget) self.center()
def adjust(self, width, height, scrollValue): QWidget.adjustSize(self) self.mwindow.adjustSize() self.mwindow.resize(width, height) if scrollValue: self.sequenceTable.verticalScrollBar().setScrollValue(value=scrollValue)
def restoreGeom( widget: QWidget, key: str, offset: Optional[int] = None, adjustSize: bool = False ) -> None: key += "Geom" if aqt.mw.pm.profile.get(key): widget.restoreGeometry(aqt.mw.pm.profile[key]) if isMac and offset: if qtminor > 6: # bug in osx toolkit s = widget.size() widget.resize(s.width(), s.height() + offset * 2) ensureWidgetInScreenBoundaries(widget) else: if adjustSize: widget.adjustSize()
def exceptionRaised(): ater = "N/C" from traceback import print_exc tps = int(time.time()) print_exc(file=open(f"./log/log_{tps}.txt", "w")) app_error = QApplication(sys.argv) win_error = QWidget() win_error.setGeometry(80, 80, 50, 50) win_error.setWindowTitle("Error Script") win_error.show() label_error = QLabel(win_error) label_error.setText( f"Une exception a été levée : {str(ater)}\n\n\n\n {open(f'./log/log_{tps}.txt').read()}" ) label_error.setStyleSheet("font-weight: bold;") label_error.setFont(QFont('Mangal', 10)) label_error.move(20, 20) label_error.adjustSize() label_error.show() temp = Online() del temp if Donnees.online_final: bouton_send_error = QPushButton(win_error) bouton_send_error.setText("Envoyer rapport d'erreur") bouton_send_error.clicked.connect( lambda: uploadftp(f"log_{tps}.txt", "./log/")) bouton_send_error.move(20, 60) bouton_send_error.show() win_error.adjustSize() sys.exit(app_error.exec_())
class GridWindow(QWidget): def __init__(self, dashboard): super(GridWindow, self).__init__(None) with open('dashboard/gui/stylesheet.txt', "r") as file: self.setStyleSheet(file.read()) self.setWindowTitle('Timing grid') self.setObjectName('timingGrid') self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.dashboard = dashboard self.picklable = False # self.dashboard.test_signal.connect(lambda: self.insert_step('test', 0)) # self.dashboard.test_signal.connect(lambda: self.swap_timesteps('load', 'probe')) self.layout = QVBoxLayout() self.setLayout(self.layout) self.selector_layout = QHBoxLayout() self.sequence_selector = QComboBox() for item in self.dashboard.get('artiq/sequences'): self.sequence_selector.addItem(item) self.sequence_selector.currentTextChanged.connect(self.activate) self.selector_layout.addWidget(self.sequence_selector) self.store_button = IconButton( 'dashboard/gui/media/Material/content-save.svg', self.store) self.selector_layout.addWidget(self.store_button) self.delete_button = IconButton( 'dashboard/gui/media/Material/trash.svg', self.delete) self.selector_layout.addWidget(self.delete_button) self.selector_layout.addWidget( IconButton('dashboard/gui/media/Material/content-add.svg', self.insert_step)) self.selector_layout.addWidget( IconButton('dashboard/gui/media/Material/outline-play-arrow.svg', self.play)) self.layout.addLayout(self.selector_layout) self.widget = QWidget() self.grid_layout = QGridLayout() self.widget.setLayout(self.grid_layout) self.layout.addWidget(self.widget) # self.add_table() self.add_labels() timesteps = self.dashboard.get('artiq/sequence') self.draw(timesteps) # self.dashboard.timestep_signal.connect(self.bold_active_step) self.dashboard.sequence_update_signal.connect(self.refresh) def activate(self, sequence): self.dashboard.post('artiq/activate', {'sequence': sequence}) def delete(self): name = self.sequence_selector.currentText() if name == 'default': return self.dashboard.post('artiq/delete', {'name': name}) self.sequence_selector.removeItem( self.sequence_selector.currentIndex()) def store(self): name, ok = QInputDialog.getText(self, 'New sequence', 'Enter preset name:') if not ok: return self.dashboard.post('artiq/store', {'name': name}) self.sequence_selector.addItem(name) self.sequence_selector.setCurrentIndex(self.sequence_selector.count() - 1) def push_sequence(self): self.dashboard.post('artiq/sequence', self.get_sequence()) def add_table(self): self.ttls = self.dashboard.get('artiq/ttl') self.table = SequencerTable() timesteps = self.dashboard.get('artiq/sequence') self.table.set_channels(self.ttls) for step in timesteps: self.table.add_timestep(self.ttls, step) self.grid_layout.addWidget(self.table, 0, 0) self.table.adjustSize() self.widget.adjustSize() self.adjustSize() def add_labels(self): ''' Create TTL labels ''' self.ttls = self.dashboard.get('artiq/ttl') label = BoldLabel('TTL') label.setBold(True) self.grid_layout.addWidget(label, 2, 0) row = 3 for ttl in self.ttls: name = str(ttl) if type(self.ttls) is dict: name += ': %s' % str(self.ttls[ttl]) self.grid_layout.addWidget(ttlLabel(name, channel=ttl, grid=self), row, 0) row += 1 ''' Create ADC labels ''' self.adcs = self.dashboard.get('artiq/adc') label = BoldLabel('ADC') label.setBold(True) self.grid_layout.addWidget(label, row, 0) row += 1 for adc in self.adcs: label = str(adc) if type(self.adcs) is dict: label += ': %s' % str(self.adcs[adc]) self.grid_layout.addWidget(QLabel(label), row, 0) row += 1 ''' Create DAC labels ''' self.dacs = self.dashboard.get('artiq/dac') label = BoldLabel('DAC') label.setBold(True) self.grid_layout.addWidget(label, row, 0) row += 1 for dac in self.dacs: self.grid_layout.addWidget(QLabel(str(dac)), row, 0) row += 1 # # ''' Create DDS labels ''' # self.dds = self.dashboard.get('artiq/dds') # self.grid_layout.addWidget(QLabel('DDS'), row, 0) # row += 1 # for dds in self.dds: # self.grid_layout.addWidget(QLabel(str(dds)), row, 0) # row += 1 def refresh(self, sequence=None): # if sequence is None: sequence = self.dashboard.get('artiq/sequence') self.redraw(sequence) def draw(self, sequence): self.order = [] self.labels = [] self.step_edits = [] self.checkboxes = [] self.adc_checkboxes = [] self.dac_edits = [] col = 1 row = 0 for step in sequence: row = self.add_step(step, col) col += 1 total_cycle_time = self.get_cycle_time() * 1000 self.total_time_label = QLabel('%.1f ms' % total_cycle_time) self.grid_layout.addWidget(QLabel('Cycle time:'), row, 0) self.grid_layout.addWidget(self.total_time_label, row, 1) # self.bold_active_step() QApplication.processEvents() # determine new minimumSize self.resize(self.minimumSize()) def redraw(self, sequence): for step in range(len(self.labels)): self.remove_step_widgets(step) self.grid_layout.removeWidget(self.total_time_label) self.total_time_label.deleteLater() self.draw(sequence) def update_cycle_time(self): total_cycle_time = self.get_cycle_time() * 1000 self.total_time_label.setText('%.1f ms' % total_cycle_time) def get_cycle_time(self): T = 0 for edit in self.step_edits: T += edit.magnitude return T def get_sequence(self): sequence = [] for i in range(len(self.labels)): name = self.labels[i].name new_step = {} new_step['duration'] = self.step_edits[i].magnitude new_step['name'] = name new_step['TTL'] = [] new_step['ADC'] = [] new_step['DAC'] = {} for ttl in self.ttls: if self.checkboxes[i][ttl].isChecked(): new_step['TTL'].append(ttl) for adc in self.adcs: if self.adc_checkboxes[i][adc].isChecked(): new_step['ADC'].append(adc) for dac in self.dacs: new_step['DAC'][int(dac)] = float( self.dac_edits[i][dac].text()) sequence.append(new_step) return sequence def add_step(self, step, col): name = step['name'] ''' Add label and edit ''' self.order.append(name) self.labels.append(StepLabel(name, self, col - 1)) self.grid_layout.addWidget(self.labels[-1], 0, col) self.step_edits.append( StepEdit(name, str(step['duration']), self.dashboard, self)) self.grid_layout.addWidget(self.step_edits[-1], 1, col) ''' Add TTL checkboxes ''' row = 3 self.checkboxes.append({}) for switch in self.ttls: state = 0 if int(switch) in step['TTL'] or str(switch) in step['TTL']: state = 1 box = StateCheckbox(name, step, state, self.dashboard, self) self.grid_layout.addWidget(box, row, col) self.checkboxes[-1][switch] = box row += 1 ''' Add ADC checkboxes ''' self.adc_checkboxes.append({}) row += 1 for adc in self.adcs: state = 0 if int(adc) in step['ADC'] or str(adc) in step['ADC']: state = 1 box = StateCheckbox(name, step, state, self.dashboard, self) self.grid_layout.addWidget(box, row, col) self.adc_checkboxes[-1][adc] = box row += 1 ''' Add DAC edits ''' self.dac_edits.append({}) row += 1 for dac in self.dacs: if int(dac) in step['DAC']: value = float(step['DAC'][int(dac)]) elif str(dac) in step['DAC']: value = float(step['DAC'][str(dac)]) else: value = 0.0 edit = DACEdit(name, str(value), self.dashboard, self) self.grid_layout.addWidget(edit, row, col) self.dac_edits[-1][dac] = edit row += 1 return row def remove_step(self, i): ''' Removes the step labeled by i ''' self.remove_step_widgets(i) self.step_edits.pop(i) self.labels.pop(i) self.checkboxes.pop(i) self.adc_checkboxes.pop(i) self.dac_edits.pop(i) for j in range(i, len(self.labels)): self.labels[j].index -= 1 self.redraw(self.get_sequence()) self.push_sequence() def remove_step_widgets(self, step): remove = [ self.labels[step], self.step_edits[step], *self.checkboxes[step].values(), *self.adc_checkboxes[step].values(), *self.dac_edits[step].values() ] # for ttl in self.ttls: # remove.append(self.checkboxes[step][ttl]) # for adc in self.adcs: # remove.append(self.adc_checkboxes[step][adc]) # for dac in self.dacs: # remove.append(self.dac_edits[step][dac]) for widget in remove: self.grid_layout.removeWidget(widget) widget.deleteLater() # # def bold_active_step(self, current_step=None): # steps = self.dashboard.get('artiq/sequence') # if current_step is None: # current_step = self.dashboard.get('artiq/current_step') # else: # current_step = current_step['name'] # for step in steps: # if step['name'] == current_step: # self.labels[step['name']].setBold(True) # else: # self.labels[step['name']].setBold(False) def insert_step(self, name=''): step = { 'name': '', 'duration': 0, 'TTL': [], 'ADC': [], 'DAC': {}, 'DDS': {} } steps = self.get_sequence() steps.append(step) self.redraw(steps) self.dashboard.post('artiq/sequence', steps) def move(self, step, n): ''' Moves the passed step (integer or string) n places to the left (negative n) or right (positive n). ''' steps = self.get_sequence() i = 0 for s in self.order: if s == step: break i += 1 if (i + n) < 0 or (i + n) > len(steps) - 1: return i_n = i for n0 in range(np.abs(n)): d_i = np.sign(n) adjacent_step = self.order[i_n + d_i] self.swap_timesteps(step, adjacent_step) steps.insert(i_n + d_i, steps.pop(i_n)) self.order.insert(i_n + d_i, self.order.pop(i_n)) i_n += d_i self.dashboard.post('artiq/sequence', steps) # def swap(self, row1, col1, row2, col2): # ''' Swaps two widgets ''' # widget1 = self.grid_layout.itemAtPosition(row1, col1).widget() # widget2 = self.grid_layout.itemAtPosition(row2, col2).widget() # self.grid_layout.removeWidget(widget1) # self.grid_layout.removeWidget(widget2) # self.grid_layout.addWidget(widget1, row2, col2) # self.grid_layout.addWidget(widget2, row1, col1) # # def swap_columns(self, col1, col2): # header_rows = [0, 1] # headers # ttl_rows = list(range(header_rows[-1]+2, header_rows[-1]+2+len(self.ttls))) # header_rows.extend(ttl_rows) # adc_rows = list(range(ttl_rows[-1]+2, ttl_rows[-1]+2+len(self.adcs))) # header_rows.extend(adc_rows) # dac_rows = list(range(adc_rows[-1]+2, adc_rows[-1]+2+len(self.dacs))) # header_rows.extend(dac_rows) # # for row in header_rows: # self.swap(row, col1, row, col2) # time.sleep(1e-6) # need a short pause here or Qt will crash # def swap_timesteps(self, name1, name2): # widget1 = self.labels[name1] # index1 = self.grid_layout.indexOf(widget1) # row1, col1, rowspan, colspan = self.grid_layout.getItemPosition(index1) # widget2 = self.labels[name2] # index2 = self.grid_layout.indexOf(widget2) # row2, col2, rowspan, colspan = self.grid_layout.getItemPosition(index2) # # self.swap_columns(col1, col2) def play(self): print(self.get_sequence()) import os os.system( 'start "" cmd /k "cd /emergent/emergent/artiq/ & call activate artiq-4 & artiq_run sequencer_loop.py"' )
class MainWindow(QMainWindow): def __init__(self, config: Config, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle("FolderPlay by Hurlenko") self.setWindowIcon(main_icon()) self.config = config self.central_widget = None self.set_style() self.basic_view_widget = BasicViewWidget(self) self.basic_view_widget.btn_advanced.clicked.connect( self.toggle_advanced_view ) self.settings_widget = SettingsWidget(self) self.settings_widget.hide() # Media list self.lst_media = QListWidget(self) self.setup_files_list() # Left Pane self.left_pane = QWidget(self) self.left_pane.setLayout(self.left_pane_layout()) self.left_pane.layout().setContentsMargins(0, 0, 0, 0) self.left_pane.layout().setSpacing(0) # Right pane self.right_pane = QWidget(self) self.right_pane.setLayout(self.right_pane_layout()) self.right_pane.layout().setContentsMargins(0, 0, 0, 0) self.right_pane.layout().setSpacing(0) self.right_pane.hide() average_char_width = self.fontMetrics().averageCharWidth() self.left_pane_width = average_char_width * (MAX_MOVIE_TITLE_LENGTH + 5) self.right_pane_width = self.left_pane_width * 2 self.left_pane.setFixedWidth(self.left_pane_width) self.right_pane.setFixedWidth(self.right_pane_width) self.central_widget.setLayout(self.advanced_view_layout()) def set_style(self): icons = IconSet[self.config.iconset] IconSet.set_current(icons) style = Style[self.config.style] if style in (Style.dark, Style.light): self.central_widget = ModernWindow(self) else: self.central_widget = QWidget(self) style.apply(QApplication.instance()) self.setCentralWidget(self.central_widget) def left_pane_layout(self): layout = QVBoxLayout() layout.addWidget(self.basic_view_widget) layout.addWidget(self.settings_widget) return layout def right_pane_layout(self): layout = QVBoxLayout() layout.addWidget(self.lst_media) return layout def advanced_view_layout(self): layout = QHBoxLayout() layout.addWidget(self.left_pane) layout.addWidget(self.right_pane) return layout def center(self): frame_gm = self.frameGeometry() screen = QApplication.desktop().screenNumber( QApplication.desktop().cursor().pos() ) center_point = QApplication.desktop().screenGeometry(screen).center() frame_gm.moveCenter(center_point) self.move(frame_gm.topLeft()) def toggle_advanced_view(self): # QApplication.processEvents(QEventLoop.ExcludeUserInputEvents) # self.adjustSize() if not self.basic_view_widget.btn_advanced.isChecked(): self.settings_widget.hide() self.right_pane.hide() else: self.settings_widget.show() self.right_pane.show() self.reset() def reset(self): QApplication.processEvents(QEventLoop.ExcludeUserInputEvents) self.adjustSize() # https://stackoverflow.com/a/30472749/8014793 # self.setFixedSize(self.layout().sizeHint()) # self.central_widget.adjustSize() QApplication.processEvents(QEventLoop.ExcludeUserInputEvents) self.central_widget.adjustSize() QApplication.processEvents(QEventLoop.ExcludeUserInputEvents) self.setFixedSize(self.layout().sizeHint()) # self.setFixedSize(self.central_widget.sizeHint()) self.center() def setup_play_button(self): self.btn_play.setIcon(IconSet.current.play) self.btn_play.setIconSize(QSize(100, 100)) def setup_files_list(self): size_policy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.lst_media.setSizePolicy(size_policy) self.lst_media.setSelectionMode(QAbstractItemView.ExtendedSelection) # self.lst_media.setSortingEnabled(True) self.lst_media.setContextMenuPolicy(Qt.CustomContextMenu)
class PyRegExpWizardCharactersDialog( QDialog, Ui_PyRegExpWizardCharactersDialog): """ Class implementing a dialog for entering character classes. """ specialChars = { 4: "\\a", 5: "\\f", 6: "\\n", 7: "\\r", 8: "\\t", 9: "\\v" } predefinedClasses = ["\\s", "\\S", "\\w", "\\W", "\\d", "\\D"] def __init__(self, parent=None): """ Constructor @param parent parent widget (QWidget) """ super(PyRegExpWizardCharactersDialog, self).__init__(parent) self.setupUi(self) self.comboItems = [] self.singleComboItems = [] # these are in addition to the above self.comboItems.append(self.tr("Normal character")) self.comboItems.append( self.tr("Unicode character in hexadecimal notation")) self.comboItems.append( self.tr("Unicode character in octal notation")) self.singleComboItems.append(self.tr("---")) self.singleComboItems.append(self.tr("Bell character (\\a)")) self.singleComboItems.append(self.tr("Page break (\\f)")) self.singleComboItems.append(self.tr("Line feed (\\n)")) self.singleComboItems.append(self.tr("Carriage return (\\r)")) self.singleComboItems.append(self.tr("Horizontal tabulator (\\t)")) self.singleComboItems.append(self.tr("Vertical tabulator (\\v)")) self.charValidator = QRegExpValidator(QRegExp(".{0,1}"), self) self.hexValidator = QRegExpValidator(QRegExp("[0-9a-fA-F]{0,4}"), self) self.octValidator = QRegExpValidator(QRegExp("[0-3]?[0-7]{0,2}"), self) # generate dialog part for single characters self.singlesBoxLayout = QVBoxLayout(self.singlesBox) self.singlesBoxLayout.setObjectName("singlesBoxLayout") self.singlesBoxLayout.setSpacing(6) self.singlesBoxLayout.setContentsMargins(6, 6, 6, 6) self.singlesBox.setLayout(self.singlesBoxLayout) self.singlesView = QScrollArea(self.singlesBox) self.singlesView.setObjectName("singlesView") self.singlesBoxLayout.addWidget(self.singlesView) self.singlesItemsBox = QWidget(self) self.singlesView.setWidget(self.singlesItemsBox) self.singlesItemsBox.setObjectName("singlesItemsBox") self.singlesItemsBoxLayout = QVBoxLayout(self.singlesItemsBox) self.singlesItemsBoxLayout.setContentsMargins(6, 6, 6, 6) self.singlesItemsBoxLayout.setSpacing(6) self.singlesItemsBox.setLayout(self.singlesItemsBoxLayout) self.singlesEntries = [] self.__addSinglesLine() hlayout0 = QHBoxLayout() hlayout0.setContentsMargins(0, 0, 0, 0) hlayout0.setSpacing(6) hlayout0.setObjectName("hlayout0") self.moreSinglesButton = QPushButton( self.tr("Additional Entries"), self.singlesBox) self.moreSinglesButton.setObjectName("moreSinglesButton") hlayout0.addWidget(self.moreSinglesButton) hspacer0 = QSpacerItem( 30, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) hlayout0.addItem(hspacer0) self.singlesBoxLayout.addLayout(hlayout0) self.moreSinglesButton.clicked.connect(self.__addSinglesLine) # generate dialog part for character ranges self.rangesBoxLayout = QVBoxLayout(self.rangesBox) self.rangesBoxLayout.setObjectName("rangesBoxLayout") self.rangesBoxLayout.setSpacing(6) self.rangesBoxLayout.setContentsMargins(6, 6, 6, 6) self.rangesBox.setLayout(self.rangesBoxLayout) self.rangesView = QScrollArea(self.rangesBox) self.rangesView.setObjectName("rangesView") self.rangesBoxLayout.addWidget(self.rangesView) self.rangesItemsBox = QWidget(self) self.rangesView.setWidget(self.rangesItemsBox) self.rangesItemsBox.setObjectName("rangesItemsBox") self.rangesItemsBoxLayout = QVBoxLayout(self.rangesItemsBox) self.rangesItemsBoxLayout.setContentsMargins(6, 6, 6, 6) self.rangesItemsBoxLayout.setSpacing(6) self.rangesItemsBox.setLayout(self.rangesItemsBoxLayout) self.rangesEntries = [] self.__addRangesLine() hlayout1 = QHBoxLayout() hlayout1.setContentsMargins(0, 0, 0, 0) hlayout1.setSpacing(6) hlayout1.setObjectName("hlayout1") self.moreRangesButton = QPushButton( self.tr("Additional Entries"), self.rangesBox) self.moreSinglesButton.setObjectName("moreRangesButton") hlayout1.addWidget(self.moreRangesButton) hspacer1 = QSpacerItem( 30, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) hlayout1.addItem(hspacer1) self.rangesBoxLayout.addLayout(hlayout1) self.moreRangesButton.clicked.connect(self.__addRangesLine) def __addSinglesLine(self): """ Private slot to add a line of entry widgets for single characters. """ hbox = QWidget(self.singlesItemsBox) hboxLayout = QHBoxLayout(hbox) hboxLayout.setContentsMargins(0, 0, 0, 0) hboxLayout.setSpacing(6) hbox.setLayout(hboxLayout) cb1 = QComboBox(hbox) cb1.setEditable(False) cb1.addItems(self.comboItems) cb1.addItems(self.singleComboItems) hboxLayout.addWidget(cb1) le1 = QLineEdit(hbox) le1.setValidator(self.charValidator) hboxLayout.addWidget(le1) cb2 = QComboBox(hbox) cb2.setEditable(False) cb2.addItems(self.comboItems) cb2.addItems(self.singleComboItems) hboxLayout.addWidget(cb2) le2 = QLineEdit(hbox) le2.setValidator(self.charValidator) hboxLayout.addWidget(le2) self.singlesItemsBoxLayout.addWidget(hbox) cb1.activated[int].connect(self.__singlesCharTypeSelected) cb2.activated[int].connect(self.__singlesCharTypeSelected) hbox.show() self.singlesItemsBox.adjustSize() self.singlesEntries.append([cb1, le1]) self.singlesEntries.append([cb2, le2]) def __addRangesLine(self): """ Private slot to add a line of entry widgets for character ranges. """ hbox = QWidget(self.rangesItemsBox) hboxLayout = QHBoxLayout(hbox) hboxLayout.setContentsMargins(0, 0, 0, 0) hboxLayout.setSpacing(6) hbox.setLayout(hboxLayout) cb1 = QComboBox(hbox) cb1.setEditable(False) cb1.addItems(self.comboItems) hboxLayout.addWidget(cb1) l1 = QLabel(self.tr("Between:"), hbox) hboxLayout.addWidget(l1) le1 = QLineEdit(hbox) le1.setValidator(self.charValidator) hboxLayout.addWidget(le1) l2 = QLabel(self.tr("And:"), hbox) hboxLayout.addWidget(l2) le2 = QLineEdit(hbox) le2.setValidator(self.charValidator) hboxLayout.addWidget(le2) self.rangesItemsBoxLayout.addWidget(hbox) cb1.activated[int].connect(self.__rangesCharTypeSelected) hbox.show() self.rangesItemsBox.adjustSize() self.rangesEntries.append([cb1, le1, le2]) def __performSelectedAction(self, index, lineedit): """ Private method performing some actions depending on the input. @param index selected list index (integer) @param lineedit line edit widget to act on (QLineEdit) """ if index < 3: lineedit.setEnabled(True) if index == 0: lineedit.setValidator(self.charValidator) elif index == 1: lineedit.setValidator(self.hexValidator) elif index == 2: lineedit.setValidator(self.octValidator) elif index > 3: lineedit.setEnabled(False) lineedit.clear() def __singlesCharTypeSelected(self, index): """ Private slot to handle the activated(int) signal of the single chars combo boxes. @param index selected list index (integer) """ combo = self.sender() for entriesList in self.singlesEntries: if combo == entriesList[0]: self.__performSelectedAction(index, entriesList[1]) break def __rangesCharTypeSelected(self, index): """ Private slot to handle the activated(int) signal of the char ranges combo boxes. @param index selected list index (integer) """ combo = self.sender() for entriesList in self.rangesEntries: if combo == entriesList[0]: self.__performSelectedAction(index, entriesList[1]) self.__performSelectedAction(index, entriesList[2]) break def __formatCharacter(self, index, char): """ Private method to format the characters entered into the dialog. @param index selected list index (integer) @param char character string enetered into the dialog (string) @return formated character string (string) """ if index == 0: return char elif index == 1: return "\\x{0}".format(char.lower()) elif index == 2: return "\\0{0}".format(char) else: try: return self.specialChars[index] except KeyError: return "" def getCharacters(self): """ Public method to return the character string assembled via the dialog. @return formatted string for character classes (string) """ regexp = "" # negative character range if self.negativeCheckBox.isChecked(): regexp += "^" # predefined character ranges if self.wordCharCheckBox.isChecked(): regexp += "\\w" if self.nonWordCharCheckBox.isChecked(): regexp += "\\W" if self.digitsCheckBox.isChecked(): regexp += "\\d" if self.nonDigitsCheckBox.isChecked(): regexp += "\\D" if self.whitespaceCheckBox.isChecked(): regexp += "\\s" if self.nonWhitespaceCheckBox.isChecked(): regexp += "\\S" # single characters for entrieslist in self.singlesEntries: index = entrieslist[0].currentIndex() char = entrieslist[1].text() regexp += self.__formatCharacter(index, char) # character ranges for entrieslist in self.rangesEntries: if entrieslist[1].text() == "" or \ entrieslist[2].text() == "": continue index = entrieslist[0].currentIndex() char1 = entrieslist[1].text() char2 = entrieslist[2].text() regexp += "{0}-{1}".format( self.__formatCharacter(index, char1), self.__formatCharacter(index, char2)) if regexp: if (len(regexp) == 2 and (regexp in self.predefinedClasses or regexp in self.specialChars)) or \ len(regexp) == 1: return regexp else: return "[{0}]".format(regexp) else: return ""
class Ui_SmainWindow(object): def setupUi(self, SmainWindow): width = QDesktopWidget().screenGeometry().width() height = QDesktopWidget().screenGeometry().height() '''screen_resolution = app.desktop().screenGeometry() width, height = screen_resolution.width(), screen_resolution.height()''' SmainWindow.setObjectName("SmainWindow") SmainWindow.resize((3400/3840)*width,(1700/2160)*height) SmainWindow.setMaximumSize(QtCore.QSize((3400/3840)*width,(1700/2160)*height)) SmainWindow.setMinimumSize(QtCore.QSize((3400/3840)*width,(1700/2160)*height)) self.centralwidget = QtWidgets.QWidget(SmainWindow) self.centralwidget.setObjectName("centralwidget") self.line = QtWidgets.QFrame(self.centralwidget) self.line.setGeometry(QtCore.QRect((20/3840)*width, (1070/2160)*height ,(3300/3840)*width, (30/2160)*height)) self.line.setFrameShape(QtWidgets.QFrame.HLine) self.line.setFrameShadow(QtWidgets.QFrame.Sunken) self.line.setLineWidth(5) self.line.setObjectName("line") self.line2 = QtWidgets.QFrame(self.centralwidget) self.line2.setGeometry(QtCore.QRect((1440/3840)*width, (290/2160)*height ,(30/3840)*width, (700/2160)*height)) self.line2.setFrameShape(QtWidgets.QFrame.VLine) self.line2.setFrameShadow(QtWidgets.QFrame.Sunken) self.line2.setLineWidth(5) self.line2.setObjectName("line2") self.line3 = QtWidgets.QFrame(self.centralwidget) self.line3.setGeometry(QtCore.QRect((2290/3840)*width, (290/2160)*height ,(30/3840)*width, (700/2160)*height)) self.line3.setFrameShape(QtWidgets.QFrame.VLine) self.line3.setFrameShadow(QtWidgets.QFrame.Sunken) self.line3.setLineWidth(5) self.line3.setObjectName("line3") self.layout = QVBoxLayout(self.centralwidget) self.fig = Figure(figsize=((8/3840)*width, (6.5/2160)*height )) self.canvas = FigureCanvas(self.fig) self.layout.addWidget(self.canvas) self.widget = QWidget(self.centralwidget) #self.toolbar = NavigationToolbar(self.canvas, self.widget) self.layout.setMenuBar(NavigationToolbar(self.canvas,self.widget)) self.widget.setLayout(self.layout) self.widget.setGeometry((1480/3840)*width,(290/2160)*height,(800/3840)*width,(600/2160)*height) #layout.addWidget(self.canvas) ''' self.graphicsView = PlotWidget(self.centralwidget) self.graphicsView.setGeometry(QtCore.QRect(700, 150, 700, 700)) self.graphicsView.setObjectName("graphicsView") ''' self.chartView = QChartView(self.centralwidget) self.chartView.setGeometry(QtCore.QRect((200/3840)*width, (1090/2160)*height, (1700/3840)*width, (500/2160)*height)) self.chartView.setObjectName("graphicsView") self.browseFile = QtWidgets.QPushButton(self.centralwidget) self.browseFile.setGeometry(QtCore.QRect((200/3840)*width, (50/2160)*height, (350/3840)*width, (50/2160)*height)) self.browseFile.setObjectName("browseFile") self.filenameLabel = QtWidgets.QLabel(self.centralwidget) self.filenameLabel.setGeometry(QtCore.QRect((700/3840)*width, (55/2160)*height, (350/3840)*width, (70/2160)*height)) self.filenameLabel.setObjectName("filenameLabel") self.datasize = QtWidgets.QLabel(self.centralwidget) self.datasize.setGeometry(QtCore.QRect((20/3840)*width, (105/2160)*height, (350/3840)*width, (70/2160)*height)) self.datasize.setObjectName("datasize") self.datasize.setText("Data Shape :") self.datasize.setStyleSheet( """QLabel { font: bold; font-size: 10pt; font-family: Typograf;}""") self.datashape = QtWidgets.QLabel(self.centralwidget) self.datashape.setGeometry(QtCore.QRect((250/3840)*width, (105/2160)*height, (350/3840)*width, (70/2160)*height)) self.datashape.setObjectName("datashape") self.datashape.setStyleSheet( """QLabel { font: bold; font-size: 12pt; font-family: Typograf;}""") self.atributelabe = QtWidgets.QLabel(self.centralwidget) self.atributelabe.setGeometry(QtCore.QRect((295/3840)*width, (200/2160)*height, (350/3840)*width, (70/2160)*height)) self.atributelabe.setObjectName("atributelabe") self.atributelabe.setText("Variables") self.atributelabe.setStyleSheet( """QLabel { font: bold; font-size: 10pt; font-family: Typograf;}""") self.statisticlabel = QtWidgets.QLabel(self.centralwidget) self.statisticlabel.setGeometry(QtCore.QRect((1020/3840)*width, (200/2160)*height, (350/3840)*width, (70/2160)*height)) self.statisticlabel.setObjectName("statisticlabel") self.statisticlabel.setText("Statistics") self.statisticlabel.setStyleSheet( """QLabel { font: bold; font-size: 10pt; font-family: Typograf;}""") self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget) self.textBrowser.setGeometry(QtCore.QRect((740/3840)*width, (290/2160)*height, (700/3840)*width, (700/2160)*height)) self.textBrowser.setObjectName("textBrowser") self.textBrowser.setStyleSheet( """QTextBrowser { font: bold; font-size: 12pt; font-family: Courier;}""") self.missingvalulabel = QtWidgets.QLabel(self.centralwidget) self.missingvalulabel.setGeometry(QtCore.QRect((2330/3840)*width, (500/2160)*height, (250/3840)*width, (100/2160)*height)) self.missingvalulabel.setObjectName("missingvalulabel") self.missingvalulabel.setText("Show Missing \nValues") self.missingvalulabel.setStyleSheet( """QLabel { font: bold; font-size: 10pt; font-family: Courier;}""") self.resetbtn = QtWidgets.QPushButton(self.centralwidget) self.resetbtn.setGeometry(QtCore.QRect((2330/3840)*width, (300/2160)*height, (250/3840)*width, (50/2160)*height)) self.resetbtn.setObjectName("resetbtn") self.resetbtn.setText("Reset") self.resetbtn.setEnabled(False) self.perclm = QtWidgets.QPushButton(self.centralwidget) self.perclm.setGeometry(QtCore.QRect((2330/3840)*width, (600/2160)*height, (250/3840)*width, (50/2160)*height)) self.perclm.setObjectName("perclm") self.perclm.setText("PerColumn") self.perclm.setEnabled(False) self.perrow = QtWidgets.QPushButton(self.centralwidget) self.perrow.setGeometry(QtCore.QRect((2330/3840)*width, (670/2160)*height, (250/3840)*width, (50/2160)*height)) self.perrow.setObjectName("perrow") self.perrow.setText("PerRow") self.perrow.setEnabled(False) self.datainfo = QtWidgets.QLabel(self.centralwidget) self.datainfo.setGeometry(QtCore.QRect((2850/3840)*width, (200/2160)*height, (350/3840)*width, (70/2160)*height)) self.datainfo.setObjectName("statisticlabel") self.datainfo.setText("Data Info") self.datainfo.setStyleSheet( """QLabel { font: bold; font-size: 10pt; font-family: Typograf;}""") self.infor = QtWidgets.QTextBrowser(self.centralwidget) self.infor.setGeometry(QtCore.QRect((2600/3840)*width, (290/2160)*height, (700/3840)*width, (700/2160)*height)) self.infor.setObjectName("infor") self.infor.setStyleSheet( """QTextBrowser { font: bold; font-family: Courier;}""") self.calstatistics = QtWidgets.QPushButton(self.centralwidget) self.calstatistics.setGeometry(QtCore.QRect((200/3840)*width, (1020/2160)*height, (350/3840)*width, (50/2160)*height)) self.calstatistics.setObjectName("calstatistics") self.listWidget = QtWidgets.QListWidget(self.centralwidget) self.listWidget.setGeometry(QtCore.QRect((20/3840)*width, (290/2160)*height, (700/3840)*width, (700/2160)*height)) self.listWidget.setObjectName("listWidget") self.listWidget.setAlternatingRowColors(True) self.comboBox = QtWidgets.QComboBox(self.centralwidget) self.comboBox.setGeometry(QtCore.QRect((1480/3840)*width,(120/2160)*height,(800/3840)*width,(50/2160)*height)) self.comboBox.setObjectName("comboBox") self.comboBox2 = QtWidgets.QComboBox(self.centralwidget) self.comboBox2.setGeometry(QtCore.QRect((1480/3840)*width,(200/2160)*height,(800/3840)*width,(50/2160)*height)) self.comboBox2.setObjectName("comboBox2") self.report = QtWidgets.QPushButton(self.centralwidget) self.report.setGeometry(QtCore.QRect((1700/3840)*width, (1020/2160)*height, (300/3840)*width, (50/2160)*height)) self.report.setObjectName("report") self.report.setText("Generate Report") self.back = QtWidgets.QPushButton(self.centralwidget) self.back.setGeometry(QtCore.QRect((5/3840)*width, (1600/2160)*height, (300/3840)*width, (50/2160)*height)) self.back.setObjectName("back") self.back.setText("Back") self.back.setStyleSheet( """QPushButton { border-radius:0; border:0; text-align:left; padding-left:70px; qproperty-icon:url('back.png'); qproperty-iconSize: 40px 40px;}""") SmainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(SmainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, (469/3840)*width, (22/2160)*height)) self.menubar.setObjectName("menubar") SmainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(SmainWindow) self.statusbar.setObjectName("statusbar") SmainWindow.setStatusBar(self.statusbar) self.retranslateUi(SmainWindow) QtCore.QMetaObject.connectSlotsByName(SmainWindow) def retranslateUi(self, SmainWindow): _translate = QtCore.QCoreApplication.translate SmainWindow.setWindowTitle(_translate("SmainWindow", "Data Statistical Analysis")) self.browseFile.setText(_translate("SmainWindow", "Open File")) self.browseFile.clicked.connect(self.pushButton_handler) self.filenameLabel.setText(_translate("SmainWindow", "")) self.calstatistics.setText(_translate("SmainWindow", "Calculate Statistics")) self.calstatistics.clicked.connect(self.cal) self.listWidget.clicked.connect(self.listview_clicked) self.resetbtn.clicked.connect(self.information) self.perclm.clicked.connect(self.num_missing) self.perrow.clicked.connect(self.row_missing) self.report.clicked.connect(self.generatereport) def pushButton_handler(self): self.open_dialog_box() def open_dialog_box(self): filename = QFileDialog.getOpenFileName(None, 'Open File', r"~/Desktop", '*.csv') path = filename[0] with open(path, "r") as fpath: self.infor.clear() self.comboBox.clear() self.comboBox2.clear() self.datasetheaders=[] self.filenameLabel.setText(str(path)) self.filenameLabel.adjustSize() pandas.set_option('display.max_rows', None) self.dataset=pandas.read_csv(fpath) buf = io.StringIO() self.dataset.info(verbose=True, null_counts=True,buf=buf) s = buf.getvalue() self.perclm.setDisabled(False) self.perrow.setDisabled(False) self.infor.append(s) SIZE=self.dataset.shape self.datashape.setText(str(SIZE)) self.create_piechart() #headers=self.dataset.columns self.datasetheaders=self.dataset.columns.to_numpy() self.listWidget.clear() for i in range(len(self.datasetheaders)-1): self.listWidget.insertItem(i,self.datasetheaders[i]) for i in range(len(self.datasetheaders)-1): self.comboBox.addItem(self.datasetheaders[i]) for i in range(len(self.datasetheaders)-1): self.comboBox2.addItem(self.datasetheaders[i]) self.setup() self.comboBox.currentIndexChanged.connect(self.setup) self.comboBox2.currentIndexChanged.connect(self.setup) #print(unique_headers) '''print ("Missing values per column:") print(self.dataset.apply(lambda x: sum(x.isnull()))) ''' def generatereport(self): try: profile = ProfileReport(self.dataset) profile.to_file(output_file="AnalysisReport.html") print("yes") except Exception as e: print(repr(e)) def information(self): self.infor.clear() self.resetbtn.setEnabled(False) self.perrow.setDisabled(False) self.perclm.setDisabled(False) buf = io.StringIO() self.dataset.info(verbose=True, null_counts=True,buf=buf) s = buf.getvalue() self.infor.append(s) def row_missing(self): self.perrow.setEnabled(False) self.perclm.setDisabled(False) self.resetbtn.setDisabled(False) self.infor.clear() #self.infor.append(str(self.dataset.apply(lambda x: sum(x.isnull())))) self.infor.append(str(self.dataset.apply(self.missing, axis=1))) def num_missing(self): self.perclm.setEnabled(False) self.perrow.setDisabled(False) self.resetbtn.setDisabled(False) self.infor.clear() #self.infor.append(str(self.dataset.apply(lambda x: sum(x.isnull())))) self.infor.append(str(self.dataset.apply(self.missing, axis=0))) def missing(self,x): return sum(x.isnull()) def setup(self): try: print("fig") iris=self.dataset x_index = 0 y_index = 1 w=iris.iloc[:,self.comboBox.currentIndex()] z=iris.iloc[:,self.comboBox2.currentIndex()] y=iris.iloc[:,-1].values # this formatter will label the colorbar with the correct target names #formatter = plt.FuncFormatter(y) #plt.figure(figsize=(5, 4)) ax = self.fig.add_subplot(111) ax.clear() scatter=ax.scatter(w, z, c=y) #self.figure.colorbar(ticks=y) #ax.xlabel("iris.feature_names[x_index]") #ax.ylabel("iris.feature_names[y_index]") ax.set_xlabel(self.comboBox.currentText(), fontsize=25) ax.set_ylabel(self.comboBox2.currentText(), fontsize=25) ax.set_title('Scatter Plot',fontsize=25) legend1 = ax.legend(*scatter.legend_elements(), loc="lower left", title="Classes") ax.add_artist(legend1) self.widget.adjustSize() print("fig123456789") except Exception as e: print(repr(e)) def cal(self): #self.graphicsView.clear() z=self.dataset w=z.iloc[:,self.a] self.textBrowser.setText("Mean:\n"+str(np.mean(w))+"\nMedian:\n"+str(np.median(w))+"\nMode:\n"+str(stats.mode(w))+"\nvariance:\n"+str(np.var(w))+"\nStdev:\n"+str(np.std(w))) #self.textBrowser.adjustSize() ''' pen = pg.mkPen(color=(255, 0, 0),width=8) self.graphicsView.setBackground('w') self.graphicsView.plot(w,symbol='+',symbolSize=30, pen=pen) ''' def listview_clicked(self): item=self.listWidget.currentRow() self.a=item def create_piechart(self): z=self.dataset w=z.iloc[:,-1] r=w.value_counts() p=r.to_numpy() y=w.nunique() df_val_counts = pandas.DataFrame(r) df_val_counts = df_val_counts.reset_index() df_val_counts.columns = ['unique_values', 'counts'] w=df_val_counts.iloc[:,0].to_numpy() k=df_val_counts.iloc[:,1].to_numpy() res = w.astype(str) series = QPieSeries() for i in range(y): series.append(res[i], k[i]) chart = self.chartView.chart() chart.removeAllSeries() chart.legend().hide() chart.addSeries(series) chart.createDefaultAxes() chart.setAnimationOptions(QChart.AllAnimations) chart.setTitle("Pie Chart") chart.legend().setVisible(True) chart.legend().setAlignment(Qt.AlignBottom) #self.chartView = QChartView(chart) self.chartView.setRenderHint(QPainter.Antialiasing)
class PythonTogether: def __init__(self, win: QMainWindow, winParent: QWidget, open: QWidget) -> None: """ Tous les utilitaires pour PTProject """ self.win = win self.winParent = winParent self.open = open self.online = Online() self.winParent.setVisible(False) self.win.setWindowTitle("Python Together") self.a, self.b = 1280, 720 self.x, self.y = center(self.a, self.b) self.win.setGeometry(self.x, self.y, self.a, self.b) self.win.show() self.label = QLabel(self.win) self.label.setText("Python Together 0.1") self.label.setFont(QFont('Mangal', 50)) self.label.adjustSize() self.label.show() self.label.move(20,10) self.bouton1 = QPushButton(self.win) self.bouton1.setText("Revenir en arrière") self.bouton1.move(20, 100) self.bouton1.adjustSize() self.bouton1.clicked.connect( lambda: (self.winParent.setVisible(True), self.win.close())) self.bouton1.show() self.winEdit = QWidget(self.win) self.winEdit.setGeometry(0, 120, 1260, 600) self.winEdit.adjustSize() self.winEdit.show() self.layout = QVBoxLayout(self.winEdit) self.textEdit = QTextEdit() # self.text.move(20, 120) self.textEdit.setFont(QFont('Mangal', 15)) self.textEdit.show() self.layout.addWidget(self.textEdit) self.winEdit.setLayout(self.layout) self.menuBar = QMenuBar(self.win) self.win.setMenuBar(self.menuBar) # Menu Bar self.fileMenu = QMenu("&Fichier", self.win) self.openAction = QAction("&Ouvrir", self.win) self.openAction.triggered.connect(self.openproject) self.openAction.setShortcut("Ctrl+O") self.saveAction = QAction("&Sauvegarder", self.win) self.saveAction.triggered.connect(self.saveFile) self.saveAction.setShortcut("Ctrl+S") self.saveOnlineAction = QAction("&Sauver en ligne", self.win) self.saveOnlineAction.triggered.connect(self.saveOnline) self.saveOnlineAction.setShortcut("Ctrl+Shift+S") self.loadOnlineAction = QAction("&Charger en ligne (Soon)", self.win) self.loadOnlineAction.triggered.connect(self.loadOnline) self.loadOnlineAction.setShortcut("Ctrl+Shift+O") self.fileMenu.addAction(self.openAction) self.fileMenu.addAction(self.saveAction) if Donnees.online: self.fileMenu.addAction(self.saveOnlineAction) self.fileMenu.addAction(self.loadOnlineAction) self.menuBar.addMenu(self.fileMenu) def openproject(self): self.open.setGeometry(50,50,200,200) self.open.setWindowTitle("Ouvrir") self.open.show() self.label11 = QLabel(self.open) self.label11.setText("Ouvrir fichier local\n(dans dossier ptprojects)") self.label11.move(20, 20) self.label11.show() self.champ = QLineEdit(self.open) self.champ.move(20, 60) self.champ.resize(160, 20) self.champ.show() self.bouton = QPushButton(self.open) self.bouton.setText("Ouvrir") self.bouton.move(20,90) self.bouton.clicked.connect(self.openFile) self.bouton.show() def openFile(self): try: with open("./module/ptprojects/"+self.champ.text(), "r") as f: Donnees.ptfile = f.read() Donnees.nameFileProject = self.champ.text() self.label.setText(self.champ.text()) self.label.adjustSize() self.textEdit.setText(Donnees.ptfile) self.open.close() except: from traceback import print_exc print_exc() self.label11.setText("Impossible d'ouvrir") def saveFile(self): try: with open("./module/ptprojects/"+Donnees.nameFileProject, "w") as f: f.write(self.textEdit.toPlainText()) except: if Donnees.online: a = f"{Donnees.current_user['user']}_python_{int(time.time())}.py" with open(f"./module/ptprojects/{a}", "w") as f: f.write(self.textEdit.toPlainText()) Donnees.nameFileProject = a self.label.setText(a) self.label.adjustSize() elif not Donnees.online: a = f'python_{int(time.time())}.py' with open(f"./module/ptprojects/{a}", "w") as f: f.write(self.textEdit.toPlainText()) Donnees.nameFileProject = a self.label.setText(a) self.label.adjustSize() def saveOnline(self): self.online.uploadftp(Donnees.nameFileProject, "./module/ptprojects/") self.saveFile() def loadOnline(self): pass
class TemplateMultipleVariablesDialog(QDialog): """ Class implementing a dialog for entering multiple template variables. """ def __init__(self, variables, parent=None): """ Constructor @param variables list of template variable names (list of strings) @param parent parent widget of this dialog (QWidget) """ super(TemplateMultipleVariablesDialog, self).__init__(parent) self.TemplateMultipleVariablesDialogLayout = QVBoxLayout(self) self.TemplateMultipleVariablesDialogLayout.setContentsMargins(6, 6, 6, 6) self.TemplateMultipleVariablesDialogLayout.setSpacing(6) self.TemplateMultipleVariablesDialogLayout.setObjectName("TemplateMultipleVariablesDialogLayout") self.setLayout(self.TemplateMultipleVariablesDialogLayout) # generate the scrollarea self.variablesView = QScrollArea(self) self.variablesView.setObjectName("variablesView") self.TemplateMultipleVariablesDialogLayout.addWidget(self.variablesView) self.variablesView.setWidgetResizable(True) self.variablesView.setFrameStyle(QFrame.NoFrame) self.top = QWidget(self) self.variablesView.setWidget(self.top) self.grid = QGridLayout(self.top) self.grid.setContentsMargins(0, 0, 0, 0) self.grid.setSpacing(6) self.top.setLayout(self.grid) # populate the scrollarea with labels and text edits self.variablesEntries = {} row = 0 for var in variables: label = QLabel("{0}:".format(var), self.top) self.grid.addWidget(label, row, 0, Qt.Alignment(Qt.AlignTop)) if var.find(":") >= 0: formatStr = var[1:-1].split(":")[1] if formatStr in ["ml", "rl"]: t = QTextEdit(self.top) t.setTabChangesFocus(True) else: t = QLineEdit(self.top) else: t = QLineEdit(self.top) self.grid.addWidget(t, row, 1) self.variablesEntries[var] = t row += 1 # add a spacer to make the entries aligned at the top spacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.grid.addItem(spacer, row, 1) self.variablesEntries[variables[0]].setFocus() self.top.adjustSize() # generate the buttons layout1 = QHBoxLayout() layout1.setContentsMargins(0, 0, 0, 0) layout1.setSpacing(6) layout1.setObjectName("layout1") spacer1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) layout1.addItem(spacer1) self.okButton = QPushButton(self) self.okButton.setObjectName("okButton") self.okButton.setDefault(True) layout1.addWidget(self.okButton) self.cancelButton = QPushButton(self) self.cancelButton.setObjectName("cancelButton") layout1.addWidget(self.cancelButton) spacer2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) layout1.addItem(spacer2) self.TemplateMultipleVariablesDialogLayout.addLayout(layout1) # set the texts of the standard widgets self.setWindowTitle(self.tr("Enter Template Variables")) self.okButton.setText(self.tr("&OK")) self.cancelButton.setText(self.tr("&Cancel")) # polish up the dialog self.resize(QSize(400, 480).expandedTo(self.minimumSizeHint())) self.okButton.clicked.connect(self.accept) self.cancelButton.clicked.connect(self.reject) def getVariables(self): """ Public method to get the values for all variables. @return dictionary with the variable as a key and its value (string) """ values = {} for var, textEdit in list(self.variablesEntries.items()): try: values[var] = textEdit.text() except AttributeError: values[var] = textEdit.toPlainText() return values
class Popup(QDialog): def __init__(self, schedule: Schedule, parent=None, edit_data=None): super(Popup, self).__init__(parent) self.schedule = schedule self.event_name, self.data = edit_data if edit_data is not None else ( None, None) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum) self.setWindowTitle("Add New Scheduled Notes" if edit_data is None else "Edit {} Details".format(self.event_name)) self.layout = QVBoxLayout() self.layout.setSpacing(0) self.form_layout = QFormLayout() self.form_layout.setContentsMargins(0, 0, 0, self.form_layout.verticalSpacing()) self.form_layout_widget = QWidget() self.form_layout_widget.setLayout(self.form_layout) #The amount of fields in the form that come before the block section (name, #blocks, start, end date, color) self.rows_before_blocks = 3 self.event_type = QPushButton() event_type_menu = QMenu() event_type_menu.addAction("Class") event_type_menu.addSection("Event") event_type_menu.addAction("One Time Event") event_type_menu.addAction("Recurring Event") event_type_menu.addAction("One Time Class Event") for action in event_type_menu.actions(): if not action.isSeparator(): action.triggered.connect( lambda state, x=action.text(): self.set_type(x)) self.event_type.setMenu(event_type_menu) self.form_layout.addRow("Type:", self.event_type) #Class Title self.name_edit = QLineEdit() self.form_layout.addRow("Name:", self.name_edit) #Color self.color_picker = QColorDialog() self.color_button = QPushButton("Pick Color") self.color_button.clicked.connect(self.color_picker.open) self.color_picker.currentColorChanged.connect(self.update_color) self.form_layout.addRow("Color Code:", self.color_button) # Initialize widgets to be added later self.start_date_model = DateTimePickerSeriesModel(self) self.class_start_date = DateTimePickerSeries(self.start_date_model, "MMM d yyyy") self.event_start_date = DateTimePickerSeries(self.start_date_model, "MMM d yyyy") self.end_date_model = DateTimePickerSeriesModel(self) self.class_end_date = DateTimePickerSeries(self.end_date_model, "MMM d yyyy") self.event_end_date = DateTimePickerSeries(self.end_date_model, "MMM d yyyy") self.event_date_model = DateTimePickerSeriesModel(self) self.class_event_date = DateTimePickerSeries(self.event_date_model, "MMM d yyyy hh:mm:AP") self.event_date = DateTimePickerSeries(self.event_date_model, "MMM d yyyy hh:mm:AP") # Blocks self.blocks = 1 self.spin_box = QSpinBox() self.spin_box.setValue(1) self.spin_box.setMinimum(1) self.spin_box.setMaximum(7) self.spin_box.valueChanged.connect(self.update_blocks) self.class_picker = QPushButton() class_picker_menu = QMenu() for class_name in self.schedule.schedule.keys(): if self.schedule.schedule[class_name]["type"] != "class": continue class_action = QAction(class_name, parent=class_picker_menu) class_action.triggered.connect(lambda state, x=class_action.text(): self.class_picker.setText(x)) class_picker_menu.addAction(class_action) class_picker_menu.aboutToShow.connect( lambda: class_picker_menu.setMinimumWidth(self.class_picker.width( ))) self.class_picker.setMenu(class_picker_menu) self.stack = QStackedWidget() self.stack.setContentsMargins(0, 0, 0, 0) class_layout = QFormLayout() class_layout.setContentsMargins(0, 0, 0, class_layout.verticalSpacing()) class_layout.addRow("Start Date:", self.class_start_date) class_layout.addRow("End Date:", self.class_end_date) class_layout.addRow("Weekly Blocks:", self.spin_box) class_layout.addRow("Block Time:", ClassTimePicker()) self.class_options = QWidget() self.class_options.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.class_options.setLayout(class_layout) recurring_event_layout = QFormLayout() recurring_event_layout.setContentsMargins( 0, 0, 0, recurring_event_layout.verticalSpacing()) recurring_event_layout.addRow("Start Date:", self.event_start_date) recurring_event_layout.addRow("End Date:", self.event_end_date) self.recurring_event_time_picker = ClassTimePicker() recurring_event_layout.addRow("Event Time:", self.recurring_event_time_picker) self.recurring_event_options = QWidget() self.recurring_event_options.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.recurring_event_options.setLayout(recurring_event_layout) one_time_event_layout = QFormLayout() one_time_event_layout.setContentsMargins( 0, 0, 0, one_time_event_layout.verticalSpacing()) one_time_event_layout.addRow("Event Date:", self.event_date) self.one_time_event_options = QWidget() self.one_time_event_options.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.one_time_event_options.setLayout(one_time_event_layout) class_event_layout = QFormLayout() class_event_layout.setContentsMargins( 0, 0, 0, class_event_layout.verticalSpacing()) class_event_layout.addRow("Class:", self.class_picker) class_event_layout.addRow("Event Date:", self.class_event_date) self.class_event_options = QWidget() self.class_event_options.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.class_event_options.setLayout(class_event_layout) self.stack.addWidget(self.class_event_options) self.stack.addWidget(self.one_time_event_options) self.stack.addWidget(self.recurring_event_options) self.stack.addWidget(self.class_options) if self.data is None: self.set_type("Class") self.layout.addWidget(self.form_layout_widget) self.layout.addWidget(self.stack) self.setLayout(self.layout) self.show_buttons() #Update Values if self.data is defined if self.data is not None: event_type = self.data["type"] self.set_type(camel_case(event_type)) # noinspection PyTypeChecker class_layout: QFormLayout = self.stack.currentWidget().layout() self.name_edit.setText(self.event_name) self.name_edit.setDisabled(True) self.color_picker.setCurrentColor(to_qcolor(self.data["color"])) if event_type in ["class", "recurring event"]: self.start_date_model.content = QDateTime( to_qdate(self.data["start"])) self.end_date_model.content = QDateTime( to_qdate(self.data["end"])) if event_type == "class": blocks = self.data["blocks"] self.update_blocks(len(blocks)) for i, row in enumerate( range(self.rows_before_blocks, class_layout.rowCount())): block = blocks[i] # noinspection PyTypeChecker block_widget: ClassTimePicker = class_layout.itemAt( row, QFormLayout.FieldRole).widget() block_widget.set_time(to_qtime(block["time"])) block_widget.set_day(block["day"]) if event_type == "recurring event": self.recurring_event_time_picker.set_day(self.data["day"]) self.recurring_event_time_picker.set_time( to_qtime(self.data["time"])) if event_type in ["one time event", "one time class event"]: date_time = QDateTime() date_time.setDate(to_qdate(self.data["date"])) date_time.setTime(to_qtime(self.data["time"])) self.event_date_model.content = date_time if event_type == "one time class event": self.class_picker.setText(self.data["class_name"]) def show_buttons(self): save_button = QDialogButtonBox.Save if self.data is None else QDialogButtonBox.Apply cancel_button = QDialogButtonBox.Cancel buttonBox = QDialogButtonBox(Qt.Horizontal) buttonBox.addButton(save_button).clicked.connect(self.accept) buttonBox.addButton(cancel_button).clicked.connect(self.reject) if self.data is not None: delete_button = buttonBox.addButton(QDialogButtonBox.Discard) delete_button.setText("Delete") delete_button.clicked.connect(self.delete_event) self.layout.addWidget(buttonBox) def set_type(self, event_type: str): if self.event_type.text() == event_type: return self.event_type.setText(event_type) self.stack.currentWidget().setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) if event_type == "Class": self.class_options.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.class_options.adjustSize() self.stack.setCurrentWidget(self.class_options) elif event_type == "Recurring Event": self.recurring_event_options.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.recurring_event_options.adjustSize() self.stack.setCurrentWidget(self.recurring_event_options) elif event_type == "One Time Event": self.one_time_event_options.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.one_time_event_options.adjustSize() self.stack.setCurrentWidget(self.one_time_event_options) elif event_type == "One Time Class Event": self.class_event_options.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.class_event_options.adjustSize() self.stack.setCurrentWidget(self.class_event_options) self.stack.adjustSize() max_width = 0 for i in range(self.form_layout.rowCount()): widget = self.form_layout.itemAt(i, QFormLayout.LabelRole).widget() widget.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) widget.adjustSize() max_width = max(widget.size().width(), max_width) # noinspection PyTypeChecker current_widget_layout: QFormLayout = self.stack.currentWidget().layout( ) for i in range(current_widget_layout.rowCount()): widget = current_widget_layout.itemAt( i, QFormLayout.LabelRole).widget() widget.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) widget.adjustSize() max_width = max(widget.size().width(), max_width) for i in range(self.form_layout.rowCount()): self.form_layout.itemAt( i, QFormLayout.LabelRole).widget().setMinimumWidth(max_width) for i in range(current_widget_layout.rowCount()): current_widget_layout.itemAt( i, QFormLayout.LabelRole).widget().setMinimumWidth(max_width) self.adjustSize() def update_color(self): self.color_button.setStyleSheet( "background-color: rgb({},{},{})".format( self.color_picker.currentColor().red(), self.color_picker.currentColor().green(), self.color_picker.currentColor().blue())) def update_blocks(self, value): if self.spin_box.value() != value: self.spin_box.setValue(value) return if self.blocks == value: return old_blocks = self.blocks self.blocks = value class_options_layout: QFormLayout = self.class_options.layout() if self.blocks > old_blocks: #Change label of block 1 if old_blocks == 1: class_options_layout.itemAt( self.rows_before_blocks, QFormLayout.LabelRole).widget().setText("Block 1 Time:") for i in range(1, self.blocks - old_blocks + 1): offset = self.rows_before_blocks + old_blocks + i - 1 widget = class_options_layout.itemAt(offset, QFormLayout.FieldRole) label = class_options_layout.itemAt(offset, QFormLayout.LabelRole) if widget is not None and label is not None: widget = widget.widget() label = label.widget() widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) widget.adjustSize() label.adjustSize() widget.show() label.show() else: picker = ClassTimePicker() picker.sizePolicy().setRetainSizeWhenHidden(False) class_options_layout.addRow( "Block {} Time:".format(old_blocks + i), picker) elif self.blocks < old_blocks: if self.blocks == 1: class_options_layout.itemAt( self.rows_before_blocks, QFormLayout.LabelRole).widget().setText("Block Time:") for i in range(old_blocks - self.blocks): offset = self.rows_before_blocks + old_blocks + i - 1 widget = class_options_layout.itemAt( offset, QFormLayout.FieldRole).widget() label = class_options_layout.itemAt( offset, QFormLayout.LabelRole).widget() widget.hide() label.hide() widget.adjustSize() label.adjustSize() self.class_options.adjustSize() self.stack.adjustSize() self.adjustSize() # self.class_options.adjustSize() # self.stack.adjustSize() # self.adjustSize() def get_name(self): return self.name_edit.text() def get_data(self): event_type = self.event_type.text() data = { "type": event_type.lower(), "name": self.get_name(), "color": { "r": self.color_picker.currentColor().red(), "g": self.color_picker.currentColor().green(), "b": self.color_picker.currentColor().blue(), } } if event_type == "Class": block_data = [] # noinspection PyTypeChecker class_layout: QFormLayout = self.stack.currentWidget().layout() for row in range(self.rows_before_blocks, class_layout.rowCount()): # noinspection PyTypeChecker block_widget: ClassTimePicker = class_layout.itemAt( row, QFormLayout.FieldRole).widget() if block_widget.isHidden(): continue time = block_widget.get_time() block_data.append({ "day": block_widget.day_picker.get_day(), "time": { "hour": time.hour(), "minute": time.minute() } }) data["blocks"] = block_data if event_type in ["Class", "Recurring Event"]: start_date = self.start_date_model.content.date() data["start"] = { "day": start_date.day(), "month": start_date.month(), "year": start_date.year() } end_date = self.end_date_model.content.date() data["end"] = { "day": end_date.day(), "month": end_date.month(), "year": end_date.year() } if event_type == "Recurring Event": data["day"] = self.recurring_event_time_picker.day_picker.get_day() time = self.recurring_event_time_picker.get_time() data["time"] = {"hour": time.hour(), "minute": time.minute()} if event_type == "One Time Class Event": data["class_name"] = self.class_picker.text() if event_type in ["One Time Event", "One Time Class Event"]: date_time = self.event_date_model.content date = date_time.date() time = date_time.time() data["date"] = { "day": date.day(), "month": date.month(), "year": date.year(), } data["time"] = {"hour": time.hour(), "minute": time.minute()} return data def delete_event(self): error = QMessageBox() error.setText("Are you sure you would like to delete this event?") error.setStandardButtons(QMessageBox.Yes | QMessageBox.Cancel) result = error.exec_() if result == QMessageBox.Yes: self.schedule.delete_event(self.event_name) self.reject() def accept(self): event_type = self.event_type.text() if event_type == "": error = QMessageBox() error.setText("Please select a type for the event.") error.exec_() self.event_type.setFocus() return # Check Name if len(self.get_name()) == 0: error = QMessageBox() error.setText("Please enter a name for the event.") error.exec_() self.name_edit.setFocus() return if event_type in ["Class", "Recurring Event"]: # Check Start/End Date start_date = self.start_date_model.content.date() end_date = self.end_date_model.content.date() if start_date >= end_date: error = QMessageBox() error.setText("End date cannot {} start date.".format( "be equal to" if start_date == end_date else "come before")) error.exec_() if event_type == "Class": self.class_end_date.setFocus() else: self.event_end_date.setFocus() return if event_type == "Class": # Check Blocks # noinspection PyTypeChecker class_layout: QFormLayout = self.stack.currentWidget().layout() for row in range(self.rows_before_blocks, class_layout.rowCount()): block_widget = class_layout.itemAt( row, QFormLayout.FieldRole).widget() if block_widget.isHidden(): continue # Make sure a day is selected for each block if not block_widget.is_valid(): block_name = "the class block" if self.blocks == 1 else str.lower( class_layout.itemAt(row, QFormLayout.LabelRole). widget().text()).replace(" time:", "") error = QMessageBox() error.setText( "Please select a valid day for {}.".format( block_name)) error.exec_() return # Check for duplicate blocks for other in range(self.rows_before_blocks, class_layout.rowCount() - 1): if row == other: continue other_block_widget = class_layout.itemAt( other, QFormLayout.FieldRole).widget() same_time = block_widget.get_time( ) == other_block_widget.get_time() same_day = block_widget.day_picker.get_day( ) == other_block_widget.day_picker.get_day() if same_time and same_day: error = QMessageBox() error.setText( "Block {} and {} cannot have the same day and time." .format(row - self.rows_before_blocks + 1, other - self.rows_before_blocks + 1)) error.exec_() return if event_type == "Recurring Event": # Make sure a day is selected if not self.recurring_event_time_picker.is_valid(): error = QMessageBox() error.setText("Please select a valid day for this event.") error.exec_() self.recurring_event_time_picker.setFocus() return if event_type == "One Time Class Event": # Check Class if len(self.class_picker.text()) == 0: error = QMessageBox() error.setText("Please select a class for this event.") error.exec_() self.class_picker.setFocus() return # Valid name if self.get_name() in self.schedule.schedule.keys(): if self.data is None: error = QMessageBox() error.setText( "An event with this name already exists, would you like to overwrite it?" ) error.setStandardButtons(error.Apply | error.Cancel) result = error.exec_() if result == error.Apply: to_overwrite = self.schedule.schedule[self.get_name()] if to_overwrite["type"] == "class": if self.event_type.text() == "One Time Class Event": if self.class_picker.text() == self.get_name(): error = QMessageBox() error.setText( "Cannot overwrite a class with a one time class event for that class.\n" "Please select a different class.") error.setStandardButtons(QMessageBox.Close) error.exec_() return self.schedule.edit_event(self.get_data()) self.reject() elif result == error.Cancel: self.name_edit.setFocus() return self.schedule.edit_event(self.get_data()) self.reject() super(Popup, self).accept() def reject(self): super(Popup, self).reject()
class ControlElement: def __init__(self, option_name: str, config_object: ConfigObject, outer_layout: QLayout, dialog: QDialog, update_callback): self.option_name = option_name self.state = config_object.value self.outer_layout = outer_layout self.dialog = dialog self.update_callback = update_callback self.edit_control = None self.add_btn = QPushButton("Add item") self.add_btn.setAutoDefault(False) self.add_btn.clicked.connect(lambda: self.add_btn_click()) self.outer_layout.addWidget(self.add_btn) self.list_layout = QVBoxLayout() self.list_widget = QWidget() self.list_widget.setContentsMargins(50, 0, 50, 0) self.list_widget.setLayout(self.list_layout) self.outer_layout.addWidget(self.list_widget) self.is_editing = False self.update_view() def init_edit_control(self): pass def set_state(self, new_value): # update state self.state = new_value self.update_view() self.update_callback(new_value) def delete_entry(self, item, h_layout): h_layout.deleteLater() self.set_state([x for x in self.state if x != item]) def render_edit_control(self, h_layout): h_layout.addWidget(self.edit_control) def render_entries(self): from .. import asset_dir for item in self.state: h_layout = QHBoxLayout() if len(item) == 0: # is editing self.render_edit_control(h_layout) else: label = QLabel("'" + item + "'") label.setStyleSheet( "font-family: monospace; text-align: right; font-size: 16px" ) h_layout.addWidget(label) btn = QPushButton("") btn.setIcon( QIcon( os.path.join( asset_dir, "checkmark-1.png" if len(item) == 0 else "trashcan.png"))) btn.setFixedWidth(30) btn.setStyleSheet( "background-color: #FFFFFF; border: 1px solid gray; border-radius: 2px; cursor: pointer" ) btn.setFixedHeight(30) btn.setIconSize(QSize(20, 20)) h_layout.addWidget(btn) btn.pressed.connect( partial(self.submit_draft) if len(item) == 0 else partial(self.delete_entry, item, h_layout)) self.list_layout.addLayout(h_layout) def update_view(self): delete_layout_contents(self.list_layout) self.init_edit_control() self.list_widget.adjustSize() self.dialog.adjustSize() self.render_entries() self.list_widget.adjustSize() self.dialog.adjustSize() def submit_draft(self): pass def add_btn_click(self): pass
class App(QMainWindow): def __init__(self): super(App, self).__init__() self.central_widget = QWidget() self.vbox = QVBoxLayout() self.lbl_img = QLabel() self.file_name = 'assets/lenna.png' self.init_ui() def init_ui(self): self.setWindowTitle('Computer Vision Playground') self.setWindowIcon(QIcon('assets/app-icon.png')) self.init_menubar() self.init_central_widget() self.statusBar().showMessage('Ready') self.center() self.show() def center(self): # Adjust the window size self.central_widget.adjustSize() self.adjustSize() # Center the app qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) def init_central_widget(self): # Show the sample image self.lbl_img.setPixmap(QPixmap(self.file_name)) self.vbox.addWidget(self.lbl_img) self.central_widget.setLayout(self.vbox) self.setCentralWidget(self.central_widget) def init_menubar(self): menubar = self.menuBar() menubar.setNativeMenuBar(False) # File menus menu_file = menubar.addMenu('&File') # Open menu action_open = QAction('Open', self) action_open.setShortcut('Ctrl+O') action_open.setStatusTip('Open an image file') action_open.triggered.connect(self.open_file) menu_file.addAction(action_open) # Exit menu menu_file.addSeparator() action_exit = QAction('Exit', self) action_exit.setShortcut('Ctrl+Q') action_exit.setStatusTip('Quit application') action_exit.triggered.connect(qApp.quit) menu_file.addAction(action_exit) def open_file(self): self.file_name = \ QFileDialog.getOpenFileName(self, 'Open an image file', '/home', 'Images (*.png *.jpg *.jpeg)')[0] if self.file_name: self.update_pixmap(self.file_name) def update_pixmap(self, file_name): pixmap = QPixmap(file_name) # Scale the pixmap if it's too large screen_avail = QDesktopWidget().availableGeometry() max_width = int(screen_avail.width() * 0.8) max_height = int(screen_avail.height() * 0.8) if pixmap.size().width() > max_width: pixmap = pixmap.scaledToWidth(max_width) if pixmap.size().height() > max_height: pixmap = pixmap.scaledToHeight(max_height) # Update the center widget with the pixmap self.lbl_img.setPixmap(pixmap) self.center()
class TemplateMultipleVariablesDialog(QDialog): """ Class implementing a dialog for entering multiple template variables. """ def __init__(self, variables, parent=None): """ Constructor @param variables list of template variable names (list of strings) @param parent parent widget of this dialog (QWidget) """ super(TemplateMultipleVariablesDialog, self).__init__(parent) self.TemplateMultipleVariablesDialogLayout = QVBoxLayout(self) self.TemplateMultipleVariablesDialogLayout.setContentsMargins( 6, 6, 6, 6) self.TemplateMultipleVariablesDialogLayout.setSpacing(6) self.TemplateMultipleVariablesDialogLayout.setObjectName( "TemplateMultipleVariablesDialogLayout") self.setLayout(self.TemplateMultipleVariablesDialogLayout) # generate the scrollarea self.variablesView = QScrollArea(self) self.variablesView.setObjectName("variablesView") self.TemplateMultipleVariablesDialogLayout.addWidget( self.variablesView) self.variablesView.setWidgetResizable(True) self.variablesView.setFrameStyle(QFrame.NoFrame) self.top = QWidget(self) self.variablesView.setWidget(self.top) self.grid = QGridLayout(self.top) self.grid.setContentsMargins(0, 0, 0, 0) self.grid.setSpacing(6) self.top.setLayout(self.grid) # populate the scrollarea with labels and text edits self.variablesEntries = {} row = 0 for var in variables: label = QLabel("{0}:".format(var), self.top) self.grid.addWidget(label, row, 0, Qt.Alignment(Qt.AlignTop)) if var.find(":") >= 0: formatStr = var[1:-1].split(":")[1] if formatStr in ["ml", "rl"]: t = QTextEdit(self.top) t.setTabChangesFocus(True) else: t = QLineEdit(self.top) else: t = QLineEdit(self.top) self.grid.addWidget(t, row, 1) self.variablesEntries[var] = t row += 1 # add a spacer to make the entries aligned at the top spacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.grid.addItem(spacer, row, 1) self.variablesEntries[variables[0]].setFocus() self.top.adjustSize() # generate the buttons layout1 = QHBoxLayout() layout1.setContentsMargins(0, 0, 0, 0) layout1.setSpacing(6) layout1.setObjectName("layout1") spacer1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) layout1.addItem(spacer1) self.okButton = QPushButton(self) self.okButton.setObjectName("okButton") self.okButton.setDefault(True) layout1.addWidget(self.okButton) self.cancelButton = QPushButton(self) self.cancelButton.setObjectName("cancelButton") layout1.addWidget(self.cancelButton) spacer2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) layout1.addItem(spacer2) self.TemplateMultipleVariablesDialogLayout.addLayout(layout1) # set the texts of the standard widgets self.setWindowTitle(self.tr("Enter Template Variables")) self.okButton.setText(self.tr("&OK")) self.cancelButton.setText(self.tr("&Cancel")) # polish up the dialog self.resize(QSize(400, 480).expandedTo(self.minimumSizeHint())) self.okButton.clicked.connect(self.accept) self.cancelButton.clicked.connect(self.reject) def getVariables(self): """ Public method to get the values for all variables. @return dictionary with the variable as a key and its value (string) """ values = {} for var, textEdit in list(self.variablesEntries.items()): try: values[var] = textEdit.text() except AttributeError: values[var] = textEdit.toPlainText() return values
class PyRegExpWizardCharactersDialog(QDialog, Ui_PyRegExpWizardCharactersDialog): """ Class implementing a dialog for entering character classes. """ specialChars = {4: "\\a", 5: "\\f", 6: "\\n", 7: "\\r", 8: "\\t", 9: "\\v"} predefinedClasses = ["\\s", "\\S", "\\w", "\\W", "\\d", "\\D"] def __init__(self, parent=None): """ Constructor @param parent parent widget (QWidget) """ super(PyRegExpWizardCharactersDialog, self).__init__(parent) self.setupUi(self) self.comboItems = [] self.singleComboItems = [] # these are in addition to the above self.comboItems.append(self.tr("Normal character")) self.comboItems.append( self.tr("Unicode character in hexadecimal notation")) self.comboItems.append(self.tr("Unicode character in octal notation")) self.singleComboItems.append(self.tr("---")) self.singleComboItems.append(self.tr("Bell character (\\a)")) self.singleComboItems.append(self.tr("Page break (\\f)")) self.singleComboItems.append(self.tr("Line feed (\\n)")) self.singleComboItems.append(self.tr("Carriage return (\\r)")) self.singleComboItems.append(self.tr("Horizontal tabulator (\\t)")) self.singleComboItems.append(self.tr("Vertical tabulator (\\v)")) self.charValidator = QRegExpValidator(QRegExp(".{0,1}"), self) self.hexValidator = QRegExpValidator(QRegExp("[0-9a-fA-F]{0,4}"), self) self.octValidator = QRegExpValidator(QRegExp("[0-3]?[0-7]{0,2}"), self) # generate dialog part for single characters self.singlesBoxLayout = QVBoxLayout(self.singlesBox) self.singlesBoxLayout.setObjectName("singlesBoxLayout") self.singlesBoxLayout.setSpacing(6) self.singlesBoxLayout.setContentsMargins(6, 6, 6, 6) self.singlesBox.setLayout(self.singlesBoxLayout) self.singlesView = QScrollArea(self.singlesBox) self.singlesView.setObjectName("singlesView") self.singlesBoxLayout.addWidget(self.singlesView) self.singlesItemsBox = QWidget(self) self.singlesView.setWidget(self.singlesItemsBox) self.singlesItemsBox.setObjectName("singlesItemsBox") self.singlesItemsBoxLayout = QVBoxLayout(self.singlesItemsBox) self.singlesItemsBoxLayout.setContentsMargins(6, 6, 6, 6) self.singlesItemsBoxLayout.setSpacing(6) self.singlesItemsBox.setLayout(self.singlesItemsBoxLayout) self.singlesEntries = [] self.__addSinglesLine() hlayout0 = QHBoxLayout() hlayout0.setContentsMargins(0, 0, 0, 0) hlayout0.setSpacing(6) hlayout0.setObjectName("hlayout0") self.moreSinglesButton = QPushButton(self.tr("Additional Entries"), self.singlesBox) self.moreSinglesButton.setObjectName("moreSinglesButton") hlayout0.addWidget(self.moreSinglesButton) hspacer0 = QSpacerItem(30, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) hlayout0.addItem(hspacer0) self.singlesBoxLayout.addLayout(hlayout0) self.moreSinglesButton.clicked.connect(self.__addSinglesLine) # generate dialog part for character ranges self.rangesBoxLayout = QVBoxLayout(self.rangesBox) self.rangesBoxLayout.setObjectName("rangesBoxLayout") self.rangesBoxLayout.setSpacing(6) self.rangesBoxLayout.setContentsMargins(6, 6, 6, 6) self.rangesBox.setLayout(self.rangesBoxLayout) self.rangesView = QScrollArea(self.rangesBox) self.rangesView.setObjectName("rangesView") self.rangesBoxLayout.addWidget(self.rangesView) self.rangesItemsBox = QWidget(self) self.rangesView.setWidget(self.rangesItemsBox) self.rangesItemsBox.setObjectName("rangesItemsBox") self.rangesItemsBoxLayout = QVBoxLayout(self.rangesItemsBox) self.rangesItemsBoxLayout.setContentsMargins(6, 6, 6, 6) self.rangesItemsBoxLayout.setSpacing(6) self.rangesItemsBox.setLayout(self.rangesItemsBoxLayout) self.rangesEntries = [] self.__addRangesLine() hlayout1 = QHBoxLayout() hlayout1.setContentsMargins(0, 0, 0, 0) hlayout1.setSpacing(6) hlayout1.setObjectName("hlayout1") self.moreRangesButton = QPushButton(self.tr("Additional Entries"), self.rangesBox) self.moreSinglesButton.setObjectName("moreRangesButton") hlayout1.addWidget(self.moreRangesButton) hspacer1 = QSpacerItem(30, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) hlayout1.addItem(hspacer1) self.rangesBoxLayout.addLayout(hlayout1) self.moreRangesButton.clicked.connect(self.__addRangesLine) def __addSinglesLine(self): """ Private slot to add a line of entry widgets for single characters. """ hbox = QWidget(self.singlesItemsBox) hboxLayout = QHBoxLayout(hbox) hboxLayout.setContentsMargins(0, 0, 0, 0) hboxLayout.setSpacing(6) hbox.setLayout(hboxLayout) cb1 = QComboBox(hbox) cb1.setEditable(False) cb1.addItems(self.comboItems) cb1.addItems(self.singleComboItems) hboxLayout.addWidget(cb1) le1 = QLineEdit(hbox) le1.setValidator(self.charValidator) hboxLayout.addWidget(le1) cb2 = QComboBox(hbox) cb2.setEditable(False) cb2.addItems(self.comboItems) cb2.addItems(self.singleComboItems) hboxLayout.addWidget(cb2) le2 = QLineEdit(hbox) le2.setValidator(self.charValidator) hboxLayout.addWidget(le2) self.singlesItemsBoxLayout.addWidget(hbox) cb1.activated[int].connect(self.__singlesCharTypeSelected) cb2.activated[int].connect(self.__singlesCharTypeSelected) hbox.show() self.singlesItemsBox.adjustSize() self.singlesEntries.append([cb1, le1]) self.singlesEntries.append([cb2, le2]) def __addRangesLine(self): """ Private slot to add a line of entry widgets for character ranges. """ hbox = QWidget(self.rangesItemsBox) hboxLayout = QHBoxLayout(hbox) hboxLayout.setContentsMargins(0, 0, 0, 0) hboxLayout.setSpacing(6) hbox.setLayout(hboxLayout) cb1 = QComboBox(hbox) cb1.setEditable(False) cb1.addItems(self.comboItems) hboxLayout.addWidget(cb1) l1 = QLabel(self.tr("Between:"), hbox) hboxLayout.addWidget(l1) le1 = QLineEdit(hbox) le1.setValidator(self.charValidator) hboxLayout.addWidget(le1) l2 = QLabel(self.tr("And:"), hbox) hboxLayout.addWidget(l2) le2 = QLineEdit(hbox) le2.setValidator(self.charValidator) hboxLayout.addWidget(le2) self.rangesItemsBoxLayout.addWidget(hbox) cb1.activated[int].connect(self.__rangesCharTypeSelected) hbox.show() self.rangesItemsBox.adjustSize() self.rangesEntries.append([cb1, le1, le2]) def __performSelectedAction(self, index, lineedit): """ Private method performing some actions depending on the input. @param index selected list index (integer) @param lineedit line edit widget to act on (QLineEdit) """ if index < 3: lineedit.setEnabled(True) if index == 0: lineedit.setValidator(self.charValidator) elif index == 1: lineedit.setValidator(self.hexValidator) elif index == 2: lineedit.setValidator(self.octValidator) elif index > 3: lineedit.setEnabled(False) lineedit.clear() def __singlesCharTypeSelected(self, index): """ Private slot to handle the activated(int) signal of the single chars combo boxes. @param index selected list index (integer) """ combo = self.sender() for entriesList in self.singlesEntries: if combo == entriesList[0]: self.__performSelectedAction(index, entriesList[1]) break def __rangesCharTypeSelected(self, index): """ Private slot to handle the activated(int) signal of the char ranges combo boxes. @param index selected list index (integer) """ combo = self.sender() for entriesList in self.rangesEntries: if combo == entriesList[0]: self.__performSelectedAction(index, entriesList[1]) self.__performSelectedAction(index, entriesList[2]) break def __formatCharacter(self, index, char): """ Private method to format the characters entered into the dialog. @param index selected list index (integer) @param char character string enetered into the dialog (string) @return formated character string (string) """ if index == 0: return char elif index == 1: return "\\x{0}".format(char.lower()) elif index == 2: return "\\0{0}".format(char) else: try: return self.specialChars[index] except KeyError: return "" def getCharacters(self): """ Public method to return the character string assembled via the dialog. @return formatted string for character classes (string) """ regexp = "" # negative character range if self.negativeCheckBox.isChecked(): regexp += "^" # predefined character ranges if self.wordCharCheckBox.isChecked(): regexp += "\\w" if self.nonWordCharCheckBox.isChecked(): regexp += "\\W" if self.digitsCheckBox.isChecked(): regexp += "\\d" if self.nonDigitsCheckBox.isChecked(): regexp += "\\D" if self.whitespaceCheckBox.isChecked(): regexp += "\\s" if self.nonWhitespaceCheckBox.isChecked(): regexp += "\\S" # single characters for entrieslist in self.singlesEntries: index = entrieslist[0].currentIndex() char = entrieslist[1].text() regexp += self.__formatCharacter(index, char) # character ranges for entrieslist in self.rangesEntries: if entrieslist[1].text() == "" or \ entrieslist[2].text() == "": continue index = entrieslist[0].currentIndex() char1 = entrieslist[1].text() char2 = entrieslist[2].text() regexp += "{0}-{1}".format(self.__formatCharacter(index, char1), self.__formatCharacter(index, char2)) if regexp: if (len(regexp) == 2 and (regexp in self.predefinedClasses or regexp in self.specialChars)) or \ len(regexp) == 1: return regexp else: return "[{0}]".format(regexp) else: return ""
class GraphTableUI(PageWindow): def __init__(self, controller, fontSize): logging.debug("GraphTableUI initialization") super().__init__() self.controller = controller self.shortestPathUI = ShortestPathUI(self.controller, 350, 120, fontSize=fontSize) self.allPathsUI = AllPathsUI(self.controller, 400, 250, fontSize=fontSize) self.__generalLayout = QGridLayout() self.__tableLayout = QGridLayout() self.__generalLayout.addLayout(self.__tableLayout, 1, 0) self.fontSize = fontSize layoutFont = QFont("Arial", self.fontSize, QFont.Bold) self.__centralWidget = QWidget() self.__centralWidget.setFont(layoutFont) self.__centralWidget.setLayout(self.__generalLayout) self.setCentralWidget(self.__centralWidget) self.createView(buttonsWidth=50) self.createTable(lineEditWidth=40) self.__generalLayout.setSizeConstraint(self.__tableLayout.SetFixedSize) self.__centralWidget.adjustSize() self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) def createView(self, buttonsWidth): """ Creates widgets of GraphTableUI. """ logging.debug("GraphTableUI.createView function started") self.backButton = QPushButton("Back") self.backButton.setFixedWidth(buttonsWidth) self.backButton.clicked.connect(self.gotoVerticesInputMenu) self.__generalLayout.addWidget(self.backButton, 0, 0) bottomLayout = QHBoxLayout() self.OkButton = QPushButton("Ok") self.OkButton.setFixedWidth(buttonsWidth) self.OkButton.clicked.connect(self.generateGraphEdges) bottomLayout.addWidget(self.OkButton) self.clearButton = QPushButton("Clear") self.clearButton.setFixedWidth(buttonsWidth) self.clearButton.clicked.connect(self.clearTable) bottomLayout.addWidget(self.clearButton) self.drawButton = QPushButton("Draw") self.drawButton.setFixedWidth(buttonsWidth) self.drawButton.clicked.connect(self.controller.drawGraph) bottomLayout.addWidget(self.drawButton) self.__generalLayout.addLayout(bottomLayout, 2, 0, alignment=Qt.AlignLeft) functionsLayout = QVBoxLayout() functionsLayout.addWidget(QLabel("")) self.shortestPathButton = QPushButton("Find the\nshortest path") self.shortestPathButton.clicked.connect(self.shortestPathUI.show) functionsLayout.addWidget(self.shortestPathButton) self.allPathsButton = QPushButton("Find all paths") self.allPathsButton.clicked.connect(self.allPathsUI.show) functionsLayout.addWidget(self.allPathsButton) self.__generalLayout.addLayout(functionsLayout, 1, 1, alignment=Qt.AlignTop) logging.debug("GraphTableUI.createView function ended\n") def createTable(self, lineEditWidth): """ Generates Table depending on numbers of vertices. """ logging.debug("GraphTableUI.createTable function started") self.vertices = self.controller.getVertices() self.cellsDict = dict() verticesNum = len(self.vertices) for rowNum in range(1, verticesNum + 1): for colNum in range(1, verticesNum + 1): if colNum == 1: vertexRowLabel = QLabel(self.vertices[rowNum - 1]) vertexColLabel = QLabel(self.vertices[rowNum - 1]) vertexRowLabel.setAlignment(Qt.AlignHCenter) vertexColLabel.setAlignment(Qt.AlignHCenter) self.__tableLayout.addWidget(vertexColLabel, 0, rowNum) self.__tableLayout.addWidget(vertexRowLabel, rowNum, 0) self.cellsDict[(0, rowNum)] = vertexColLabel self.cellsDict[(rowNum, 0)] = vertexRowLabel lineEdit = QLineEdit() lineEdit.setFixedWidth(lineEditWidth) lineEdit.textChanged.connect( partial(self.__clearErrorInfo, lineEdit, (rowNum, colNum))) lineEdit.setStyleSheet("""font: bold; font-size: {self.fontSize}pt; font-family: Arial""") if rowNum == colNum: lineEdit.setReadOnly(True) lineEdit.setStyleSheet("background: gray") self.__tableLayout.addWidget(lineEdit, rowNum, colNum) self.cellsDict[(rowNum, colNum)] = lineEdit logging.debug("GraphTableUI.createTable function ended\n") def removeTable(self): """ Removes Table from generalLayout. """ logging.debug("GraphTableUI.removeTable function started") for widget in self.cellsDict.values(): self.__tableLayout.removeWidget(widget) widget.setParent(None) self.cellsDict = dict() self.__generalLayout.setSizeConstraint(self.__tableLayout.SetFixedSize) self.__centralWidget.adjustSize() logging.debug("GraphTableUI.removeTable function ended\n") def clearTable(self): """ Clears a Table. """ logging.debug("GraphTableUI.clearTable function started") for widget in self.cellsDict.values(): if isinstance(widget, QLineEdit): widget.setText("") logging.debug("GraphTableUI.clearTable function ended\n") def createDisplay(self): """ Creates a Table after going to Graph Table page. """ logging.debug("GraphTableUI.createDisplay function started") self.createTable(lineEditWidth=40) logging.debug("GraphTableUI.createDisplay function ended\n") def getEdgesList(self): """ Creates list of Edges based on a Table. """ logging.debug("GraphTableUI.getEdgesList function started") edgesList = [] error = False for gridPlace, widget in self.cellsDict.items(): self.__clearErrorInfo(widget, gridPlace) if 0 in gridPlace or not widget.text(): continue rowNum, colNum = gridPlace fromVertex = self.cellsDict[(rowNum, 0)].text() toVertex = self.cellsDict[(0, colNum)].text() try: weight = int(widget.text()) except: self.__drawErrorInfo(widget) error = True continue edgesList.append((fromVertex, toVertex, weight)) logging.debug("GraphTableUI.getEdgesList function ended\n") if not error: return edgesList def generateGraphEdges(self): """ Makes Controller add edges to Graph. """ logging.debug("GraphTableUI.generateGraphEdges function started") edgesList = self.getEdgesList() if edgesList: self.controller.addEdgesToGraph(edgesList) logging.debug("GraphTableUI.generateGraphEdges function ended\n") def gotoVerticesInputMenu(self): """ Go to VerticesInputMenu page. """ logging.debug("GraphTableUI.gotoVerticesInputMenu function started") self.getEdgesList() self.removeTable() self.controller.deleteVertices() self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.goto("VerticesInput") logging.debug("GraphTableUI.gotoVerticesInputMenu function ended\n") def keyPressEvent(self, event): if event.key() == Qt.Key_Return: self.generateGraphEdges() def __drawErrorInfo(self, widget): widget.setStyleSheet(f"""border: 1px solid red; font-size: {self.fontSize}pt; font-family: Arial""") def __clearErrorInfo(self, widget, gridPlace): if gridPlace[0] != gridPlace[1]: widget.setStyleSheet(f"""font: bold; font-size: {self.fontSize}pt; font-family: Arial""")
class PreferencesWidget(QWidget): def __init__(self): super().__init__() self.setLayout(QVBoxLayout()) # backup directory self.backup_directory_widget = QWidget() self.backup_directory_widget.setLayout(QHBoxLayout()) self.backup_directory_line_edit = PreferencesLineEdit() self.backup_directory_line_edit.textChanged.connect( self.backup_directory_changed) self.select_backup_directory_button = QPushButton( "Select Backup Directory") self.select_backup_directory_button.clicked.connect( self.select_backup_directory) self.backup_directory_widget.layout().addWidget( QLabel("Backup Directory:")) self.backup_directory_widget.layout().addWidget( self.backup_directory_line_edit) self.backup_directory_widget.layout().addWidget( self.select_backup_directory_button) self.backup_directory_widget.layout().addStretch() self.backup_directory_widget.adjustSize( ) # all done adding - figure out what the height should be self.backup_directory_widget.setMaximumHeight( self.backup_directory_widget.minimumHeight()) self.layout().addWidget(self.backup_directory_widget) self.layout().addWidget(QLabel()) # space self.layout().addWidget(QLabel()) # space # AWS Credentials # profile self.aws_profile_widget = QWidget() self.aws_profile_widget.setLayout(QHBoxLayout()) self.aws_profile_widget.layout().addWidget(QLabel("AWS Profile:")) self.aws_profile_line_edit = PreferencesLineEdit() self.aws_profile_line_edit.textChanged.connect( self.aws_profile_changed) self.aws_profile_widget.layout().addWidget(self.aws_profile_line_edit) self.aws_profile_widget.layout().addStretch() self.layout().addWidget(self.aws_profile_widget) or_label = QLabel("or") # italicize "or" or_font = or_label.font() or_font.setItalic(True) or_label.setFont(or_font) self.layout().addWidget(or_label) # access key ID and secret access key self.aws_key_widget = QWidget() self.aws_key_widget.setLayout(QHBoxLayout()) self.aws_key_widget.layout().addWidget(QLabel("AWS Access Key ID:")) self.aws_access_key_id_line_edit = PreferencesLineEdit() self.aws_access_key_id_line_edit.textChanged.connect( self.aws_access_key_id_changed) self.aws_key_widget.layout().addWidget( self.aws_access_key_id_line_edit) self.aws_key_widget.layout().addWidget( QLabel("AWS Secret Access Key:")) self.aws_secret_access_key_line_edit = PreferencesLineEdit() self.aws_secret_access_key_line_edit.textChanged.connect( self.aws_secret_access_key_changed) self.aws_secret_access_key_line_edit.setEchoMode( PreferencesLineEdit.Password) self.aws_key_widget.layout().addWidget( self.aws_secret_access_key_line_edit) self.aws_show_button = QPushButton("Show") self.aws_show_button.clicked.connect( self.aws_secret_access_key_visible_clicked) self.aws_key_widget.layout().addWidget(self.aws_show_button) self.aws_key_widget.layout().addStretch() self.layout().addWidget(self.aws_key_widget) self.layout().addWidget(QLabel()) # space # region self.aws_region_widget = QWidget() self.aws_region_widget.setLayout(QHBoxLayout()) self.aws_region_widget.layout().addWidget(QLabel("AWS Region:")) self.aws_region_line_edit = PreferencesLineEdit() self.aws_region_line_edit.textChanged.connect(self.aws_region_changed) self.aws_region_widget.layout().addWidget(self.aws_region_line_edit) self.aws_region_widget.layout().addStretch() self.layout().addWidget(self.aws_region_widget) self.layout().addWidget(QLabel()) # space self.layout().addWidget(QLabel()) # space # github self.github_widget = QWidget() self.github_widget.setLayout(QHBoxLayout()) self.github_widget.layout().addWidget(QLabel("github token:")) self.github_token_line_edit = PreferencesLineEdit() self.github_token_line_edit.setEchoMode(PreferencesLineEdit.Password) self.github_token_line_edit.textChanged.connect( self.github_token_changed) self.github_widget.layout().addWidget(self.github_token_line_edit) self.github_show_button = QPushButton("Show") self.github_show_button.clicked.connect(self.github_visible_clicked) self.github_widget.layout().addWidget(self.github_show_button) self.github_widget.layout().addStretch() self.layout().addWidget(self.github_widget) self.layout().addWidget(QLabel()) # space self.layout().addWidget(QLabel()) # space # automatic backup self.automatic_backup_widget = QWidget() self.automatic_backup_widget.setLayout(QHBoxLayout()) self.automatic_backup_period = QSpinBox() self.automatic_backup_period.textChanged.connect( self.automatic_backup_changed) self.automatic_backup_widget.layout().addWidget( QLabel("Backup every (hours):")) self.automatic_backup_widget.layout().addWidget( self.automatic_backup_period) self.automatic_backup_enable_check_box = QCheckBox("enable") self.automatic_backup_enable_check_box.clicked.connect( self.automatic_backup_changed) self.automatic_backup_widget.layout().addWidget( self.automatic_backup_enable_check_box) self.automatic_backup_widget.layout().addStretch() self.layout().addWidget(self.automatic_backup_widget) self.layout().addWidget(QLabel()) # space self.layout().addWidget(QLabel()) # space # dry run self.dry_run_check_box = QCheckBox("Dry run") self.dry_run_check_box.clicked.connect(self.dry_run_clicked) self.layout().addWidget(self.dry_run_check_box) # verbose self.verbose_check_box = QCheckBox("Verbose") self.verbose_check_box.clicked.connect(self.verbose_clicked) self.layout().addWidget(self.verbose_check_box) self.layout().addStretch() # bottom padding self.load_preferences() def load_preferences(self): preferences = get_gui_preferences() self.backup_directory_line_edit.setText(preferences.backup_directory) self.aws_profile_line_edit.setText(preferences.aws_profile) self.aws_access_key_id_line_edit.setText(preferences.aws_access_key_id) self.aws_secret_access_key_line_edit.setText( preferences.aws_secret_access_key) self.aws_region_line_edit.setText(preferences.aws_region) self.github_token_line_edit.setText(preferences.github_token) self.verbose_check_box.setChecked(bool( preferences.verbose)) # None translates to False self.automatic_backup_enable_check_box.setChecked( bool(preferences.automatic_backup)) if preferences.backup_period is not None: self.automatic_backup_period.setValue(preferences.backup_period) def select_backup_directory(self): new_backup_directory = QFileDialog.getExistingDirectory( self, "Select Backup Directory") if new_backup_directory is not None and len(new_backup_directory) > 0: self.backup_directory_line_edit.setText(new_backup_directory) def backup_directory_changed(self): get_gui_preferences( ).backup_directory = self.backup_directory_line_edit.text() def aws_profile_changed(self): get_gui_preferences().aws_profile = self.aws_profile_line_edit.text() def aws_access_key_id_changed(self): get_gui_preferences( ).aws_access_key_id = self.aws_access_key_id_line_edit.text() def aws_secret_access_key_changed(self): get_gui_preferences( ).aws_secret_access_key = self.aws_secret_access_key_line_edit.text() def aws_secret_access_key_visible_clicked(self): if self.aws_secret_access_key_line_edit.echoMode( ) == PreferencesLineEdit.Password: self.aws_show_button.setText("Hide") self.aws_secret_access_key_line_edit.setEchoMode( PreferencesLineEdit.Normal) else: self.aws_show_button.setText("Show") self.aws_secret_access_key_line_edit.setEchoMode( PreferencesLineEdit.Password) def aws_region_changed(self): get_gui_preferences().aws_region = self.aws_region_line_edit.text() def github_token_changed(self): get_gui_preferences().github_token = self.github_token_line_edit.text() def github_visible_clicked(self): if self.github_token_line_edit.echoMode( ) == PreferencesLineEdit.Password: self.github_show_button.setText("Hide") self.github_token_line_edit.setEchoMode(PreferencesLineEdit.Normal) else: self.github_show_button.setText("Show") self.github_token_line_edit.setEchoMode( PreferencesLineEdit.Password) def verbose_clicked(self): get_gui_preferences().verbose = self.verbose_check_box.isChecked() def dry_run_clicked(self): get_gui_preferences().dry_run = self.dry_run_check_box.isChecked() def automatic_backup_changed(self): preferences = get_gui_preferences() preferences.automatic_backup = self.automatic_backup_enable_check_box.isChecked( ) if len(backup_period := self.automatic_backup_period.text().strip()) > 0: preferences.backup_period = int(round(float(backup_period)))
def init_ui(self): self.setWindowTitle("About") self.setFixedSize(550, 700) layout = QVBoxLayout() about_text = QLabel( "<b>DESCRIPTION</b> <br>" "In a time of great conflict, new kingdoms are born in minds of ambitious rules and willing hearts of dedicated serfs. " "Every great kingdom needs a powerful army, vivid homeland culture and thoughtful diplomacy. " "Be ready to conquer civilizations and win extensive battles, in which the key to defeating your enemy will be both hands and minds. " "Will you win by being a despotic tyrant or maybe by creating a web of secret pacts? Will your kingdom story be written by romantic tales or fearful half lies? " "Nevertheless, keep your kingdom in order and do not find your domain in the age of divisiveness.", self) about_text.setWordWrap(True) about_text.setAlignment(Qt.AlignCenter) about_text.move(10, 20) link_button = QPushButton() link_button.setMaximumHeight(150) link_button.setIconSize(QSize(300, 400)) link_button.setIcon(QIcon("resources/images/aod_logo.png")) link_button.setFlat(True) link_button.clicked.connect(self.show_github) authors_text = QLabel( "<b>AUTHORS </b> <br> Patryk Majewski, Krzysztof Szymaniak, Gabriel Wechta, Błażej Wróbel" ) authors_text.setAlignment(Qt.AlignCenter) attributions_fonts = QLabel() attributions_fonts.setText( "<b>ATTRIBUTIONS</b> <br> <a href='https://www.1001fonts.com/november-font.html'>November</a> - in game font<br> <a href='https://fontenddev.com/fonts/alkhemikal/ '>Alkhemikal</a> - logo font" ) attributions_fonts.setOpenExternalLinks(True) attributions_fonts.setAlignment(Qt.AlignCenter) attributions_images = QLabel() attributions_images.setText( "Image authors: <br> " "Aneta Pawska [<a href='https://commons.wikimedia.org/wiki/File:Ko%C5%9Bci%C3%B3%C5%82_Wang,_Karpacz.jpg#/media/File:Ko%C5%9Bci%C3%B3%C5%82_Wang,_Karpacz.jpg'>1</a>] <br>" "Paul Berzinn [<a href='https://commons.wikimedia.org/wiki/Category:Longhouse_at_Lofotr_Vikingmuseum#/media/File:Viking_museum_at_Borge_-_panoramio.jpg'>1</a>] <br>" "Jarek Tarnogórski [<a href='https://commons.wikimedia.org/wiki/Category:Archeopark_in_Chot%C4%9Bbuz#/media/File:Cieszynisko_017.JPG'>1</a>] <br>" "Boryslav Javir [<a href='https://commons.wikimedia.org/wiki/Category:Perun#/media/File:Perun7516_1_21.jpg'>1</a>] <br>" "Maunus [<a href='https://commons.wikimedia.org/wiki/File:StaCeciliaAcatitlanNorte.jpg'>1</a>] <br>" "Arian Zwegers [<a href='https://commons.wikimedia.org/wiki/File:El_Tajin,_Pyramid_of_the_Niches_(20686703945).jpg'>1</a>] " "[<a href='https://commons.wikimedia.org/wiki/File:Mitla,_Group_of_the_Columns,_Palace_of_Columns_(20064199284).jpg'>2</a>] <br>" "Martin Falbisoner [<a href='https://commons.wikimedia.org/wiki/File:Himeji_Castle,_November_2016_-02.jpg'>1</a>] <br>" "Basile Morin [<a href='https://commons.wikimedia.org/w/index.php?search=japan+&title=Special%3ASearch&go=Go&ns0=1&ns6=1&ns12=1&ns14=1&ns100=1&ns106=1#/media/File:Yasaka-dori_early_morning_with_street_lanterns_and_the_Tower_of_Yasaka_(Hokan-ji_Temple),_Kyoto,_Japan.jpg'>1</a>] <br>" "Nobrinskii [<a href='https://commons.wikimedia.org/wiki/File:Eigen-ji_(Rinzai_temple)_-_front_area.jpg'>1</a>] <br>" ) attributions_images.setOpenExternalLinks(True) attributions_images.setAlignment(Qt.AlignCenter) # for future development - "Aneta Pawska [<a href=''>1</a>] <br>" thanks_label = QLabel("Big thanks to all sources!") thanks_label.setAlignment(Qt.AlignCenter) layout.addWidget(link_button) layout.addWidget(about_text) layout.addWidget(authors_text) layout.addWidget(attributions_fonts) layout.addWidget(attributions_images) layout.addWidget(thanks_label) main_widget = QWidget() main_widget.setLayout(layout) main_widget.adjustSize() self.setCentralWidget(main_widget) self.center()
class QRegularExpressionWizardCharactersDialog( QDialog, Ui_QRegularExpressionWizardCharactersDialog): """ Class implementing a dialog for entering character classes. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(QRegularExpressionWizardCharactersDialog, self).__init__(parent) self.setupUi(self) self.__initCharacterSelectors() self.comboItems = [] self.singleComboItems = [] # these are in addition to the above self.comboItems.append((self.tr("Normal character"), "-c")) self.comboItems.append((self.tr( "Unicode character in hexadecimal notation"), "-h")) self.comboItems.append((self.tr( "ASCII/Latin1 character in octal notation"), "-o")) self.singleComboItems.extend([ ("---", "-i"), (self.tr("Bell character (\\a)"), "\\a"), (self.tr("Escape character (\\e)"), "\\e"), (self.tr("Page break (\\f)"), "\\f"), (self.tr("Line feed (\\n)"), "\\n"), (self.tr("Carriage return (\\r)"), "\\r"), (self.tr("Horizontal tabulator (\\t)"), "\\t"), ("---", "-i"), (self.tr("Character Category"), "-ccp"), (self.tr("Special Character Category"), "-csp"), (self.tr("Character Block"), "-cbp"), (self.tr("POSIX Named Set"), "-psp"), (self.tr("Not Character Category"), "-ccn"), (self.tr("Not Character Block"), "-cbn"), (self.tr("Not Special Character Category"), "-csn"), (self.tr("Not POSIX Named Set"), "-psn"), ]) self.charValidator = QRegExpValidator(QRegExp(".{0,1}"), self) self.hexValidator = QRegExpValidator(QRegExp("[0-9a-fA-F]{0,4}"), self) self.octValidator = QRegExpValidator(QRegExp("[0-3]?[0-7]{0,2}"), self) # generate dialog part for single characters self.singlesBoxLayout = QVBoxLayout(self.singlesBox) self.singlesBoxLayout.setObjectName("singlesBoxLayout") self.singlesBoxLayout.setSpacing(6) self.singlesBoxLayout.setContentsMargins(6, 6, 6, 6) self.singlesBox.setLayout(self.singlesBoxLayout) self.singlesView = QScrollArea(self.singlesBox) self.singlesView.setObjectName("singlesView") self.singlesBoxLayout.addWidget(self.singlesView) self.singlesItemsBox = QWidget(self) self.singlesView.setWidget(self.singlesItemsBox) self.singlesItemsBox.setObjectName("singlesItemsBox") self.singlesItemsBox.setMinimumWidth(1000) self.singlesItemsBoxLayout = QVBoxLayout(self.singlesItemsBox) self.singlesItemsBoxLayout.setContentsMargins(6, 6, 6, 6) self.singlesItemsBoxLayout.setSpacing(6) self.singlesItemsBox.setLayout(self.singlesItemsBoxLayout) self.singlesEntries = [] self.__addSinglesLine() hlayout0 = QHBoxLayout() hlayout0.setContentsMargins(0, 0, 0, 0) hlayout0.setSpacing(6) hlayout0.setObjectName("hlayout0") self.moreSinglesButton = QPushButton( self.tr("Additional Entries"), self.singlesBox) self.moreSinglesButton.setObjectName("moreSinglesButton") hlayout0.addWidget(self.moreSinglesButton) hspacer0 = QSpacerItem( 30, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) hlayout0.addItem(hspacer0) self.singlesBoxLayout.addLayout(hlayout0) self.moreSinglesButton.clicked.connect(self.__addSinglesLine) # generate dialog part for character ranges self.rangesBoxLayout = QVBoxLayout(self.rangesBox) self.rangesBoxLayout.setObjectName("rangesBoxLayout") self.rangesBoxLayout.setSpacing(6) self.rangesBoxLayout.setContentsMargins(6, 6, 6, 6) self.rangesBox.setLayout(self.rangesBoxLayout) self.rangesView = QScrollArea(self.rangesBox) self.rangesView.setObjectName("rangesView") self.rangesBoxLayout.addWidget(self.rangesView) self.rangesItemsBox = QWidget(self) self.rangesView.setWidget(self.rangesItemsBox) self.rangesItemsBox.setObjectName("rangesItemsBox") self.rangesItemsBox.setMinimumWidth(1000) self.rangesItemsBoxLayout = QVBoxLayout(self.rangesItemsBox) self.rangesItemsBoxLayout.setContentsMargins(6, 6, 6, 6) self.rangesItemsBoxLayout.setSpacing(6) self.rangesItemsBox.setLayout(self.rangesItemsBoxLayout) self.rangesEntries = [] self.__addRangesLine() hlayout1 = QHBoxLayout() hlayout1.setContentsMargins(0, 0, 0, 0) hlayout1.setSpacing(6) hlayout1.setObjectName("hlayout1") self.moreRangesButton = QPushButton( self.tr("Additional Entries"), self.rangesBox) self.moreSinglesButton.setObjectName("moreRangesButton") hlayout1.addWidget(self.moreRangesButton) hspacer1 = QSpacerItem( 30, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) hlayout1.addItem(hspacer1) self.rangesBoxLayout.addLayout(hlayout1) self.moreRangesButton.clicked.connect(self.__addRangesLine) def __initCharacterSelectors(self): """ Private method to initialize the W3C character selector entries. """ self.__characterCategories = ( # display name code (self.tr("Letter, Any"), "L"), (self.tr("Letter, Lower case"), "Ll"), (self.tr("Letter, Modifier"), "Lm"), (self.tr("Letter, Other"), "Lo"), (self.tr("Letter, Title case"), "Lt"), (self.tr("Letter, Upper case"), "Lu"), (self.tr("Letter, Lower, Upper or Title"), "L&"), (self.tr("Mark, Any"), "M"), (self.tr("Mark, Spacing"), "Mc"), (self.tr("Mark, Enclosing"), "Me"), (self.tr("Mark, Non-spacing"), "Mn"), (self.tr("Number, Any"), "N"), (self.tr("Number, Decimal"), "Nd"), (self.tr("Number, Letter"), "Nl"), (self.tr("Number, Other"), "No"), (self.tr("Punctuation, Any"), "P"), (self.tr("Punctuation, Connector"), "Pc"), (self.tr("Punctuation, Dash"), "Pd"), (self.tr("Punctuation, Close"), "Pe"), (self.tr("Punctuation, Final"), "Pf"), (self.tr("Punctuation, Initial"), "Pi"), (self.tr("Punctuation, Other"), "Po"), (self.tr("Punctuation, Open"), "Ps"), (self.tr("Symbol, Any"), "S"), (self.tr("Symbol, Currency"), "Sc"), (self.tr("Symbol, Modifier"), "Sk"), (self.tr("Symbol, Mathematical"), "Sm"), (self.tr("Symbol, Other"), "So"), (self.tr("Separator, Any"), "Z"), (self.tr("Separator, Line"), "Zl"), (self.tr("Separator, Paragraph"), "Zp"), (self.tr("Separator, Space"), "Zs"), (self.tr("Other, Any"), "C"), (self.tr("Other, Control"), "Cc"), (self.tr("Other, Format"), "Cf"), (self.tr("Other, Unassigned"), "Cn"), (self.tr("Other, Private Use"), "Co"), (self.tr("Other, Surrogat"), "Cn"), ) self.__specialCharacterCategories = ( # display name code (self.tr("Alphanumeric"), "Xan"), (self.tr("POSIX Space"), "Xps"), (self.tr("Perl Space"), "Xsp"), (self.tr("Universal Character"), "Xuc"), (self.tr("Perl Word"), "Xan"), ) self.__characterBlocks = ( # display name code (self.tr("Arabic"), "Arabic"), (self.tr("Armenian"), "Armenian"), (self.tr("Avestan"), "Avestan"), (self.tr("Balinese"), "Balinese"), (self.tr("Bamum"), "Bamum"), (self.tr("Batak"), "Batak"), (self.tr("Bengali"), "Bengali"), (self.tr("Bopomofo"), "Bopomofo"), (self.tr("Brahmi"), "Brahmi"), (self.tr("Braille"), "Braille"), (self.tr("Buginese"), "Buginese"), (self.tr("Buhid"), "Buhid"), (self.tr("Canadian Aboriginal"), "Canadian_Aboriginal"), (self.tr("Carian"), "Carian"), (self.tr("Chakma"), "Chakma"), (self.tr("Cham"), "Cham"), (self.tr("Cherokee"), "Cherokee"), (self.tr("Common"), "Common"), (self.tr("Coptic"), "Coptic"), (self.tr("Cuneiform"), "Cuneiform"), (self.tr("Cypriot"), "Cypriot"), (self.tr("Cyrillic"), "Cyrillic"), (self.tr("Deseret"), "Deseret,"), (self.tr("Devanagari"), "Devanagari"), (self.tr("Egyptian Hieroglyphs"), "Egyptian_Hieroglyphs"), (self.tr("Ethiopic"), "Ethiopic"), (self.tr("Georgian"), "Georgian"), (self.tr("Glagolitic"), "Glagolitic"), (self.tr("Gothic"), "Gothic"), (self.tr("Greek"), "Greek"), (self.tr("Gujarati"), "Gujarati"), (self.tr("Gurmukhi"), "Gurmukhi"), (self.tr("Han"), "Han"), (self.tr("Hangul"), "Hangul"), (self.tr("Hanunoo"), "Hanunoo"), (self.tr("Hebrew"), "Hebrew"), (self.tr("Hiragana"), "Hiragana"), (self.tr("Imperial Aramaic"), "Imperial_Aramaic"), (self.tr("Inherited"), "Inherited"), (self.tr("Inscriptional Pahlavi"), "Inscriptional_Pahlavi"), (self.tr("Inscriptional Parthian"), "Inscriptional_Parthian"), (self.tr("Javanese"), "Javanese"), (self.tr("Kaithi"), "Kaithi"), (self.tr("Kannada"), "Kannada"), (self.tr("Katakana"), "Katakana"), (self.tr("Kayah Li"), "Kayah_Li"), (self.tr("Kharoshthi"), "Kharoshthi"), (self.tr("Khmer"), "Khmer"), (self.tr("Lao"), "Lao"), (self.tr("Latin"), "Latin"), (self.tr("Lepcha"), "Lepcha"), (self.tr("Limbu"), "Limbu"), (self.tr("Linear B"), "Linear_B"), (self.tr("Lisu"), "Lisu"), (self.tr("Lycian"), "Lycian"), (self.tr("Lydian"), "Lydian"), (self.tr("Malayalam"), "Malayalam"), (self.tr("Mandaic"), "Mandaic"), (self.tr("Meetei Mayek"), "Meetei_Mayek"), (self.tr("Meroitic Cursive"), "Meroitic_Cursive"), (self.tr("Meroitic Hieroglyphs"), "Meroitic_Hieroglyphs"), (self.tr("Miao"), "Miao"), (self.tr("Mongolian"), "Mongolian"), (self.tr("Myanmar"), "Myanmar"), (self.tr("New Tai Lue"), "New_Tai_Lue"), (self.tr("N'Ko"), "Nko"), (self.tr("Ogham"), "Ogham"), (self.tr("Old Italic"), "Old_Italic"), (self.tr("Old Persian"), "Old_Persian"), (self.tr("Old South Arabian"), "Old_South_Arabian"), (self.tr("Old Turkic"), "Old_Turkic,"), (self.tr("Ol Chiki"), "Ol_Chiki"), (self.tr("Oriya"), "Oriya"), (self.tr("Osmanya"), "Osmanya"), (self.tr("Phags-pa"), "Phags_Pa"), (self.tr("Phoenician"), "Phoenician"), (self.tr("Rejang"), "Rejang"), (self.tr("Runic"), "Runic"), (self.tr("Samaritan"), "Samaritan"), (self.tr("Saurashtra"), "Saurashtra"), (self.tr("Sharada"), "Sharada"), (self.tr("Shavian"), "Shavian"), (self.tr("Sinhala"), "Sinhala"), (self.tr("Sora Sompeng"), "Sora_Sompeng"), (self.tr("Sundanese"), "Sundanese"), (self.tr("Syloti Nagri"), "Syloti_Nagri"), (self.tr("Syriac"), "Syriac"), (self.tr("Tagalog"), "Tagalog"), (self.tr("Tagbanwa"), "Tagbanwa"), (self.tr("Tai Le"), "Tai_Le"), (self.tr("Tai Tham"), "Tai_Tham"), (self.tr("Tai Viet"), "Tai_Viet"), (self.tr("Takri"), "Takri"), (self.tr("Tamil"), "Tamil"), (self.tr("Telugu"), "Telugu"), (self.tr("Thaana"), "Thaana"), (self.tr("Thai"), "Thai"), (self.tr("Tibetan"), "Tibetan"), (self.tr("Tifinagh"), "Tifinagh"), (self.tr("Ugaritic"), "Ugaritic"), (self.tr("Vai"), "Vai"), (self.tr("Yi"), "Yi"), ) self.__posixNamedSets = ( # display name code (self.tr("Alphanumeric"), "alnum"), (self.tr("Alphabetic"), "alpha"), (self.tr("ASCII"), "ascii"), (self.tr("Word Letter"), "word"), (self.tr("Lower Case Letter"), "lower"), (self.tr("Upper Case Letter"), "upper"), (self.tr("Decimal Digit"), "digit"), (self.tr("Hexadecimal Digit"), "xdigit"), (self.tr("Space or Tab"), "blank"), (self.tr("White Space"), "space"), (self.tr("Printing (excl. space)"), "graph"), (self.tr("Printing (incl. space)"), "print"), (self.tr("Printing (excl. alphanumeric)"), "punct"), (self.tr("Control Character"), "cntrl"), ) def __populateCharTypeCombo(self, combo, isSingle): """ Private method to populate a given character type selection combo box. @param combo reference to the combo box to be populated (QComboBox) @param isSingle flag indicating a singles combo (boolean) """ for txt, value in self.comboItems: combo.addItem(txt, value) if isSingle: for txt, value in self.singleComboItems: combo.addItem(txt, value) def __addSinglesLine(self): """ Private slot to add a line of entry widgets for single characters. """ hbox = QWidget(self.singlesItemsBox) hboxLayout = QHBoxLayout(hbox) hboxLayout.setContentsMargins(0, 0, 0, 0) hboxLayout.setSpacing(6) hbox.setLayout(hboxLayout) cb1 = QComboBox(hbox) cb1.setEditable(False) self.__populateCharTypeCombo(cb1, True) hboxLayout.addWidget(cb1) le1 = QLineEdit(hbox) le1.setValidator(self.charValidator) hboxLayout.addWidget(le1) cb1a = QComboBox(hbox) cb1a.setEditable(False) cb1a.setSizeAdjustPolicy(QComboBox.AdjustToContents) hboxLayout.addWidget(cb1a) cb1a.hide() cb2 = QComboBox(hbox) cb2.setEditable(False) self.__populateCharTypeCombo(cb2, True) hboxLayout.addWidget(cb2) le2 = QLineEdit(hbox) le2.setValidator(self.charValidator) hboxLayout.addWidget(le2) cb2a = QComboBox(hbox) cb2a.setEditable(False) cb2a.setSizeAdjustPolicy(QComboBox.AdjustToContents) hboxLayout.addWidget(cb2a) cb2a.hide() self.singlesItemsBoxLayout.addWidget(hbox) cb1.activated[int].connect(self.__singlesCharTypeSelected) cb2.activated[int].connect(self.__singlesCharTypeSelected) hbox.show() self.singlesItemsBox.adjustSize() self.singlesEntries.append([cb1, le1, cb1a]) self.singlesEntries.append([cb2, le2, cb2a]) def __addRangesLine(self): """ Private slot to add a line of entry widgets for character ranges. """ hbox = QWidget(self.rangesItemsBox) hboxLayout = QHBoxLayout(hbox) hboxLayout.setContentsMargins(0, 0, 0, 0) hboxLayout.setSpacing(6) hbox.setLayout(hboxLayout) cb1 = QComboBox(hbox) cb1.setEditable(False) self.__populateCharTypeCombo(cb1, False) hboxLayout.addWidget(cb1) l1 = QLabel(self.tr("Between:"), hbox) hboxLayout.addWidget(l1) le1 = QLineEdit(hbox) le1.setValidator(self.charValidator) hboxLayout.addWidget(le1) l2 = QLabel(self.tr("And:"), hbox) hboxLayout.addWidget(l2) le2 = QLineEdit(hbox) le2.setValidator(self.charValidator) hboxLayout.addWidget(le2) self.rangesItemsBoxLayout.addWidget(hbox) cb1.activated[int].connect(self.__rangesCharTypeSelected) hbox.show() self.rangesItemsBox.adjustSize() self.rangesEntries.append([cb1, le1, le2]) def __populateCharacterCombo(self, combo, format): """ Private method to populate a character selection combo. @param combo combo box to be populated (QComboBox) @param format format identifier (one of "-ccp", "-ccn", "-cbp", "-cbn", "-csp", "-csn", "-psp", "-psn") """ combo.clear() if format in ["-ccp", "-ccn"]: items = self.__characterCategories elif format in ["-csp", "-csn"]: items = self.__specialCharacterCategories elif format in ["-cbp", "-cbn"]: items = self.__characterBlocks elif format in ["-psp", "-psn"]: items = self.__posixNamedSets comboLen = 0 for txt, code in items: combo.addItem(txt, code) comboLen = max(comboLen, len(txt)) combo.setMinimumContentsLength(comboLen) def __performSelectedAction(self, format, lineedit, combo): """ Private method performing some actions depending on the input. @param format format of the selected entry (string) @param lineedit line edit widget to act on (QLineEdit) @param combo combo box widget to act on (QComboBox) """ if format == "-i": return if format in ["-c", "-h", "-o"]: lineedit.show() lineedit.setEnabled(True) if combo is not None: combo.hide() if format == "-c": lineedit.setValidator(self.charValidator) elif format == "-h": lineedit.setValidator(self.hexValidator) elif format == "-o": lineedit.setValidator(self.octValidator) elif format in ["-ccp", "-ccn", "-cbp", "-cbn", "-csp", "-csn", "-psp", "-psn"]: lineedit.setEnabled(False) lineedit.hide() if combo is not None: combo.show() self.__populateCharacterCombo(combo, format) else: lineedit.setEnabled(False) lineedit.hide() if combo is not None: combo.hide() lineedit.clear() def __singlesCharTypeSelected(self, index): """ Private slot to handle the activated(int) signal of the single chars combo boxes. @param index selected list index (integer) """ combo = self.sender() for entriesList in self.singlesEntries: if combo == entriesList[0]: format = combo.itemData(index) self.__performSelectedAction( format, entriesList[1], entriesList[2]) break def __rangesCharTypeSelected(self, index): """ Private slot to handle the activated(int) signal of the char ranges combo boxes. @param index selected list index (integer) """ combo = self.sender() for entriesList in self.rangesEntries: if combo == entriesList[0]: format = combo.itemData(index) self.__performSelectedAction(format, entriesList[1], None) self.__performSelectedAction(format, entriesList[2], None) break def __formatCharacter(self, char, format): """ Private method to format the characters entered into the dialog. @param char character string entered into the dialog (string) @param format string giving a special format (-c, -h, -i or -o) or the already formatted character (string) @return formatted character string (string) """ if format == "-c": return char elif format == "-i": return "" if format == "-h": while len(char) < 2: char = "0" + char if len(char) > 2: return "\\x{{{0}}}".format(char.lower()) else: return "\\x{0}".format(char.lower()) elif format == "-o": while len(char) < 3: char = "0" + char if len(char) > 3: char = char[:3] return "\\{0}".format(char) elif format in ["-ccp", "-cbp", "-csp"]: return "\\p{{{0}}}".format(char) elif format in ["-ccn", "-cbn", "-csn"]: return "\\P{{{0}}}".format(char) elif format == "-psp": return "[:{0}:]".format(char) elif format == "-psn": return "[:^{0}:]".format(char) else: return format def getCharacters(self): """ Public method to return the character string assembled via the dialog. @return formatted string for character classes (string) """ regexp = "" # negative character range if self.negativeCheckBox.isChecked(): regexp += "^" # predefined character ranges if self.wordCharCheckBox.isChecked(): regexp += "\\w" if self.nonWordCharCheckBox.isChecked(): regexp += "\\W" if self.digitsCheckBox.isChecked(): regexp += "\\d" if self.nonDigitsCheckBox.isChecked(): regexp += "\\D" if self.newlineCheckBox.isChecked(): regexp += "\\R" if self.nonNewlineCheckBox.isChecked(): regexp += "\\N" if self.whitespaceCheckBox.isChecked(): regexp += "\\s" if self.nonWhitespaceCheckBox.isChecked(): regexp += "\\S" if self.horizontalWhitespaceCheckBox.isChecked(): regexp += "\\h" if self.nonHorizontalWhitespaceCheckBox.isChecked(): regexp += "\\H" if self.verticalWhitespaceCheckBox.isChecked(): regexp += "\\v" if self.nonVerticalWhitespaceCheckBox.isChecked(): regexp += "\\V" # single characters for entrieslist in self.singlesEntries: format = entrieslist[0].itemData(entrieslist[0].currentIndex()) if format in ["-ccp", "-ccn", "-cbp", "-cbn", "-csp", "-csn", "-psp", "-psn"]: char = entrieslist[2].itemData(entrieslist[2].currentIndex()) else: char = entrieslist[1].text() regexp += self.__formatCharacter(char, format) # character ranges for entrieslist in self.rangesEntries: if not entrieslist[1].text() or \ not entrieslist[2].text(): continue format = entrieslist[0].itemData(entrieslist[0].currentIndex()) char1 = entrieslist[1].text() char2 = entrieslist[2].text() regexp += "{0}-{1}".format( self.__formatCharacter(char1, format), self.__formatCharacter(char2, format)) if regexp: if (regexp.startswith("\\") and regexp.count("\\") == 1 and "-" not in regexp) or \ len(regexp) == 1: return regexp else: return "[{0}]".format(regexp) else: return ""
class QRegExpWizardCharactersDialog(QDialog, Ui_QRegExpWizardCharactersDialog): """ Class implementing a dialog for entering character classes. """ RegExpMode = 0 WildcardMode = 1 W3CMode = 2 def __init__(self, mode=RegExpMode, parent=None): """ Constructor @param mode mode of the dialog (one of RegExpMode, WildcardMode, W3CMode) @param parent parent widget (QWidget) """ super(QRegExpWizardCharactersDialog, self).__init__(parent) self.setupUi(self) self.__mode = mode if mode == QRegExpWizardCharactersDialog.WildcardMode: self.predefinedBox.setEnabled(False) self.predefinedBox.hide() elif mode == QRegExpWizardCharactersDialog.RegExpMode: self.w3cInitialIdentifierCheckBox.hide() self.w3cNonInitialIdentifierCheckBox.hide() self.w3cNmtokenCheckBox.hide() self.w3cNonNmtokenCheckBox.hide() elif mode == QRegExpWizardCharactersDialog.W3CMode: self.__initCharacterSelectors() self.comboItems = [] self.singleComboItems = [] # these are in addition to the above self.comboItems.append((self.tr("Normal character"), "-c")) if mode == QRegExpWizardCharactersDialog.RegExpMode: self.comboItems.append( (self.tr("Unicode character in hexadecimal notation"), "-h")) self.comboItems.append( (self.tr("ASCII/Latin1 character in octal notation"), "-o")) self.singleComboItems.append(("---", "-i")) self.singleComboItems.append( (self.tr("Bell character (\\a)"), "\\a")) self.singleComboItems.append((self.tr("Page break (\\f)"), "\\f")) self.singleComboItems.append((self.tr("Line feed (\\n)"), "\\n")) self.singleComboItems.append( (self.tr("Carriage return (\\r)"), "\\r")) self.singleComboItems.append( (self.tr("Horizontal tabulator (\\t)"), "\\t")) self.singleComboItems.append( (self.tr("Vertical tabulator (\\v)"), "\\v")) elif mode == QRegExpWizardCharactersDialog.W3CMode: self.comboItems.append( (self.tr("Unicode character in hexadecimal notation"), "-h")) self.comboItems.append( (self.tr("ASCII/Latin1 character in octal notation"), "-o")) self.singleComboItems.append(("---", "-i")) self.singleComboItems.append((self.tr("Line feed (\\n)"), "\\n")) self.singleComboItems.append( (self.tr("Carriage return (\\r)"), "\\r")) self.singleComboItems.append( (self.tr("Horizontal tabulator (\\t)"), "\\t")) self.singleComboItems.append(("---", "-i")) self.singleComboItems.append( (self.tr("Character Category"), "-ccp")) self.singleComboItems.append((self.tr("Character Block"), "-cbp")) self.singleComboItems.append( (self.tr("Not Character Category"), "-ccn")) self.singleComboItems.append( (self.tr("Not Character Block"), "-cbn")) self.charValidator = QRegExpValidator(QRegExp(".{0,1}"), self) self.hexValidator = QRegExpValidator(QRegExp("[0-9a-fA-F]{0,4}"), self) self.octValidator = QRegExpValidator(QRegExp("[0-3]?[0-7]{0,2}"), self) # generate dialog part for single characters self.singlesBoxLayout = QVBoxLayout(self.singlesBox) self.singlesBoxLayout.setObjectName("singlesBoxLayout") self.singlesBoxLayout.setSpacing(6) self.singlesBoxLayout.setContentsMargins(6, 6, 6, 6) self.singlesBox.setLayout(self.singlesBoxLayout) self.singlesView = QScrollArea(self.singlesBox) self.singlesView.setObjectName("singlesView") self.singlesBoxLayout.addWidget(self.singlesView) self.singlesItemsBox = QWidget(self) self.singlesView.setWidget(self.singlesItemsBox) self.singlesItemsBox.setObjectName("singlesItemsBox") self.singlesItemsBox.setMinimumWidth(1000) self.singlesItemsBoxLayout = QVBoxLayout(self.singlesItemsBox) self.singlesItemsBoxLayout.setContentsMargins(6, 6, 6, 6) self.singlesItemsBoxLayout.setSpacing(6) self.singlesItemsBox.setLayout(self.singlesItemsBoxLayout) self.singlesEntries = [] self.__addSinglesLine() hlayout0 = QHBoxLayout() hlayout0.setContentsMargins(0, 0, 0, 0) hlayout0.setSpacing(6) hlayout0.setObjectName("hlayout0") self.moreSinglesButton = QPushButton(self.tr("Additional Entries"), self.singlesBox) self.moreSinglesButton.setObjectName("moreSinglesButton") hlayout0.addWidget(self.moreSinglesButton) hspacer0 = QSpacerItem(30, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) hlayout0.addItem(hspacer0) self.singlesBoxLayout.addLayout(hlayout0) self.moreSinglesButton.clicked.connect(self.__addSinglesLine) # generate dialog part for character ranges self.rangesBoxLayout = QVBoxLayout(self.rangesBox) self.rangesBoxLayout.setObjectName("rangesBoxLayout") self.rangesBoxLayout.setSpacing(6) self.rangesBoxLayout.setContentsMargins(6, 6, 6, 6) self.rangesBox.setLayout(self.rangesBoxLayout) self.rangesView = QScrollArea(self.rangesBox) self.rangesView.setObjectName("rangesView") self.rangesBoxLayout.addWidget(self.rangesView) self.rangesItemsBox = QWidget(self) self.rangesView.setWidget(self.rangesItemsBox) self.rangesItemsBox.setObjectName("rangesItemsBox") self.rangesItemsBox.setMinimumWidth(1000) self.rangesItemsBoxLayout = QVBoxLayout(self.rangesItemsBox) self.rangesItemsBoxLayout.setContentsMargins(6, 6, 6, 6) self.rangesItemsBoxLayout.setSpacing(6) self.rangesItemsBox.setLayout(self.rangesItemsBoxLayout) self.rangesEntries = [] self.__addRangesLine() hlayout1 = QHBoxLayout() hlayout1.setContentsMargins(0, 0, 0, 0) hlayout1.setSpacing(6) hlayout1.setObjectName("hlayout1") self.moreRangesButton = QPushButton(self.tr("Additional Entries"), self.rangesBox) self.moreSinglesButton.setObjectName("moreRangesButton") hlayout1.addWidget(self.moreRangesButton) hspacer1 = QSpacerItem(30, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) hlayout1.addItem(hspacer1) self.rangesBoxLayout.addLayout(hlayout1) self.moreRangesButton.clicked.connect(self.__addRangesLine) def __initCharacterSelectors(self): """ Private method to initialize the W3C character selector entries. """ self.__characterCategories = ( # display name code (self.tr("Letter, Any"), "L"), (self.tr("Letter, Uppercase"), "Lu"), (self.tr("Letter, Lowercase"), "Ll"), (self.tr("Letter, Titlecase"), "Lt"), (self.tr("Letter, Modifier"), "Lm"), (self.tr("Letter, Other"), "Lo"), (self.tr("Mark, Any"), "M"), (self.tr("Mark, Nonspacing"), "Mn"), (self.tr("Mark, Spacing Combining"), "Mc"), (self.tr("Mark, Enclosing"), "Me"), (self.tr("Number, Any"), "N"), (self.tr("Number, Decimal Digit"), "Nd"), (self.tr("Number, Letter"), "Nl"), (self.tr("Number, Other"), "No"), (self.tr("Punctuation, Any"), "P"), (self.tr("Punctuation, Connector"), "Pc"), (self.tr("Punctuation, Dash"), "Pd"), (self.tr("Punctuation, Open"), "Ps"), (self.tr("Punctuation, Close"), "Pe"), (self.tr("Punctuation, Initial Quote"), "Pi"), (self.tr("Punctuation, Final Quote"), "Pf"), (self.tr("Punctuation, Other"), "Po"), (self.tr("Symbol, Any"), "S"), (self.tr("Symbol, Math"), "Sm"), (self.tr("Symbol, Currency"), "Sc"), (self.tr("Symbol, Modifier"), "Sk"), (self.tr("Symbol, Other"), "So"), (self.tr("Separator, Any"), "Z"), (self.tr("Separator, Space"), "Zs"), (self.tr("Separator, Line"), "Zl"), (self.tr("Separator, Paragraph"), "Zp"), (self.tr("Other, Any"), "C"), (self.tr("Other, Control"), "Cc"), (self.tr("Other, Format"), "Cf"), (self.tr("Other, Private Use"), "Co"), (self.tr("Other, Not Assigned"), "Cn"), ) self.__characterBlocks = ( (self.tr("Basic Latin"), "IsBasicLatin"), (self.tr("Latin-1 Supplement"), "IsLatin-1Supplement"), (self.tr("Latin Extended-A"), "IsLatinExtended-A"), (self.tr("Latin Extended-B"), "IsLatinExtended-B"), (self.tr("IPA Extensions"), "IsIPAExtensions"), (self.tr("Spacing Modifier Letters"), "IsSpacingModifierLetters"), (self.tr("Combining Diacritical Marks"), "IsCombiningDiacriticalMarks"), (self.tr("Greek"), "IsGreek"), (self.tr("Cyrillic"), "IsCyrillic"), (self.tr("Armenian"), "IsArmenian"), (self.tr("Hebrew"), "IsHebrew"), (self.tr("Arabic"), "IsArabic"), (self.tr("Syriac"), "IsSyriac"), (self.tr("Thaana"), "IsThaana"), (self.tr("Devanagari"), "IsDevanagari"), (self.tr("Bengali"), "IsBengali"), (self.tr("Gurmukhi"), "IsBengali"), (self.tr("Gujarati"), "IsGujarati"), (self.tr("Oriya"), "IsOriya"), (self.tr("Tamil"), "IsTamil"), (self.tr("Telugu"), "IsTelugu"), (self.tr("Kannada"), "IsKannada"), (self.tr("Malayalam"), "IsMalayalam"), (self.tr("Sinhala"), "IsSinhala"), (self.tr("Thai"), "IsThai"), (self.tr("Lao"), "IsLao"), (self.tr("Tibetan"), "IsTibetan"), (self.tr("Myanmar"), "IsMyanmar"), (self.tr("Georgian"), "IsGeorgian"), (self.tr("Hangul Jamo"), "IsHangulJamo"), (self.tr("Ethiopic"), "IsEthiopic"), (self.tr("Cherokee"), "IsCherokee"), (self.tr("Unified Canadian Aboriginal Syllabics"), "IsUnifiedCanadianAboriginalSyllabics"), (self.tr("Ogham"), "IsOgham"), (self.tr("Runic"), "IsRunic"), (self.tr("Khmer"), "IsKhmer"), (self.tr("Mongolian"), "IsMongolian"), (self.tr("Latin Extended Additional"), "IsLatinExtendedAdditional"), (self.tr("Greek Extended"), "IsGreekExtended"), (self.tr("General Punctuation"), "IsGeneralPunctuation"), (self.tr("Superscripts and Subscripts"), "IsSuperscriptsandSubscripts"), (self.tr("Currency Symbols"), "IsCurrencySymbols"), (self.tr("Combining Marks for Symbols"), "IsCombiningMarksforSymbols"), (self.tr("Letterlike Symbols"), "IsLetterlikeSymbols"), (self.tr("Number Forms"), "IsNumberForms"), (self.tr("Arrows"), "IsArrows"), (self.tr("Mathematical Operators"), "IsMathematicalOperators"), (self.tr("Miscellaneous Technical"), "IsMiscellaneousTechnical"), (self.tr("Control Pictures"), "IsControlPictures"), (self.tr("Optical Character Recognition"), "IsOpticalCharacterRecognition"), (self.tr("Enclosed Alphanumerics"), "IsEnclosedAlphanumerics"), (self.tr("Box Drawing"), "IsBoxDrawing"), (self.tr("Block Elements"), "IsBlockElements"), (self.tr("Geometric Shapes"), "IsGeometricShapes"), (self.tr("Miscellaneous Symbols"), "IsMiscellaneousSymbols"), (self.tr("Dingbats"), "IsDingbats"), (self.tr("Braille Patterns"), "IsBraillePatterns"), (self.tr("CJK Radicals Supplement"), "IsCJKRadicalsSupplement"), (self.tr("KangXi Radicals"), "IsKangXiRadicals"), (self.tr("Ideographic Description Chars"), "IsIdeographicDescriptionChars"), (self.tr("CJK Symbols and Punctuation"), "IsCJKSymbolsandPunctuation"), (self.tr("Hiragana"), "IsHiragana"), (self.tr("Katakana"), "IsKatakana"), (self.tr("Bopomofo"), "IsBopomofo"), (self.tr("Hangul Compatibility Jamo"), "IsHangulCompatibilityJamo"), (self.tr("Kanbun"), "IsKanbun"), (self.tr("Bopomofo Extended"), "IsBopomofoExtended"), (self.tr("Enclosed CJK Letters and Months"), "IsEnclosedCJKLettersandMonths"), (self.tr("CJK Compatibility"), "IsCJKCompatibility"), (self.tr("CJK Unified Ideographs Extension A"), "IsCJKUnifiedIdeographsExtensionA"), (self.tr("CJK Unified Ideographs"), "IsCJKUnifiedIdeographs"), (self.tr("Yi Syllables"), "IsYiSyllables"), (self.tr("Yi Radicals"), "IsYiRadicals"), (self.tr("Hangul Syllables"), "IsHangulSyllables"), (self.tr("Private Use"), "IsPrivateUse"), (self.tr("CJK Compatibility Ideographs"), "IsCJKCompatibilityIdeographs"), (self.tr("Alphabetic Presentation Forms"), "IsAlphabeticPresentationForms"), (self.tr("Arabic Presentation Forms-A"), "IsArabicPresentationForms-A"), (self.tr("Combining Half Marks"), "IsCombiningHalfMarks"), (self.tr("CJK Compatibility Forms"), "IsCJKCompatibilityForms"), (self.tr("Small Form Variants"), "IsSmallFormVariants"), (self.tr("Arabic Presentation Forms-B"), "IsArabicPresentationForms-B"), (self.tr("Halfwidth and Fullwidth Forms"), "IsHalfwidthandFullwidthForms"), (self.tr("Specials"), "IsSpecials"), (self.tr("Old Italic"), "IsOldItalic"), (self.tr("Gothic"), "IsGothic"), (self.tr("Deseret"), "IsDeseret"), (self.tr("Byzantine Musical Symbols"), "IsByzantineMusicalSymbols"), (self.tr("Musical Symbols"), "IsMusicalSymbols"), (self.tr("Mathematical Alphanumeric Symbols"), "IsMathematicalAlphanumericSymbols"), (self.tr("CJK Unified Ideographic Extension B"), "IsCJKUnifiedIdeographicExtensionB"), (self.tr("CJK Compatapility Ideographic Supplement"), "IsCJKCompatapilityIdeographicSupplement"), (self.tr("Tags"), "IsTags"), ) def __populateCharTypeCombo(self, combo, isSingle): """ Private method to populate a given character type selection combo box. @param combo reference to the combo box to be populated (QComboBox) @param isSingle flag indicating a singles combo (boolean) """ for txt, value in self.comboItems: combo.addItem(txt, value) if isSingle: for txt, value in self.singleComboItems: combo.addItem(txt, value) def __addSinglesLine(self): """ Private slot to add a line of entry widgets for single characters. """ hbox = QWidget(self.singlesItemsBox) hboxLayout = QHBoxLayout(hbox) hboxLayout.setContentsMargins(0, 0, 0, 0) hboxLayout.setSpacing(6) hbox.setLayout(hboxLayout) cb1 = QComboBox(hbox) cb1.setEditable(False) self.__populateCharTypeCombo(cb1, True) hboxLayout.addWidget(cb1) le1 = QLineEdit(hbox) le1.setValidator(self.charValidator) hboxLayout.addWidget(le1) cb1a = QComboBox(hbox) cb1a.setEditable(False) cb1a.setSizeAdjustPolicy(QComboBox.AdjustToContents) hboxLayout.addWidget(cb1a) cb1a.hide() cb2 = QComboBox(hbox) cb2.setEditable(False) self.__populateCharTypeCombo(cb2, True) hboxLayout.addWidget(cb2) le2 = QLineEdit(hbox) le2.setValidator(self.charValidator) hboxLayout.addWidget(le2) cb2a = QComboBox(hbox) cb2a.setEditable(False) cb2a.setSizeAdjustPolicy(QComboBox.AdjustToContents) hboxLayout.addWidget(cb2a) cb2a.hide() self.singlesItemsBoxLayout.addWidget(hbox) cb1.activated[int].connect(self.__singlesCharTypeSelected) cb2.activated[int].connect(self.__singlesCharTypeSelected) hbox.show() self.singlesItemsBox.adjustSize() self.singlesEntries.append([cb1, le1, cb1a]) self.singlesEntries.append([cb2, le2, cb2a]) def __addRangesLine(self): """ Private slot to add a line of entry widgets for character ranges. """ hbox = QWidget(self.rangesItemsBox) hboxLayout = QHBoxLayout(hbox) hboxLayout.setContentsMargins(0, 0, 0, 0) hboxLayout.setSpacing(6) hbox.setLayout(hboxLayout) cb1 = QComboBox(hbox) cb1.setEditable(False) self.__populateCharTypeCombo(cb1, False) hboxLayout.addWidget(cb1) l1 = QLabel(self.tr("Between:"), hbox) hboxLayout.addWidget(l1) le1 = QLineEdit(hbox) le1.setValidator(self.charValidator) hboxLayout.addWidget(le1) l2 = QLabel(self.tr("And:"), hbox) hboxLayout.addWidget(l2) le2 = QLineEdit(hbox) le2.setValidator(self.charValidator) hboxLayout.addWidget(le2) self.rangesItemsBoxLayout.addWidget(hbox) cb1.activated[int].connect(self.__rangesCharTypeSelected) hbox.show() self.rangesItemsBox.adjustSize() self.rangesEntries.append([cb1, le1, le2]) def __populateW3cCharacterCombo(self, combo, format): """ Private method to populate a W3C character selection combo. @param combo combo box to be populated (QComboBox) @param format format identifier (one of "-ccp", "-ccn", "-cbp", "-cbn") """ combo.clear() if format in ["-ccp", "-ccn"]: comboLen = 0 for txt, code in self.__characterCategories: combo.addItem(txt, code) comboLen = max(comboLen, len(txt)) combo.setMinimumContentsLength(comboLen) elif format in ["-cbp", "-cbn"]: comboLen = 0 for txt, code in self.__characterBlocks: combo.addItem(txt, code) comboLen = max(comboLen, len(txt)) combo.setMinimumContentsLength(comboLen) def __performSelectedAction(self, format, lineedit, combo): """ Private method performing some actions depending on the input. @param format format of the selected entry (string) @param lineedit line edit widget to act on (QLineEdit) @param combo combo box widget to act on (QComboBox) """ if format == "-i": return if format in ["-c", "-h", "-o"]: lineedit.show() lineedit.setEnabled(True) if combo is not None: combo.hide() if format == "-c": lineedit.setValidator(self.charValidator) elif format == "-h": lineedit.setValidator(self.hexValidator) elif format == "-o": lineedit.setValidator(self.octValidator) elif format in ["-ccp", "-ccn", "-cbp", "-cbn"]: lineedit.setEnabled(False) lineedit.hide() if combo is not None: combo.show() self.__populateW3cCharacterCombo(combo, format) else: lineedit.setEnabled(False) lineedit.hide() if combo is not None: combo.hide() lineedit.clear() def __singlesCharTypeSelected(self, index): """ Private slot to handle the activated(int) signal of the single chars combo boxes. @param index selected list index (integer) """ combo = self.sender() for entriesList in self.singlesEntries: if combo == entriesList[0]: format = combo.itemData(index) self.__performSelectedAction(format, entriesList[1], entriesList[2]) break def __rangesCharTypeSelected(self, index): """ Private slot to handle the activated(int) signal of the char ranges combo boxes. @param index selected list index (integer) """ combo = self.sender() for entriesList in self.rangesEntries: if combo == entriesList[0]: format = combo.itemData(index) self.__performSelectedAction(format, entriesList[1], None) self.__performSelectedAction(format, entriesList[2], None) break def __formatCharacter(self, char, format): """ Private method to format the characters entered into the dialog. @param char character string entered into the dialog (string) @param format string giving a special format (-c, -h, -i or -o) or the already formatted character (string) @return formatted character string (string) """ if format == "-c": return char elif format == "-i": return "" if self.__mode in [ QRegExpWizardCharactersDialog.RegExpMode, QRegExpWizardCharactersDialog.W3CMode ]: if format == "-h": return "\\x{0}".format(char.lower()) elif format == "-o": return "\\0{0}".format(char) elif format in ["-ccp", "-cbp"]: return "\\p{{{0}}}".format(char) elif format in ["-ccn", "-cbn"]: return "\\P{{{0}}}".format(char) else: return format def getCharacters(self): """ Public method to return the character string assembled via the dialog. @return formatted string for character classes (string) """ regexp = "" # negative character range if self.negativeCheckBox.isChecked(): regexp += "^" # predefined character ranges if self.wordCharCheckBox.isChecked(): regexp += "\\w" if self.nonWordCharCheckBox.isChecked(): regexp += "\\W" if self.digitsCheckBox.isChecked(): regexp += "\\d" if self.nonDigitsCheckBox.isChecked(): regexp += "\\D" if self.whitespaceCheckBox.isChecked(): regexp += "\\s" if self.nonWhitespaceCheckBox.isChecked(): regexp += "\\S" if self.w3cInitialIdentifierCheckBox.isChecked(): regexp += "\\i" if self.w3cNonInitialIdentifierCheckBox.isChecked(): regexp += "\\I" if self.w3cNmtokenCheckBox.isChecked(): regexp += "\\c" if self.w3cNonNmtokenCheckBox.isChecked(): regexp += "\\C" # single characters for entrieslist in self.singlesEntries: format = entrieslist[0].itemData(entrieslist[0].currentIndex()) if format in ["-ccp", "-ccn", "-cbp", "-cbn"]: char = entrieslist[2].itemData(entrieslist[2].currentIndex()) else: char = entrieslist[1].text() regexp += self.__formatCharacter(char, format) # character ranges for entrieslist in self.rangesEntries: if not entrieslist[1].text() or \ not entrieslist[2].text(): continue format = entrieslist[0].itemData(entrieslist[0].currentIndex()) char1 = entrieslist[1].text() char2 = entrieslist[2].text() regexp += "{0}-{1}".format(self.__formatCharacter(char1, format), self.__formatCharacter(char2, format)) if regexp: if (regexp.startswith("\\") and regexp.count("\\") == 1 and "-" not in regexp) or \ len(regexp) == 1: return regexp else: return "[{0}]".format(regexp) else: return ""
class QRegularExpressionWizardCharactersDialog( QDialog, Ui_QRegularExpressionWizardCharactersDialog): """ Class implementing a dialog for entering character classes. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(QRegularExpressionWizardCharactersDialog, self).__init__(parent) self.setupUi(self) self.__initCharacterSelectors() self.comboItems = [] self.singleComboItems = [] # these are in addition to the above self.comboItems.append((self.tr("Normal character"), "-c")) self.comboItems.append( (self.tr("Unicode character in hexadecimal notation"), "-h")) self.comboItems.append( (self.tr("ASCII/Latin1 character in octal notation"), "-o")) self.singleComboItems.extend([ ("---", "-i"), (self.tr("Bell character (\\a)"), "\\a"), (self.tr("Escape character (\\e)"), "\\e"), (self.tr("Page break (\\f)"), "\\f"), (self.tr("Line feed (\\n)"), "\\n"), (self.tr("Carriage return (\\r)"), "\\r"), (self.tr("Horizontal tabulator (\\t)"), "\\t"), ("---", "-i"), (self.tr("Character Category"), "-ccp"), (self.tr("Special Character Category"), "-csp"), (self.tr("Character Block"), "-cbp"), (self.tr("POSIX Named Set"), "-psp"), (self.tr("Not Character Category"), "-ccn"), (self.tr("Not Character Block"), "-cbn"), (self.tr("Not Special Character Category"), "-csn"), (self.tr("Not POSIX Named Set"), "-psn"), ]) self.charValidator = QRegExpValidator(QRegExp(".{0,1}"), self) self.hexValidator = QRegExpValidator(QRegExp("[0-9a-fA-F]{0,4}"), self) self.octValidator = QRegExpValidator(QRegExp("[0-3]?[0-7]{0,2}"), self) # generate dialog part for single characters self.singlesBoxLayout = QVBoxLayout(self.singlesBox) self.singlesBoxLayout.setObjectName("singlesBoxLayout") self.singlesBoxLayout.setSpacing(6) self.singlesBoxLayout.setContentsMargins(6, 6, 6, 6) self.singlesBox.setLayout(self.singlesBoxLayout) self.singlesView = QScrollArea(self.singlesBox) self.singlesView.setObjectName("singlesView") self.singlesBoxLayout.addWidget(self.singlesView) self.singlesItemsBox = QWidget(self) self.singlesView.setWidget(self.singlesItemsBox) self.singlesItemsBox.setObjectName("singlesItemsBox") self.singlesItemsBox.setMinimumWidth(1000) self.singlesItemsBoxLayout = QVBoxLayout(self.singlesItemsBox) self.singlesItemsBoxLayout.setContentsMargins(6, 6, 6, 6) self.singlesItemsBoxLayout.setSpacing(6) self.singlesItemsBox.setLayout(self.singlesItemsBoxLayout) self.singlesEntries = [] self.__addSinglesLine() hlayout0 = QHBoxLayout() hlayout0.setContentsMargins(0, 0, 0, 0) hlayout0.setSpacing(6) hlayout0.setObjectName("hlayout0") self.moreSinglesButton = QPushButton(self.tr("Additional Entries"), self.singlesBox) self.moreSinglesButton.setObjectName("moreSinglesButton") hlayout0.addWidget(self.moreSinglesButton) hspacer0 = QSpacerItem(30, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) hlayout0.addItem(hspacer0) self.singlesBoxLayout.addLayout(hlayout0) self.moreSinglesButton.clicked.connect(self.__addSinglesLine) # generate dialog part for character ranges self.rangesBoxLayout = QVBoxLayout(self.rangesBox) self.rangesBoxLayout.setObjectName("rangesBoxLayout") self.rangesBoxLayout.setSpacing(6) self.rangesBoxLayout.setContentsMargins(6, 6, 6, 6) self.rangesBox.setLayout(self.rangesBoxLayout) self.rangesView = QScrollArea(self.rangesBox) self.rangesView.setObjectName("rangesView") self.rangesBoxLayout.addWidget(self.rangesView) self.rangesItemsBox = QWidget(self) self.rangesView.setWidget(self.rangesItemsBox) self.rangesItemsBox.setObjectName("rangesItemsBox") self.rangesItemsBox.setMinimumWidth(1000) self.rangesItemsBoxLayout = QVBoxLayout(self.rangesItemsBox) self.rangesItemsBoxLayout.setContentsMargins(6, 6, 6, 6) self.rangesItemsBoxLayout.setSpacing(6) self.rangesItemsBox.setLayout(self.rangesItemsBoxLayout) self.rangesEntries = [] self.__addRangesLine() hlayout1 = QHBoxLayout() hlayout1.setContentsMargins(0, 0, 0, 0) hlayout1.setSpacing(6) hlayout1.setObjectName("hlayout1") self.moreRangesButton = QPushButton(self.tr("Additional Entries"), self.rangesBox) self.moreSinglesButton.setObjectName("moreRangesButton") hlayout1.addWidget(self.moreRangesButton) hspacer1 = QSpacerItem(30, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) hlayout1.addItem(hspacer1) self.rangesBoxLayout.addLayout(hlayout1) self.moreRangesButton.clicked.connect(self.__addRangesLine) def __initCharacterSelectors(self): """ Private method to initialize the W3C character selector entries. """ self.__characterCategories = ( # display name code (self.tr("Letter, Any"), "L"), (self.tr("Letter, Lower case"), "Ll"), (self.tr("Letter, Modifier"), "Lm"), (self.tr("Letter, Other"), "Lo"), (self.tr("Letter, Title case"), "Lt"), (self.tr("Letter, Upper case"), "Lu"), (self.tr("Letter, Lower, Upper or Title"), "L&"), (self.tr("Mark, Any"), "M"), (self.tr("Mark, Spacing"), "Mc"), (self.tr("Mark, Enclosing"), "Me"), (self.tr("Mark, Non-spacing"), "Mn"), (self.tr("Number, Any"), "N"), (self.tr("Number, Decimal"), "Nd"), (self.tr("Number, Letter"), "Nl"), (self.tr("Number, Other"), "No"), (self.tr("Punctuation, Any"), "P"), (self.tr("Punctuation, Connector"), "Pc"), (self.tr("Punctuation, Dash"), "Pd"), (self.tr("Punctuation, Close"), "Pe"), (self.tr("Punctuation, Final"), "Pf"), (self.tr("Punctuation, Initial"), "Pi"), (self.tr("Punctuation, Other"), "Po"), (self.tr("Punctuation, Open"), "Ps"), (self.tr("Symbol, Any"), "S"), (self.tr("Symbol, Currency"), "Sc"), (self.tr("Symbol, Modifier"), "Sk"), (self.tr("Symbol, Mathematical"), "Sm"), (self.tr("Symbol, Other"), "So"), (self.tr("Separator, Any"), "Z"), (self.tr("Separator, Line"), "Zl"), (self.tr("Separator, Paragraph"), "Zp"), (self.tr("Separator, Space"), "Zs"), (self.tr("Other, Any"), "C"), (self.tr("Other, Control"), "Cc"), (self.tr("Other, Format"), "Cf"), (self.tr("Other, Unassigned"), "Cn"), (self.tr("Other, Private Use"), "Co"), (self.tr("Other, Surrogat"), "Cn"), ) self.__specialCharacterCategories = ( # display name code (self.tr("Alphanumeric"), "Xan"), (self.tr("POSIX Space"), "Xps"), (self.tr("Perl Space"), "Xsp"), (self.tr("Universal Character"), "Xuc"), (self.tr("Perl Word"), "Xan"), ) self.__characterBlocks = ( # display name code (self.tr("Arabic"), "Arabic"), (self.tr("Armenian"), "Armenian"), (self.tr("Avestan"), "Avestan"), (self.tr("Balinese"), "Balinese"), (self.tr("Bamum"), "Bamum"), (self.tr("Batak"), "Batak"), (self.tr("Bengali"), "Bengali"), (self.tr("Bopomofo"), "Bopomofo"), (self.tr("Brahmi"), "Brahmi"), (self.tr("Braille"), "Braille"), (self.tr("Buginese"), "Buginese"), (self.tr("Buhid"), "Buhid"), (self.tr("Canadian Aboriginal"), "Canadian_Aboriginal"), (self.tr("Carian"), "Carian"), (self.tr("Chakma"), "Chakma"), (self.tr("Cham"), "Cham"), (self.tr("Cherokee"), "Cherokee"), (self.tr("Common"), "Common"), (self.tr("Coptic"), "Coptic"), (self.tr("Cuneiform"), "Cuneiform"), (self.tr("Cypriot"), "Cypriot"), (self.tr("Cyrillic"), "Cyrillic"), (self.tr("Deseret"), "Deseret,"), (self.tr("Devanagari"), "Devanagari"), (self.tr("Egyptian Hieroglyphs"), "Egyptian_Hieroglyphs"), (self.tr("Ethiopic"), "Ethiopic"), (self.tr("Georgian"), "Georgian"), (self.tr("Glagolitic"), "Glagolitic"), (self.tr("Gothic"), "Gothic"), (self.tr("Greek"), "Greek"), (self.tr("Gujarati"), "Gujarati"), (self.tr("Gurmukhi"), "Gurmukhi"), (self.tr("Han"), "Han"), (self.tr("Hangul"), "Hangul"), (self.tr("Hanunoo"), "Hanunoo"), (self.tr("Hebrew"), "Hebrew"), (self.tr("Hiragana"), "Hiragana"), (self.tr("Imperial Aramaic"), "Imperial_Aramaic"), (self.tr("Inherited"), "Inherited"), (self.tr("Inscriptional Pahlavi"), "Inscriptional_Pahlavi"), (self.tr("Inscriptional Parthian"), "Inscriptional_Parthian"), (self.tr("Javanese"), "Javanese"), (self.tr("Kaithi"), "Kaithi"), (self.tr("Kannada"), "Kannada"), (self.tr("Katakana"), "Katakana"), (self.tr("Kayah Li"), "Kayah_Li"), (self.tr("Kharoshthi"), "Kharoshthi"), (self.tr("Khmer"), "Khmer"), (self.tr("Lao"), "Lao"), (self.tr("Latin"), "Latin"), (self.tr("Lepcha"), "Lepcha"), (self.tr("Limbu"), "Limbu"), (self.tr("Linear B"), "Linear_B"), (self.tr("Lisu"), "Lisu"), (self.tr("Lycian"), "Lycian"), (self.tr("Lydian"), "Lydian"), (self.tr("Malayalam"), "Malayalam"), (self.tr("Mandaic"), "Mandaic"), (self.tr("Meetei Mayek"), "Meetei_Mayek"), (self.tr("Meroitic Cursive"), "Meroitic_Cursive"), (self.tr("Meroitic Hieroglyphs"), "Meroitic_Hieroglyphs"), (self.tr("Miao"), "Miao"), (self.tr("Mongolian"), "Mongolian"), (self.tr("Myanmar"), "Myanmar"), (self.tr("New Tai Lue"), "New_Tai_Lue"), (self.tr("N'Ko"), "Nko"), (self.tr("Ogham"), "Ogham"), (self.tr("Old Italic"), "Old_Italic"), (self.tr("Old Persian"), "Old_Persian"), (self.tr("Old South Arabian"), "Old_South_Arabian"), (self.tr("Old Turkic"), "Old_Turkic,"), (self.tr("Ol Chiki"), "Ol_Chiki"), (self.tr("Oriya"), "Oriya"), (self.tr("Osmanya"), "Osmanya"), (self.tr("Phags-pa"), "Phags_Pa"), (self.tr("Phoenician"), "Phoenician"), (self.tr("Rejang"), "Rejang"), (self.tr("Runic"), "Runic"), (self.tr("Samaritan"), "Samaritan"), (self.tr("Saurashtra"), "Saurashtra"), (self.tr("Sharada"), "Sharada"), (self.tr("Shavian"), "Shavian"), (self.tr("Sinhala"), "Sinhala"), (self.tr("Sora Sompeng"), "Sora_Sompeng"), (self.tr("Sundanese"), "Sundanese"), (self.tr("Syloti Nagri"), "Syloti_Nagri"), (self.tr("Syriac"), "Syriac"), (self.tr("Tagalog"), "Tagalog"), (self.tr("Tagbanwa"), "Tagbanwa"), (self.tr("Tai Le"), "Tai_Le"), (self.tr("Tai Tham"), "Tai_Tham"), (self.tr("Tai Viet"), "Tai_Viet"), (self.tr("Takri"), "Takri"), (self.tr("Tamil"), "Tamil"), (self.tr("Telugu"), "Telugu"), (self.tr("Thaana"), "Thaana"), (self.tr("Thai"), "Thai"), (self.tr("Tibetan"), "Tibetan"), (self.tr("Tifinagh"), "Tifinagh"), (self.tr("Ugaritic"), "Ugaritic"), (self.tr("Vai"), "Vai"), (self.tr("Yi"), "Yi"), ) self.__posixNamedSets = ( # display name code (self.tr("Alphanumeric"), "alnum"), (self.tr("Alphabetic"), "alpha"), (self.tr("ASCII"), "ascii"), (self.tr("Word Letter"), "word"), (self.tr("Lower Case Letter"), "lower"), (self.tr("Upper Case Letter"), "upper"), (self.tr("Decimal Digit"), "digit"), (self.tr("Hexadecimal Digit"), "xdigit"), (self.tr("Space or Tab"), "blank"), (self.tr("White Space"), "space"), (self.tr("Printing (excl. space)"), "graph"), (self.tr("Printing (incl. space)"), "print"), (self.tr("Printing (excl. alphanumeric)"), "punct"), (self.tr("Control Character"), "cntrl"), ) def __populateCharTypeCombo(self, combo, isSingle): """ Private method to populate a given character type selection combo box. @param combo reference to the combo box to be populated (QComboBox) @param isSingle flag indicating a singles combo (boolean) """ for txt, value in self.comboItems: combo.addItem(txt, value) if isSingle: for txt, value in self.singleComboItems: combo.addItem(txt, value) def __addSinglesLine(self): """ Private slot to add a line of entry widgets for single characters. """ hbox = QWidget(self.singlesItemsBox) hboxLayout = QHBoxLayout(hbox) hboxLayout.setContentsMargins(0, 0, 0, 0) hboxLayout.setSpacing(6) hbox.setLayout(hboxLayout) cb1 = QComboBox(hbox) cb1.setEditable(False) self.__populateCharTypeCombo(cb1, True) hboxLayout.addWidget(cb1) le1 = QLineEdit(hbox) le1.setValidator(self.charValidator) hboxLayout.addWidget(le1) cb1a = QComboBox(hbox) cb1a.setEditable(False) cb1a.setSizeAdjustPolicy(QComboBox.AdjustToContents) hboxLayout.addWidget(cb1a) cb1a.hide() cb2 = QComboBox(hbox) cb2.setEditable(False) self.__populateCharTypeCombo(cb2, True) hboxLayout.addWidget(cb2) le2 = QLineEdit(hbox) le2.setValidator(self.charValidator) hboxLayout.addWidget(le2) cb2a = QComboBox(hbox) cb2a.setEditable(False) cb2a.setSizeAdjustPolicy(QComboBox.AdjustToContents) hboxLayout.addWidget(cb2a) cb2a.hide() self.singlesItemsBoxLayout.addWidget(hbox) cb1.activated[int].connect(self.__singlesCharTypeSelected) cb2.activated[int].connect(self.__singlesCharTypeSelected) hbox.show() self.singlesItemsBox.adjustSize() self.singlesEntries.append([cb1, le1, cb1a]) self.singlesEntries.append([cb2, le2, cb2a]) def __addRangesLine(self): """ Private slot to add a line of entry widgets for character ranges. """ hbox = QWidget(self.rangesItemsBox) hboxLayout = QHBoxLayout(hbox) hboxLayout.setContentsMargins(0, 0, 0, 0) hboxLayout.setSpacing(6) hbox.setLayout(hboxLayout) cb1 = QComboBox(hbox) cb1.setEditable(False) self.__populateCharTypeCombo(cb1, False) hboxLayout.addWidget(cb1) l1 = QLabel(self.tr("Between:"), hbox) hboxLayout.addWidget(l1) le1 = QLineEdit(hbox) le1.setValidator(self.charValidator) hboxLayout.addWidget(le1) l2 = QLabel(self.tr("And:"), hbox) hboxLayout.addWidget(l2) le2 = QLineEdit(hbox) le2.setValidator(self.charValidator) hboxLayout.addWidget(le2) self.rangesItemsBoxLayout.addWidget(hbox) cb1.activated[int].connect(self.__rangesCharTypeSelected) hbox.show() self.rangesItemsBox.adjustSize() self.rangesEntries.append([cb1, le1, le2]) def __populateCharacterCombo(self, combo, format): """ Private method to populate a character selection combo. @param combo combo box to be populated (QComboBox) @param format format identifier (one of "-ccp", "-ccn", "-cbp", "-cbn", "-csp", "-csn", "-psp", "-psn") """ combo.clear() if format in ["-ccp", "-ccn"]: items = self.__characterCategories elif format in ["-csp", "-csn"]: items = self.__specialCharacterCategories elif format in ["-cbp", "-cbn"]: items = self.__characterBlocks elif format in ["-psp", "-psn"]: items = self.__posixNamedSets comboLen = 0 for txt, code in items: combo.addItem(txt, code) comboLen = max(comboLen, len(txt)) combo.setMinimumContentsLength(comboLen) def __performSelectedAction(self, format, lineedit, combo): """ Private method performing some actions depending on the input. @param format format of the selected entry (string) @param lineedit line edit widget to act on (QLineEdit) @param combo combo box widget to act on (QComboBox) """ if format == "-i": return if format in ["-c", "-h", "-o"]: lineedit.show() lineedit.setEnabled(True) if combo is not None: combo.hide() if format == "-c": lineedit.setValidator(self.charValidator) elif format == "-h": lineedit.setValidator(self.hexValidator) elif format == "-o": lineedit.setValidator(self.octValidator) elif format in [ "-ccp", "-ccn", "-cbp", "-cbn", "-csp", "-csn", "-psp", "-psn" ]: lineedit.setEnabled(False) lineedit.hide() if combo is not None: combo.show() self.__populateCharacterCombo(combo, format) else: lineedit.setEnabled(False) lineedit.hide() if combo is not None: combo.hide() lineedit.clear() def __singlesCharTypeSelected(self, index): """ Private slot to handle the activated(int) signal of the single chars combo boxes. @param index selected list index (integer) """ combo = self.sender() for entriesList in self.singlesEntries: if combo == entriesList[0]: format = combo.itemData(index) self.__performSelectedAction(format, entriesList[1], entriesList[2]) break def __rangesCharTypeSelected(self, index): """ Private slot to handle the activated(int) signal of the char ranges combo boxes. @param index selected list index (integer) """ combo = self.sender() for entriesList in self.rangesEntries: if combo == entriesList[0]: format = combo.itemData(index) self.__performSelectedAction(format, entriesList[1], None) self.__performSelectedAction(format, entriesList[2], None) break def __formatCharacter(self, char, format): """ Private method to format the characters entered into the dialog. @param char character string entered into the dialog (string) @param format string giving a special format (-c, -h, -i or -o) or the already formatted character (string) @return formatted character string (string) """ if format == "-c": return char elif format == "-i": return "" if format == "-h": while len(char) < 2: char = "0" + char if len(char) > 2: return "\\x{{{0}}}".format(char.lower()) else: return "\\x{0}".format(char.lower()) elif format == "-o": while len(char) < 3: char = "0" + char if len(char) > 3: char = char[:3] return "\\{0}".format(char) elif format in ["-ccp", "-cbp", "-csp"]: return "\\p{{{0}}}".format(char) elif format in ["-ccn", "-cbn", "-csn"]: return "\\P{{{0}}}".format(char) elif format == "-psp": return "[:{0}:]".format(char) elif format == "-psn": return "[:^{0}:]".format(char) else: return format def getCharacters(self): """ Public method to return the character string assembled via the dialog. @return formatted string for character classes (string) """ regexp = "" # negative character range if self.negativeCheckBox.isChecked(): regexp += "^" # predefined character ranges if self.wordCharCheckBox.isChecked(): regexp += "\\w" if self.nonWordCharCheckBox.isChecked(): regexp += "\\W" if self.digitsCheckBox.isChecked(): regexp += "\\d" if self.nonDigitsCheckBox.isChecked(): regexp += "\\D" if self.newlineCheckBox.isChecked(): regexp += "\\R" if self.nonNewlineCheckBox.isChecked(): regexp += "\\N" if self.whitespaceCheckBox.isChecked(): regexp += "\\s" if self.nonWhitespaceCheckBox.isChecked(): regexp += "\\S" if self.horizontalWhitespaceCheckBox.isChecked(): regexp += "\\h" if self.nonHorizontalWhitespaceCheckBox.isChecked(): regexp += "\\H" if self.verticalWhitespaceCheckBox.isChecked(): regexp += "\\v" if self.nonVerticalWhitespaceCheckBox.isChecked(): regexp += "\\V" # single characters for entrieslist in self.singlesEntries: format = entrieslist[0].itemData(entrieslist[0].currentIndex()) if format in [ "-ccp", "-ccn", "-cbp", "-cbn", "-csp", "-csn", "-psp", "-psn" ]: char = entrieslist[2].itemData(entrieslist[2].currentIndex()) else: char = entrieslist[1].text() regexp += self.__formatCharacter(char, format) # character ranges for entrieslist in self.rangesEntries: if not entrieslist[1].text() or \ not entrieslist[2].text(): continue format = entrieslist[0].itemData(entrieslist[0].currentIndex()) char1 = entrieslist[1].text() char2 = entrieslist[2].text() regexp += "{0}-{1}".format(self.__formatCharacter(char1, format), self.__formatCharacter(char2, format)) if regexp: if (regexp.startswith("\\") and regexp.count("\\") == 1 and "-" not in regexp) or \ len(regexp) == 1: return regexp else: return "[{0}]".format(regexp) else: return ""
def init_ui(self): mainLayout = QVBoxLayout() self.setGeometry(600, 200, 1000, 800) self.flag = False self.done_red = 'font-size: 18px; color: rgb(200,50,50)' self.done_blue = 'font-size: 18px; color: rgb(50,50,200)' self.done_green = 'font-size: 20px; color: rgb(50,200,100)' #H box for vertical panes paneLayout = QHBoxLayout() paneWidget = QWidget() paneWidget.setLayout(paneLayout) doneLayout = QHBoxLayout() doneWidget = QWidget() doneWidget.setLayout(doneLayout) #First vertical pane: Input layout self.inputLayout = QVBoxLayout() self.inputLayout.setAlignment(Qt.AlignTop) inputWidget = QWidget() inputWidget.setFixedWidth(250) inputWidget.setLayout(self.inputLayout) #Drop down menu for phantom plans lbl = QLabel("Select Phantom Plan") lbl.setFixedHeight(20) dropdown = QComboBox(self) dropdown.setFixedHeight(20) self.phantom_path = './MGH_Phantoms/' phantoms = gen1.get_phantom_list(self.phantom_path) dropdown.addItem('Select Phantom') for name in phantoms: dropdown.addItem(name) dropdown.activated[str].connect(self.onActivated) self.inputLayout.addWidget(lbl) self.inputLayout.addWidget(dropdown) #Text box for patient name name_lbl1 = QLabel("Enter Patient First Name (required)") name_lbl2 = QLabel("Enter Patient Last Name (required)") name_lbl1.setFixedHeight(20) name_lbl2.setFixedHeight(20) self.patientfirstname = QLineEdit() self.patientlastname = QLineEdit() self.inputLayout.addWidget(name_lbl1) self.inputLayout.addWidget(self.patientfirstname) self.inputLayout.addWidget(name_lbl2) self.inputLayout.addWidget(self.patientlastname) #Current Isocenter values self.currentiso_lbl = QLabel() self.currentiso_lbl.setFixedHeight(30) #Hbox for isocenter isoLayout = QHBoxLayout() isoWidget = QWidget() isoWidget.setFixedWidth(250) isoWidget.setLayout(isoLayout) #Isocenter parameters lbl_iso = QLabel("Enter new isocenter values below") lbl_iso.setFixedHeight(20) lbl_x = QLabel("X (mm)") lbl_y = QLabel("Y (mm)") lbl_z = QLabel("Z (mm)") self.le_x = QLineEdit() self.le_y = QLineEdit() self.le_z = QLineEdit() self.inputLayout.addWidget(self.currentiso_lbl) self.inputLayout.addWidget(lbl_iso) isoLayout.addWidget(lbl_x) isoLayout.addWidget(self.le_x) isoLayout.addWidget(lbl_y) isoLayout.addWidget(self.le_y) isoLayout.addWidget(lbl_z) isoLayout.addWidget(self.le_z) self.inputLayout.addWidget(isoWidget) #Gantry Angle gantry_lbl = QLabel("Gantry Angle") gantry_lbl.setFixedHeight(20) self.gantry = QLineEdit() self.inputLayout.addWidget(gantry_lbl) self.inputLayout.addWidget(self.gantry) #Generate new set and upload to WB new_lbl = QLabel("Click below to generate new phantom set") new_lbl.setFixedHeight(30) new_btn = QPushButton("Generate") new_btn.setFixedHeight(30) new_btn.setStyleSheet('font-size: 18px') new_btn.clicked.connect(self.generate_dicom) self.upload_btn = QPushButton("Upload to WB") self.upload_btn.setFixedHeight(30) self.upload_btn.setStyleSheet(self.done_red) self.upload_btn.clicked.connect(self.upload_to_WB) self.inputLayout.addWidget(new_lbl) self.inputLayout.addWidget(new_btn) self.inputLayout.addWidget(self.upload_btn) #Second vertical pane self.rtipLayout = QVBoxLayout() self.rtipLayout.setAlignment(Qt.AlignTop) rtipWidget = QWidget() rtipWidget.adjustSize() rtipWidget.setLayout(self.rtipLayout) #Current spot map self.spot_lbl = QLabel("Spot map specs") self.spot_lbl.setStyleSheet("font-size : 12px") self.spot_lbl.setFixedHeight(20) self.spot_stats = QLabel() self.spot_stats.setWordWrap(True) self.spot_stats.adjustSize() # Button to load new spot map spot_lbl2 = QLabel("Click below to browse for new spot map") spot_lbl2.setStyleSheet("font-size : 12px") spot_lbl2.setFixedHeight(30) dataLoadBtn = QPushButton("Browse") dataLoadBtn.setFixedHeight(30) dataLoadBtn.clicked.connect(self.load_spot_map) self.chkbox = QCheckBox("Check box to use loaded csv file") self.chkbox2 = QCheckBox( "Check box if the first beam is the setup beam") self.rtipLayout.addWidget(self.spot_lbl) self.rtipLayout.addWidget(self.spot_stats) self.rtipLayout.addWidget(spot_lbl2) self.rtipLayout.addWidget(dataLoadBtn) self.rtipLayout.addWidget(self.chkbox) self.rtipLayout.addWidget(self.chkbox2) # Add space for spot map statistics self.loadstatus = QLabel() self.loadstatus.setFixedHeight(40) self.csv_stats = QLabel() self.csv_stats.setAlignment(Qt.AlignTop) self.csv_stats.setWordWrap(True) self.rtipLayout.addWidget(self.loadstatus) self.rtipLayout.addWidget(self.csv_stats) #Third pane plotWidget = QWidget() plotLayout = QVBoxLayout() #Make figures and navi toolbar self.fig = Figure() self.canvas = FigureCanvas(self.fig) self.axes11 = self.fig.add_subplot(2, 1, 1) self.axes12 = self.fig.add_subplot(2, 1, 2) self.fig.tight_layout() navi_toolbar = NavigationToolbar(self.canvas, plotWidget) plotLayout.addWidget(navi_toolbar) plotLayout.addWidget(self.canvas, Qt.AlignHCenter) #Done status self.done_lbl = QLabel() self.done_lbl.setStyleSheet(self.done_green) self.done_lbl.setAlignment(Qt.AlignHCenter) doneLayout.addWidget(self.done_lbl) #Add widgets to main window paneLayout.addWidget(inputWidget) paneLayout.addWidget(rtipWidget) paneLayout.addLayout(plotLayout) mainLayout.addWidget(paneWidget) mainLayout.addWidget(doneWidget) self.setLayout(mainLayout) self.show()
class QRegExpWizardCharactersDialog(QDialog, Ui_QRegExpWizardCharactersDialog): """ Class implementing a dialog for entering character classes. """ RegExpMode = 0 WildcardMode = 1 W3CMode = 2 def __init__(self, mode=RegExpMode, parent=None): """ Constructor @param mode mode of the dialog (one of RegExpMode, WildcardMode, W3CMode) @param parent parent widget (QWidget) """ super(QRegExpWizardCharactersDialog, self).__init__(parent) self.setupUi(self) self.__mode = mode if mode == QRegExpWizardCharactersDialog.WildcardMode: self.predefinedBox.setEnabled(False) self.predefinedBox.hide() elif mode == QRegExpWizardCharactersDialog.RegExpMode: self.w3cInitialIdentifierCheckBox.hide() self.w3cNonInitialIdentifierCheckBox.hide() self.w3cNmtokenCheckBox.hide() self.w3cNonNmtokenCheckBox.hide() elif mode == QRegExpWizardCharactersDialog.W3CMode: self.__initCharacterSelectors() self.comboItems = [] self.singleComboItems = [] # these are in addition to the above self.comboItems.append((self.tr("Normal character"), "-c")) if mode == QRegExpWizardCharactersDialog.RegExpMode: self.comboItems.append((self.tr( "Unicode character in hexadecimal notation"), "-h")) self.comboItems.append((self.tr( "ASCII/Latin1 character in octal notation"), "-o")) self.singleComboItems.append(("---", "-i")) self.singleComboItems.append( (self.tr("Bell character (\\a)"), "\\a")) self.singleComboItems.append( (self.tr("Page break (\\f)"), "\\f")) self.singleComboItems.append( (self.tr("Line feed (\\n)"), "\\n")) self.singleComboItems.append( (self.tr("Carriage return (\\r)"), "\\r")) self.singleComboItems.append( (self.tr("Horizontal tabulator (\\t)"), "\\t")) self.singleComboItems.append( (self.tr("Vertical tabulator (\\v)"), "\\v")) elif mode == QRegExpWizardCharactersDialog.W3CMode: self.comboItems.append((self.tr( "Unicode character in hexadecimal notation"), "-h")) self.comboItems.append((self.tr( "ASCII/Latin1 character in octal notation"), "-o")) self.singleComboItems.append(("---", "-i")) self.singleComboItems.append( (self.tr("Line feed (\\n)"), "\\n")) self.singleComboItems.append( (self.tr("Carriage return (\\r)"), "\\r")) self.singleComboItems.append( (self.tr("Horizontal tabulator (\\t)"), "\\t")) self.singleComboItems.append(("---", "-i")) self.singleComboItems.append( (self.tr("Character Category"), "-ccp")) self.singleComboItems.append( (self.tr("Character Block"), "-cbp")) self.singleComboItems.append( (self.tr("Not Character Category"), "-ccn")) self.singleComboItems.append( (self.tr("Not Character Block"), "-cbn")) self.charValidator = QRegExpValidator(QRegExp(".{0,1}"), self) self.hexValidator = QRegExpValidator(QRegExp("[0-9a-fA-F]{0,4}"), self) self.octValidator = QRegExpValidator(QRegExp("[0-3]?[0-7]{0,2}"), self) # generate dialog part for single characters self.singlesBoxLayout = QVBoxLayout(self.singlesBox) self.singlesBoxLayout.setObjectName("singlesBoxLayout") self.singlesBoxLayout.setSpacing(6) self.singlesBoxLayout.setContentsMargins(6, 6, 6, 6) self.singlesBox.setLayout(self.singlesBoxLayout) self.singlesView = QScrollArea(self.singlesBox) self.singlesView.setObjectName("singlesView") self.singlesBoxLayout.addWidget(self.singlesView) self.singlesItemsBox = QWidget(self) self.singlesView.setWidget(self.singlesItemsBox) self.singlesItemsBox.setObjectName("singlesItemsBox") self.singlesItemsBox.setMinimumWidth(1000) self.singlesItemsBoxLayout = QVBoxLayout(self.singlesItemsBox) self.singlesItemsBoxLayout.setContentsMargins(6, 6, 6, 6) self.singlesItemsBoxLayout.setSpacing(6) self.singlesItemsBox.setLayout(self.singlesItemsBoxLayout) self.singlesEntries = [] self.__addSinglesLine() hlayout0 = QHBoxLayout() hlayout0.setContentsMargins(0, 0, 0, 0) hlayout0.setSpacing(6) hlayout0.setObjectName("hlayout0") self.moreSinglesButton = QPushButton( self.tr("Additional Entries"), self.singlesBox) self.moreSinglesButton.setObjectName("moreSinglesButton") hlayout0.addWidget(self.moreSinglesButton) hspacer0 = QSpacerItem( 30, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) hlayout0.addItem(hspacer0) self.singlesBoxLayout.addLayout(hlayout0) self.moreSinglesButton.clicked.connect(self.__addSinglesLine) # generate dialog part for character ranges self.rangesBoxLayout = QVBoxLayout(self.rangesBox) self.rangesBoxLayout.setObjectName("rangesBoxLayout") self.rangesBoxLayout.setSpacing(6) self.rangesBoxLayout.setContentsMargins(6, 6, 6, 6) self.rangesBox.setLayout(self.rangesBoxLayout) self.rangesView = QScrollArea(self.rangesBox) self.rangesView.setObjectName("rangesView") self.rangesBoxLayout.addWidget(self.rangesView) self.rangesItemsBox = QWidget(self) self.rangesView.setWidget(self.rangesItemsBox) self.rangesItemsBox.setObjectName("rangesItemsBox") self.rangesItemsBox.setMinimumWidth(1000) self.rangesItemsBoxLayout = QVBoxLayout(self.rangesItemsBox) self.rangesItemsBoxLayout.setContentsMargins(6, 6, 6, 6) self.rangesItemsBoxLayout.setSpacing(6) self.rangesItemsBox.setLayout(self.rangesItemsBoxLayout) self.rangesEntries = [] self.__addRangesLine() hlayout1 = QHBoxLayout() hlayout1.setContentsMargins(0, 0, 0, 0) hlayout1.setSpacing(6) hlayout1.setObjectName("hlayout1") self.moreRangesButton = QPushButton( self.tr("Additional Entries"), self.rangesBox) self.moreSinglesButton.setObjectName("moreRangesButton") hlayout1.addWidget(self.moreRangesButton) hspacer1 = QSpacerItem( 30, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) hlayout1.addItem(hspacer1) self.rangesBoxLayout.addLayout(hlayout1) self.moreRangesButton.clicked.connect(self.__addRangesLine) def __initCharacterSelectors(self): """ Private method to initialize the W3C character selector entries. """ self.__characterCategories = ( # display name code (self.tr("Letter, Any"), "L"), (self.tr("Letter, Uppercase"), "Lu"), (self.tr("Letter, Lowercase"), "Ll"), (self.tr("Letter, Titlecase"), "Lt"), (self.tr("Letter, Modifier"), "Lm"), (self.tr("Letter, Other"), "Lo"), (self.tr("Mark, Any"), "M"), (self.tr("Mark, Nonspacing"), "Mn"), (self.tr("Mark, Spacing Combining"), "Mc"), (self.tr("Mark, Enclosing"), "Me"), (self.tr("Number, Any"), "N"), (self.tr("Number, Decimal Digit"), "Nd"), (self.tr("Number, Letter"), "Nl"), (self.tr("Number, Other"), "No"), (self.tr("Punctuation, Any"), "P"), (self.tr("Punctuation, Connector"), "Pc"), (self.tr("Punctuation, Dash"), "Pd"), (self.tr("Punctuation, Open"), "Ps"), (self.tr("Punctuation, Close"), "Pe"), (self.tr("Punctuation, Initial Quote"), "Pi"), (self.tr("Punctuation, Final Quote"), "Pf"), (self.tr("Punctuation, Other"), "Po"), (self.tr("Symbol, Any"), "S"), (self.tr("Symbol, Math"), "Sm"), (self.tr("Symbol, Currency"), "Sc"), (self.tr("Symbol, Modifier"), "Sk"), (self.tr("Symbol, Other"), "So"), (self.tr("Separator, Any"), "Z"), (self.tr("Separator, Space"), "Zs"), (self.tr("Separator, Line"), "Zl"), (self.tr("Separator, Paragraph"), "Zp"), (self.tr("Other, Any"), "C"), (self.tr("Other, Control"), "Cc"), (self.tr("Other, Format"), "Cf"), (self.tr("Other, Private Use"), "Co"), (self.tr("Other, Not Assigned"), "Cn"), ) self.__characterBlocks = ( (self.tr("Basic Latin"), "IsBasicLatin"), (self.tr("Latin-1 Supplement"), "IsLatin-1Supplement"), (self.tr("Latin Extended-A"), "IsLatinExtended-A"), (self.tr("Latin Extended-B"), "IsLatinExtended-B"), (self.tr("IPA Extensions"), "IsIPAExtensions"), (self.tr("Spacing Modifier Letters"), "IsSpacingModifierLetters"), (self.tr("Combining Diacritical Marks"), "IsCombiningDiacriticalMarks"), (self.tr("Greek"), "IsGreek"), (self.tr("Cyrillic"), "IsCyrillic"), (self.tr("Armenian"), "IsArmenian"), (self.tr("Hebrew"), "IsHebrew"), (self.tr("Arabic"), "IsArabic"), (self.tr("Syriac"), "IsSyriac"), (self.tr("Thaana"), "IsThaana"), (self.tr("Devanagari"), "IsDevanagari"), (self.tr("Bengali"), "IsBengali"), (self.tr("Gurmukhi"), "IsBengali"), (self.tr("Gujarati"), "IsGujarati"), (self.tr("Oriya"), "IsOriya"), (self.tr("Tamil"), "IsTamil"), (self.tr("Telugu"), "IsTelugu"), (self.tr("Kannada"), "IsKannada"), (self.tr("Malayalam"), "IsMalayalam"), (self.tr("Sinhala"), "IsSinhala"), (self.tr("Thai"), "IsThai"), (self.tr("Lao"), "IsLao"), (self.tr("Tibetan"), "IsTibetan"), (self.tr("Myanmar"), "IsMyanmar"), (self.tr("Georgian"), "IsGeorgian"), (self.tr("Hangul Jamo"), "IsHangulJamo"), (self.tr("Ethiopic"), "IsEthiopic"), (self.tr("Cherokee"), "IsCherokee"), (self.tr("Unified Canadian Aboriginal Syllabics"), "IsUnifiedCanadianAboriginalSyllabics"), (self.tr("Ogham"), "IsOgham"), (self.tr("Runic"), "IsRunic"), (self.tr("Khmer"), "IsKhmer"), (self.tr("Mongolian"), "IsMongolian"), (self.tr("Latin Extended Additional"), "IsLatinExtendedAdditional"), (self.tr("Greek Extended"), "IsGreekExtended"), (self.tr("General Punctuation"), "IsGeneralPunctuation"), (self.tr("Superscripts and Subscripts"), "IsSuperscriptsandSubscripts"), (self.tr("Currency Symbols"), "IsCurrencySymbols"), (self.tr("Combining Marks for Symbols"), "IsCombiningMarksforSymbols"), (self.tr("Letterlike Symbols"), "IsLetterlikeSymbols"), (self.tr("Number Forms"), "IsNumberForms"), (self.tr("Arrows"), "IsArrows"), (self.tr("Mathematical Operators"), "IsMathematicalOperators"), (self.tr("Miscellaneous Technical"), "IsMiscellaneousTechnical"), (self.tr("Control Pictures"), "IsControlPictures"), (self.tr("Optical Character Recognition"), "IsOpticalCharacterRecognition"), (self.tr("Enclosed Alphanumerics"), "IsEnclosedAlphanumerics"), (self.tr("Box Drawing"), "IsBoxDrawing"), (self.tr("Block Elements"), "IsBlockElements"), (self.tr("Geometric Shapes"), "IsGeometricShapes"), (self.tr("Miscellaneous Symbols"), "IsMiscellaneousSymbols"), (self.tr("Dingbats"), "IsDingbats"), (self.tr("Braille Patterns"), "IsBraillePatterns"), (self.tr("CJK Radicals Supplement"), "IsCJKRadicalsSupplement"), (self.tr("KangXi Radicals"), "IsKangXiRadicals"), (self.tr("Ideographic Description Chars"), "IsIdeographicDescriptionChars"), (self.tr("CJK Symbols and Punctuation"), "IsCJKSymbolsandPunctuation"), (self.tr("Hiragana"), "IsHiragana"), (self.tr("Katakana"), "IsKatakana"), (self.tr("Bopomofo"), "IsBopomofo"), (self.tr("Hangul Compatibility Jamo"), "IsHangulCompatibilityJamo"), (self.tr("Kanbun"), "IsKanbun"), (self.tr("Bopomofo Extended"), "IsBopomofoExtended"), (self.tr("Enclosed CJK Letters and Months"), "IsEnclosedCJKLettersandMonths"), (self.tr("CJK Compatibility"), "IsCJKCompatibility"), (self.tr("CJK Unified Ideographs Extension A"), "IsCJKUnifiedIdeographsExtensionA"), (self.tr("CJK Unified Ideographs"), "IsCJKUnifiedIdeographs"), (self.tr("Yi Syllables"), "IsYiSyllables"), (self.tr("Yi Radicals"), "IsYiRadicals"), (self.tr("Hangul Syllables"), "IsHangulSyllables"), (self.tr("Private Use"), "IsPrivateUse"), (self.tr("CJK Compatibility Ideographs"), "IsCJKCompatibilityIdeographs"), (self.tr("Alphabetic Presentation Forms"), "IsAlphabeticPresentationForms"), (self.tr("Arabic Presentation Forms-A"), "IsArabicPresentationForms-A"), (self.tr("Combining Half Marks"), "IsCombiningHalfMarks"), (self.tr("CJK Compatibility Forms"), "IsCJKCompatibilityForms"), (self.tr("Small Form Variants"), "IsSmallFormVariants"), (self.tr("Arabic Presentation Forms-B"), "IsArabicPresentationForms-B"), (self.tr("Halfwidth and Fullwidth Forms"), "IsHalfwidthandFullwidthForms"), (self.tr("Specials"), "IsSpecials"), (self.tr("Old Italic"), "IsOldItalic"), (self.tr("Gothic"), "IsGothic"), (self.tr("Deseret"), "IsDeseret"), (self.tr("Byzantine Musical Symbols"), "IsByzantineMusicalSymbols"), (self.tr("Musical Symbols"), "IsMusicalSymbols"), (self.tr("Mathematical Alphanumeric Symbols"), "IsMathematicalAlphanumericSymbols"), (self.tr("CJK Unified Ideographic Extension B"), "IsCJKUnifiedIdeographicExtensionB"), (self.tr("CJK Compatapility Ideographic Supplement"), "IsCJKCompatapilityIdeographicSupplement"), (self.tr("Tags"), "IsTags"), ) def __populateCharTypeCombo(self, combo, isSingle): """ Private method to populate a given character type selection combo box. @param combo reference to the combo box to be populated (QComboBox) @param isSingle flag indicating a singles combo (boolean) """ for txt, value in self.comboItems: combo.addItem(txt, value) if isSingle: for txt, value in self.singleComboItems: combo.addItem(txt, value) def __addSinglesLine(self): """ Private slot to add a line of entry widgets for single characters. """ hbox = QWidget(self.singlesItemsBox) hboxLayout = QHBoxLayout(hbox) hboxLayout.setContentsMargins(0, 0, 0, 0) hboxLayout.setSpacing(6) hbox.setLayout(hboxLayout) cb1 = QComboBox(hbox) cb1.setEditable(False) self.__populateCharTypeCombo(cb1, True) hboxLayout.addWidget(cb1) le1 = QLineEdit(hbox) le1.setValidator(self.charValidator) hboxLayout.addWidget(le1) cb1a = QComboBox(hbox) cb1a.setEditable(False) cb1a.setSizeAdjustPolicy(QComboBox.AdjustToContents) hboxLayout.addWidget(cb1a) cb1a.hide() cb2 = QComboBox(hbox) cb2.setEditable(False) self.__populateCharTypeCombo(cb2, True) hboxLayout.addWidget(cb2) le2 = QLineEdit(hbox) le2.setValidator(self.charValidator) hboxLayout.addWidget(le2) cb2a = QComboBox(hbox) cb2a.setEditable(False) cb2a.setSizeAdjustPolicy(QComboBox.AdjustToContents) hboxLayout.addWidget(cb2a) cb2a.hide() self.singlesItemsBoxLayout.addWidget(hbox) cb1.activated[int].connect(self.__singlesCharTypeSelected) cb2.activated[int].connect(self.__singlesCharTypeSelected) hbox.show() self.singlesItemsBox.adjustSize() self.singlesEntries.append([cb1, le1, cb1a]) self.singlesEntries.append([cb2, le2, cb2a]) def __addRangesLine(self): """ Private slot to add a line of entry widgets for character ranges. """ hbox = QWidget(self.rangesItemsBox) hboxLayout = QHBoxLayout(hbox) hboxLayout.setContentsMargins(0, 0, 0, 0) hboxLayout.setSpacing(6) hbox.setLayout(hboxLayout) cb1 = QComboBox(hbox) cb1.setEditable(False) self.__populateCharTypeCombo(cb1, False) hboxLayout.addWidget(cb1) l1 = QLabel(self.tr("Between:"), hbox) hboxLayout.addWidget(l1) le1 = QLineEdit(hbox) le1.setValidator(self.charValidator) hboxLayout.addWidget(le1) l2 = QLabel(self.tr("And:"), hbox) hboxLayout.addWidget(l2) le2 = QLineEdit(hbox) le2.setValidator(self.charValidator) hboxLayout.addWidget(le2) self.rangesItemsBoxLayout.addWidget(hbox) cb1.activated[int].connect(self.__rangesCharTypeSelected) hbox.show() self.rangesItemsBox.adjustSize() self.rangesEntries.append([cb1, le1, le2]) def __populateW3cCharacterCombo(self, combo, format): """ Private method to populate a W3C character selection combo. @param combo combo box to be populated (QComboBox) @param format format identifier (one of "-ccp", "-ccn", "-cbp", "-cbn") """ combo.clear() if format in ["-ccp", "-ccn"]: comboLen = 0 for txt, code in self.__characterCategories: combo.addItem(txt, code) comboLen = max(comboLen, len(txt)) combo.setMinimumContentsLength(comboLen) elif format in ["-cbp", "-cbn"]: comboLen = 0 for txt, code in self.__characterBlocks: combo.addItem(txt, code) comboLen = max(comboLen, len(txt)) combo.setMinimumContentsLength(comboLen) def __performSelectedAction(self, format, lineedit, combo): """ Private method performing some actions depending on the input. @param format format of the selected entry (string) @param lineedit line edit widget to act on (QLineEdit) @param combo combo box widget to act on (QComboBox) """ if format == "-i": return if format in ["-c", "-h", "-o"]: lineedit.show() lineedit.setEnabled(True) if combo is not None: combo.hide() if format == "-c": lineedit.setValidator(self.charValidator) elif format == "-h": lineedit.setValidator(self.hexValidator) elif format == "-o": lineedit.setValidator(self.octValidator) elif format in ["-ccp", "-ccn", "-cbp", "-cbn"]: lineedit.setEnabled(False) lineedit.hide() if combo is not None: combo.show() self.__populateW3cCharacterCombo(combo, format) else: lineedit.setEnabled(False) lineedit.hide() if combo is not None: combo.hide() lineedit.clear() def __singlesCharTypeSelected(self, index): """ Private slot to handle the activated(int) signal of the single chars combo boxes. @param index selected list index (integer) """ combo = self.sender() for entriesList in self.singlesEntries: if combo == entriesList[0]: format = combo.itemData(index) self.__performSelectedAction( format, entriesList[1], entriesList[2]) break def __rangesCharTypeSelected(self, index): """ Private slot to handle the activated(int) signal of the char ranges combo boxes. @param index selected list index (integer) """ combo = self.sender() for entriesList in self.rangesEntries: if combo == entriesList[0]: format = combo.itemData(index) self.__performSelectedAction(format, entriesList[1], None) self.__performSelectedAction(format, entriesList[2], None) break def __formatCharacter(self, char, format): """ Private method to format the characters entered into the dialog. @param char character string entered into the dialog (string) @param format string giving a special format (-c, -h, -i or -o) or the already formatted character (string) @return formatted character string (string) """ if format == "-c": return char elif format == "-i": return "" if self.__mode in [QRegExpWizardCharactersDialog.RegExpMode, QRegExpWizardCharactersDialog.W3CMode]: if format == "-h": return "\\x{0}".format(char.lower()) elif format == "-o": return "\\0{0}".format(char) elif format in ["-ccp", "-cbp"]: return "\\p{{{0}}}".format(char) elif format in ["-ccn", "-cbn"]: return "\\P{{{0}}}".format(char) else: return format def getCharacters(self): """ Public method to return the character string assembled via the dialog. @return formatted string for character classes (string) """ regexp = "" # negative character range if self.negativeCheckBox.isChecked(): regexp += "^" # predefined character ranges if self.wordCharCheckBox.isChecked(): regexp += "\\w" if self.nonWordCharCheckBox.isChecked(): regexp += "\\W" if self.digitsCheckBox.isChecked(): regexp += "\\d" if self.nonDigitsCheckBox.isChecked(): regexp += "\\D" if self.whitespaceCheckBox.isChecked(): regexp += "\\s" if self.nonWhitespaceCheckBox.isChecked(): regexp += "\\S" if self.w3cInitialIdentifierCheckBox.isChecked(): regexp += "\\i" if self.w3cNonInitialIdentifierCheckBox.isChecked(): regexp += "\\I" if self.w3cNmtokenCheckBox.isChecked(): regexp += "\\c" if self.w3cNonNmtokenCheckBox.isChecked(): regexp += "\\C" # single characters for entrieslist in self.singlesEntries: format = entrieslist[0].itemData(entrieslist[0].currentIndex()) if format in ["-ccp", "-ccn", "-cbp", "-cbn"]: char = entrieslist[2].itemData(entrieslist[2].currentIndex()) else: char = entrieslist[1].text() regexp += self.__formatCharacter(char, format) # character ranges for entrieslist in self.rangesEntries: if not entrieslist[1].text() or \ not entrieslist[2].text(): continue format = entrieslist[0].itemData(entrieslist[0].currentIndex()) char1 = entrieslist[1].text() char2 = entrieslist[2].text() regexp += "{0}-{1}".format( self.__formatCharacter(char1, format), self.__formatCharacter(char2, format)) if regexp: if (regexp.startswith("\\") and regexp.count("\\") == 1 and "-" not in regexp) or \ len(regexp) == 1: return regexp else: return "[{0}]".format(regexp) else: return ""