class About(QDialog): ICON = util.file_path(__file__, "icon.png") def __init__(self, parent=None): super().__init__(parent) self.setWindowModality(QtCore.Qt.ApplicationModal) self.setWindowTitle('About Linux Show Player') self.setMaximumSize(500, 420) self.setMinimumSize(500, 420) self.resize(500, 420) self.setLayout(QGridLayout()) self.icon = QLabel(self) self.icon.setPixmap(QPixmap(self.ICON).scaled(100, 100, transformMode=Qt.SmoothTransformation)) self.layout().addWidget(self.icon, 0, 0) self.shortInfo = QLabel(self) self.shortInfo.setAlignment(Qt.AlignCenter) self.shortInfo.setText('<h2>Linux Show Player ' + str(lisp.__version__) + '</h2>' 'Copyright © Francesco Ceruti') self.layout().addWidget(self.shortInfo, 0, 1) self.layout().addWidget(QWidget(), 1, 0, 1, 2) # Informations tabs self.tabWidget = QTabWidget(self) self.layout().addWidget(self.tabWidget, 2, 0, 1, 2) self.info = QTextBrowser(self) self.info.setOpenExternalLinks(True) self.info.setHtml(self.INFO) self.tabWidget.addTab(self.info, 'Info') self.license = QTextBrowser(self) self.license.setOpenExternalLinks(True) self.license.setHtml(self.LICENSE) self.tabWidget.addTab(self.license, 'License') self.contributors = QTextBrowser(self) self.contributors.setOpenExternalLinks(True) self.contributors.setHtml(self.CONTRIBUTORS) self.tabWidget.addTab(self.contributors, 'Contributors') # Ok button self.buttons = QDialogButtonBox(QDialogButtonBox.Ok) self.buttons.accepted.connect(self.accept) self.layout().addWidget(self.buttons, 3, 1) self.layout().setColumnStretch(0, 1) self.layout().setColumnStretch(1, 3) self.layout().setRowStretch(0, 6) self.layout().setRowStretch(1, 1) self.layout().setRowStretch(2, 16) self.layout().setRowStretch(3, 3) self.buttons.setFocus() LICENSE = ''' <center> Linux Show Player is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.<br /> <br /> Linux Show Player is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. </center>''' INFO = ''' <center><br /> Linux Show Player is a cue-player designed for stage productions.<br \> </center> <center><br /> Web site: <a href="http://linux-show-player.sourceforge.net">linux-show-player.sourceforge.net</a><br \> User group: <a href="http://groups.google.com/group/linux-show-player---users">groups.google.com</a><br \> Source code: <a href="https://github.com/FrancescoCeruti/linux-show-player">GitHub</a> </center>''' CONTRIBUTORS = '''
class TriggerRecordDialog(QDialog): def __init__(self, initialTriggerChannel, initialTriggerPolarity, initialTriggerBuffer, initialPostTrigger, initialSaveTriggerChannel, parent): super().__init__(parent) self.setWindowTitle("Episodic Triggered Recording Control") label1 = QLabel( "Digital or analog inputs lines may be used to trigger recording. If an analog input line is selected, the threshold between logic high and logic low is 1.65 V.") label1.setWordWrap(True) digitalInputComboBox = QComboBox() digitalInputComboBox.addItem("Digital Input 0") digitalInputComboBox.addItem("Digital Input 1") digitalInputComboBox.addItem("Digital Input 2") digitalInputComboBox.addItem("Digital Input 3") digitalInputComboBox.addItem("Digital Input 4") digitalInputComboBox.addItem("Digital Input 5") digitalInputComboBox.addItem("Digital Input 6") digitalInputComboBox.addItem("Digital Input 7") digitalInputComboBox.addItem("Digital Input 8") digitalInputComboBox.addItem("Digital Input 9") digitalInputComboBox.addItem("Digital Input 10") digitalInputComboBox.addItem("Digital Input 11") digitalInputComboBox.addItem("Digital Input 12") digitalInputComboBox.addItem("Digital Input 13") digitalInputComboBox.addItem("Digital Input 14") digitalInputComboBox.addItem("Digital Input 15") digitalInputComboBox.addItem("Analog Input 1") digitalInputComboBox.addItem("Analog Input 2") digitalInputComboBox.addItem("Analog Input 3") digitalInputComboBox.addItem("Analog Input 4") digitalInputComboBox.addItem("Analog Input 5") digitalInputComboBox.addItem("Analog Input 6") digitalInputComboBox.addItem("Analog Input 7") digitalInputComboBox.addItem("Analog Input 8") digitalInputComboBox.setCurrentIndex(initialTriggerChannel) digitalInputComboBox.currentIndexChanged.connect(self.setDigitalInput) triggerPolarityComboBox = QComboBox() triggerPolarityComboBox.addItem("Trigger on Logic High") triggerPolarityComboBox.addItem("Trigger on Logic Low") triggerPolarityComboBox.setCurrentIndex(initialTriggerPolarity) triggerPolarityComboBox.currentIndexChanged.connect( self.setTriggerPolarity) self.saveTriggerChannelCheckBox = QCheckBox( "Automatically Save Trigger Channel") self.saveTriggerChannelCheckBox.setChecked(initialSaveTriggerChannel) triggerControls = QVBoxLayout() triggerControls.addWidget(digitalInputComboBox) triggerControls.addWidget(triggerPolarityComboBox) triggerControls.addWidget(self.saveTriggerChannelCheckBox) triggerHBox = QHBoxLayout() triggerHBox.addLayout(triggerControls) triggerHBox.addStretch(1) triggerLayout = QVBoxLayout() triggerLayout.addWidget(label1) triggerLayout.addLayout(triggerHBox) triggerGroupBox = QGroupBox("Trigger Source") triggerGroupBox.setLayout(triggerLayout) triggerHLayout = QHBoxLayout() triggerHLayout.addWidget(triggerGroupBox) recordBufferSpinBox = QSpinBox() recordBufferSpinBox.setRange(1, 30) recordBufferSpinBox.setValue(initialTriggerBuffer) recordBufferSpinBox.valueChanged.connect(self.recordBufferSeconds) bufferSpinBoxLayout = QHBoxLayout() bufferSpinBoxLayout.addWidget(recordBufferSpinBox) bufferSpinBoxLayout.addWidget(QLabel("seconds")) bufferSpinBoxLayout.addStretch(1) label2 = QLabel("If a pretrigger buffer size of N seconds is selected, " "slightly more than N seconds of pretrigger data will be " "saved to disk when a trigger is detected, assuming that " "data acquisition has been running for at least N seconds.") label2.setWordWrap(True) bufferSelectLayout = QVBoxLayout() bufferSelectLayout.addWidget( QLabel("Pretrigger data saved (range: 1-30 seconds):")) bufferSelectLayout.addLayout(bufferSpinBoxLayout) bufferSelectLayout.addWidget(label2) bufferGroupBox = QGroupBox("Pretrigger Buffer") bufferGroupBox.setLayout(bufferSelectLayout) bufferHLayout = QHBoxLayout() bufferHLayout.addWidget(bufferGroupBox) # bufferHLayout.addStretch(1) postTriggerSpinBox = QSpinBox() postTriggerSpinBox.setRange(1, 9999) postTriggerSpinBox.setValue(initialPostTrigger) postTriggerSpinBox.valueChanged.connect(self.postTriggerSeconds) postTriggerSpinBoxLayout = QHBoxLayout() postTriggerSpinBoxLayout.addWidget(postTriggerSpinBox) postTriggerSpinBoxLayout.addWidget(QLabel("seconds")) postTriggerSpinBoxLayout.addStretch(1) label4 = QLabel("If a posttrigger time of M seconds is selected, " "slightly more than M seconds of data will be " "saved to disk after the trigger is de-asserted.") label4.setWordWrap(True) postTriggerSelectLayout = QVBoxLayout() postTriggerSelectLayout.addWidget( QLabel("Posttrigger data saved (range: 1-9999 seconds):")) postTriggerSelectLayout.addLayout(postTriggerSpinBoxLayout) postTriggerSelectLayout.addWidget(label4) postTriggerGroupBox = QGroupBox("Posttrigger Buffer") postTriggerGroupBox.setLayout(postTriggerSelectLayout) postTriggerHLayout = QHBoxLayout() postTriggerHLayout.addWidget(postTriggerGroupBox) # postTriggerHLayout.addStretch(1) self.buttonBox = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) label3 = QLabel("Press OK to start triggered recording with selected settings. " "Waveforms will be displayed in real time, but recording will " "not start until the trigger is detected. A tone will indicate " "when the trigger has been detected. A different tone indicates " "that recording has stopped after a trigger has been de-asserted. " "Successive trigger events will create saved data files. " "Press the Stop button to exit triggered recording mode.") label3.setWordWrap(True) mainLayout = QVBoxLayout() mainLayout.addLayout(triggerHLayout) mainLayout.addLayout(bufferHLayout) mainLayout.addLayout(postTriggerHLayout) mainLayout.addWidget(label3) mainLayout.addWidget(self.buttonBox) self.setLayout(mainLayout) self.setDigitalInput(digitalInputComboBox.currentIndex()) self.setTriggerPolarity(triggerPolarityComboBox.currentIndex()) self.recordBufferSeconds(recordBufferSpinBox.value()) self.postTriggerSeconds(postTriggerSpinBox.value()) def setDigitalInput(self, index): self.digitalInput = index def setTriggerPolarity(self, index): self.triggerPolarity = index def recordBufferSeconds(self, value): self.recordBuffer = value self.buttonBox.setFocus() def postTriggerSeconds(self, value): self.postTriggerTime = value self.buttonBox.setFocus()
class GuiTimeLineView(QDialog): def __init__(self, theParent, theProject, theIndex): QDialog.__init__(self, theParent) logger.debug("Initialising TimeLineView ...") self.mainConf = nw.CONFIG self.theProject = theProject self.theParent = theParent self.theIndex = theIndex self.optState = TimeLineLastState(self.theProject, nwFiles.TLINE_OPT) self.optState.loadSettings() self.theMatrix = {} self.numRows = 0 self.numCols = 0 self.outerBox = QVBoxLayout() self.filterBox = QVBoxLayout() self.centreBox = QHBoxLayout() self.bottomBox = QHBoxLayout() self.setWindowTitle("Timeline View") self.setMinimumWidth(700) self.setMinimumHeight(400) winWidth = self.optState.validIntRange( self.optState.getSetting("winWidth"), 700, 10000, 700) winHeight = self.optState.validIntRange( self.optState.getSetting("winHeight"), 400, 10000, 400) self.resize(winWidth, winHeight) # TimeLine Table self.mainTable = QTableWidget() self.mainTable.setGridStyle(Qt.NoPen) self.hHeader = self.mainTable.horizontalHeader() self.hHeader.setSectionResizeMode(QHeaderView.ResizeToContents) self.mainTable.setHorizontalHeader(self.hHeader) self.vHeader = self.mainTable.verticalHeader() self.vHeader.setSectionResizeMode(QHeaderView.ResizeToContents) self.mainTable.setVerticalHeader(self.vHeader) # Option Box self.optFilter = QGroupBox("Include Tags", self) self.optFilterGrid = QGridLayout(self) self.optFilter.setLayout(self.optFilterGrid) self.filterPlot = QCheckBox("Plot tags", self) self.filterPlot.setChecked(self.optState.getSetting("fPlot")) self.filterPlot.stateChanged.connect(self._filterChange) self.filterChar = QCheckBox("Character tags", self) self.filterChar.setChecked(self.optState.getSetting("fChar")) self.filterChar.stateChanged.connect(self._filterChange) self.filterWorld = QCheckBox("Location tags", self) self.filterWorld.setChecked(self.optState.getSetting("fWorld")) self.filterWorld.stateChanged.connect(self._filterChange) self.filterTime = QCheckBox("Timeline tags", self) self.filterTime.setChecked(self.optState.getSetting("fTime")) self.filterTime.stateChanged.connect(self._filterChange) self.filterObject = QCheckBox("Object tags", self) self.filterObject.setChecked(self.optState.getSetting("fObject")) self.filterObject.stateChanged.connect(self._filterChange) self.filterCustom = QCheckBox("Custom tags", self) self.filterCustom.setChecked(self.optState.getSetting("fCustom")) self.filterCustom.stateChanged.connect(self._filterChange) self.optFilterGrid.addWidget(self.filterPlot, 0, 1) self.optFilterGrid.addWidget(self.filterChar, 1, 1) self.optFilterGrid.addWidget(self.filterWorld, 2, 1) self.optFilterGrid.addWidget(self.filterTime, 3, 1) self.optFilterGrid.addWidget(self.filterObject, 4, 1) self.optFilterGrid.addWidget(self.filterCustom, 5, 1) self.optHide = QGroupBox("Filters", self) self.optHideGrid = QGridLayout(self) self.optHide.setLayout(self.optHideGrid) self.hideUnused = QCheckBox("Hide unused", self) self.hideUnused.setChecked(self.optState.getSetting("hUnused")) self.hideUnused.stateChanged.connect(self._filterChange) self.optHideGrid.addWidget(self.hideUnused, 0, 1) # Button Box self.buttonBox = QDialogButtonBox(QDialogButtonBox.Close) self.buttonBox.rejected.connect(self._doClose) self.btnRebuild = QPushButton("Rebuild Index") self.btnRebuild.clicked.connect(self.theParent.rebuildIndex) self.btnRefresh = QPushButton("Refresh Table") self.btnRefresh.clicked.connect(self._buildNovelList) self.bottomBox.addWidget(self.btnRebuild) self.bottomBox.addWidget(self.btnRefresh) self.bottomBox.addStretch() self.bottomBox.addWidget(self.buttonBox) # Assemble self.filterBox.addWidget(self.optFilter) self.filterBox.addWidget(self.optHide) self.filterBox.addStretch() self.centreBox.addWidget(self.mainTable) self.centreBox.addLayout(self.filterBox) self.outerBox.addLayout(self.centreBox) self.outerBox.addLayout(self.bottomBox) self.setLayout(self.outerBox) self._buildNovelList() self.buttonBox.setFocus() self.show() logger.debug("TimeLineView initialisation complete") return def _buildNovelList(self): self.mainTable.clear() self.theIndex.buildNovelList() self.numRows = len(self.theIndex.novelList) self.mainTable.setRowCount(self.numRows) theFilters = {} theFilters["exClass"] = [] theFilters["hUnused"] = self.hideUnused.isChecked() if not self.filterPlot.isChecked(): theFilters["exClass"].append(nwItemClass.PLOT) if not self.filterChar.isChecked(): theFilters["exClass"].append(nwItemClass.CHARACTER) if not self.filterWorld.isChecked(): theFilters["exClass"].append(nwItemClass.WORLD) if not self.filterTime.isChecked(): theFilters["exClass"].append(nwItemClass.TIMELINE) if not self.filterObject.isChecked(): theFilters["exClass"].append(nwItemClass.OBJECT) if not self.filterCustom.isChecked(): theFilters["exClass"].append(nwItemClass.CUSTOM) for n in range(len(self.theIndex.novelList)): iDepth = self.theIndex.novelList[n][1] iTitle = self.theIndex.novelList[n][2] newItem = QTableWidgetItem("%s%s " % (" " * iDepth, iTitle)) self.mainTable.setVerticalHeaderItem(n, newItem) theMap = self.theIndex.buildTagNovelMap(self.theIndex.tagIndex.keys(), theFilters) self.numCols = len(theMap.keys()) self.mainTable.setColumnCount(self.numCols) nCol = 0 for theTag, theCols in theMap.items(): newItem = QTableWidgetItem(" %s " % theTag) self.mainTable.setHorizontalHeaderItem(nCol, newItem) for n in range(len(theCols)): if theCols[n] == 1: pxNew = QPixmap(10, 10) pxNew.fill(QColor(0, 120, 0)) lblNew = QLabel() lblNew.setPixmap(pxNew) lblNew.setAlignment(Qt.AlignCenter) lblNew.setAttribute(Qt.WA_TranslucentBackground) self.mainTable.setCellWidget(n, nCol, lblNew) elif theCols[n] == 2: pxNew = QPixmap(10, 10) pxNew.fill(QColor(0, 0, 120)) lblNew = QLabel() lblNew.setPixmap(pxNew) lblNew.setAlignment(Qt.AlignCenter) lblNew.setAttribute(Qt.WA_TranslucentBackground) self.mainTable.setCellWidget(n, nCol, lblNew) nCol += 1 return def _doClose(self): logger.verbose("GuiTimeLineView close button clicked") winWidth = self.width() winHeight = self.height() fPlot = self.filterPlot.isChecked() fChar = self.filterChar.isChecked() fWorld = self.filterWorld.isChecked() fTime = self.filterTime.isChecked() fObject = self.filterObject.isChecked() fCustom = self.filterCustom.isChecked() hUnused = self.hideUnused.isChecked() self.optState.setSetting("winWidth", winWidth) self.optState.setSetting("winHeight", winHeight) self.optState.setSetting("fPlot", fPlot) self.optState.setSetting("fChar", fChar) self.optState.setSetting("fWorld", fWorld) self.optState.setSetting("fTime", fTime) self.optState.setSetting("fObject", fObject) self.optState.setSetting("fCustom", fCustom) self.optState.setSetting("hUnused", hUnused) self.optState.saveSettings() self.close() return def _filterChange(self, checkState): self._buildNovelList() return
class GuiTimeLineView(QDialog): def __init__(self, theParent, theProject, theIndex): QDialog.__init__(self, theParent) logger.debug("Initialising TimeLineView ...") self.mainConf = nw.CONFIG self.theProject = theProject self.theParent = theParent self.theIndex = theIndex self.theMatrix = {} self.numRows = 0 self.numCols = 0 self.outerBox = QVBoxLayout() self.bottomBox = QHBoxLayout() self.setWindowTitle("Timeline View") self.setMinimumSize(*self.mainConf.dlgTimeLine) self.mainTable = QTableWidget() self.mainTable.setGridStyle(Qt.NoPen) self.hHeader = self.mainTable.horizontalHeader() self.hHeader.setSectionResizeMode(QHeaderView.ResizeToContents) self.mainTable.setHorizontalHeader(self.hHeader) self.vHeader = self.mainTable.verticalHeader() self.vHeader.setSectionResizeMode(QHeaderView.ResizeToContents) self.mainTable.setVerticalHeader(self.vHeader) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Close) self.buttonBox.rejected.connect(self._doClose) self.btnRebuild = QPushButton("Rebuild Index") self.btnRebuild.clicked.connect(self.theParent.rebuildIndex) self.btnRefresh = QPushButton("Refresh Table") self.btnRefresh.clicked.connect(self._buildNovelList) self.setLayout(self.outerBox) self.outerBox.addWidget(self.mainTable) self.outerBox.addLayout(self.bottomBox) self.bottomBox.addWidget(self.btnRebuild) self.bottomBox.addWidget(self.btnRefresh) self.bottomBox.addStretch() self.bottomBox.addWidget(self.buttonBox) self._buildNovelList() self.buttonBox.setFocus() self.show() logger.debug("TimeLineView initialisation complete") return def _buildNovelList(self): self.theIndex.buildNovelList() self.numRows = len(self.theIndex.novelList) self.numCols = len(self.theIndex.tagIndex.keys()) self.mainTable.clear() self.mainTable.setRowCount(self.numRows) self.mainTable.setColumnCount(self.numCols) for n in range(len(self.theIndex.novelList)): iDepth = self.theIndex.novelList[n][1] iTitle = self.theIndex.novelList[n][2] newItem = QTableWidgetItem("%s%s " % (" " * iDepth, iTitle)) self.mainTable.setVerticalHeaderItem(n, newItem) theMap = self.theIndex.buildTagNovelMap(self.theIndex.tagIndex.keys()) nCol = 0 for theTag, theCols in theMap.items(): newItem = QTableWidgetItem(" %s " % theTag) self.mainTable.setHorizontalHeaderItem(nCol, newItem) for n in range(len(theCols)): if theCols[n] == 1: pxNew = QPixmap(10, 10) pxNew.fill(QColor(0, 120, 0)) lblNew = QLabel() lblNew.setPixmap(pxNew) lblNew.setAlignment(Qt.AlignCenter) lblNew.setAttribute(Qt.WA_TranslucentBackground) self.mainTable.setCellWidget(n, nCol, lblNew) elif theCols[n] == 2: pxNew = QPixmap(10, 10) pxNew.fill(QColor(0, 0, 120)) lblNew = QLabel() lblNew.setPixmap(pxNew) lblNew.setAlignment(Qt.AlignCenter) lblNew.setAttribute(Qt.WA_TranslucentBackground) self.mainTable.setCellWidget(n, nCol, lblNew) nCol += 1 return def _doClose(self): self.mainConf.setTLineSize(self.width(), self.height()) self.close() return
class About(QDialog): LICENSE = ''' <p> Linux Show Player is free software: you can redistribute it and/or<br /> modify it under the terms of the GNU General Public License as published by<br /> the Free Software Foundation, either version 3 of the License, or<br /> (at your option) any later version.<br /> <br /> Linux Show Player is distributed in the hope that it will be useful,<br /> but WITHOUT ANY WARRANTY; without even the implied warranty of<br /> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br /> GNU General Public License for more details. </p> ''' DESCRIPTION = QT_TRANSLATE_NOOP( 'AboutDialog', 'Linux Show Player is a cue-player designed for stage productions.') WEB_SITE = 'http://linux-show-player.sourceforge.net' USER_GROUP = 'http://groups.google.com/group/linux-show-player---users' SOURCE_CODE = 'https://github.com/FrancescoCeruti/linux-show-player' CONTRIBUTORS = OrderedDict({ QT_TRANSLATE_NOOP('About', 'Authors'): [('Francesco Ceruti', '*****@*****.**')], QT_TRANSLATE_NOOP('About', 'Contributors'): [('Yinameah', 'https://github.com/Yinameah'), ('nodiscc', 'https://github.com/nodiscc'), ('Thomas Achtner', '*****@*****.**')], QT_TRANSLATE_NOOP('About', 'Translators'): [('aroomthedoomed', 'https://github.com/aroomthedoomed'), ('fri', 'https://www.transifex.com/user/profile/fri'), ('Luis García-Tornel', '*****@*****.**'), ('miharix', 'https://github.com/miharix'), ('Olivier Humbert', 'https://github.com/trebmuh')], }) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowModality(QtCore.Qt.ApplicationModal) self.setWindowTitle(translate('About', 'About Linux Show Player')) self.setMaximumSize(500, 420) self.setMinimumSize(500, 420) self.resize(500, 420) self.setLayout(QGridLayout()) self.iconLabel = QLabel(self) self.iconLabel.setPixmap( QIcon.fromTheme('linux-show-player').pixmap(100, 100)) self.layout().addWidget(self.iconLabel, 0, 0) self.shortInfo = QLabel(self) self.shortInfo.setAlignment(Qt.AlignCenter) self.shortInfo.setText('<h2>Linux Show Player {0}</h2>' 'Copyright © Francesco Ceruti'.format( str(lisp.__version__))) self.layout().addWidget(self.shortInfo, 0, 1) self.layout().addWidget(QWidget(), 1, 0, 1, 2) # Information tabs self.tabWidget = QTabWidget(self) self.layout().addWidget(self.tabWidget, 2, 0, 1, 2) self.info = QTextBrowser(self) self.info.setOpenExternalLinks(True) self.info.setHtml(''' <center><br />{0}<br /><br /> <a href="{1}">{2}</a><br /> <a href="{3}">{4}</a><br /> <a href="{5}">{6}</a><br /><center>'''.format( translate('AboutDialog', self.DESCRIPTION), self.WEB_SITE, translate('AboutDialog', 'Web site'), self.USER_GROUP, translate('AboutDialog', 'Users group'), self.SOURCE_CODE, translate('AboutDialog', 'Source code'))) self.tabWidget.addTab(self.info, translate('AboutDialog', 'Info')) self.license = QTextBrowser(self) self.license.setOpenExternalLinks(True) self.license.setHtml(self.LICENSE) self.tabWidget.addTab(self.license, translate('AboutDialog', 'License')) self.contributors = QTextBrowser(self) self.contributors.setOpenExternalLinks(True) self.contributors.setHtml(self.__contributors()) self.tabWidget.addTab(self.contributors, translate('AboutDialog', 'Contributors')) # Ok button self.buttons = QDialogButtonBox(QDialogButtonBox.Ok) self.buttons.accepted.connect(self.accept) self.layout().addWidget(self.buttons, 3, 1) self.layout().setColumnStretch(0, 1) self.layout().setColumnStretch(1, 3) self.layout().setRowStretch(0, 6) self.layout().setRowStretch(1, 1) self.layout().setRowStretch(2, 16) self.layout().setRowStretch(3, 3) self.buttons.setFocus() def __contributors(self): text = '' for section, people in self.CONTRIBUTORS.items(): text += '<u><b>{0}:</b></u><br />'.format( translate('About', section)) for person in people: text += person[0] if '://' in person[1]: text += ' - <a href="{0}">{1}</a>'.format( person[1], person[1][person[1].index('://') + 3:]) elif person[1]: text += ' - <a href="mailto:{0}">{0}</a>'.format(person[1]) text += '<br />' text += '<br />' return text