def showData(self, line): unicode_fonts = UnicodeFonts() for i, column in enumerate(line): text_edit = QGrowingTextEdit() unicode_fonts.applyFontAndSizeToQWidget(str(column), text_edit) text_edit.setText(str(column)) text_edit.setObjectName("bla") text_edit.setReadOnly(True) self.layout.addWidget(text_edit)
def editorTab(self, filepath): editor = QTextEdit() data = "" with open(filepath[0]) as fobj: for line in fobj: data += line unicode_fonts = UnicodeFonts() unicode_fonts.applyFontAndSizeToQWidget(data, editor) editor.setText(data) return editor
def __init__(self): super().__init__() self.setWindowTitle("virtual keyboard") self.resize(450, 150) self.unicode_fonts = UnicodeFonts() #self.language = None self.keys = None self.level_one_chars = None self.level_two_chars = None self.modifier = Qt.NoModifier self.ipa_keyboard = IPAKeyboard()
def __init__(self): super().__init__() self.unicode_fonts = UnicodeFonts() self.grid = QGridLayout() self.grid.setContentsMargins(0, 0, 0, 6) self.setLayout(self.grid) self.display_widget = QTextEditEnhanced() self.display_widget.setText( "type in the command 'man' down in the command line for getting started ..." ) self.display_widget.setReadOnly(True) self.addDisplayWidget() line = QInputLine() line.setPlaceholderText( "This is the command line. See 'man commandline' for details.") line.return_pressed.connect(self.commandEntered) self.grid.addWidget(line, 1, 0) vkbdButton = QPushButton(self) vkbdButton.clicked.connect(partial(self.vkbdButtonClicked, line)) vkbdButton.setIcon(QIcon.fromTheme('input-keyboard')) self.grid.addWidget(vkbdButton, 1, 1) zoomOutButton = QPushButton(self) zoomOutButton.setIcon(QIcon.fromTheme('zoom-out')) zoomOutButton.clicked.connect(self.onZoomOutClicked) self.grid.addWidget(zoomOutButton, 1, 2) zoomResetButton = QPushButton(self) zoomResetButton.setIcon(QIcon.fromTheme('zoom-original')) zoomResetButton.clicked.connect(self.onZoomResetClicked) self.grid.addWidget(zoomResetButton, 1, 3) zoomInButton = QPushButton(self) zoomInButton.setIcon(QIcon.fromTheme('zoom-in')) zoomInButton.clicked.connect(self.onZoomInClicked) self.grid.addWidget(zoomInButton, 1, 4) self.applyStylesheet()
def __init__(self): super().__init__() self.unicode_fonts = UnicodeFonts()
class QDeckLearnWidget(QWidget): deckpath = None selectDeck = pyqtSignal() grid = None dataset = None number_of_data = None current_index = 0 def __init__(self): super().__init__() self.unicode_fonts = UnicodeFonts() def initialize(self, deckpath): self.deckpath = deckpath try: self.clear() except SystemError: pass db_path = path.join(deckpath, "database.sqlite") self.dbAdapter = DeckDbAdapter() self.dbAdapter.initialize(db_path) deck_select_button = QPushButton("<<<") self.data_counter = QLabel() self.data_counter.setAlignment(Qt.AlignVCenter | Qt.AlignHCenter) deck_select_button.clicked.connect(self.selectDeckButtonClicked) self.current_name = QLabel() self.current_name.setAlignment(Qt.AlignVCenter | Qt.AlignHCenter) self.current_word = QLabel() self.current_word.setFont(QFont("Helvetica", 20)) self.current_word.setAlignment(Qt.AlignVCenter | Qt.AlignHCenter) self.current_translation = QLabel() self.current_translation.setAlignment(Qt.AlignVCenter | Qt.AlignHCenter) button_prev = QPushButton('prev') button_next = QPushButton('next') button_show_translation = QPushButton('show translation') button_new_set = QPushButton('new set') button_known = QPushButton('known') button_not_known = QPushButton('not known') button_prev.clicked.connect(self.buttonPrevClicked) button_next.clicked.connect(self.buttonNextClicked) button_show_translation.clicked.connect(self.buttonShowTranslationClicked) button_new_set.clicked.connect(self.buttonNewSetClicked) button_known.clicked.connect(self.buttonKnownClicked) button_not_known.clicked.connect(self.buttonNotKnownClicked) self.svgWidget = QtSvg.QSvgWidget() self.svgWidget.setFixedSize(300, 150) self.svgWidget.setStyleSheet("background-color: rgb(255,0,0); margin:5px; border:1px solid rgb(0, 255, 0); ") self.buttonNewSetClicked() if not self.layout(): self.grid = QGridLayout() self.grid.setContentsMargins(0, 0, 0, 0) self.grid.addWidget(deck_select_button, 0, 0) self.grid.addWidget(self.data_counter, 0, 2) #self.grid.addWidget(self.svgWidget, 1, 1) self.grid.addWidget(self.current_name, 4, 1) self.grid.addWidget(self.current_word, 5, 1) self.grid.addWidget(self.current_translation, 6, 1) self.grid.addWidget(button_prev, 7, 0) self.grid.addWidget(button_next, 8, 0) self.grid.addWidget(button_show_translation, 7, 1) self.grid.addWidget(button_new_set, 8, 1) self.grid.addWidget(button_known, 7, 2) self.grid.addWidget(button_not_known, 8, 2) layout = self.setLayout(self.grid) def clear(self): if self.grid: # just reparent the layout to a temporary one for delete it QWidget().setLayout(self.grid) def selectDeckButtonClicked(self): self.selectDeck.emit() def buttonPrevClicked(self): if self.current_index > 0: self.current_index -= 1 else: self.current_index = len(self.dataset)-1 self.setTexts() def buttonNextClicked(self): if self.current_index < len(self.dataset)-1: self.current_index += 1 else: self.current_index = 0 self.setTexts() def setTexts(self): try: self.current_word.setText(self.dataset[self.current_index]['word']) except IndexError: self.current_word.setText('ERROR: empty set') self.current_name.setText("") self.current_translation.setText("") self.svgWidget.load(path.join(self.deckpath, self.dataset[self.current_index]['svg_filename'])) self.data_counter.setText(str(self.current_index+1) + "/" + str(self.number_of_data)) def buttonShowTranslationClicked(self): try: self.current_name.setText(self.dataset[self.current_index]['name']) self.unicode_fonts.applyFontAndSizeToQWidget(self.dataset[self.current_index]['name'], self.current_name) self.current_translation.setText(self.dataset[self.current_index]['translation']) #self.current_translation.setFontPointSize(40) self.unicode_fonts.applyFontAndSizeToQWidget(self.dataset[self.current_index]['translation'], self.current_translation) except IndexError: self.current_name.setText('ERROR: empty set') self.current_translation.setText('ERROR: empty set') def buttonNewSetClicked(self): self.current_index = 0 self.dataset = self.dbAdapter.getDataset() self.number_of_data = len(self.dataset) self.data_counter.setText(str(self.current_index+1) + "/" + str(self.number_of_data)) self.current_name.setText("")#self.dataset[self.current_index]['name']) try: self.current_word.setText(self.dataset[self.current_index]['word']) except IndexError: self.current_word.setText("ERROR: empty set") self.current_translation.setText("")#self.dataset[self.current_index]['translation']) try: self.svgWidget.load(path.join(self.deckpath, self.dataset[self.current_index]['svg_filename'])) except IndexError: """ we just do not have an svg-image """ pass def buttonKnownClicked(self): self.dbAdapter.updateKnown(self.dataset[self.current_index]['rowid'], 1) self.buttonNextClicked() def buttonNotKnownClicked(self): self.dbAdapter.updateKnown(self.dataset[self.current_index]['rowid'], -1) self.buttonNextClicked()
class QCliWidget(QWidget): interpreter = Interpreter() display_widget = None vkbd = None beamer = None result_from_queue = False set_tab_text = pyqtSignal(str) def __init__(self): super().__init__() self.unicode_fonts = UnicodeFonts() self.grid = QGridLayout() self.grid.setContentsMargins(0, 0, 0, 6) self.setLayout(self.grid) self.display_widget = QTextEditEnhanced() self.display_widget.setText( "type in the command 'man' down in the command line for getting started ..." ) self.display_widget.setReadOnly(True) self.addDisplayWidget() line = QInputLine() line.setPlaceholderText( "This is the command line. See 'man commandline' for details.") line.return_pressed.connect(self.commandEntered) self.grid.addWidget(line, 1, 0) vkbdButton = QPushButton(self) vkbdButton.clicked.connect(partial(self.vkbdButtonClicked, line)) vkbdButton.setIcon(QIcon.fromTheme('input-keyboard')) self.grid.addWidget(vkbdButton, 1, 1) zoomOutButton = QPushButton(self) zoomOutButton.setIcon(QIcon.fromTheme('zoom-out')) zoomOutButton.clicked.connect(self.onZoomOutClicked) self.grid.addWidget(zoomOutButton, 1, 2) zoomResetButton = QPushButton(self) zoomResetButton.setIcon(QIcon.fromTheme('zoom-original')) zoomResetButton.clicked.connect(self.onZoomResetClicked) self.grid.addWidget(zoomResetButton, 1, 3) zoomInButton = QPushButton(self) zoomInButton.setIcon(QIcon.fromTheme('zoom-in')) zoomInButton.clicked.connect(self.onZoomInClicked) self.grid.addWidget(zoomInButton, 1, 4) self.applyStylesheet() def applyStylesheet(self): config = ConfigFile(None, None) path = config.readVar('global', 'stylesheet') stylesheet = '' try: with open(path) as css: for line in css: stylesheet += line self.display_widget.setStyleSheet(stylesheet) except FileNotFoundError: pass def addDisplayWidget(self): self.view = QGraphicsView() self.scene = QGraphicsScene() self.scene.addWidget(self.display_widget) self.view.setScene(self.scene) self.view.setStyleSheet("QGraphicsView { border-style: none; }") self.grid.addWidget(self.view, 0, 0, 1, 0) self.resizeDisplayWidget() self.applyStylesheet() def resizeDisplayWidget(self): # the magick numbers are for keeping the size of the view allways small enough not to spawn an outer set of scrollbars: x = self.view.width() - 2.1 y = self.view.height() - 2.1 self.x, self.y = x, y mapped_rect = self.view.mapToScene(QRect(0, 0, x, y)).boundingRect() self.display_widget.setFixedSize(mapped_rect.width(), mapped_rect.height()) self.scene.setSceneRect(0, 0, mapped_rect.width(), mapped_rect.height()) def resizeEvent(self, event): self.resizeDisplayWidget() def vkbdButtonClicked(self, lineEdit): self.vkbd = QVirtualKeyboardWindow() self.vkbd.setLineEdit(lineEdit) def commandEntered(self, command): # to keep the display_widget in the correct size self.resize(self.x, self.y) print("command:", command) if '|' in command: command, pipe = command.split('|') self.handleCommand(command) pipe = pipe.strip() if pipe == 'beamer': if self.beamer: self.beamer.destroy() print('destroyed!!!') self.beamer = QBeamerWindow() from PyQt5.QtWidgets import QLabel, QPushButton widget = QLabel('blaaaa') self.beamer.setWidget(self.display_widget) #self.beamer.setText('test') self.beamer.routeToScreen() self.beamer.showFullScreen() else: #self.handleCommand(command) self.set_tab_text.emit(command) #self.activityIndicator() q = queue.Queue() self.interpreter_thread = HandleCommandThread(command, q) self.interpreter_thread.processResult.connect(self.processResult) self.interpreter_thread.clearDisplayWidget.connect( self.clearDisplayWidget) self.interpreter_thread.makeSnapshot.connect(self.makeSnapshot) self.interpreter_thread.stopQueueListener.connect( self.stopQueueListener) self.interpreter_thread.start() self.queue_thread = GetQueueItemsThread(q) self.queue_thread.processQueueItem.connect(self.processQueueItem) self.queue_thread.start() def stopQueueListener(self): self.queue_thread.stop() def processQueueItem(self, item): self.result_from_queue = True item = item.getItem() json_dict = json.loads(item) if json_dict['category'] == 'progressbar': last_type = type(self.display_widget) if not last_type == QProgressBar: self.display_widget.deleteLater() self.display_widget = QProgressBar() self.display_widget.setMinimum(json_dict['minimum']) self.display_widget.setMaximum(json_dict['maximum']) self.display_widget.setValue(json_dict['value']) if not last_type == QProgressBar: self.addDisplayWidget() else: result_object = Result() result_object.payload = item.getItem() self.resultInTextEdit(result_object) def processResult(self, result): if self.result_from_queue: self.result_from_queue = False else: #if result is None: #self.showErrorMessage('no result found') if hasattr(result, 'payload') and result.payload: if hasattr(result, 'category') and result.category == "table": try: result.payload[0] except IndexError: pass # datastructure does not fit to display type 'table' else: self.resultInTable(result) elif hasattr( result, 'category') and result.category == "multimedia_table": self.resultInMultimediaTable(result) elif hasattr(result, 'category') and result.category == "list": self.resultInTextEdit(result) elif hasattr(result, 'category') and result.category == "text": self.resultInTextEdit(result) elif hasattr(result, 'category') and result.category == "string": self.resultInTextEdit(result) elif hasattr(result, 'category') and result.category == "itemized": self.resultInItemizedWidget(result) elif hasattr(result, 'category') and result.category == "image": self.resultInImageWidget(result) elif hasattr(result, 'category') and result.category == "html": #self.resultInHTMLWidget(result) self.resultInTextEdit(result) elif hasattr(result, 'category') and result.category == 'diagram': self.resultInDiagram(result) elif hasattr(result, 'category') and result.category == 'bloodline': self.resultInBloodlineDiagram(result) elif hasattr(result, 'category') and result.category == 'command': self.showMapWidget() elif hasattr(result, 'error') and result.error: self.showErrorMessage(result.error) else: result = Result() result.payload = 'empty result set' self.resultInTextEdit(result) def activityIndicator(self): self.display_widget.deleteLater() label = QLabel() movie = QMovie('./assets/images/activity_indicator.gif') movie.start() label.setMovie(movie) self.display_widget = QWidget() layout = QVBoxLayout() self.display_widget.setLayout(layout) layout.addWidget(label, Qt.AlignCenter) self.addDisplayWidget() def clearDisplayWidget(self): self.display_widget.deleteLater() self.display_widget = QTextEditEnhanced() self.display_widget.setReadOnly(True) self.addDisplayWidget() def makeSnapshot(self): image = QImage(self.display_widget.size(), QImage.Format_ARGB32) painter = QPainter(image) if painter.isActive(): self.render(painter) painter.end() default_dir = path.join(path.expanduser('~')) filename = QFileDialog.getSaveFileName(self, 'Save Snapshot', default_dir) image.save(filename[0]) def resultInTable(self, result): self.display_widget.deleteLater() self.display_widget = QTableWidget() self.display_widget.setRowCount(len(result.payload)) self.display_widget.setColumnCount(len(result.payload[0])) try: self.display_widget.setHorizontalHeaderLabels(result.header) except TypeError: pass try: self.display_widget.setVerticalHeaderLabels(result.header_left) except TypeError: pass for row, line in enumerate(result.payload): for column, item in enumerate(line): table_item = QTableWidgetItem(str(item)) table_item.setFlags(Qt.ItemIsEnabled) self.unicode_fonts.applyFontToQWidget(str(item), table_item) self.display_widget.setItem(row, column, table_item) self.display_widget.resizeColumnsToContents() self.addDisplayWidget() def resultInMultimediaTable(self, result): self.display_widget.deleteLater() max_length = 0 for line in result.payload: if len(line) > max_length: max_length = len(line) self.display_widget = QTableWidget() self.display_widget.setRowCount(len(result.payload)) self.display_widget.setColumnCount(max_length) audio_count = 0 config = ConfigFile(None, None) deckpath = config.readPath("vocable", "deckpath") for row, line in enumerate(result.payload): deckname = line[0] for column, item in enumerate(line): if self.isImage(str(item)): pixmap = QPixmap() pixmap.load(path.join(deckpath, deckname, str(item))) pixmap = pixmap.scaled(QSize(60, 30), Qt.KeepAspectRatio) image_widget = QLabel() image_widget.setPixmap(pixmap) self.display_widget.setCellWidget(row, column, image_widget) elif self.isAudio(str(item)): splitted = item.split(',') if audio_count < len(splitted): audio_count = len(splitted) audio_widget = QAudioItems(path.join(deckpath, deckname), self.display_widget, 7, max_length) audio_widget.appendPlayButtonsList(splitted, row) else: table_item = QTableWidgetItem(str(item)) table_item.setFlags(Qt.ItemIsEnabled) #self.unicode_fonts.applyFontToQWidget(str(item), table_item) self.display_widget.setItem(row, column, table_item) self.display_widget.setColumnCount(max_length + audio_count) self.display_widget.resizeColumnsToContents() self.addDisplayWidget() def resultInTextEdit(self, result): self.display_widget.deleteLater() self.display_widget = QTextEditEnhanced() self.unicode_fonts.applyFontAndSizeToQWidget(result.toString(), self.display_widget) self.display_widget.setAcceptRichText(True) self.display_widget.setText(result.toString()) self.display_widget.setReadOnly(True) self.display_widget.setTextInteractionFlags( self.display_widget.textInteractionFlags() | Qt.TextSelectableByKeyboard) self.addDisplayWidget() def resultInHTMLWidget(self, result): self.display_widget.deleteLater() self.display_widget = QWebView() self.display_widget.setHtml(result.payload) self.addDisplayWidget() def resultInItemizedWidget(self, result): self.display_widget.deleteLater() self.display_widget = QItemizedWidget(result.payload) self.addDisplayWidget() def resultInImageWidget(self, result): self.display_widget.deleteLater() self.display_widget = QCustomizedGraphicsView() import PIL if type(result.payload) == PIL.Image.Image: from PIL.ImageQt import ImageQt qimage = ImageQt(result.payload) pixmap = QPixmap.fromImage(qimage) #pixmap = QPixmap("/tmp/tmprp3q0gi9.PNG") #pixmap.fromImage(image) item = self.display_widget.scene().addPixmap(pixmap) item.setPos(0, 0) self.addDisplayWidget() def resultInDiagram(self, result): self.display_widget.deleteLater() curve = QLineSeries() pen = curve.pen() pen.setColor(Qt.red) pen.setWidthF(2) curve.setPen(pen) for data in result.payload: if type(data['y']) == str: data['y'] = 0 curve.append(data['x'], data['y'], 10) chart = QChart() chart.setTitle(result.name) chart.legend().hide() chart.addSeries(curve) chart.createDefaultAxes() view = QChartViewEnhanced(chart) view.setRenderHint(QPainter.Antialiasing) self.display_widget = view self.addDisplayWidget() def resultInBloodlineDiagram(self, result): self.display_widget.deleteLater() self.display_widget = QBloodlineWidget(result.payload) self.addDisplayWidget() def showMapWidget(self): self.display_widget.deleteLater() self.display_widget = QMapWidget() self.display_widget.showPosition() self.addDisplayWidget() def showErrorMessage(self, message): self.display_widget.deleteLater() self.display_widget = QTextEditEnhanced() self.display_widget.setText(message) self.display_widget.setReadOnly(True) self.addDisplayWidget() def onZoomInClicked(self): if type(self.display_widget) == QTextEditEnhanced: self.display_widget.zoomIn() elif type(self.display_widget) == QChartViewEnhanced: self.display_widget.chart().zoomIn() else: self.view.scale(SCALE_FACTOR, SCALE_FACTOR) self.resizeDisplayWidget() def onZoomOutClicked(self): if type(self.display_widget) == QTextEditEnhanced: self.display_widget.zoomOut() elif type(self.display_widget) == QChartViewEnhanced: self.display_widget.chart().zoomOut() else: self.view.scale(1 / SCALE_FACTOR, 1 / SCALE_FACTOR) self.resizeDisplayWidget() def onZoomResetClicked(self): if type(self.display_widget) == QTextEditEnhanced: self.display_widget.zoomReset() elif type(self.display_widget) == QChartViewEnhanced: self.display_widget.chart().zoomReset() else: self.view.resetTransform() self.resizeDisplayWidget() def keyPressEvent(self, event): if (event.modifiers() & Qt.ControlModifier): if event.key() == Qt.Key_Plus: self.onZoomInClicked() elif event.key() == Qt.Key_Minus: self.onZoomOutClicked() def isImage(self, data): suffixes = ['.png', '.jpg', '.jpe', '.jpeg', '.svg', '.bmp'] for suffix in suffixes: if data.lower().endswith(suffix): return True return False def isAudio(self, data): suffixes = ['.ogg', '.wav', '.mp3', '.aiff', '.wma'] for suffix in suffixes: if data.lower().endswith(suffix): return True return False
class QDeckOverviewWidget(QWidget): deckpath = None selectDeck = pyqtSignal() createNewItem = pyqtSignal(str, object, str) editDeckItem = pyqtSignal(str, object, int, str) tableWidget = None audioWidget = None def __init__(self): super().__init__() self.unicodeFonts = UnicodeFonts() def initialize(self, deckpath, deckname): self.deckpath = deckpath self.deckname = deckname db_path = path.join(deckpath, "database.sqlite") self.dbAdapter = DeckDbAdapter() self.dbAdapter.initialize(db_path) deck_select_button = QPushButton("<<<") deck_select_button.clicked.connect(self.selectDeckButtonClicked) new_item_button = QPushButton("new item") new_item_button.clicked.connect(self.newItemButtonClicked) stop_all_sounds_button = QPushButton("stop all sounds") stop_all_sounds_button.clicked.connect(self.stopAllSounds) self.initTableWidget() if not self.layout(): self.grid = QGridLayout() self.grid.setContentsMargins(0, 0, 0, 0) self.grid.addWidget(deck_select_button, 0, 0) self.grid.addWidget(self.tableWidget, 1, 0, 1, 3) self.grid.addWidget(new_item_button, 2, 0) self.grid.addWidget(stop_all_sounds_button, 2, 2) layout = self.setLayout(self.grid) self.initWithDbData() def initTableWidget(self): if not self.tableWidget: self.tableWidget = QTableWidget() self.tableWidget.setColumnCount(8) self.tableWidget.setRowCount(0) self.tableWidget.setHorizontalHeaderLabels( ["", "", "id", "name", "word", "translation", "svg", "audio"]) self.tableWidget.verticalHeader().hide() self.tableWidget.horizontalHeader().hide() def initWithDbData(self): self.tableWidget.clear() data = self.dbAdapter.selectDeckItems() #data = self.dbAdapter.selectDeckItemsWithAudio() self.tableWidget.setRowCount(len(data)) max_audio_count = self.dbAdapter.getMaxAudioCount() self.audioWidget = QAudioItems(self.deckpath, self.tableWidget, max_audio_count, COLUMN_OFFSET) for i, line in enumerate(data): rowid = line["rowid"] order_index = line["order_index"] name = line["name"] word = line["word"] phonetical = line["phonetical"] translation = line["translation"] svg_filename = line["svg_filename"] image_filename = None imageWidget = QLabel() try: image_filename = line["image"] except: """ maybe we have an image, maybe not ... """ pass else: pixmap = QPixmap() try: pixmap.load(path.join(self.deckpath, image_filename)) except TypeError: """ probably we have an None-image here """ pass else: pixmap = pixmap.scaled(QSize(60, 30), Qt.KeepAspectRatio) imageWidget.setPixmap(pixmap) audio_filenames = self.dbAdapter.audioFilenamesForDeckRowID(rowid) try: svgWidget = QtSvg.QSvgWidget( path.join(self.deckpath, svg_filename)) except TypeError: svgWidget = QtSvg.QSvgWidget() #svgWidget.setGeometry(50,50,759,668) svgWidget.setFixedSize(60, 30) edit_button = QPushButton() #"edit") edit_button.setIcon(QIcon.fromTheme("document-properties")) edit_button.clicked.connect( partial(self.editRowButtonClicked, rowid)) delete_button = QPushButton() #"delete") delete_button.setIcon(QIcon.fromTheme('edit-delete')) delete_button.clicked.connect( partial(self.deleteRowButtonClicked, rowid)) self.tableWidget.setCellWidget(i, 0, edit_button) self.tableWidget.setCellWidget(i, 1, delete_button) self.tableWidget.setItem(i, 2, QTableWidgetItem(str(order_index))) self.tableWidget.setItem(i, 3, QTableWidgetItem(name)) self.tableWidget.setItem(i, 4, QTableWidgetItem(word)) phonetical_item = QTableWidgetItem(phonetical) self.unicodeFonts.setFont('ipa', phonetical_item) self.tableWidget.setItem(i, 5, phonetical_item) self.tableWidget.setItem(i, 6, QTableWidgetItem(translation)) self.tableWidget.setCellWidget(i, 7, svgWidget) self.tableWidget.setCellWidget(i, 8, imageWidget) #if audio_filenames: print("AUDIO_FILENAMES") print(audio_filenames) self.audioWidget.appendPlayButtonsDict(audio_filenames, i) #column_count = self.audioWidget.getMaxColCount() #self.tableWidget.setColumnCount(column_count) self.tableWidget.setColumnCount(COLUMN_OFFSET + max_audio_count) self.tableWidget.resizeColumnsToContents() def selectDeckButtonClicked(self): self.selectDeck.emit() def newItemButtonClicked(self): self.createNewItem.emit(self.deckpath, self.dbAdapter, self.deckname) def editRowButtonClicked(self, rowid): self.editDeckItem.emit(self.deckpath, self.dbAdapter, int(rowid), self.deckname) def deleteRowButtonClicked(self, rowid): delete_msg = "really?" reply = QMessageBox.question(self, 'Delete', delete_msg, QMessageBox.Yes, QMessageBox.No) if reply == QMessageBox.Yes: svg_filename, audio_filenames = self.dbAdapter.deleteItem(rowid) if svg_filename: remove(path.join(self.deckpath, svg_filename)) pass for audio in audio_filenames: if path.exists(path.join(self.deckpath, audio)): remove(path.join(self.deckpath, audio)) self.initWithDbData() def stopAllSounds(self): self.audioWidget.stopAllSounds()
def __init__(self): super().__init__() self.unicode_fonts = UnicodeFonts() self.default_bible = self.config.readVar('global', 'default_bible') self.grid = QGridLayout() self.grid.setContentsMargins(0, 0, 0, 6) self.setLayout(self.grid) self.text_edit = QTextEditEnhanced() self.combo_language = QComboBox() self.combo_translation = QComboBox() self.combo_book = QComboBox() self.combo_chapter = QComboBox() self.combo_language.currentTextChanged.connect(self.languageChanged) self.combo_translation.currentTextChanged.connect( self.translationChanged) self.combo_book.currentTextChanged.connect(self.bookChanged) self.prev_verse_button = QPushButton("<") self.prev_verse_button.setMaximumSize(25, 25) self.next_verse_button = QPushButton(">") self.next_verse_button.setMaximumSize(25, 25) self.prev_verse_button.clicked.connect(self.prevChapter) self.next_verse_button.clicked.connect(self.nextChapter) self.grid.addWidget(QLabel("Language"), 0, 0) self.grid.addWidget(QLabel("Translation"), 0, 1) self.grid.addWidget(QLabel("Book"), 0, 2) self.grid.addWidget(QLabel("Chapter"), 0, 3) self.grid.addWidget(self.combo_language, 1, 0) self.grid.addWidget(self.combo_translation, 1, 1) self.grid.addWidget(self.combo_book, 1, 2) self.grid.addWidget(self.combo_chapter, 1, 3) self.grid.addWidget(self.prev_verse_button, 1, 4) self.grid.addWidget(self.next_verse_button, 1, 5) zoom_in_button = QPushButton(self) zoom_in_button.setIcon(QIcon.fromTheme('zoom-in')) zoom_in_button.clicked.connect(self.onZoomInClicked) zoom_in_button.setMaximumSize(25, 25) zoom_out_button = QPushButton(self) zoom_out_button.setIcon(QIcon.fromTheme('zoom-out')) zoom_out_button.clicked.connect(self.onZoomOutClicked) zoom_out_button.setMaximumSize(25, 25) zoom_reset_button = QPushButton(self) zoom_reset_button.setIcon(QIcon.fromTheme('zoom-original')) zoom_reset_button.clicked.connect(self.onZoomResetClicked) zoom_reset_button.setMaximumSize(25, 25) self.grid.addWidget(zoom_out_button, 1, 6) self.grid.addWidget(zoom_reset_button, 1, 7) self.grid.addWidget(zoom_in_button, 1, 8) self.grid.addWidget(self.text_edit, 2, 0, 1000, 9) self.getLanguagesForDropdown() self.getBooksForDropdown() self.setDefaultBible() self.restoreLastBookAndChapter() """ this has to be after setting the default values to avoid spamming the history on init and to avoid to much gui-updates on init """ self.combo_chapter.currentTextChanged.connect(self.chapterChanged)
class QSwordGui(QWidget): interpreter = Interpreter() queue = queue.Queue() sword = Sword() config = ConfigFile(os.path.join('modules', 'sword'), 'sword.conf') history = History("history_sword") set_tab_text = pyqtSignal(str) def __init__(self): super().__init__() self.unicode_fonts = UnicodeFonts() self.default_bible = self.config.readVar('global', 'default_bible') self.grid = QGridLayout() self.grid.setContentsMargins(0, 0, 0, 6) self.setLayout(self.grid) self.text_edit = QTextEditEnhanced() self.combo_language = QComboBox() self.combo_translation = QComboBox() self.combo_book = QComboBox() self.combo_chapter = QComboBox() self.combo_language.currentTextChanged.connect(self.languageChanged) self.combo_translation.currentTextChanged.connect( self.translationChanged) self.combo_book.currentTextChanged.connect(self.bookChanged) self.prev_verse_button = QPushButton("<") self.prev_verse_button.setMaximumSize(25, 25) self.next_verse_button = QPushButton(">") self.next_verse_button.setMaximumSize(25, 25) self.prev_verse_button.clicked.connect(self.prevChapter) self.next_verse_button.clicked.connect(self.nextChapter) self.grid.addWidget(QLabel("Language"), 0, 0) self.grid.addWidget(QLabel("Translation"), 0, 1) self.grid.addWidget(QLabel("Book"), 0, 2) self.grid.addWidget(QLabel("Chapter"), 0, 3) self.grid.addWidget(self.combo_language, 1, 0) self.grid.addWidget(self.combo_translation, 1, 1) self.grid.addWidget(self.combo_book, 1, 2) self.grid.addWidget(self.combo_chapter, 1, 3) self.grid.addWidget(self.prev_verse_button, 1, 4) self.grid.addWidget(self.next_verse_button, 1, 5) zoom_in_button = QPushButton(self) zoom_in_button.setIcon(QIcon.fromTheme('zoom-in')) zoom_in_button.clicked.connect(self.onZoomInClicked) zoom_in_button.setMaximumSize(25, 25) zoom_out_button = QPushButton(self) zoom_out_button.setIcon(QIcon.fromTheme('zoom-out')) zoom_out_button.clicked.connect(self.onZoomOutClicked) zoom_out_button.setMaximumSize(25, 25) zoom_reset_button = QPushButton(self) zoom_reset_button.setIcon(QIcon.fromTheme('zoom-original')) zoom_reset_button.clicked.connect(self.onZoomResetClicked) zoom_reset_button.setMaximumSize(25, 25) self.grid.addWidget(zoom_out_button, 1, 6) self.grid.addWidget(zoom_reset_button, 1, 7) self.grid.addWidget(zoom_in_button, 1, 8) self.grid.addWidget(self.text_edit, 2, 0, 1000, 9) self.getLanguagesForDropdown() self.getBooksForDropdown() self.setDefaultBible() self.restoreLastBookAndChapter() """ this has to be after setting the default values to avoid spamming the history on init and to avoid to much gui-updates on init """ self.combo_chapter.currentTextChanged.connect(self.chapterChanged) def languageChanged(self, language): self.getTranslationsForDropdown(language) def translationChanged(self, translation): self.showText() def bookChanged(self, book): self.getChaptersForDropdown(book) def chapterChanged(self, chapter): self.showText() def prevChapter(self): chapter = self.combo_chapter.currentText() self.combo_chapter.setCurrentText(str(int(chapter) - 1)) self.showText() def nextChapter(self): chapter = self.combo_chapter.currentText() self.combo_chapter.setCurrentText(str(int(chapter) + 1)) self.showText() def getLanguagesForDropdown(self): #result = self.interpreter.interpreter('sword.languages', self.queue).payload result = self.sword.listLanguages(None, []).payload if result is None: self.text_edit.clear() self.text_edit.setText( "no sword modules (=bibles) installed. please install some using the \"Sword->Module Manager\" menu entry." ) else: self.combo_language.clear() self.combo_language.insertItems(0, result) def getTranslationsForDropdown(self, language): #result = self.interpreter.interpreter('sword.modules '+language, self.queue).payload result = self.sword.listModules(None, [language]).payload translations = [] for translation in result: translations.append(translation[0]) self.combo_translation.clear() self.combo_translation.insertItems(0, translations) def setDefaultBible(self): #sword_modules = self.interpreter.interpreter('sword.modules', self.queue).payload sword_modules = self.sword.listModules(None, []).payload for module in sword_modules: if module[0] == self.default_bible: self.combo_language.setCurrentText(module[1]) self.combo_translation.setCurrentText(self.default_bible) def restoreLastBookAndChapter(self): last = self.history.historyReadAtIndex(3) try: translation, book, chapter = last.split(" ") self.combo_book.setCurrentText(book) self.combo_chapter.setCurrentText(chapter) self.showText() except ValueError: # probably we have an empty history-file pass def getBooksForDropdown(self): #books = self.interpreter.interpreter('sword.books', self.queue).payload books = self.sword.books(None, []).payload self.combo_book.clear() self.combo_book.insertItems(0, books) def getChaptersForDropdown(self, book): books = self.sword.canons() for testament in books: for _b in books[testament]: if _b[0] == book: chapters = [] for i, length in enumerate(_b[3]): chapters.append(str(i + 1)) self.combo_chapter.clear() self.combo_chapter.insertItems(0, chapters) break # if the inner 'break' was executed, we also want to break the outer loop: else: continue # executed if the loop ended normally (no break) break # executed if 'continue' was skipped (break) def showText(self): current_translation = self.interpreter.interpreter( 'sword.getModule', self.queue).payload translation = self.combo_translation.currentText() book = self.combo_book.currentText() chapter = self.combo_chapter.currentText() if translation: self.interpreter.interpreter('sword.setModule ' + translation, self.queue) text = self.interpreter.interpreter( 'sword.word "' + book + '" ' + chapter, self.queue) text = text.toString() self.interpreter.interpreter( 'sword.setModule ' + current_translation, self.queue) self.text_edit.clear() self.text_edit.setText(text) self.text_edit.append("\nEND") self.text_edit.setReadOnly(True) self.text_edit.setTextInteractionFlags( self.text_edit.textInteractionFlags() | Qt.TextSelectableByKeyboard) self.unicode_fonts.applyFontAndSizeToQWidget(text, self.text_edit) if book and chapter: self.set_tab_text.emit(translation + ": " + book + " " + chapter) self.history.historyWrite(translation + ": " + book + " " + chapter) def onZoomInClicked(self): self.text_edit.zoomIn() def onZoomOutClicked(self): self.text_edit.zoomOut() def onZoomResetClicked(self): self.text_edit.zoomReset()
class QDeckDirtyDozenWidget(QWidget): deckpath = None grid = None selectDeck = pyqtSignal() dataset = None #audio_data = None audioPlayer = None curent_audio_deck_id = None last_random_audio = None """ holds one of DISPLAY_COMBO_ITEMS: """ test_mode = 'image' def __init__(self): super().__init__() self.unicode_fonts = UnicodeFonts() def initialize(self, deckpath): self.deckpath = deckpath #self.clear() self.audioPlayer = QMediaPlayer() db_path = path.join(deckpath, "database.sqlite") self.dbAdapter = DeckDbAdapter() self.dbAdapter.initialize(db_path) self.full_dataset = self.dbAdapter.selectDeckDirtyDozenItems() self.counter = 1 self.delay_counter = 0 self.delay = 2 self.update() def update(self): self.clear() self.dataset = self.full_dataset[0:self.counter] deck_select_button = QPushButton("<<<") deck_select_button.clicked.connect(self.selectDeckButtonClicked) self.show_all_button = QPushButton("show all") self.show_all_button.clicked.connect(self.showAllButtonClicked) self.show_all_button_state = "show_all" replay_audio_button = QPushButton("replay audio") replay_audio_button.setIcon(QIcon.fromTheme('media-playback-start')) replay_audio_button.clicked.connect(self.replayAudioClicked) select_display_combo_label = QLabel('select display:') select_display_combo_label.setAlignment(QtCore.Qt.AlignRight) select_display_combo = QComboBox() select_display_combo.addItems(DISPLAY_COMBO_ITEMS) select_display_combo.setCurrentIndex( DISPLAY_COMBO_ITEMS.index(self.test_mode)) select_display_combo.currentIndexChanged.connect( self.selectDisplayCurrentIndexChanged) instruction_label = QLabel( "[please click the image which you think is assigned to the spoken word!]" ) if not self.layout(): self.grid = QGridLayout() self.grid.setContentsMargins(0, 0, 0, 0) self.grid.addWidget(deck_select_button, 0, 0) self.grid.addWidget(select_display_combo_label, 0, 1) self.grid.addWidget(select_display_combo, 0, 2) self.grid.addWidget(replay_audio_button, 0, 3) for i, value in enumerate(self.dataset, COLUMNS): label = QClickLabel() if self.test_mode == 'image': preview_pixmap = QPixmap() try: preview_pixmap.load( path.join(self.deckpath, value["image"])) except (KeyError, TypeError): try: preview_pixmap.load( path.join(self.deckpath, value["svg_filename"])) except (KeyError, TypeError): pass scaled_pixmap = preview_pixmap.scaled( QtCore.QSize(200, 200), QtCore.Qt.KeepAspectRatio) label.setGeometry(scaled_pixmap.rect()) label.setPixmap(scaled_pixmap) elif self.test_mode == 'name': label.setText(value['name']) elif self.test_mode == 'word': label.setText(value['word']) elif self.test_mode == 'translation': label.setText(value['translation']) self.unicode_fonts.applyFontAndSizeToQWidget(label.text(), label) label.setAlignment(QtCore.Qt.AlignCenter) label.clicked.connect( functools.partial(self.labelClicked, value["rowid"])) self.grid.addWidget(label, int(i / COLUMNS), i % COLUMNS) self.grid.addWidget(self.show_all_button, len(self.dataset) + 1, 0) self.grid.addWidget(instruction_label, len(self.dataset) + 1, 1, 1, 3) self.setLayout(self.grid) self.playRandomAudio() def clear(self): if self.grid: for i in range(0, self.layout().count()): widget = self.layout().itemAt(i).widget() widget.setVisible(False) def selectDeckButtonClicked(self): self.selectDeck.emit() def showAllButtonClicked(self): if self.show_all_button_state == "show_all": self.counter = len(self.full_dataset) self.update() self.show_all_button.setText("start over") self.show_all_button_state = "start_over" else: self.counter = 1 self.delay_counter = 0 self.delay = 2 self.update() def labelClicked(self, row_id): try: if row_id == self.current_audio_deck_id: self.delay_counter += 1 if len(self.full_dataset) > self.counter: if self.delay_counter >= self.delay: if self.delay_counter == 1: self.delay = 5 elif self.delay_counter == 2: self.delay = 5 else: self.delay = 10 self.delay_counter = 0 self.counter += 1 self.update() self.playNextAudio() else: self.playRandomAudio() else: self.playRandomAudio() except AttributeError: """ we probably have no audio file in this module """ pass def playNextAudio(self): self.playAudio(len(self.dataset) - 1) def playRandomAudio(self): try: selector = randint(0, len(self.dataset) - 1) if self.counter > 1: """ we do not want the same audio played multiple times on a row """ depth = 0 while selector == self.last_random_audio: selector = randint(0, len(self.dataset) - 1) """ to avoid infinite loops with just one element """ depth += 1 if depth > 20: break self.last_random_audio = selector self.playAudio(selector) except ValueError: """ probably an empty deck. just do nothing""" pass def playAudio(self, selector): filename = self.dataset[selector]["filename"] self.current_audio_deck_id = self.dataset[selector]["rowid"] filepath = path.join(self.deckpath, filename) url = QtCore.QUrl.fromLocalFile( QtCore.QFileInfo(filepath).absoluteFilePath()) content = QMediaContent(url) self.audioPlayer.setMedia(content) self.audioPlayer.play() def replayAudioClicked(self): self.audioPlayer.play() def selectDisplayCurrentIndexChanged(self, test): selected_label = DISPLAY_COMBO_ITEMS[test] self.clear() self.test_mode = selected_label self.initialize(self.deckpath)
class QVirtualKeyboardWidget(QWidget): keyPressedAny = pyqtSignal(int) lineEdit = None layout = None language = None def __init__(self): super().__init__() self.setWindowTitle("virtual keyboard") self.resize(450, 150) self.unicode_fonts = UnicodeFonts() #self.language = None self.keys = None self.level_one_chars = None self.level_two_chars = None self.modifier = Qt.NoModifier self.ipa_keyboard = IPAKeyboard() def setLineEdit(self, lineEdit): self.lineEdit = lineEdit def drawKeyboard(self, layout, language): self.layout, self.language = layout, language self.level_one_chars, self.level_two_chars = self.getChars(language) self.keys = self.getKeys(layout) self.drawButtons(self.level_one_chars, self.keys) #self.enter = QPushButton("\u23ce", self) #self.enter.resize(50, 60) #self.enter.move(400, line_pos + line_width) def drawLevelOneKeyboard(self): self.destroyKeyboard() self.drawButtons(self.level_one_chars, self.keys) def drawLevelTwoKeyboard(self): self.destroyKeyboard() self.drawButtons(self.level_two_chars, self.keys) def drawButtons(self, chars, keys): button_sizes = self.getButtonSizes() button_colors = self.getButtonColors() for row in range(0, 5): row_offset = 0 for i in range(len(chars[row])): if i > 0: button_a, button_b = button_sizes[row][i-1], button_sizes[row][i] if button_a > button_b: if button_b >= 30: offset = button_a / button_b row_offset = row_offset + offset - 1 #button = QPushButton(chars[row][i], self) button = QVkeybdPushButton(chars[row][i], self) self.unicode_fonts.applyFontToQWidgetFiltered(chars[row][i], button, ['hebrew']) button.resize(button_sizes[row][i], 30) button.move((i + row_offset)*30, row*30) r, g, b = button_colors[row][i] button.setBackgroundColor(QColor(r, g, b)) button.show() self.connectButton(button, chars[row][i], keys[row][i]) def connectButton(self, button, char, key): button.clicked.connect(functools.partial(self.printChar, char)) self.keyPressedAny.connect(functools.partial(self.keyPressed, key, button)) def printChar(self, char): if self.lineEdit: if char == '⇄': print("TAB PRESSED") elif char == '↑': event = QKeyEvent(QEvent.KeyPress, Qt.Key_Up, Qt.NoModifier) self.lineEdit.keyPressEvent(event) elif char == '↓': event = QKeyEvent(QEvent.KeyPress, Qt.Key_Down, Qt.NoModifier) self.lineEdit.keyPressEvent(event) elif char == '←': event = QKeyEvent(QEvent.KeyPress, Qt.Key_Left, Qt.NoModifier) self.lineEdit.keyPressEvent(event) elif char == '→': event = QKeyEvent(QEvent.KeyPress, Qt.Key_Right, Qt.NoModifier) self.lineEdit.keyPressEvent(event) elif char == '⏎': event = QKeyEvent(QEvent.KeyPress, Qt.Key_Enter, Qt.NoModifier) self.lineEdit.keyPressEvent(event) elif char == '⌫': event = QKeyEvent(QEvent.KeyPress, Qt.Key_Backspace, Qt.NoModifier) self.lineEdit.keyPressEvent(event) elif char == '⇧': # shift self.modifier = Qt.ShiftModifier self.drawLevelTwoKeyboard() elif char == '⇪': # capslock if self.modifier == Qt.ShiftModifier: self.modifier = Qt.NoModifier self.drawLevelOneKeyboard() elif self.modifier == Qt.NoModifier: self.modifier = Qt.ShiftModifier self.drawLevelTwoKeyboard() elif char == 'ctrl': print("CONTROL PRESSED") elif char == 'alt': print("ALT PRESSED") elif char == '⌘': print("WIndows key pressed") elif char == '⌥': print("anykey pressed") else: if self.language == "ipa": ipa_char = self.ipa_keyboard.analyzeInput(char) if ipa_char: event = QKeyEvent(QEvent.KeyPress, Qt.Key_Backspace, Qt.NoModifier) self.lineEdit.keyPressEvent(event) char = ipa_char self.lineEdit.appendText(char) else: print(char) def keyPressed(self, key, button, event): if event == key: button.animateClick() def keyPressEvent(self, e): if e.key() == Qt.Key_Return: pass elif e.key() == Qt.Key_Escape: pass elif e.key() >= Qt.Key_F1 and e.key() <= Qt.Key_F12: pass else: self.keyPressedAny.emit(e.key()) def getChars(self, language): if language == "german": return self.getGermanChars(), self.getLevel2GermanChars() elif language == "greek": return self.getGreekChars(), self.getLevel2GreekChars() elif language == "hebrew": return self.getHebrewChars(), self.getLevel2HebrewChars() elif language == "arabic": return self.getArabicChars(), self.getLevel2ArabicChars() elif language == "hindi": return self.getDevanagariChars(), self.getLevel2DevanagariChars() elif language == "futhark": return self.getFutharkChars(), self.getLevel2FutharkChars() elif language == "ipa": return self.getGermanChars(), self.getLevel2GermanChars() else: return self.getHebrewChars(), self.getLevel2HebrewChars() def getGreekChars(self): return [["`", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", "\u232b"], ["⇄", ";", "ς", "ε", "ρ", "τ", "υ", "θ", "ι", "ο", "π", "[", "]", ""], ["\u21ea", "α", "σ", "δ", "φ", "γ", "η", "ξ", "κ", "λ", "´", "'", "\u23ce"], ["\u21E7", "", "ζ", "χ", "ψ", "ω", "β", "ν", "μ", ",", ".", "/", "\u21E7"], ["ctrl", "\u2318", "alt", " ", "←", "↓", "↑", "→", "alt", "\u2325", "ctrl"]] def getLevel2GreekChars(self): return [["`", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", "\u232b"], ["⇄", ";", "Σ", "Ε", "Ρ", "Τ", "Υ", "Θ", "Ι", "Ο", "Π", "[", "]", ""], ["\u21ea", "Α", "Σ", "Δ", "Φ", "Γ", "Η", "Ξ", "Κ", "Λ", "΄", "'", "\u23ce"], ["\u21E7", "", "Ζ", "Χ", "Ψ", "Ω", "Β", "Ν", "Μ", ",", ".", "/", "\u21E7"], ["ctrl", "\u2318", "alt", " ", "←", "↓", "↑", "→", "alt", "\u2325", "ctrl"]] def getHebrewChars(self): return [[";", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", "\u232b"], ["⇄", "/", "'", "ק", "ר", "א", "ט", "ו", "ן", "ם", "פ", "]", "[", ""], ["\u21ea", "ש", "ד", "ג", "כ", "ע", "י", "ח", "ל", "ך", "ף", ",", "\u23ce"], ["\u21E7", "", "ז", "ס", "ב", "ה", "נ", "מ", "צ", "ת", "ץ", ".", "\u21E7"], ["ctrl", "\u2318", "alt", " ", "←", "↓", "↑", "→", "alt", "\u2325", "ctrl"]] def getLevel2HebrewChars(self): return [[";", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", "\u232b"], ["⇄", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "]", "[", ""], ["\u21ea", "A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "\u23ce"], ["\u21E7", "", "Z", "X", "C", "V", "B", "N", "M", ",", ".", "/" , "\u21E7"], ["ctrl", "\u2318", "alt", " ", "←", "↓", "↑", "→", "alt", "\u2325", "ctrl"]] def getGermanChars(self): return [["^", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "ß", "´", "\u232b"], ["⇄", "q", "w", "e", "r", "t", "z", "u", "i", "o", "p", "ü", "+", "#"], ["\u21ea", "a", "s", "d", "f", "g", "h", "j", "k", "l", "ö", "ä", "\u23ce"], ["\u21E7", "<", "y", "x", "c", "v", "b", "n", "m", ",", "." ,"-", "\u21E7"], ["ctrl", "\u2318", "alt", " ", "←", "↓", "↑", "→", "agr", "\u2325", "ctrl"]] def getLevel2GermanChars(self): return [["°", "!", "\"", "§", "$", "%", "\u0038", "/", "(", ")", "=", "?", "`", "\u232b"], ["⇄", "Q", "W", "E", "R", "T", "Z", "U", "I", "O", "P", "Ü", "*"], ["\u21ea", "A", "S", "D", "F", "G", "H", "J", "K", "L", "Ö", "Ä", "'"], ["\u21E7", ">", "Y", "X", "C", "V", "B", "N", "M", ";", ":" ,"_", "\u21E7"], ["ctrl", "\u2318", "alt", " ", "←", "↓", "↑", "→", "agr", "\u2325", "ctrl"]] def getArabicChars(self): return [["ذ", "١", "٢", "٣", "٤", "٥", "٦", "٧", "٨", "٩", "٠", "~", "!", "\u232b"], ["⇄", "ض", "ص", "ث", "ق", "ف", "غ", "ع", "ه", "خ", "ح", "ج", "د", "\\"], ["\u21ea", "ش", "س", "ي", "ب", "ل", "ا", "ت", "ن", "م", "ك", "ط", "\u23ce"], ["\u21E7", "ئ", "ء", "ؤ", "ر", "لا", "ى", "ة", "و", "ز", "ظ" ,"ـ", "\u21E7"], ["ctrl", "\u2318", "alt", " ", "←", "↓", "↑", "→", "alt", "\u2325", "ctrl"]] def getLevel2ArabicChars(self): return [["ّ", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "°", "+", "\u232b"], ["⇄", "ََ", "ً", "ُ", "ٌ", "ﻹ", "إ", "`", "÷", "×", "؛", "<", ">", ""], ["\u21ea", "ِ", "ٍ", "]", "[", "ﻷ", "أ", "ـ", "،", "/", ":", "", "\u23ce"], ["\u21E7", "~", "ْ", "}", "{", "ﻵ", "آ", "'", ",", ".", "؟" ,"ـ", "\u21E7"], ["ctrl", "\u2318", "alt", " ", "←", "↓", "↑", "→", "alt", "\u2325", "ctrl"]] def getDevanagariChars(self): return [["ॊ", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "ृ", "\u232b"], ["⇄", "ौ", "ै", "ा", "ी", "ू", "ब", "ह", "ग", "द", "ज", "ड", "ड़", "़"], ["\u21ea", "ो", "े", "्", "ि", "ु", "प", "र", "क", "त", "च", "ट", "\u23ce"], ["\u21E7", "ॆ", "ं", "म", "न", "व", "ल", "स", ",", ".", "य" ,"", "\u21E7"], ["ctrl", "\u2318", "alt", " ", "←", "↓", "↑", "→", "alt", "\u2325", "ctrl"]] def getLevel2DevanagariChars(self): return [["", "", "", "", "", "", "", "", "", "", "", "", "", "\u232b"], ["⇄", "", "", "", "", "", "", "", "", "", "", "", "", ""], ["\u21ea", "", "", "", "", "", "", "", "", "", "", "", "\u23ce"], ["\u21E7", "", "", "", "", "", "", "", "", "", "" ,"ـ", "\u21E7"], ["ctrl", "\u2318", "alt", " ", "←", "↓", "↑", "→", "alt", "\u2325", "ctrl"]] def getFutharkChars(self): return [["ᛢ", "ᚨ", "\u16b1", "", "", "", "", "", "", "", "", "", "", "\u232b"], ["⇄", "", "", "", "", "", "", "", "", "", "", "", "", ""], ["\u21ea", "", "", "", "", "", "", "", "", "", "", "", "\u23ce"], ["\u21E7", "", "", "", "", "", "", "", "", "", "" ,"ـ", "\u21E7"], ["ctrl", "\u2318", "alt", " ", "←", "↓", "↑", "→", "alt", "\u2325", "ctrl"]] def getLevel2FutharkChars(self): return [["", "", "", "", "", "", "", "", "", "", "", "", "", "\u232b"], ["⇄", "", "", "", "", "", "", "", "", "", "", "", "", ""], ["\u21ea", "", "", "", "", "", "", "", "", "", "", "", "\u23ce"], ["\u21E7", "", "", "", "", "", "", "", "", "", "" ,"ـ", "\u21E7"], ["ctrl", "\u2318", "alt", " ", "←", "↓", "↑", "→", "alt", "\u2325", "ctrl"]] "Template for copying it if you want to make new layouts" def getCharsTemplate(self): return [["", "", "", "", "", "", "", "", "", "", "", "", "", "\u232b"], ["⇄", "", "", "", "", "", "", "", "", "", "", "", "", ""], ["\u21ea", "", "", "", "", "", "", "", "", "", "", "", "\u23ce"], ["\u21E7", "", "", "", "", "", "", "", "", "", "" ,"ـ", "\u21E7"], ["ctrl", "\u2318", "alt", " ", "←", "↓", "↑", "→", "alt", "\u2325", "ctrl"]] def getButtonSizes(self): return [[30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 60], [40, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 50], [50, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 70], [40, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 80], [30, 30, 30, 150, 30, 30, 30, 30, 30, 30, 30]] def getKeys(self, layout): if layout == "qwertz": return self.getQwertzKeys() elif layout == "neo": return self.getNeoKeys() else: return self.getQwertzKeys() def getQwertzKeys(self): return [[16781906, Qt.Key_1, Qt.Key_2, Qt.Key_3, Qt.Key_4, Qt.Key_5, Qt.Key_6, Qt.Key_7, Qt.Key_8, Qt.Key_9, Qt.Key_0, Qt.Key_ssharp, 16781905, Qt.Key_Backspace], [Qt.Key_Tab, Qt.Key_Q, Qt.Key_W, Qt.Key_E, Qt.Key_R, Qt.Key_T, Qt.Key_Z, Qt.Key_U, Qt.Key_I, Qt.Key_O, Qt.Key_P, Qt.Key_Udiaeresis, Qt.Key_Plus, Qt.Key_NumberSign], [Qt.Key_CapsLock, Qt.Key_A, Qt.Key_S, Qt.Key_D, Qt.Key_F, Qt.Key_G, Qt.Key_H, Qt.Key_J, Qt.Key_K, Qt.Key_L, Qt.Key_Odiaeresis, Qt.Key_Adiaeresis, Qt.Key_Return], [Qt.Key_Shift, Qt.Key_Less, Qt.Key_Y, Qt.Key_X, Qt.Key_C, Qt.Key_V, Qt.Key_B, Qt.Key_N, Qt.Key_M, Qt.Key_Comma, Qt.Key_Period, Qt.Key_Minus, -1], [Qt.Key_Control, Qt.Key_Meta, Qt.Key_Alt, Qt.Key_Space, Qt.Key_Left, Qt.Key_Down, Qt.Key_Up, Qt.Key_Right, Qt.Key_AltGr, -1, -1]] def getNeoKeys(self): return [[16781906, Qt.Key_1, Qt.Key_2, Qt.Key_3, Qt.Key_4, Qt.Key_5, Qt.Key_6, Qt.Key_7, Qt.Key_8, Qt.Key_9, Qt.Key_0, Qt.Key_Minus, 16781905, Qt.Key_Backspace], [Qt.Key_Tab, Qt.Key_X, Qt.Key_V, Qt.Key_L, Qt.Key_C, Qt.Key_W, Qt.Key_K, Qt.Key_H, Qt.Key_G, Qt.Key_F, Qt.Key_Q, Qt.Key_ssharp, Qt.Key_Plus, Qt.Key_NumberSign], [Qt.Key_CapsLock, Qt.Key_U, Qt.Key_I, Qt.Key_A, Qt.Key_E, Qt.Key_O, Qt.Key_S, Qt.Key_N, Qt.Key_R, Qt.Key_T, Qt.Key_D, Qt.Key_Y, Qt.Key_Return], [Qt.Key_Shift, Qt.Key_Less, Qt.Key_Udiaeresis, Qt.Key_Odiaeresis, Qt.Key_Adiaeresis, Qt.Key_P, Qt.Key_Z, Qt.Key_B, Qt.Key_M, Qt.Key_Comma, Qt.Key_Period, Qt.Key_Minus, -1], [Qt.Key_Control, Qt.Key_Meta, Qt.Key_Alt, Qt.Key_Space, Qt.Key_Left, Qt.Key_Down, Qt.Key_Up, Qt.Key_Right, Qt.Key_AltGr, -1, -1]] def getButtonColors(self): a = [255, 255, 255] b = [200, 200, 200] c = a d = b e = b f = a g = b h = a x = [127, 127, 127] z = [145, 145, 145] return [[a, a, a, b, c, d, d, e, e, f, g, h, h, z], [z, a, b, c, d, d, e, e, f, g, h, h, h, h], [z, a, b, c, x, d, e, x, f, g, h, h, z], [z, a, a, b, c, d, d, e, e, f, g, h, z], [z, z, z, z, z, z, z, z, z, z, z]] def destroyKeyboard(self): for button in self.findChildren(QVkeybdPushButton): button.clicked.disconnect() button.deleteLater() self.keyPressedAny.disconnect()