def __init__(self, parent=None): from radiance import __version__ self.__version = __version__ self.parent = parent pixmap = QPixmap(QString(':/Radiance/splashscreen.png')) flags = Qt.WindowStaysOnTopHint QSplashScreen.__init__(self, pixmap, flags) self.setMask(pixmap.mask()) # Custom progress bar stylesheet progressbar_stylesheet = """ QProgressBar:horizontal { border: 1px solid black; background: white; padding: 1px; } QProgressBar::chunk:horizontal { background-color: qlineargradient(spread: pad, x1: 1, y1: 0.5, x2: 0, y2: 0.5, stop: 0 black, stop: 1 white); } """ # Place progress bar to bottom of splash screen. progressbar = QProgressBar(self) progressbar.setRange(0, 0) progressbar.setGeometry(10, self.height() - 20, self.width() - 20, 10) progressbar.setTextVisible(False) progressbar.setStyleSheet(progressbar_stylesheet) self.progressbar = progressbar self.show()
def _before_upload(self, doc_type): """ Activated just before an upload. It disables user actions and shows a progress bar. """ doc_info = self.row_document_info_from_type(doc_type) if not doc_info: return row_num = doc_info.row_num # Disable user actions in the given row self._enable_user_action_widgets( row_num, False ) # Show progress bar pg_bar = QProgressBar() pg_bar.setRange(0, 0) pg_bar.setTextVisible(False) # Remove text before showing progress bar ti = self.item(row_num, 2) ti.setText('') self.setCellWidget(row_num, 2, pg_bar)
class BusyBar(QThread): """ Adapted from: http://stackoverflow.com/questions/8007602/ looping-qprogressbar-gives-error-qobjectinstalleventfilter-cannot-filter-e Looping progress bar create the signal that the thread will emit .. note:: This function creates a busy bar but I have not figured out how to \ attach it to a process. Therefore, it is currently functionally \ useless. """ changeValue = pyqtSignal(int) def __init__(self, text=""): QThread.__init__(self, parent=None) self.text = text self.stop = False self.proBar = QProgressBar() self.proBar.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.SplashScreen) self.proBar.setRange(0, 100) self.proBar.setTextVisible(True) self.proBar.setFormat(self.text) self.proBar.setValue(0) self.proBar.setFixedSize(300, 40) self.proBar.setAlignment(Qt.AlignCenter) self.proBar.show() #self.changeValue.connect(self.proBar.setValue, Qt.QueuedConnection) # Make the Busybar delete itself and the QProgressBar when done self.finished.connect(self.onFinished) def run(self): """ """ while not self.stop: # keep looping while self is visible # Loop sending mail for i in range(100): # emit the signal instead of calling setValue # also we can't read the progress bar value from the thread self.changeValue.emit(i) time.sleep(0.01) self.changeValue.emit(0) def onFinished(self): """ """ self.proBar.deleteLater() self.deleteLater() def Kill(self): """ """ self.stop = True
class BusyBar(QThread): """ Adapted from: http://stackoverflow.com/questions/8007602/ looping-qprogressbar-gives-error-qobjectinstalleventfilter-cannot-filter-e Looping progress bar create the signal that the thread will emit .. note:: This function creates a busy bar but I have not figured out how to \ attach it to a process. Therefore, it is currently functionally \ useless. """ changeValue = pyqtSignal(int) def __init__(self, text = "" ): QThread.__init__(self, parent = None) self.text = text self.stop = False self.proBar = QProgressBar() self.proBar.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.SplashScreen ) self.proBar.setRange( 0, 100 ) self.proBar.setTextVisible( True ) self.proBar.setFormat( self.text ) self.proBar.setValue( 0 ) self.proBar.setFixedSize( 300 , 40 ) self.proBar.setAlignment(Qt.AlignCenter) self.proBar.show() #self.changeValue.connect(self.proBar.setValue, Qt.QueuedConnection) # Make the Busybar delete itself and the QProgressBar when done self.finished.connect(self.onFinished) def run(self): """ """ while not self.stop: # keep looping while self is visible # Loop sending mail for i in range(100): # emit the signal instead of calling setValue # also we can't read the progress bar value from the thread self.changeValue.emit( i ) time.sleep(0.01) self.changeValue.emit( 0 ) def onFinished(self): """ """ self.proBar.deleteLater() self.deleteLater() def Kill(self): """ """ self.stop = True
class AsyncProgressDialog(QDialog): """ dialog with progress bar to be shown during the asynchronous process """ def __init__(self, parent=None): super(AsyncProgressDialog, self).__init__(parent) self.setFixedSize(300, 40) self.setLayout(QBoxLayout(QBoxLayout.TopToBottom, self)) self.progress_bar = QProgressBar(self) self.progress_bar.setFixedSize(280, 20) self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(10) self.progress_bar.setTextVisible(False) self.layout().addWidget(self.progress_bar)
class QtProgressBar(QtControl, ProxyProgressBar): """ A Qt implementation of an Enaml ProxyProgressBar. """ #: A reference to the widget created by the proxy. widget = Typed(QProgressBar) #-------------------------------------------------------------------------- # Initialization API #-------------------------------------------------------------------------- def create_widget(self): """ Create the underlying progress bar widget. """ self.widget = QProgressBar(self.parent_widget()) def init_widget(self): """ Create and initialize the underlying widget. """ super(QtProgressBar, self).init_widget() d = self.declaration self.set_minimum(d.minimum) self.set_maximum(d.maximum) self.set_value(d.value) self.set_text_visible(d.text_visible) #-------------------------------------------------------------------------- # ProxyProgressBar API #-------------------------------------------------------------------------- def set_minimum(self, value): """ Set the minimum value of the widget. """ self.widget.setMinimum(value) def set_maximum(self, value): """ Set the maximum value of the widget. """ self.widget.setMaximum(value) def set_value(self, value): """ Set the value of the widget. """ self.widget.setValue(value) def set_text_visible(self, visible): """ Set the text visibility on the widget. """ self.widget.setTextVisible(visible)
def __changeDirectory(self, path): for c in self.filesview: c.setParent(None) c.deleteLater() self.filesview = [] self.checkBox_2.setChecked(False) self.progressBars = {} for f in self.__getFiles(path): try: group = QGroupBox(f, self) group.setGeometry(QRect(20, 20, 100, 150)) group.setCheckable(True) group.setChecked(False) group.setFixedSize(100, 150) group.setFlat(True) group.setToolTip(f) label = QLabel(group) label.setScaledContents(True) label.setGeometry(QRect(5, 25, 90, 90)) label.setToolTip(f) progressBar = QProgressBar(group) progressBar.setGeometry(QRect(0, 70, 111, 10)) progressBar.setProperty("value", 0) progressBar.setTextVisible(False) progressBar.setToolTip('0%') progressBar.setVisible(False) self.progressBars[f] = progressBar self.filesview.append(group) from os.path import isfile if isfile(path + '/' + f): ext = f.split('.')[-1] if isfile('icons/' + ext.lower() + '.png'): label.setPixmap( QPixmap('icons/' + ext.lower() + '.png')) else: label.setPixmap(QPixmap('icons/default.png')) else: label.setPixmap(QPixmap('icons/folder.png')) self.connect(group, SIGNAL("clicked()"), self.__deselectFile) except ValueError: pass i = 0 for x in list(range(len(self.filesview))): if (x % 4) == 0: i = i + 1 self.rowsview[i].addWidget(self.filesview[x])
class InputDockWidget(QDockWidget): def __init__(self, *args): QDockWidget.__init__(self, *args) self.setupUi(self) self.setWindowIcon(QIcon(':/icons/qtsixa.png')) self.color = QColor(Qt.lightGray) self.setMinimumWidth(350) self.setContentsMargins(0, 0, 0, 0) self.adjustSize() def setupUi(self, QtSixAMainW): QtSixAMainW.setObjectName(_fromUtf8('QtSixAMainW')) QtSixAMainW.resize(935, 513) triggers = TiggersView(self) triggers.show() bumpers = BumpersView(self) bumpers.show() face = FaceButtonsView(self) face.show() dpad = DpadView(self) dpad.show() select = StartSelectView(self) select.show() sixaxis = SixAxisView(self) sixaxis.show() hbox = QHBoxLayout() hbox.addStretch(1) hbox.addWidget(triggers) hbox.addWidget(bumpers) hbox.addWidget(dpad) hbox.addWidget(face) hbox.addWidget(select) hbox.addWidget(sixaxis) vbox = QVBoxLayout() vbox.addStretch(1) vbox.addLayout(hbox) self.setLayout(vbox) self.progress = QProgressBar(self) self.progress.setGeometry(20, 2, 50, 20) self.progress.setTextVisible(False) self.progress.setOrientation(Qt.Vertical) self.progress.setValue(80) self.progress.move(60,28) self.progress.show() print self.style().objectName() QApplication.setStyle(QStyleFactory.create('Cleanlooks')) def paintEvent(self, event = None): pass
def processToa(self): """Converts DN to TOA reflectance""" startTime = time.time() if self.dlg.cbOutput.isChecked() and os.path.exists(self.dlg.leOutput.text()): outputPath = self.dlg.leOutput.text() else: outputPath = os.path.dirname(self.dlg.leInput.text().split(',')[0]) if self.dlg.rbRefNorm.isChecked(): bitcode = '32' outname = '_refToa32.tif' elif self.dlg.rbRefMilli.isChecked(): bitcode = '16' outname = '_refToa16.tif' progressMessageBar = self.iface.messageBar().createMessage("DN to TOA conversion...") progress = QProgressBar() progress.setMaximum(100) progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) progress.setTextVisible(False) label = QLabel() label.setText(' {0}%'.format(0)) progressMessageBar.layout().addWidget(label) progressMessageBar.layout().addWidget(progress) self.iface.messageBar().pushWidget(progressMessageBar, self.iface.messageBar().INFO) if self.dlg.comboBox.currentIndex() == 0: bandList = self.dlg.leInput.text().split(',') idBand = {int(os.path.splitext(os.path.basename(i))[0][-1])-1:i for i in bandList} for band in idBand.keys(): self.imgfile = idBand[band] nbBand = band self.history(outputPath, outname) for i in self.meta.dnToToa(self.imgfile, outname=outname, bitcode=bitcode, outpath=outputPath, nbBand=nbBand): progress.setValue(i) label.setText('{0}%'.format(i)) else: self.imgfile = self.dlg.leInput.text().split(',')[0] self.history(outputPath, outname) for i in self.meta.dnToToa(self.imgfile, outname=outname, bitcode=bitcode, outpath=outputPath): progress.setValue(i) label.setText('{0}%'.format(i)) self.iface.messageBar().clearWidgets() self.bar.pushMessage("Image processed !", level=QgsMessageBar.INFO, duration=3) endTime = time.time() self.dlg.teHistory.append('<b>reflectance processing duration:</b><br>{0} seconds<br>'.format(str(endTime - startTime)))
def progress_dialog(progress=0, title='CQFS Progress', label='Running...'): dialog = QProgressDialog() dialog.setWindowTitle(title) dialog.setLabelText(label) dialog.setAutoClose(True) bar = QProgressBar(dialog) bar.setTextVisible(True) bar.setValue(progress) bar.setMaximum(100) dialog.setBar(bar) dialog.setMinimumWidth(300) dialog.show() if int(progress) == 0: bar.setValue(0) return dialog, bar
def start(self): """ To start the rebuild """ snap_util = self.__iface.mapCanvas().snappingUtils() extent = self.__iface.mapCanvas().extent() self.__progressDialog = QProgressDialog() self.__progressDialog.setWindowTitle( QCoreApplication.translate("VDLTools", "Rebuild Index...")) self.__progressDialog.setLabelText( QCoreApplication.translate("VDLTools", "Percentage of indexed layers")) progressBar = QProgressBar(self.__progressDialog) progressBar.setTextVisible(True) cancelButton = QPushButton() cancelButton.setText(QCoreApplication.translate("VDLTools", "Cancel")) cancelButton.clicked.connect(self.kill) self.__progressDialog.setBar(progressBar) self.__progressDialog.setCancelButton(cancelButton) self.__progressDialog.setMinimumWidth(300) self.__progressDialog.show() lcs_list = snap_util.layers() step = 0 self.killed = False for lc in lcs_list: if self.killed: break locator = snap_util.locatorForLayer(lc.layer) if locator.extent() is not None: txt = locator.extent().toString() else: txt = "None" print("old extent : " + txt) print("new extent : " + extent.toString()) locator.setExtent(extent) if not locator.hasIndex(): locator.init() else: locator.rebuildIndex() locator.setExtent(None) progressBar.setValue(100 * step / len(lcs_list)) step += 1 self.__progressDialog.close()
def initUI(self): self.setWindowTitle(APPNAME) file_menu = self.menuBar().addMenu('File') new_proj_action = create_action(self, 'New Project', self.new_project) open_proj_action = create_action(self, 'Open Project', self.open_project) import_orosMat_action = create_action(self, 'Import Oros Mat', self.import_orosMat) quit_action = create_action(self, 'Quit', self.quit) add_actions(file_menu, (new_proj_action, open_proj_action, None, import_orosMat_action, None, quit_action)) progress_bar = QProgressBar(self) progress_bar.setFixedWidth(200) progress_bar.setTextVisible(False) progress_bar.setVisible(False) self.progress_bar = progress_bar self.statusBar().addPermanentWidget(progress_bar) self.toolBar = self.addToolBar('Curves') main_widget = QWidget(self) main_layout = QGridLayout(main_widget) side_layout = QGridLayout() plot_widget = PlotWidget(main_widget) self.plot_widget = plot_widget list_widget = ListWidget() prop_widget = PropertyWidget() list_widget.registerPropertyWindow(prop_widget) side_layout.addWidget(list_widget, 0, 0) side_layout.addWidget(prop_widget, 1, 0) side_layout.setRowStretch(0, 2) side_layout.setRowStretch(1, 1) self.list_widget = list_widget main_layout.addLayout(side_layout, 0, 0) main_layout.addWidget(plot_widget, 0, 1) main_layout.setColumnStretch(0, 1) main_layout.setColumnStretch(1, 3) self.setCentralWidget(main_widget)
class downloadItemMainInfoClass(QWidget): def __init__(self, title, parent = None): QWidget.__init__(self, parent) self.vLayout = QVBoxLayout(self) margins = self.vLayout.contentsMargins() self.vLayout.setContentsMargins(margins.left(), 0, margins.right(), 0) # Torrent primary data self.title = title # Torrent title self.vLayout.addWidget(QLabel("<b>%s</b>" % title)) self.progressLabel = QLabel() self.vLayout.addWidget(self.progressLabel) # Progress percent self.progressLayout = QHBoxLayout() self.vLayout.addLayout(self.progressLayout) # Progress percent label self.percentLabel = QLabel("0%") self.progressLayout.addWidget(self.percentLabel) # Progress percent bar self.downloadedBar = QProgressBar() self.downloadedBar.setTextVisible(False) self.progressLayout.addWidget(self.downloadedBar) # Pause/Stop/etc buttons... # Speed self.speedLabel = QLabel() self.vLayout.addWidget(self.speedLabel) def fillData(self, size, downloaded, uploaded, ratio, percent, downspeed, upspeed, state): progressLabel = "%s/%s, uploaded %s (Ratio %0.1f)" speedLabel = "%s, ↓ %s/s ↑ %s/s" self.progressLabel.setText(progressLabel % (from_bit_to(downloaded), from_bit_to(size), from_bit_to(uploaded), ratio)) self.percentLabel.setText(("%0.1f" % percent) + "%") self.speedLabel.setText(self.trUtf8(speedLabel % (states[state][0], from_bit_to(downspeed), from_bit_to(upspeed)))) self.downloadedBar.setValue(percent)
class ExpandingProgressDialog(QProgressDialog): def __init__(self, parent=None): QProgressDialog.__init__(self, parent) self.progress = QProgressBar(self) self.progress.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.setBar(self.progress) def set_progress_text_visible(self, visible): self.progress.setTextVisible(visible) def set_progress_text(self, text): self.progress.setFormat(text) # overrides QProgressDialog.sizeHint def sizeHint(self): size = QProgressDialog.sizeHint(self) if size.width() < 400: size.setWidth(400) return size
class ApBbaDlg(QDialog): def __init__(self, parent=None, **kwargs): super(ApBbaDlg, self).__init__(parent) self.bpms = [] self.quads = [] self.corrs = [] self.quad_dkicks = [] self.cor_dkicks = [] self.bba = ap.bba.BbaBowtie() self.table = QTableWidget(0, 5) self.table.setMinimumHeight(120) self.table.setMinimumWidth(500) self.table.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) hdview = QHeaderView(Qt.Horizontal) self.table.setHorizontalHeaderLabels(["QUAD", "BPM.field", "BPM center", "Corr", "Kick"]) fmbox = QFormLayout() self.subprogress = QProgressBar() self.subprogress.setTextVisible(True) self.subprogress.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) self.progress = QProgressBar() self.progress.setTextVisible(True) self.progress.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) fmbox.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow) fmbox.addRow("Current BPM", self.subprogress) fmbox.addRow("All Alignment", self.progress) # self.progress.setMaximum(self.repeatbox.value()) vbox = QVBoxLayout() vbox.addWidget(self.table) vbox.addLayout(fmbox) # hbox.addStretch() self.widtab = QTabWidget() vbox.addWidget(self.widtab) self.setLayout(vbox) self.connect(self.widtab, SIGNAL("currentChanged(int)"), self.activateResult) self.connect(self.table, SIGNAL("cellClicked(int, int)"), self.activateResult) # self.bbathread = ApBbaThread() # self.connect(self.bbathread, # SIGNAL("aligned(QString, QString, float, float)"), # self.setResult) # self.connect(self.bbathread, # SIGNAL("startAlign(QString, QString, QString)"), # self.appendRecord) # self.connect(self.bbathread, # SIGNAL("aligned(QString, QString, float, float)"), # self.bbadlg.appendResult) def setInput(self, **kwargs): self.bpms = kwargs.get("bpms", []) self.quads = kwargs.get("quads", []) self.cors = kwargs.get("cors", []) self.quad_dkicks = kwargs.get("quad_dkicks", []) self.cor_dkicks = kwargs.get("cor_dkicks", []) def runAlignment(self, **kwargs): self.setInput(**kwargs) # self.bbathread.start() print "Starting %d measurements" % len(self.bpms) self.progress.setMaximum(len(self.bpms)) self.subprogress.setMaximum(100) from cothread.catools import caget, caput print __file__, "BBA align", caget("V:2-SR:C30-BI:G2{PH1:11}SA:X") self.table.setRowCount(len(self.bpms)) for i, bpmrec in enumerate(self.bpms): print i, bpmrec[0].name, self.quads[i][0].name self.bba.setInput(bpmrec, self.quads[i], self.cors[i], self.quad_dkicks[i], self.cor_dkicks[i]) # self.emit(SIGNAL("startAlign(QString, QString, QString)"), # self.quads[i][0].name, bpmrec[0].name, bpmrec[1]) self.setNames(i, self.quads[i][0].name, bpmrec[0].name, bpmrec[1], self.cors[i][0].name) self.bba.align(verbose=2, guihook=QApplication.processEvents, logger=None, progress=self.subprogress) cv1 = BbaMplCanvas() cv2 = BbaMplCanvas() self.bba.plot(cv1.axes, cv2.axes, factor=(1e6, 1e6)) cv1.draw() cv2.draw() wid = QWidget(self) hbox = QHBoxLayout() hbox.addWidget(cv1) hbox.addWidget(cv2) wid.setLayout(hbox) self.widtab.addTab(wid, "%s.%s" % (bpmrec[0].name, bpmrec[1])) self.widtab.setCurrentIndex(i) # time.sleep(.1) # self.emit(SIGNAL("aligned(QString, QString, float, float)"), # bpmrec[0].name, bpmrec[1], 0.0, 0.0) self.setResult(i, bpmrec[0].name, bpmrec[1], self.bba.bpm_fitted, self.bba.cor_fitted) self.progress.setValue(i + 1) def activateResult(self, i=0, j=0): if i < self.widtab.count() and i != self.widtab.currentIndex(): self.widtab.setCurrentIndex(i) if i < self.table.rowCount() and i != self.table.currentRow(): self.table.setCurrentCell(i, 1) def setNames(self, i, quadname, bpmname, fld, corname): self.table.setItem(i, 0, QTableWidgetItem(quadname)) self.table.setItem(i, 1, QTableWidgetItem("{0}.{1}".format(bpmname, fld))) self.table.setItem(i, 3, QTableWidgetItem(corname)) def setResult(self, i, bpmname, fld, bpmval, corval): # self.table.setItem(n, 1, QTableWidgetItem(bpmname)) # self.table.setItem(n, 2, QTableWidgetItem(fld)) self.table.setItem(i, 2, QTableWidgetItem("%g" % bpmval)) self.table.setItem(i, 4, QTableWidgetItem("%g" % corval)) self.table.setCurrentCell(i, 1)
class Entity(QWidget): def __init__(self, base_image, size, hp=100, pos=(0, 0), parent=None): super().__init__(parent) self._base_label = QLabel(self) self._base_image = base_image self._size = size self._decor_label = None self._decor_pixmap = None self._hp_max = hp self.__pixmap = None """:type: PyQt4.QtGui.QPixmap""" self.__cord_x = pos[0] self.__cord_y = pos[1] self.__angle = 0 self.__hp_bar = QProgressBar(self) self.__hp_bar.setMaximum(self._hp_max) self.__hp_bar.setValue(self._hp_max) self.__hp_bar.setTextVisible(False) self.__hp_bar.setMaximumSize(size[0], 5) self.setAlignment(Qt.AlignCenter) self.updatePixmap() if _debugging: self.setStyleSheet("border: 1px solid black") @property def health(self): return self.__hp_bar.value() @health.setter def health(self, hp): if hp > self._hp_max: hp = self._hp_max elif hp < 0: hp = 0 self.__hp_bar.setValue(hp) @property def angle(self): return self.__angle @angle.setter def angle(self, angle): self.__angle = angle self.updatePixmap() @property def cord_x(self): return self.__cord_x @cord_x.setter def cord_x(self, cord): self.__cord_x = cord self.move(self.cord_x, self.cord_y) @property def cord_y(self): return self.__cord_y @cord_y.setter def cord_y(self, cord): self.__cord_y = cord self.move(self.cord_x, self.cord_y) def hide_hp_bar(self, bool=False): if bool: self.__hp_bar.hide() else: self.__hp_bar.show() def add_decoration(self, path): if path is None: self._decor_label.deleteLater() self._decor_label = None else: self._decor_label = QLabel(self) self._decor_pixmap = QPixmap(path) # self._decor_pixmap = self._decor_pixmap.scaled(self._size[0], self._size[1]) self._decor_pixmap = self._decor_pixmap.transformed(QTransform().rotate(self.angle)) self._decor_label.setPixmap(self._decor_pixmap) self._decor_label.setAlignment(Qt.AlignCenter) self._decor_label.show() def updatePixmap(self): path = get_asset_path(self._base_image) self.__pixmap = QPixmap(path) self.__pixmap = self.__pixmap.scaled(self._size[0], self._size[1]) self.__pixmap = self.__pixmap.transformed(QTransform().rotate(self.angle)) self._base_label.setPixmap(self.__pixmap) self._base_label.show() # self.setFixedSize(self.__pixmap.width(), self.__pixmap.height()) def setFixedSize(self, x, y): super().setFixedSize(x, y) self._base_label.setFixedSize(x, y) def setAlignment(self, alignment): self._base_label.setAlignment(alignment)
class DocumentGeneratorDialog(QDialog, Ui_DocumentGeneratorDialog): """ Dialog that enables a user to generate documents by using configuration information for different entities. """ def __init__(self, iface, parent=None, plugin=None): QDialog.__init__(self, parent) self.setupUi(self) self._iface = iface self.plugin = plugin self._docTemplatePath = "" self._outputFilePath = "" self.curr_profile = current_profile() self.last_data_source = None self._config_mapping = OrderedDict() self._notif_bar = NotificationBar(self.vlNotification) self._doc_generator = DocumentGenerator(self._iface, self) self._data_source = "" enable_drag_sort(self.lstDocNaming) #Configure generate button generateBtn = self.buttonBox.button(QDialogButtonBox.Ok) if not generateBtn is None: generateBtn.setText( QApplication.translate("DocumentGeneratorDialog", "Generate")) #Load supported image types supportedImageTypes = QImageWriter.supportedImageFormats() for imageType in supportedImageTypes: imageTypeStr = imageType.data() self.cboImageType.addItem(imageTypeStr) self._init_progress_dialog() #Connect signals self.btnSelectTemplate.clicked.connect(self.onSelectTemplate) self.buttonBox.accepted.connect(self.onGenerate) self.chkUseOutputFolder.stateChanged.connect( self.onToggledOutputFolder) self.rbExpImage.toggled.connect(self.onToggleExportImage) self.tabWidget.currentChanged.connect(self.on_tab_index_changed) self.chk_template_datasource.stateChanged.connect( self.on_use_template_datasource) self.btnShowOutputFolder.clicked.connect(self.onShowOutputFolder) def _init_progress_dialog(self): """ Initializes the progress dialog. """ self.progress = QProgressBar(self) self.progress.resize(self.width(), 10) self.progress.setTextVisible(False) def add_entity_configuration(self, **kwargs): ent_config = EntityConfig(**kwargs) self.add_entity_config(ent_config) def add_entity_config(self, ent_config, progress_value=0): QApplication.processEvents() if not self._config_mapping.get(ent_config.title(), ""): fk_mapper = self._create_fk_mapper(ent_config) self.tabWidget.addTab(fk_mapper, ent_config.title()) self._config_mapping[ent_config.title()] = ent_config #Force list of column names to be loaded if self.tabWidget.currentIndex() != 0: self.tabWidget.setCurrentIndex(0) else: self.on_tab_index_changed(0) self.progress.setValue(progress_value) def on_tab_index_changed(self, index): if index == -1: return config = self.config(index) if not config is None: #Set data source name self._data_source = config.data_source() def on_use_template_datasource(self, state): if state == Qt.Checked: self.tabWidget.setEnabled(False) self.chkUseOutputFolder.setEnabled(False) self.chkUseOutputFolder.setChecked(False) elif state == Qt.Unchecked: self.tabWidget.setEnabled(True) self.chkUseOutputFolder.setEnabled(True) self.chkUseOutputFolder.setChecked(False) self.on_tab_index_changed(self.tabWidget.currentIndex()) def onShowOutputFolder(self): reg_config = RegistryConfig() path = reg_config.read([COMPOSER_OUTPUT]) output_path = path.get(COMPOSER_OUTPUT, '') # windows if sys.platform.startswith('win32'): os.startfile(output_path) # *nix systems if sys.platform.startswith('linux'): subprocess.Popen(['xdg-open', output_path]) # macOS if sys.platform.startswith('darwin'): subprocess.Popen(['open', output_path]) def notification_bar(self): """ :return: Returns an instance of the notification bar. :rtype: NotificationBar """ return self._notif_bar def config(self, index): """ Returns the configuration for the current mapper in the tab widget. """ tab_key = self.tabWidget.tabText(index) return self._config_mapping.get(tab_key, None) def current_config(self): """ Returns the configuration corresponding to the current widget in the tab. """ return self.config(self.tabWidget.currentIndex()) def _load_model_columns(self, config): """ Load model columns into the view for specifying file output name. Only those columns of display type variants will be used. """ model_attr_mapping = OrderedDict() for c in config.data_source_columns(): model_attr_mapping[c] = format_name(c) self.lstDocNaming.load_mapping(model_attr_mapping) def _load_data_source_columns(self, entity): """ Load the columns of a data source for use in the file naming. """ table_cols = entity_display_columns(entity, True) attr_mapping = OrderedDict() for c, header in table_cols.iteritems(): attr_mapping[c] = header self.lstDocNaming.load_mapping(attr_mapping) def _create_fk_mapper(self, config): fk_mapper = ForeignKeyMapper(config.ds_entity, self.tabWidget, self._notif_bar, enable_list=True, can_filter=True, plugin=self.plugin) fk_mapper.setDatabaseModel(config.model()) fk_mapper.setSupportsList(True) fk_mapper.setDeleteonRemove(False) fk_mapper.setNotificationBar(self._notif_bar) return fk_mapper def onSelectTemplate(self): """ Slot raised to load the template selector dialog. """ current_config = self.current_config() if current_config is None: msg = QApplication.translate( 'DocumentGeneratorDialog', 'An error occured while trying to determine the data source ' 'for the current entity.\nPlease check your current profile ' 'settings.') QMessageBox.critical( self, QApplication.translate('DocumentGeneratorDialog', 'Template Selector'), msg) return #Set the template selector to only load those templates that # reference the current data source. filter_table = current_config.data_source() templateSelector = TemplateDocumentSelector( self, filter_data_source=filter_table) if templateSelector.exec_() == QDialog.Accepted: docName, docPath = templateSelector.documentMapping() self.lblTemplateName.setText(docName) self._docTemplatePath = docPath if filter_table != self.last_data_source: #Load template data source fields self._load_template_datasource_fields() def _load_template_datasource_fields(self): #If using template data source template_doc, err_msg = self._doc_generator.template_document( self._docTemplatePath) if template_doc is None: QMessageBox.critical( self, "Error Generating documents", QApplication.translate( "DocumentGeneratorDialog", "Error Generating documents - %s" % (err_msg))) return composer_ds, err_msg = self._doc_generator.composer_data_source( template_doc) if composer_ds is None: QMessageBox.critical( self, "Error Generating documents", QApplication.translate( "DocumentGeneratorDialog", "Error Generating documents - %s" % (err_msg))) return #Load data source columns self._data_source = self.current_config().data_source() self.ds_entity = self.curr_profile.entity_by_name(self._data_source) self._load_data_source_columns(self.ds_entity) def onToggledOutputFolder(self, state): """ Slot raised to enable/disable the generated output documents to be written to the plugin composer output folder using the specified naming convention. """ if state == Qt.Checked: self.gbDocNaming.setEnabled(True) elif state == Qt.Unchecked: self.gbDocNaming.setEnabled(False) def reset(self, success_status=False): """ Clears/resets the dialog from user-defined options. """ self._docTemplatePath = "" self._data_source = "" self.lblTemplateName.setText("") # reset form only if generation is successful if success_status: fk_table_view = self.tabWidget.currentWidget().\ findChild(QTableView) while fk_table_view.model().rowCount() > 0: fk_table_view.model().rowCount(0) fk_table_view.model().removeRow(0) if self.tabWidget.count() > 0 and \ not self.chk_template_datasource.isChecked(): self.on_tab_index_changed(0) if self.cboImageType.count() > 0: self.cboImageType.setCurrentIndex(0) def onToggleExportImage(self, state): """ Slot raised to enable/disable the image formats combobox. """ if state: self.cboImageType.setEnabled(True) else: self.cboImageType.setEnabled(False) def onGenerate(self): """ Slot raised to initiate the certificate generation process. """ self._notif_bar.clear() success_status = True config = self.current_config() self.last_data_source = config.data_source() if config is None: self._notif_bar.insertErrorNotification(QApplication.translate("DocumentGeneratorDialog", \ "The entity configuration could not be extracted.")) return #Get selected records and validate records = self.tabWidget.currentWidget().entities() if self.chk_template_datasource.isChecked(): records = self._dummy_template_records() if len(records) == 0: self._notif_bar.insertErrorNotification(QApplication.translate("DocumentGeneratorDialog", \ "Please load at least one entity record")) return if not self._docTemplatePath: self._notif_bar.insertErrorNotification(QApplication.translate("DocumentGeneratorDialog", \ "Please select a document template to use")) return documentNamingAttrs = self.lstDocNaming.selectedMappings() if self.chkUseOutputFolder.checkState() == Qt.Checked and len( documentNamingAttrs) == 0: self._notif_bar.insertErrorNotification(QApplication.translate("DocumentGeneratorDialog", \ "Please select at least one field for naming the output document")) return #Set output file properties if self.rbExpImage.isChecked(): outputMode = DocumentGenerator.Image fileExtension = self.cboImageType.currentText() saveAsText = "Image File" else: outputMode = DocumentGenerator.PDF fileExtension = "pdf" saveAsText = "PDF File" #Show save file dialog if not using output folder if self.chkUseOutputFolder.checkState() == Qt.Unchecked: docDir = source_document_location() if self._outputFilePath: fileInfo = QFileInfo(self._outputFilePath) docDir = fileInfo.dir().path() self._outputFilePath = QFileDialog.getSaveFileName( self, QApplication.translate("DocumentGeneratorDialog", "Save Document"), docDir, "{0} (*.{1})".format( QApplication.translate("DocumentGeneratorDialog", saveAsText), fileExtension)) if not self._outputFilePath: self._notif_bar.insertErrorNotification( QApplication.translate( "DocumentGeneratorDialog", "Process aborted. No output file was specified.")) return #Include extension in file name self._outputFilePath = self._outputFilePath #+ "." + fileExtension #else: #Multiple files to be generated. #pass self._doc_generator.set_link_field(config.link_field()) self._doc_generator.clear_attr_value_formatters() if not self.chk_template_datasource.isChecked(): #Apply cell formatters for naming output files self._doc_generator.set_attr_value_formatters(config.formatters()) entity_field_name = "id" #Iterate through the selected records progressDlg = QProgressDialog(self) progressDlg.setMaximum(len(records)) try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) for i, record in enumerate(records): progressDlg.setValue(i) if progressDlg.wasCanceled(): success_status = False break #User-defined location if self.chkUseOutputFolder.checkState() == Qt.Unchecked: status, msg = self._doc_generator.run( self._docTemplatePath, entity_field_name, record.id, outputMode, data_source=self.ds_entity.name, filePath=self._outputFilePath) self._doc_generator.clear_temporary_layers() #Output folder location using custom naming else: status, msg = self._doc_generator.run( self._docTemplatePath, entity_field_name, record.id, outputMode, dataFields=documentNamingAttrs, fileExtension=fileExtension, data_source=self.ds_entity.name) self._doc_generator.clear_temporary_layers() if not status: result = QMessageBox.warning( self, QApplication.translate("DocumentGeneratorDialog", "Document Generate Error"), msg, QMessageBox.Ignore | QMessageBox.Abort) if result == QMessageBox.Abort: progressDlg.close() success_status = False #Restore cursor QApplication.restoreOverrideCursor() return #If its the last record and user has selected to ignore if i + 1 == len(records): progressDlg.close() success_status = False #Restore cursor QApplication.restoreOverrideCursor() return else: progressDlg.setValue(len(records)) QApplication.restoreOverrideCursor() QMessageBox.information( self, QApplication.translate("DocumentGeneratorDialog", "Document Generation Complete"), QApplication.translate( "DocumentGeneratorDialog", "Document generation has successfully completed.")) except Exception as ex: LOGGER.debug(str(ex)) err_msg = sys.exc_info()[1] QApplication.restoreOverrideCursor() QMessageBox.critical( self, "STDM", QApplication.translate( "DocumentGeneratorDialog", "Error Generating documents - %s" % (err_msg))) success_status = False #Reset UI self.reset(success_status) def _dummy_template_records(self): """ This is applied when records from a template data source are to be used to generate the documents where no related entity will be used to filter matching records in the data source. The iteration of the data source records will be done internally within the DocumentGenerator class. """ class _DummyRecord: id = 1 return [_DummyRecord()] def showEvent(self, event): """ Notifies if there are not entity configuration objects defined. :param event: Window event :type event: QShowEvent """ QTimer.singleShot(500, self.check_entity_config) return QDialog.showEvent(self, event) def check_entity_config(self): if len(self._config_mapping) == 0: self._notif_bar.clear() msg = QApplication.translate( "DocumentGeneratorDialog", "Table " "configurations do not exist or have not been configured properly" ) self._notif_bar.insertErrorNotification(msg)
class ApBbaDlg(QDialog): def __init__(self, parent=None, **kwargs): super(ApBbaDlg, self).__init__(parent) self.bpms = [] self.quads = [] self.corrs = [] self.quad_dkicks = [] self.cor_dkicks = [] self.bba = ap.bba.BbaBowtie() self.table = QTableWidget(0, 5) self.table.setMinimumHeight(120) self.table.setMinimumWidth(500) self.table.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) hdview = QHeaderView(Qt.Horizontal) self.table.setHorizontalHeaderLabels( ['QUAD', 'BPM.field', 'BPM center', "Corr", "Kick"]) fmbox = QFormLayout() self.subprogress = QProgressBar() self.subprogress.setTextVisible(True) self.subprogress.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) self.progress = QProgressBar() self.progress.setTextVisible(True) self.progress.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) fmbox.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow) fmbox.addRow("Current BPM", self.subprogress) fmbox.addRow("All Alignment", self.progress) #self.progress.setMaximum(self.repeatbox.value()) vbox = QVBoxLayout() vbox.addWidget(self.table) vbox.addLayout(fmbox) #hbox.addStretch() self.widtab = QTabWidget() vbox.addWidget(self.widtab) self.setLayout(vbox) self.connect(self.widtab, SIGNAL("currentChanged(int)"), self.activateResult) self.connect(self.table, SIGNAL("cellClicked(int, int)"), self.activateResult) #self.bbathread = ApBbaThread() #self.connect(self.bbathread, # SIGNAL("aligned(QString, QString, float, float)"), # self.setResult) #self.connect(self.bbathread, # SIGNAL("startAlign(QString, QString, QString)"), # self.appendRecord) #self.connect(self.bbathread, # SIGNAL("aligned(QString, QString, float, float)"), # self.bbadlg.appendResult) def setInput(self, **kwargs): self.bpms = kwargs.get('bpms', []) self.quads = kwargs.get('quads', []) self.cors = kwargs.get('cors', []) self.quad_dkicks = kwargs.get('quad_dkicks', []) self.cor_dkicks = kwargs.get('cor_dkicks', []) def runAlignment(self, **kwargs): self.setInput(**kwargs) #self.bbathread.start() print "Starting %d measurements" % len(self.bpms) self.progress.setMaximum(len(self.bpms)) self.subprogress.setMaximum(100) from cothread.catools import caget, caput print __file__, "BBA align", caget('V:2-SR:C30-BI:G2{PH1:11}SA:X') self.table.setRowCount(len(self.bpms)) for i, bpmrec in enumerate(self.bpms): print i, bpmrec[0].name, self.quads[i][0].name self.bba.setInput(bpmrec, self.quads[i], self.cors[i], self.quad_dkicks[i], self.cor_dkicks[i]) #self.emit(SIGNAL("startAlign(QString, QString, QString)"), # self.quads[i][0].name, bpmrec[0].name, bpmrec[1]) self.setNames(i, self.quads[i][0].name, bpmrec[0].name, bpmrec[1], self.cors[i][0].name) self.bba.align(verbose=2, guihook=QApplication.processEvents, logger=None, progress=self.subprogress) cv1 = BbaMplCanvas() cv2 = BbaMplCanvas() self.bba.plot(cv1.axes, cv2.axes, factor=(1e6, 1e6)) cv1.draw() cv2.draw() wid = QWidget(self) hbox = QHBoxLayout() hbox.addWidget(cv1) hbox.addWidget(cv2) wid.setLayout(hbox) self.widtab.addTab(wid, "%s.%s" % (bpmrec[0].name, bpmrec[1])) self.widtab.setCurrentIndex(i) #time.sleep(.1) #self.emit(SIGNAL("aligned(QString, QString, float, float)"), # bpmrec[0].name, bpmrec[1], 0.0, 0.0) self.setResult(i, bpmrec[0].name, bpmrec[1], self.bba.bpm_fitted, self.bba.cor_fitted) self.progress.setValue(i + 1) def activateResult(self, i=0, j=0): if i < self.widtab.count() and i != self.widtab.currentIndex(): self.widtab.setCurrentIndex(i) if i < self.table.rowCount() and i != self.table.currentRow(): self.table.setCurrentCell(i, 1) def setNames(self, i, quadname, bpmname, fld, corname): self.table.setItem(i, 0, QTableWidgetItem(quadname)) self.table.setItem(i, 1, QTableWidgetItem("{0}.{1}".format(bpmname, fld))) self.table.setItem(i, 3, QTableWidgetItem(corname)) def setResult(self, i, bpmname, fld, bpmval, corval): #self.table.setItem(n, 1, QTableWidgetItem(bpmname)) #self.table.setItem(n, 2, QTableWidgetItem(fld)) self.table.setItem(i, 2, QTableWidgetItem("%g" % bpmval)) self.table.setItem(i, 4, QTableWidgetItem("%g" % corval)) self.table.setCurrentCell(i, 1)
class ViewDataTools(QMainWindow): def __init__(self, parent=None): super(ViewDataTools, self).__init__(parent) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # DATATOOLS WINDOWS: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ self.setWindowTitle(ui_strings.DATATOOLS_TITLE) self._width = 680 self._height = 560 self._left_margin = 10 self.resize(self._width, self._height) size_policy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) size_policy.setHorizontalStretch(0) size_policy.setVerticalStretch(0) size_policy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) self.setSizePolicy(size_policy) self.setMinimumSize(QtCore.QSize(self._width, self._height)) self.setMaximumSize(QtCore.QSize(self._width, self._height)) self.setWindowIcon(QIcon(resources.ICON_LOGO)) # central widget self.central_widget = QWidget(self) # DataTools description self.lbl_description = QLabel(self.central_widget) self.lbl_description.setGeometry(QtCore.QRect(0, 0, self._width, 30)) self.lbl_description.setAlignment(QtCore.Qt.AlignCenter) self.lbl_description.setText(ui_strings.DATATOOLS_DESCRIPTION) # group input files self.group_input_file = QGroupBox(self.central_widget) self.group_input_file.setGeometry(QtCore.QRect(self._left_margin, 30, 660, 80)) self.group_input_file.setTitle(ui_strings.DATATOOLS_GROUP_INPUT) # frame input files self.frame_inputs = QFrame(self.group_input_file) self.frame_inputs.setGeometry(QtCore.QRect(self._left_margin, 0, 270, 80)) self.frame_inputs.setFrameShape(QFrame.StyledPanel) self.frame_inputs.setFrameShadow(QFrame.Raised) # label input type self.lbl_input_type = QLabel(self.frame_inputs) self.lbl_input_type.setGeometry(QtCore.QRect(20, 20, 60, 15)) self.lbl_input_type.setText(ui_strings.DATATOOLS_INPUT_TYPE) # button xls self.btn_xls = QToolButton(self.frame_inputs) self.btn_xls.setGeometry(QtCore.QRect(20, 35, 35, 35)) icon_xls = QIcon() icon_xls.addPixmap(QPixmap(resources.ICON_XLS), QIcon.Normal, QIcon.Off) self.btn_xls.setIcon(icon_xls) self.btn_xls.setIconSize(QtCore.QSize(24, 24)) self.btn_xls.setCheckable(True) self.btn_xls.setAutoExclusive(True) self.btn_xls.setObjectName("xls_button") # button csv self.btn_csv = QToolButton(self.frame_inputs) self.btn_csv.setGeometry(QtCore.QRect(60, 35, 35, 35)) icon_csv = QIcon() icon_csv.addPixmap(QPixmap(resources.ICON_CSV), QIcon.Normal, QIcon.Off) self.btn_csv.setIcon(icon_csv) self.btn_csv.setIconSize(QtCore.QSize(24, 24)) self.btn_csv.setCheckable(True) self.btn_csv.setAutoExclusive(True) self.btn_csv.setObjectName("csv_button") # checkbox csv with headers self.chk_csv_headers = QCheckBox(ui_strings.DATATOOLS_WITH_HEADERS, self.frame_inputs) self.chk_csv_headers.setGeometry(QtCore.QRect(100, 45, 110, 15)) self.chk_csv_headers.setEnabled(False) # TextEdit + PushButton (FindFolder) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # lbl sheet name self.lbl_file_path = QLabel(self.group_input_file) self.lbl_file_path.setGeometry(QtCore.QRect(250, 20, 120, 15)) self.lbl_file_path.setText(ui_strings.DATATOOLS_SELECT_FILE) self.txt_file = QLineEdit(self.group_input_file) self.txt_file.setGeometry(QtCore.QRect(250, 35, 160, 20)) self.txt_file.setReadOnly(True) self.btn_path = QPushButton(self.group_input_file) self.btn_path.setGeometry(QtCore.QRect(410, 34, 50, 22)) self.btn_path.setText(ui_strings.DATATOOLS_SELECT_BUTTON) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # lbl sheet name self.lbl_sheet_name = QLabel(self.group_input_file) self.lbl_sheet_name.setGeometry(QtCore.QRect(500, 20, 120, 15)) self.lbl_sheet_name.setText(ui_strings.DATATOOLS_SHEET_NAME) # Combobox select sheet - initially does not contain values self.cbo_sheet = QComboBox(self.group_input_file) self.cbo_sheet.setGeometry(QtCore.QRect(500, 35, 130, 20)) # data grid to visualize error messages self.tbl_errors = QTableWidget(self.central_widget) self.tbl_errors.setGeometry(QtCore.QRect(self._left_margin, 420, 660, 100)) # data grid to visualize those records with errors. self.tbl_uploaded_data = QTableWidget(self.central_widget) self.tbl_uploaded_data.setGeometry(QtCore.QRect(self._left_margin, 120, 500, 220)) # group run options self.group_run_options = QGroupBox(self.central_widget) self.group_run_options.setGeometry(QtCore.QRect(520, 120, 150, 220)) self.group_run_options.setTitle(ui_strings.DATATOOLS_GROUP_RUN) # Errors summary: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # group summary errors self.group_errors = QGroupBox(self.central_widget) self.group_errors.setGeometry(QtCore.QRect(self._left_margin, 350, 660, 60)) self.group_errors.setTitle(ui_strings.DATATOOLS_HEADER_ERRORS) # lbl records self.lbl_records = QLabel(self.group_errors) self.lbl_records.setGeometry(QtCore.QRect(165, 15, 80, 15)) self.lbl_records.setAlignment(QtCore.Qt.AlignCenter) self.lbl_records.setText(ui_strings.DATATOOLS_RECORDS) self.txt_records = QLineEdit(self.group_errors) self.txt_records.setGeometry(QtCore.QRect(165, 30, 80, 20)) self.txt_records.setAlignment(QtCore.Qt.AlignCenter) self.txt_records.setReadOnly(True) # lbl errors self.lbl_errors = QLabel(self.group_errors) self.lbl_errors.setGeometry(QtCore.QRect(275, 15, 80, 15)) self.lbl_errors.setAlignment(QtCore.Qt.AlignCenter) self.lbl_errors.setText(ui_strings.DATATOOLS_ERRORS) self.txt_errors = QLineEdit(self.group_errors) self.txt_errors.setGeometry(QtCore.QRect(275, 30, 80, 20)) self.txt_errors.setAlignment(QtCore.Qt.AlignCenter) self.txt_errors.setReadOnly(True) # lbl time self.lbl_time = QLabel(self.group_errors) self.lbl_time.setGeometry(QtCore.QRect(385, 15, 80, 15)) self.lbl_time.setAlignment(QtCore.Qt.AlignCenter) self.lbl_time.setText(ui_strings.DATATOOLS_TIME) self.txt_time = QLineEdit(self.group_errors) self.txt_time.setGeometry(QtCore.QRect(385, 30, 80, 20)) self.txt_time.setAlignment(QtCore.Qt.AlignCenter) self.txt_time.setReadOnly(True) # history button self.btn_history = QToolButton(self.group_errors) self.btn_history.setGeometry(QtCore.QRect(500, 25, 100, 25)) icon_history = QIcon() icon_history.addPixmap(QPixmap(resources.ICON_HISTORY), QIcon.Normal, QIcon.Off) self.btn_history.setIcon(icon_history) self.btn_history.setIconSize(QtCore.QSize(20, 20)) self.btn_history.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) self.btn_history.setText(ui_strings.DATATOOLS_HISTORY) self.btn_history.setCheckable(True) self.btn_history.setAutoExclusive(True) self.btn_history.setObjectName("history_button") # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # btn data uploader self.btn_data_uploader = QPushButton(ui_strings.DATATOOLS_DATA_UPLOADER, self.group_run_options) self.btn_data_uploader.setGeometry(QtCore.QRect(10, 120, 90, 25)) self.btn_data_uploader.setCheckable(True) self.btn_data_uploader.setAutoExclusive(True) self.btn_data_uploader.setFlat(False) # btn data testing self.btn_data_testing = QPushButton(ui_strings.DATATOOLS_DATA_TESTING, self.group_run_options) self.btn_data_testing.setEnabled(False) self.btn_data_testing.setGeometry(QtCore.QRect(10, 150, 90, 25)) self.btn_data_testing.setCheckable(True) self.btn_data_testing.setAutoExclusive(True) # btn data to database self.btn_data_db = QPushButton(ui_strings.DATATOOLS_DATA_DB, self.group_run_options) self.btn_data_db.setEnabled(False) self.btn_data_db.setGeometry(QtCore.QRect(10, 179, 91, 23)) self.btn_data_db.setCheckable(True) self.btn_data_db.setAutoExclusive(True) # frame run options self.frame_run = QFrame(self.group_run_options) self.frame_run.setGeometry(QtCore.QRect(10, 30, 130, 80)) self.frame_run.setFrameShape(QFrame.StyledPanel) self.frame_run.setFrameShadow(QFrame.Raised) # option process until first error self.rbtn_process_error = QRadioButton(ui_strings.DATATOOLS_PROCESS_ERROR, self.frame_run) self.rbtn_process_error.setGeometry(QtCore.QRect(0, 0, 150, 20)) # option process all data self.rbtn_process_all = QRadioButton(ui_strings.DATATOOLS_PROCESS_ALL, self.frame_run) self.rbtn_process_all.setGeometry(QtCore.QRect(0, 20, 150, 30)) # checkbox to filter by records with errors. #self.chk_filter_errors = QCheckBox(ui_strings.DATATOOLS_FILTER_ERRORS, self.frame_run) #self.chk_filter_errors.setGeometry(QtCore.QRect(0, 50, 100, 15)) #self.chk_filter_errors.setEnabled(False) # icons -> pass - error: Initially are empty labels # if not started -> ICON_MINI_WAIT # if error -> ICON_DELETE # if pass -> ICON_CHECK # state icon data uploader self.lbl_state_du = QLabel(self.group_run_options) self.lbl_state_du.setGeometry(QtCore.QRect(110, 120, 20, 20)) self.lbl_state_du.setPixmap(QPixmap(resources.ICON_MINI_WAIT)) self.lbl_state_du.setScaledContents(True) # state icon data to database self.lbl_state_dt = QLabel(self.group_run_options) self.lbl_state_dt.setGeometry(QtCore.QRect(110, 150, 20, 20)) self.lbl_state_dt.setPixmap(QPixmap(resources.ICON_MINI_WAIT)) self.lbl_state_dt.setScaledContents(True) # state icon data testing self.lbl_state_db = QLabel(self.group_run_options) self.lbl_state_db.setGeometry(QtCore.QRect(110, 180, 20, 20)) self.lbl_state_db.setPixmap(QPixmap(resources.ICON_MINI_WAIT)) self.lbl_state_db.setScaledContents(True) # progress bar self.progress_bar = QProgressBar(self.central_widget) self.progress_bar.setGeometry(QtCore.QRect(self._left_margin, 530, 660, 15)) self.progress_bar.setMaximum(100) self.progress_bar.setProperty("value", 0) self.progress_bar.setTextVisible(True) self.progress_bar.setOrientation(QtCore.Qt.Horizontal) self.progress_bar.setInvertedAppearance(False) self.progress_bar.setTextDirection(QProgressBar.TopToBottom) self.setCentralWidget(self.central_widget)
class CompileWidget(QWidget): progress = pyqtSignal(int) def __init__(self, parent=None): QWidget.__init__(self, parent) self._options = None self._conf = None self._go = QPushButton('Go') self._go.setMaximumWidth(100) font = self._go.font() font.setPointSizeF(font.pointSizeF() * 2.0) font.setWeight(QFont.Bold) self._go.setFont(font) self._go.clicked.connect(self.go) self._saveLog = QPushButton('Save') saveLogLabel = QLabel('Log File:') saveLogBrowse = QPushButton('&Browse') saveLogBrowse.clicked.connect(self.browseSaveLog) self._saveLogEdit = QLineEdit('') gLayout = QGridLayout() gLayout.addWidget(saveLogLabel, 0, 0, 1, 1, Qt.AlignRight) gLayout.addWidget(self._saveLogEdit, 0, 1, 1, 6) gLayout.addWidget(saveLogBrowse, 0, 7, 1, 1) self._console = QTextEdit() self._console.setLineWrapMode(QTextEdit.NoWrap) self._console.setMinimumSize(800, 400) palette = self._console.palette() palette.setColor(QPalette.Base, QColor.fromRgb(255, 255, 221)) # ffffdd. self._console.setPalette(palette) font = QFont('Bitstream Vera Sans Mono', self._console.font().pointSize()) self._console.setFont(font) self._highlighter = Highlighter(self._console.document()) self._progressBar = QProgressBar() self._progressBar.setRange(0, 100) self._progressBar.setTextVisible(True) hLayout = QHBoxLayout() hLayout.addStretch() hLayout.addWidget(self._go) hLayout.addStretch() hLayout.addWidget(self._saveLog) hLayout.addStretch() vLayout = QVBoxLayout() vLayout.addLayout(hLayout) vLayout.addLayout(gLayout) vLayout.addWidget(self._progressBar) vLayout.addWidget(self._console) self.setLayout(vLayout) self.progress.connect(self._progressBar.setValue) self._saveLog.clicked.connect(self.saveLog) self.readSettings() return def _setOptions(self, options): self._options = options def _setConf(self, conf): self._conf = conf def _getOptions(self): return self._options def _getConf(self): return self._conf options = property(_getOptions, _setOptions) conf = property(_getConf, _setConf) def browseSaveLog(self): self._saveLogEdit.setText( QFileDialog.getSaveFileName(self, 'Select Log File Report', self._saveLogEdit.text(), 'Report Files (*.log *.txt)')) return def saveLog(self): if self._saveLogEdit.text(): fd = open(self._saveLogEdit.text(), 'w+') fd.write(self._console.toPlainText()) fd.close() return def shellCommand(self): command = [self.conf.bootstrapDir + '/ccb.py'] for project in self.options.projects: for tool in project.actives: command += ['--tool=' + tool] toolsCount = len(command) - 1 if self.conf.rootDir: command += ['--root=%s' % self.conf.rootDir] #if self.options.svnUpdate: command += [ '--svn-update' ] #if self.options.svnStatus: command += [ '--svn-update' ] if self.options.enableDoc: command += ['--doc'] if self.options.devtoolset2: command += ['--devtoolset-2'] if self.options.qt5: command += ['--qt5'] if self.options.noCache: command += ['--no-cache'] if self.options.rmBuild: command += ['--rm-build'] if self.options.verbose: command += ['--verbose'] if self.options.make: makeArguments = 'install ' + self.options.threads command += ['--make=%s' % makeArguments] if self.options.buildMode == 'Debug': command += ['--debug'] return toolsCount, command def go(self): rePercentage = re.compile(r'^\[\s*(?P<percent>\d+)%\].*') reProcessTool = re.compile(r'^Processing tool:\s*"(?P<tool>.+)"') if not self.options or not self.conf: return toolsCount, command = self.shellCommand() if not toolsCount: return self._progressBar.reset() self._progressBar.setRange(0, toolsCount * 100) strCommand = command[0] for arg in command[1:]: strCommand += ' ' + arg strCommand += '\n\n' self._console.setFontItalic(True) self._console.insertPlainText(strCommand) self._console.setFontItalic(False) toolsDone = -1 builderProcess = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) while True: line = builderProcess.stdout.readline() if line == '': break m = rePercentage.match(line) if m: self.progress.emit(toolsDone * 100 + int(m.group('percent'))) else: m = reProcessTool.match(line) if m: toolsDone += 1 self._console.insertPlainText(line) scrollBar = self._console.verticalScrollBar() scrollBar.setValue(scrollBar.maximum()) QApplication.processEvents() builderProcess.wait() if builderProcess.returncode == None: pass return def readSettings(self): settings = QSettings() self._saveLogEdit.setText(settings.value('compile/saveLog').toString()) return def saveSettings(self): settings = QSettings() settings.setValue('compile/saveLog', self._saveLogEdit.text()) return
class UploadTransactionView(QTreeWidgetItem,View): #The widget that shows the progress of the upload. #TODO: Add time estimate. Might want to alter the core #to include timestamps on the upload transaction for each #new uploadToken received. #IDEA: Instead of updating the upload token on the UploadTransaction #we can add each token to a list on the UploadTransaction (transaction_tokens), and add the #timestamp. Then based on past progress, we can tell 3 things: # - Get an approximation of the transfer rate kb/s # - Time spent uploading # - Time left COLUMN_FILENAME = 0 COLUMN_STATUS = 1 COLUMN_PERCENTAGE = 2 COLUMN_TEST_WIDGET = 3 _uploadTransactionModel = None #UploadTransactionModel object _treeWidget = None def __init__(self, parentWidget, uploadTransaction): QTreeWidgetItem.__init__(self, None,QTreeWidgetItem.UserType) View.__init__(self) self.setTreeWidget(parentWidget) #we bootstrap the inner components and put the "LEGO" together self._uploadTransactionModel = uploadTransaction self._uploadTransactionProgressBar = QProgressBar() self._uploadTransactionProgressBar.setTextVisible(True) self._uploadTransactionProgressBar.setAutoFillBackground(True) self.setText(UploadTransactionView.COLUMN_FILENAME,utils.getFileName(uploadTransaction.getFilePath())) self.setText(UploadTransactionView.COLUMN_STATUS,uploadTransaction.getHumanUploadStatus()) self.getTreeWidget().setItemWidget(self,UploadTransactionView.COLUMN_PERCENTAGE,self._uploadTransactionProgressBar) def getUploadTransactionModel(self): return self._uploadTransactionModel def updateUploadTransactionModel(self,uploadTransaction): #Given the latest transaction object, we grab its token object #and we update the percentage of the transaction #and other things #print "UploadTransactionView.updateUploadTransactionModel",uploadTransaction self._uploadTransactionModel = uploadTransaction self.setText(UploadTransactionView.COLUMN_PERCENTAGE,str(uploadTransaction.getUploadPercentage())+'%') self.setText(UploadTransactionView.COLUMN_STATUS,uploadTransaction.getHumanUploadStatus()) self.updateStatus() def updateStatus(self): self.setText(UploadTransactionView.COLUMN_STATUS,self._uploadTransactionModel.getHumanUploadStatus()) #Update the progress bar if self._uploadTransactionModel: #self._uploadTransactionProgressBar.setValue(self._uploadTransactionModel.getUploadPercentage()) self._uploadTransactionProgressBar = QProgressBar() self._uploadTransactionProgressBar.setAutoFillBackground(True) self._uploadTransactionProgressBar.setValue(self._uploadTransactionModel.getUploadPercentage()) self.getTreeWidget().setItemWidget(self,UploadTransactionView.COLUMN_PERCENTAGE,self._uploadTransactionProgressBar) def setTreeWidget(self, parent): self._treeWidget = parent def getTreeWidget(self): return self._treeWidget
class Qt4SysTrayIcon: def __init__(self): self.snapshots = snapshots.Snapshots() self.config = self.snapshots.config if len(sys.argv) > 1: if not self.config.set_current_profile(sys.argv[1]): logger.warning("Failed to change Profile_ID %s" % sys.argv[1], self) self.qapp = qt4tools.create_qapplication(self.config.APP_NAME) import icon self.icon = icon self.qapp.setWindowIcon(icon.BIT_LOGO) self.status_icon = QSystemTrayIcon(icon.BIT_LOGO) #self.status_icon.actionCollection().clear() self.contextMenu = QMenu() self.menuProfileName = self.contextMenu.addAction( _('Profile: "%s"') % self.config.get_profile_name()) qt4tools.set_font_bold(self.menuProfileName) self.contextMenu.addSeparator() self.menuStatusMessage = self.contextMenu.addAction(_('Done')) self.menuProgress = self.contextMenu.addAction('') self.menuProgress.setVisible(False) self.contextMenu.addSeparator() self.startBIT = self.contextMenu.addAction(icon.BIT_LOGO, _('Start BackInTime')) QObject.connect(self.startBIT, SIGNAL('triggered()'), self.onStartBIT) self.status_icon.setContextMenu(self.contextMenu) self.pixmap = icon.BIT_LOGO.pixmap(24) self.progressBar = QProgressBar() self.progressBar.setMinimum(0) self.progressBar.setMaximum(100) self.progressBar.setValue(0) self.progressBar.setTextVisible(False) self.progressBar.resize(24, 6) self.progressBar.render(self.pixmap, sourceRegion=QRegion(0, -14, 24, 6), flags=QWidget.RenderFlags( QWidget.DrawChildren)) self.first_error = self.config.is_notify_enabled() self.popup = None self.last_message = None self.timer = QTimer() QObject.connect(self.timer, SIGNAL('timeout()'), self.update_info) self.ppid = os.getppid() def prepare_exit(self): self.timer.stop() if not self.status_icon is None: self.status_icon.hide() self.status_icon = None if not self.popup is None: self.popup.deleteLater() self.popup = None self.qapp.processEvents() def run(self): self.status_icon.show() self.timer.start(500) logger.info("[qt4systrayicon] begin loop", self) self.qapp.exec_() logger.info("[qt4systrayicon] end loop", self) self.prepare_exit() def update_info(self): if not tools.is_process_alive(self.ppid): self.prepare_exit() self.qapp.exit(0) return message = self.snapshots.get_take_snapshot_message() if message is None and self.last_message is None: message = (0, _('Working...')) if not message is None: if message != self.last_message: self.last_message = message self.menuStatusMessage.setText('\n'.join(tools.wrap_line(self.last_message[1],\ size = 80,\ delimiters = '',\ new_line_indicator = '') \ )) self.status_icon.setToolTip(self.last_message[1]) pg = progress.ProgressFile(self.config) if pg.isFileReadable(): pg.load() percent = pg.get_int_value('percent') if percent != self.progressBar.value(): self.progressBar.setValue(percent) self.progressBar.render(self.pixmap, sourceRegion=QRegion(0, -14, 24, 6), flags=QWidget.RenderFlags( QWidget.DrawChildren)) self.status_icon.setIcon(QIcon(self.pixmap)) self.menuProgress.setText(' | '.join(self.getMenuProgress(pg))) self.menuProgress.setVisible(True) else: self.status_icon.setIcon(self.icon.BIT_LOGO) self.menuProgress.setVisible(False) def getMenuProgress(self, pg): d = (('sent', _('Sent:')), \ ('speed', _('Speed:')),\ ('eta', _('ETA:')) ) for key, txt in d: value = pg.get_str_value(key, '') if not value: continue yield txt + ' ' + value def onStartBIT(self): profileID = self.config.get_current_profile() cmd = [ 'backintime-qt4', ] if not profileID == '1': cmd += ['--profile-id', profileID] proc = subprocess.Popen(cmd)
def run(iface, lineLayer, nodeLayer, nodeRadiiExpr="0", lineWidthExpr="1", iterations=100, w_flows=1, w_nodes=0.5, w_antiTorsion=0.8, w_spring=1, w_angRes=3.75, snapThreshold=0, bezierRes=15, alpha=4, beta=4, kShort=0.5, kLong=0.05, Cp=2.5, K=4, C=4, constraintRectAspect=0.5, nodeBuffer=0): """ Runs the algorithm :return: """ # Generate a progress bar progDialog = QProgressDialog() progDialog.setWindowTitle("Progress") progDialog.setLabelText("Generating flowmap from layers") progBar = QProgressBar(progDialog) progBar.setTextVisible(True) progBar.setValue(0) progDialog.setBar(progBar) progDialog.setMinimumWidth(300) progBar.setMaximum(iterations) progDialog.show() # Load the nodes and flows into a data structure fm = FlowMap(w_flows=w_flows, w_nodes=w_nodes, w_antiTorsion=w_antiTorsion, w_spring=w_spring, w_angRes=w_angRes, snapThreshold=snapThreshold, bezierRes=bezierRes, alpha=alpha, beta=beta, kShort=kShort, kLong=kLong, Cp=Cp, K=K, C=C, constraintRectAspect=constraintRectAspect, nodeBuffer=nodeBuffer) fm.getNodesFromLineLayer(lineLayer) if nodeLayer is not None: fm.getNodeRadiiFromLayer(nodeLayer, nodeRadiiExpr) else: fm.nodeRadii = [0 for node in fm.nodes] fm.getLineWidthFromLayer(lineLayer, lineWidthExpr) fm.calculateMapScale() fm.loadFlowLinesFromLayer(lineLayer) # Iterate j = 0 # used in node collision avoidance algorithm progDialog.setLabelText("Iterating") for i in range(iterations): progBar.setValue(i) if progDialog.wasCanceled(): break w = 1 - float(i) / iterations # Calculate flowline-against-flowline forces flowline_forces, Fs = fm.calculateInterFlowLineForces( returnSumOfMagnitudes=True) # Calculate node-against-flowline forces node_forces = fm.calculateNodeToFlowLineForces() # Calculate anti-torsion forces antitorsion_forces = fm.calculateAntiTorsionForces() # Calculate spring forces spring_forces = fm.calculateSpringForces(flowline_forces, Fs) # Calculate angular-resolution-of-flowlines-around-nodes forces angRes_forces = fm.calculateAngleResForces() # Apply forces to arc control points resultantForces = [] for i in range(len(fm.flowlines)): rForce = (flowline_forces[i]*fm.w_flows + node_forces[i]*fm.w_nodes + antitorsion_forces[i]*fm.w_antiTorsion + spring_forces[i]*fm.w_spring)*w +\ (angRes_forces[i]*fm.w_angRes)*(w - w**2) resultantForces.append(rForce) fm.applyForces(resultantForces) # Apply rectangle constraint fm.applyRectangleConstraints() # Reduce intersections of flowlines with a common node fm.reduceFlowLineIntersections() # Move flows off of nodes if i > 0.1 * iterations and j <= 0: N = fm.getFlowLinesOverlappingNodes() j = (iterations - i) / (len(N) + 1) / 2 n = math.ceil(float(len(N)) / (iterations - i - 1)) movedFlows = 0 # number of flows which have been moved. Iterate until this equals n for flowline in N: movedFlows += 1 if fm.moveFlowLineOffNodes(flowline) else 0 if movedFlows >= n: break else: j -= 1 progDialog.setLabelText("Updating Geometry") # Update the geometry of the layer fm.updateGeometryOnLayer(lineLayer) iface.mapCanvas().refresh() # close the dialog progDialog.close()
class _CancellableProgressEditor(Editor): title = Unicode # synced from factory.title_name message = Unicode # synced from factory.message_name min = Int#Float # synced from factory.min_name max = Int#Float # synced from factory.max_name show_time = Bool # synced from factory.show_time_name def _title_changed(self): if self._title is not None: self._title.setText('<B>%s</B>' % self.title) self._title.setVisible(len(self.title) > 0) def _message_changed(self): if self._message is not None: self._message.setText(self.message) self._message.setVisible(len(self.message) > 0) if self.factory.prefix_message: self.set_text() def _show_time_changed(self): if self._time_widget is not None: self._time_widget.setVisible(self.show_time) @on_trait_change('min, max') def change_range(self): if self._progress_bar is not None: self._progress_bar.setRange(self.min, self.max) self.update_editor() def init(self, parent): self.title = self.factory.title if len(self.factory.title_name) > 0: self.sync_value(self.factory.title_name, 'title')#, 'from') self.message = self.factory.message if len(self.factory.message_name) > 0: self.sync_value(self.factory.message_name, 'message')#, 'from') self.min = self.factory.min if len(self.factory.min_name) > 0: self.sync_value(self.factory.min_name, 'min')#, 'from') self.max = self.factory.max if len(self.factory.max_name) > 0: self.sync_value(self.factory.max_name, 'max')#, 'from') self.show_time = self.factory.show_time if len(self.factory.show_time_name) > 0: self.sync_value(self.factory.show_time_name, 'show_time')#, 'from') self.control = self._create_control(parent) self.can_cancel = self.factory.can_cancel if len(self.factory.can_cancel_name) > 0: self.sync_value(self.factory.can_cancel_name, 'can_cancel')#, 'from') self.set_tooltip() self.reset() can_cancel = Bool(False) from traits.api import Any buttons = Any @on_trait_change('can_cancel') def set_buttons_visible(self, value): self.buttons.setVisible(value) def _create_control(self, parent): layout = QVBoxLayout() if len(self.title) > 0: self._title = QLabel('<B>%s</B>' % self.title) layout.addWidget(self._title) if not self.factory.prefix_message and len(self.message) > 0: self._message = QLabel(self.message) # self._message = QTextEdit(self.message) # self._message.setReadOnly(True) layout.addWidget(self._message) self._progress_bar = QProgressBar() self._progress_bar.setRange(self.min, self.max) if not self.factory.can_cancel: layout.addWidget(self._progress_bar) else: self.buttons = QDialogButtonBox() self.buttons.addButton(u'Cancel', QDialogButtonBox.RejectRole) self.buttons.connect(self.buttons, SIGNAL('rejected()'), self.factory.cancelled) grid_layout = QGridLayout() grid_layout.addWidget(self._progress_bar, 0, 0) grid_layout.setColumnStretch(0, 1) grid_layout.addWidget(self.buttons, 0, 1) layout.addLayout(grid_layout) if self.factory.show_time: elapsed_label = QLabel('Elapsed time:') estimated_label = QLabel('Estimated time:') remaining_label = QLabel('Remaining time:') self._elapsed_control = QLabel('unknown') self._estimated_control = QLabel('unknown') self._remaining_control = QLabel('unknown') grid_layout = QGridLayout() grid_layout.addWidget(elapsed_label, 0, 0) grid_layout.addWidget(self._elapsed_control, 0, 1) grid_layout.addWidget(estimated_label, 1, 0) grid_layout.addWidget(self._estimated_control, 1, 1) grid_layout.addWidget(remaining_label, 2, 0) grid_layout.addWidget(self._remaining_control, 2, 1) grid_layout.setColumnStretch(1, 1) self._time_widget = QWidget() self._time_widget.setLayout(grid_layout) layout.addWidget(self._time_widget) if self.factory.show_text: self.set_text() else: self._progress_bar.setTextVisible(False) widget = QWidget() widget.setLayout(layout) return widget def set_text(self): if self._progress_bar is None: return if self.factory.prefix_message: format = self.message + ' ' else: format = '' if self.factory.show_value: format += '%v' if self.factory.show_max: if self.factory.show_value: format += '/' format += '%m' if self.factory.show_value or self.factory.show_max: format += ' ' if self.factory.show_percent: if self.factory.show_value or self.factory.show_max: format += '(%p%)' else: format += '%p%' self._progress_bar.setFormat(format) def _set_time_label(self, value, control): hours = value / 3600 minutes = (value % 3600) / 60 seconds = value % 60 label = "%1u:%02u:%02u" % (hours, minutes, seconds) control.setText(control.text()[:-7] + label) def update_editor(self): if self.factory.min <= self.value <= self.factory.max: if self.value == self.factory.min: self.reset() self._progress_bar.setValue(self.value) if self.factory.show_time: if (self.factory.max != self.factory.min): percent = (float(self.value) - self.factory.min) / (self.factory.max - self.factory.min) # if float(<undefined>) raises an error here then probably the # name of the trait this is editing is mispelled or owned by # the handler, e.g. 'handler.progress' instead of 'progress'. else: percent = 1.0 if self.factory.show_time and (percent != 0): current_time = time.time() elapsed = current_time - self._start_time estimated = elapsed / percent remaining = estimated - elapsed self._set_time_label(elapsed, self._elapsed_control) self._set_time_label(estimated, self._estimated_control) self._set_time_label(remaining, self._remaining_control) def reset(self): self._progress_bar.reset() self._start_time = time.time()
class ErrorLabel(QWidget): WARNING, ERROR = range(2) def __init__(self, parent): QWidget.__init__(self, parent) self.ticks = 5 self.elapsedTicks = 0 self.lastSeverity = None self.icon_label = QLabel() self.icon_label.setGeometry(0, 0, 48, 48) self.message_edit = QTextEdit() self.message_edit.setReadOnly(True) self.message_edit.setFrameStyle(QFrame.NoFrame) palette = self.message_edit.palette() palette.setBrush(QPalette.Base, QBrush()) self.message_edit.setPalette(palette) self.time_bar = QProgressBar() self.time_bar.setOrientation(Qt.Vertical) self.time_bar.setMaximum(self.ticks) self.time_bar.setTextVisible(False) self.pauseButton = QPushButton(QIcon(QPixmap(":/icons/images/pause.png")), "") self.pauseButton.setFixedSize(32, 32) self.connect(self.pauseButton, SIGNAL('clicked()'), self.stopTimer) self.stopButton = QPushButton(QIcon(QPixmap(":/icons/images/stop.png")), "") self.stopButton.setFixedSize(32, 32) self.connect(self.stopButton, SIGNAL('clicked()'), self.closeWidget) self.layout = QGridLayout(self) self.layout.addWidget(self.time_bar, 0, 0, 2, 1) self.layout.addWidget(self.icon_label, 0, 1, 2, 1) self.layout.addWidget(self.message_edit, 0, 2, 2, 1) self.layout.addWidget(self.pauseButton, 0, 3) self.layout.addWidget(self.stopButton, 1, 3) self.layout.setColumnStretch(2, 1) self.setAutoFillBackground(True) self.timer = QTimer() self.connect(self.timer, SIGNAL("timeout()"), self.decrementTime) def stopTimer(self): self.timer.stop() self.pauseButton.setEnabled(False) def closeWidget(self): self.timer.stop() QWidget.hide(self) @pyqtSlot() def decrementTime(self): if self.elapsedTicks == self.ticks: self.hide() self.timer.stop() else: self.elapsedTicks += 1 self.time_bar.setValue(self.ticks - self.elapsedTicks) def updatePosition(self): self.setGeometry(0, self.parent().height() - self.height(), self.width(), self.height()) def setSize(self, w, h): self.setGeometry(0, self.parent().height() - h, w, h) def setErrorMessage(self, msg): self.lastSeverity = self.ERROR self.icon_label.setPixmap(QApplication.style().standardIcon(QStyle.SP_MessageBoxCritical).pixmap(48, 48)) self._setMessage(msg) def setWarningMessage(self, msg): self.lastSeverity = self.WARNING self.icon_label.setPixmap(QApplication.style().standardIcon(QStyle.SP_MessageBoxWarning).pixmap(48, 48)) self._setMessage(msg) def _setMessage(self, msg): self.message_edit.setText(msg) self.updatePosition() self.elapsedTicks = 0 self.time_bar.setValue(self.ticks) self.timer.start(1000) self.pauseButton.setEnabled(True) self.show()
class InputForm(QWidget): __instance = None @staticmethod def instance(): return InputForm.__instance def __init__(self): if not InputForm.__instance: InputForm.__instance = self super(InputForm, self).__init__() Global.event.task_started.connect(self._on_task_started) Global.event.task_completed.connect(self._on_task_completed) Global.event.task_progressed.connect(self._on_task_progressed) Global.event.task_range_progressed.connect(self._on_task_range_progressed) Global.event.interface_load_task_params.connect(self._on_interface_load_task_params) self.vl = QVBoxLayout() self.vl.setContentsMargins(0,0,0,0) self.setLayout(self.vl) self.setFixedWidth(290) self.tab = QTabWidget() self.vl.addWidget(self.tab) self.input_parameters = InputParameters() self.input_parameters.ranges_state_changed.connect(self._on_ranges_state_changed) self.tab.addTab(self.input_parameters, 'Parameters') self.import_parameters = ImportParameters() self.tab.addTab(self.import_parameters, 'Observation') control_buttons = QWidget() control_buttons.setLayout(QVBoxLayout()) control_buttons.layout().setContentsMargins(0, 0, 0, 0) control_buttons.layout().setAlignment(Qt.AlignBottom) self._progress = QProgressBar() self._progress.setValue(0) self._progress.setTextVisible(True) self._progress.setAlignment(Qt.AlignCenter) self._progress.hide() control_buttons.layout().addWidget(self._progress) self._range_progress = QProgressBar() self._range_progress.setValue(0) self._range_progress.setTextVisible(True) self._range_progress.setAlignment(Qt.AlignCenter) self._range_progress.hide() control_buttons.layout().addWidget(self._range_progress) self._calculate = QPushButton('Calculate') self._calculate.clicked.connect(self._on_calculate) control_buttons.layout().addWidget(self._calculate) self._cancel = QPushButton('Cancel') self._cancel.hide() self._cancel.clicked.connect(self._on_cancel) control_buttons.layout().addWidget(self._cancel) self.vl.addWidget(control_buttons) if exists("./config/last-session.ini") : self.load_params("./config/last-session.ini") def _on_ranges_state_changed(self, parameters): Global.task_range().reset() if len(parameters): keys = parameters.keys() for key in parameters: Global.task_range().set_range(key, copy(parameters[key].range.values)) self._calculate.setText('Calculate ' + str(Global.task_range()._total_count) + ' variations') else: self._calculate.setText('Calculate') def _on_calculate(self): self.import_parameters.import_observation() combination = Global.task_range().get_next_combination() Global.task().input.semi_major_axis = self.input_parameters.semi_major_axis.getValue() Global.task().input.star_radius = self.input_parameters.star_radius.getValue() Global.task().input.planet_radius = self.input_parameters.planet_radius.getValue() Global.task().input.star_temperature = self.input_parameters.star_temperature.getValue() Global.task().input.planet_temperature = self.input_parameters.planet_temperature.getValue() Global.task().input.darkening_law = self.input_parameters.darkening_law.value.itemData(self.input_parameters.darkening_law.value.currentIndex()).toString() Global.task().input.darkening_1 = self.input_parameters.darkening_coefficient_1.getValue() Global.task().input.darkening_2 = self.input_parameters.darkening_coefficient_2.getValue() Global.task().input.inclination = self.input_parameters.inclination.getValue() Global.task().input.phase_start = 0 Global.task().input.phase_end = self.input_parameters.phase_end.getValue() Global.task().input.phase_step = self.input_parameters.phase_step.getValue() Global.task().input.precision = 10**self.input_parameters.integration_precision.getValue() if combination: for param in combination: setattr(Global.task().input, param[0], param[1]) Global.task().start() def _on_task_range_progressed(self, progress): self._range_progress.setFormat( str(Global.task_range().completed_count()) + ' of ' + str(Global.task_range().total_count())) self._range_progress.setValue(math.ceil(((float(Global.task_range().completed_count()))/Global.task_range().total_count())*100)) self._on_calculate() def _on_task_started(self, task): self._calculate.hide() self._progress.show() self._progress.setValue(0) self._cancel.show() self.tab.setDisabled(True) if Global.task_range().total_count(): self._range_progress.show() if Global.task_range().completed_count() == 0: self._range_progress.setFormat('0 of ' + str(Global.task_range().total_count())) self._range_progress.setValue(0) def _on_task_progressed(self, task, progress): self._progress.setValue(progress) def _on_task_completed(self, task): if Global.task_range().total_count() and Global.task_range().completed_count(): return self._calculate.show() self._progress.hide() self._progress.setValue(0) self._cancel.hide() self.tab.setDisabled(False) self._range_progress.hide() self._range_progress.setValue(0) def _on_cancel(self): Global.task().stop() self._calculate.show() self._progress.hide() self._progress.setValue(0) self._range_progress.hide() self._range_progress.setValue(0) self._cancel.hide() self.tab.setDisabled(False) def _on_interface_load_task_params(self, task): self.input_parameters.semi_major_axis.value.setValue(task.input.semi_major_axis) self.input_parameters.star_radius.value.setValue(task.input.star_radius) self.input_parameters.planet_radius.value.setValue(task.input.planet_radius) self.input_parameters.star_temperature.value.setValue(task.input.star_temperature) self.input_parameters.planet_temperature.value.setValue(task.input.planet_temperature) self.input_parameters.inclination.value.setValue(task.input.inclination) darkening_law_index = 0 for item in DarkeningLaw.items: if item[1] == task.input.darkening_law: break darkening_law_index += 1 self.input_parameters.darkening_law.value.setCurrentIndex(darkening_law_index) self.input_parameters.darkening_coefficient_1.value.setValue(task.input.darkening_1) self.input_parameters.darkening_coefficient_2.value.setValue(task.input.darkening_2) self.input_parameters.phase_end.value.setValue(task.input.phase_end) self.input_parameters.phase_step.value.setValue(task.input.phase_step) self.input_parameters.integration_precision.value.setValue(log10(task.input.precision)) for parameter_name in copy(self.input_parameters.range_parameters): parameter = getattr(self.input_parameters, parameter_name) if parameter.range: parameter.range.set_active(False) self.repaint() def load_params(self, filename): config = ConfigParser() config.read(filename) self._normalize_config(config) # Input Parameters self._load_config_param(config, 'input', 'semi_major_axis') self._load_config_param(config, 'input', 'star_radius') self._load_config_param(config, 'input', 'planet_radius') self._load_config_param(config, 'input', 'star_temperature') self._load_config_param(config, 'input', 'planet_temperature') self._load_config_param(config, 'input', 'inclination') self._load_config_param(config, 'input', 'darkening_law') self._load_config_param(config, 'input', 'darkening_coefficient_1') self._load_config_param(config, 'input', 'darkening_coefficient_2') self._load_config_param(config, 'input', 'phase_end') self._load_config_param(config, 'input', 'phase_step') self._load_config_param(config, 'input', 'integration_precision') # Import Parameters if config.has_option('import', 'filename') and config.get('import', 'filename'): if '/data/' in config.get('import', 'filename') and config.get('import', 'filename').index('/data/') == 0: self.import_parameters.filename = os.getcwd().replace('\\', '/') + config.get('import', 'filename') else: self.import_parameters.filename = config.get('import', 'filename') self.import_parameters.update_file_label() if config.has_option('import', 'jd2phase') and config.getboolean('import', 'jd2phase') == True : self.import_parameters.hjd_to_phases.setCheckState(Qt.Checked) if config.has_option('import', 'jd2phase_tzero') : self.import_parameters.time_zero.setValue(config.getfloat('import', 'jd2phase_tzero')) if config.has_option('import', 'jd2phase_period') : self.import_parameters.period.setValue(config.getfloat('import', 'jd2phase_period')) if config.has_option('import', 'mag2flux') and config.getboolean('import', 'mag2flux') == True : self.import_parameters.magnitude_to_flux.setCheckState(Qt.Checked) if config.has_option('import', 'mag2flux_mag') : self.import_parameters.magnitude_max.setValue(config.getfloat('import', 'mag2flux_mag')) # Fixes painting bug with range buttons when loading new file # the active ranges stayed active even if they are inactive self.repaint() def _normalize_config(self, config): if config.has_option('input', 'darkening_1'): config.set('input', 'darkening_coefficient_1', config.get('input', 'darkening_1')) config.remove_option('input', 'darkening_1') if config.has_option('input', 'darkening_2'): config.set('input', 'darkening_coefficient_2', config.get('input', 'darkening_2')) config.remove_option('input', 'darkening_2') if config.has_option('input', 'precision'): config.set('input', 'integration_precision', config.get('input', 'precision')) config.remove_option('input', 'precision') def _load_config_param(self, config, section, name): param = getattr(self.input_parameters, name) if config.has_option(section, name): if type(param.value) is QComboBox: param.value.setCurrentIndex(config.getint(section, name)) else: param.value.setValue(literal_eval(config.get(section, name))) if param.range: _from = _to = _step = _values = None _active = False if config.has_option(section, name + '_range_from'): _from = literal_eval(config.get(section, name + '_range_from')) if config.has_option(section, name + '_range_to'): _to = literal_eval(config.get(section, name + '_range_to')) if config.has_option(section, name + '_range_step'): _step = literal_eval(config.get(section, name + '_range_step')) if config.has_option(section, name + '_range_values'): _values = literal_eval(config.get(section, name + '_range_values')) if config.has_option(section, name + '_range_active'): _active = config.getboolean(section, name + '_range_active') if _values: param.range.set_range(_values) elif _from and _to and _step: param.range.set_range(_from, _to, _step) param.range.set_active(_active) def _save_config_param(self, config, section, name): param = getattr(self.input_parameters, name) if type(param.value) is QComboBox: config.set(section, name, param.value.currentIndex()) else: config.set(section, name, param.getValue()) if param.range: if param.range.range_from and param.range.range_to and param.range.range_step: config.set(section, name + '_range_from', param.range.range_from) config.set(section, name + '_range_to', param.range.range_to) config.set(section, name + '_range_step', param.range.range_step) elif param.range.values: config.set(section, name + '_range_values', param.range.values) if param.range.is_active(): config.set(section, name + '_range_active', param.range.is_active()) def save_params(self, filename): config = ConfigParser() config.add_section('input') # Input Parameters self._save_config_param(config, 'input', 'semi_major_axis') self._save_config_param(config, 'input', 'star_radius') self._save_config_param(config, 'input', 'planet_radius') self._save_config_param(config, 'input', 'star_temperature') self._save_config_param(config, 'input', 'planet_temperature') self._save_config_param(config, 'input', 'inclination') self._save_config_param(config, 'input', 'darkening_law') self._save_config_param(config, 'input', 'darkening_coefficient_1') self._save_config_param(config, 'input', 'darkening_coefficient_2') self._save_config_param(config, 'input', 'phase_end') self._save_config_param(config, 'input', 'phase_step') self._save_config_param(config, 'input', 'integration_precision') config.add_section('import') if os.getcwd().replace('\\', '/') in str(self.import_parameters.filename) and str(self.import_parameters.filename).index(os.getcwd().replace('\\', '/')) == 0 : save_file_path = str(self.import_parameters.filename).replace(os.getcwd().replace('\\', '/'), '') else: save_file_path = str(self.import_parameters.filename) config.set('import', 'filename', save_file_path) config.set('import', 'jd2phase', self.import_parameters.hjd_to_phases.checkState() == Qt.Checked) config.set('import', 'jd2phase_tzero', self.import_parameters.time_zero.value()) config.set('import', 'jd2phase_period', self.import_parameters.period.value()) config.set('import', 'mag2flux', self.import_parameters.magnitude_to_flux.checkState() == Qt.Checked) config.set('import', 'mag2flux_mag', self.import_parameters.magnitude_max.value()) with open(filename, 'wb') as configfile: config.write(configfile) pass
class FeedLol(QMainWindow): def __init__(self, parent = None): QMainWindow.__init__(self, parent) self.setWindowTitle("FeedLol") self.aboutAction = QAction(QIcon("data/icons/help-about.svg"), "&About FeedLol...", self) self.connect(self.aboutAction, SIGNAL("triggered()"), self.slotAbout) self.reloadAction = QAction(QIcon("data/icons/view-refresh.svg"), "&Reload", self) self.reloadAction.setShortcut(QKeySequence.Refresh) self.homeAction = QAction(QIcon("data/icons/go-home.svg"), "Go &Home", self) self.homeAction.setShortcut("Alt+Home") self.userAction = QAction(QIcon("data/icons/user-identity.svg"), "&Me", self) self.userAction.setShortcut("Ctrl+M") self.logoutAction = QAction(QIcon("data/icons/dialog-close.svg"), "Log&out", self) self.logoutAction.setShortcut(QKeySequence.Close) self.settingsAction = QAction(QIcon("data/icons/configure.svg"), "&Preferences...", self) self.connect(self.settingsAction, SIGNAL("triggered()"), self.slotSettings) self.toolbar = QToolBar("Toolbar", self) self.toolbar.setObjectName("toolbar") self.toolbar.addAction(self.homeAction) self.toolbar.addAction(self.userAction) self.toolbar.addAction(self.reloadAction) self.toolbar.addSeparator() self.toolbar.addAction(self.logoutAction) self.toolbar.addSeparator() self.toolbar.addAction(self.settingsAction) self.toolbar.addAction(self.aboutAction) self.addToolBar(self.toolbar) self.loadStatus = QProgressBar(self) self.loadStatus.setRange(0, 100) self.loadStatus.setMaximumWidth(200) self.loadStatus.setTextVisible(False) self.loadStatus.hide() self.statusBar().addPermanentWidget(self.loadStatus) self.feedView = FeedView(self) self.setCentralWidget(self.feedView) self.connect(self.feedView, SIGNAL("titleChanged(const QString&)"), self.slotSetTitle) self.connect(self.feedView, SIGNAL("statusBarMessage(const QString&)"), self.statusBar(), SLOT("showMessage(const QString&)")) self.connect(self.feedView, SIGNAL("loadStarted()"), self.loadStart) self.connect(self.feedView, SIGNAL("loadFinished(bool)"), self.loadStop) self.connect(self.feedView, SIGNAL("loadProgress(int)"), self.loadProgress) self.connect(self.reloadAction, SIGNAL("triggered()"), self.feedView.reload) self.connect(self.homeAction, SIGNAL("triggered()"), self.feedView.goHome) self.connect(self.userAction, SIGNAL("triggered()"), self.feedView.goToUserPage) self.connect(self.logoutAction, SIGNAL("triggered()"), self.feedView.logout) self.connect(self.feedView.page(), SIGNAL("linkHovered(const QString&, const QString&, const QString&)"), self.linkHovered) self.settingsDialog = SettingsDialog(self.feedView, self) settings = QSettings() if settings.contains("proxy/type"): proxy = QNetworkProxy() proxyType = settings.value("proxy/type").toInt()[0] proxy.setType( (proxyType == 2) and QNetworkProxy.Socks5Proxy or ( (proxyType == 1) and QNetworkProxy.HttpProxy or QNetworkProxy.NoProxy ) ) if proxy.type() != QNetworkProxy.NoProxy: proxy.setHostName(settings.value("proxy/host").toString()) proxy.setPort(settings.value("proxy/port").toInt()[0]) if settings.value("proxy/user").toString(): proxy.setUser(settings.value("proxy/user").toString()) proxy.setPassword(settings.value("proxy/password").toString()) QNetworkProxy.setApplicationProxy(proxy) if settings.contains("mainWindow/geometry"): self.restoreGeometry(settings.value("mainWindow/geometry").toByteArray()) else: self.resize(320,480) if settings.contains("mainWindow/state"): self.restoreState(settings.value("mainWindow/state").toByteArray()) self.feedView.goHome() def saveConfig(self): settings = QSettings() settings.setValue("mainWindow/geometry", QVariant(self.saveGeometry())) settings.setValue("mainWindow/state", QVariant(self.saveState())) session = self.feedView.siteServer.session from cPickle import dumps session = dumps(session) settings.setValue("session", QVariant(session)) proxy = QNetworkProxy.applicationProxy() proxyType = (proxy.type() == QNetworkProxy.Socks5Proxy) and 2 or ( (proxy.type() == QNetworkProxy.HttpProxy) and 1 or 0 ) settings.setValue("proxy/type", QVariant(proxyType)) settings.setValue("proxy/host", QVariant(proxy.hostName())) settings.setValue("proxy/port", QVariant(proxy.port())) settings.setValue("proxy/user", QVariant(proxy.user())) settings.setValue("proxy/password", QVariant(proxy.password())) def slotAbout(self): from PyQt4.QtGui import QMessageBox QMessageBox.about(self, "FeedLol", "<h2>FeedLol 0.1</h2><p>Copyright © 2008 <a href=\"mailto:[email protected]\">Bodil Stokke</a></p>") def slotSettings(self): self.settingsDialog.updateSettings() if self.settingsDialog.exec_() == QDialog.Accepted: self.settingsDialog.applySettings() def slotSetTitle(self, title): self.setWindowTitle("FeedLol: " + title) def loadStart(self): self.loadStatus.show() def loadStop(self): self.loadStatus.hide() def loadProgress(self, progress): self.loadStatus.setValue(progress) def linkHovered(self, url, title, text): if url and QUrl(url).scheme() != "chrome": self.statusBar().showMessage(url) else: self.statusBar().clearMessage()
def __init__(self, parent=None): QWidget.__init__(self, parent) self.home_url = None self.webview = WebView(self) self.connect(self.webview, SIGNAL("loadFinished(bool)"), self.load_finished) self.connect(self.webview, SIGNAL("titleChanged(QString)"), self.setWindowTitle) self.connect(self.webview, SIGNAL("urlChanged(QUrl)"), self.url_changed) home_button = create_toolbutton(self, icon=get_icon('home.png'), tip=_("Home"), triggered=self.go_home) zoom_out_button = action2button(self.webview.zoom_out_action) zoom_in_button = action2button(self.webview.zoom_in_action) pageact2btn = lambda prop: action2button(self.webview.pageAction(prop), parent=self.webview) refresh_button = pageact2btn(QWebPage.Reload) stop_button = pageact2btn(QWebPage.Stop) previous_button = pageact2btn(QWebPage.Back) next_button = pageact2btn(QWebPage.Forward) stop_button.setEnabled(False) self.connect(self.webview, SIGNAL("loadStarted()"), lambda: stop_button.setEnabled(True)) self.connect(self.webview, SIGNAL("loadFinished(bool)"), lambda: stop_button.setEnabled(False)) progressbar = QProgressBar(self) progressbar.setTextVisible(False) progressbar.hide() self.connect(self.webview, SIGNAL("loadStarted()"), progressbar.show) self.connect(self.webview, SIGNAL("loadProgress(int)"), progressbar.setValue) self.connect(self.webview, SIGNAL("loadFinished(bool)"), lambda _state: progressbar.hide()) label = QLabel(self.get_label()) self.url_combo = UrlComboBox(self) self.connect(self.url_combo, SIGNAL('valid(bool)'), self.url_combo_activated) self.connect(self.webview, SIGNAL("iconChanged()"), self.icon_changed) self.find_widget = FindReplace(self) self.find_widget.set_editor(self.webview) self.find_widget.hide() find_button = create_toolbutton(self, icon='find.png', tip=_("Find text"), toggled=self.toggle_find_widget) self.connect(self.find_widget, SIGNAL("visibility_changed(bool)"), find_button.setChecked) hlayout = QHBoxLayout() for widget in (previous_button, next_button, home_button, find_button, label, self.url_combo, zoom_out_button, zoom_in_button, refresh_button, progressbar, stop_button): hlayout.addWidget(widget) layout = QVBoxLayout() layout.addLayout(hlayout) layout.addWidget(self.webview) layout.addWidget(self.find_widget) self.setLayout(layout)
class GUI(QWidget): def __init__(self, parent=None): global f f = open(filename, "a") f.write("Widget init.\n") f.close() QWidget.__init__(self, parent, Qt.WindowStaysOnTopHint) self.__setup_gui__(self) self._flag = False self._change = False f = open(filename, "a") f.write("End of widget init.\n") f.close() def closeEvent(self, event): reply = QMessageBox.question(self, "Confirm", "Are you sure You want to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: event.accept() else: event.ignore() def __setup_gui__(self, Dialog): global f f = open(filename, "a") f.write("Setup of gui.\n") f.close() Dialog.setObjectName("Dialog") Dialog.resize(270, 145) self.setWindowTitle("Map Layer") screen = QDesktopWidget().screenGeometry() size = self.geometry() self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2) self.Render = QPushButton("Render", Dialog) self.Render.setGeometry(QRect(85, 90, 100, 25)) self.Render.setObjectName("Render") self.comboBox = QComboBox(Dialog) self.comboBox.setGeometry(QRect(100, 34, 115, 18)) self.comboBox.setEditable(False) self.comboBox.setMaxVisibleItems(11) self.comboBox.setInsertPolicy(QComboBox.InsertAtBottom) self.comboBox.setObjectName("comboBox") self.comboBox.addItems([ "Google Roadmap", "Google Terrain", "Google Satellite", "Google Hybrid", "Yahoo Roadmap", "Yahoo Satellite", "Yahoo Hybrid", "Bing Roadmap", "Bing Satellite", "Bing Hybrid", "Open Street Maps" ]) self.comboBox.setCurrentIndex(10) self.label1 = QLabel("Source:", Dialog) self.label1.setGeometry(QRect(55, 35, 35, 16)) self.label1.setObjectName("label1") self.slider = QSlider(Dialog) self.slider.setOrientation(Qt.Horizontal) self.slider.setMinimum(1) self.slider.setMaximum(12) self.slider.setValue(4) self.slider.setGeometry(QRect(110, 61, 114, 16)) self.label2 = QLabel("Quality: " + str(self.slider.value()), Dialog) self.label2.setGeometry(QRect(47, 61, 54, 16)) self.label2.setObjectName("label2") self.doubleSpinBox = QDoubleSpinBox(Dialog) self.doubleSpinBox.setGeometry(QRect(160, 5, 40, 20)) self.doubleSpinBox.setDecimals(0) self.doubleSpinBox.setObjectName("doubleSpinBox") self.doubleSpinBox.setMinimum(10.0) self.doubleSpinBox.setValue(20.0) self.doubleSpinBox.setEnabled(False) self.checkBox = QCheckBox("Auto refresh", Dialog) self.checkBox.setGeometry(QRect(50, 6, 100, 20)) self.checkBox.setLayoutDirection(Qt.RightToLeft) self.checkBox.setObjectName("checkBox") self.progressBar = QProgressBar(Dialog) self.progressBar.setGeometry(QRect(5, 130, 260, 10)) self.progressBar.setProperty("value", 0) self.progressBar.setTextVisible(False) self.progressBar.setObjectName("progressBar") self.progressBar.setVisible(False) QObject.connect(self.Render, SIGNAL("clicked()"), Dialog.__repaint__) QMetaObject.connectSlotsByName(Dialog) QObject.connect(self.slider, SIGNAL("valueChanged(int)"), self.__update_slider_label__) QObject.connect(self.comboBox, SIGNAL("activated(int)"), self.__combobox_changed__) self.timerRepaint = QTimer() QObject.connect(self.checkBox, SIGNAL("clicked()"), self.__activate_timer__) QObject.connect(self.timerRepaint, SIGNAL("timeout()"), self.__on_timer__) f = open(filename, "a") f.write("End of setup of gui.\n") f.close() def __combobox_changed__(self): self._change = True def __activate_timer__(self): self.doubleSpinBox.setEnabled(self.checkBox.isChecked()) if self.checkBox.isChecked(): self.timerRepaint.start(self.doubleSpinBox.value() * 1000) self.Render.setEnabled(False) if _progress == 0: self.__repaint__() else: self.timerRepaint.stop() self.Render.setEnabled(True) def __get_net_size__(self): global f f = open(filename, "a") f.write("Geting net size...\n") f.close() if not os.path.exists(Paths["Screenshot"]): Visum.Graphic.Screenshot(Paths["Screenshot"]) size = Image.open(Paths["Screenshot"]).size f = open(filename, "a") f.write("Read net size:" + str(size) + ".\n") f.close() return size def __on_timer__(self): global _paramGlobal self._flag = False Visum.Graphic.MaximizeNetWindow() param = _paramGlobal _paramGlobal = Visum.Graphic.GetWindow() shift = abs((param[0] - _paramGlobal[0]) / (param[2] - param[0])) zoom = abs((param[2] - param[0]) / (_paramGlobal[2] - _paramGlobal[0]) - 1) print _windowSizeGlobal if _windowSizeGlobal[2:4] != Visum.Graphic.GetMainWindowPos()[2:4]: self.__get_net_size__() self._flag = True elif shift > 0.4 or zoom > 0.2: self._flag = True if self._flag or self._change and _progress == 0: self.__repaint__() self._change = False def __update_slider_label__(self, value): self.label2.setText("Quality: " + str(value)) self._change = True def __update_progress_bar__(self): if _progress != 0: self.progressBar.setVisible(True) self.progressBar.setValue(_progress) else: self.progressBar.setVisible(False) def __rebuild_paths__(self): global Paths Paths["Images"] = [] list = os.listdir(Paths["ScriptFolder"]) imageList = [] for i in range(len(list)): if list[i][-3:] == "png": imageList.append(list[i]) for i in range(len(imageList)): try: Visum.Graphic.Backgrounds.ItemByKey(imageList[i]) Paths["Images"].append(Paths["ScriptFolder"] + "\\" + imageList[i]) except: pass def __repaint__(self): global _progress, f if len(Visum.Graphic.Backgrounds.GetAll) != len(Paths["Images"]): self.__rebuild_paths__() if _progress == 0: f = open(filename, "a") f.write("Doing repaint...\n") f.close() QWebSettings.clearMemoryCaches() timer = QTimer() timer.start(100) QObject.connect(timer, SIGNAL("timeout()"), self.__update_progress_bar__) Main(self.comboBox.currentIndex(), Visum.Graphic.GetWindow(), self.slider.value() / 4.0, self.__get_net_size__()) Visum.Graphic.Draw() self.__update_progress_bar__() _progress = 0 QTimer().singleShot(1500, self.__update_progress_bar__) f = open(filename, "a") f.write("End of doing repaint.\n") f.close()
class HomeWidget(BaseWidget): def __init__(self, parent=0, *args, **kwargs): super(HomeWidget, self).__init__(parent=parent, *args, **kwargs) # inputs self._json_fpath = None self._destination_folder = self.guess_destination() self._from_date, self._to_date = self.guess_dates() self.nb_instances = 0 self.setup_ui() @property def json_fpath(self): return self._json_fpath @json_fpath.setter def json_fpath(self, value): self._json_fpath = value self.json_select_button.setText( value if value else "Sélection fichier JSON ODK Aggregate ...") self.update_start_button_state() @property def destination_folder(self): return self._destination_folder @destination_folder.setter def destination_folder(self, value): self._destination_folder = value self.destination_select_button.setText(self.destination_folder) self.update_start_button_state() @property def from_date(self): return self._from_date @from_date.setter def from_date(self, value): self._from_date = value self.from_date_selector.setPythonDate(self.from_date) self.update_start_button_state() @property def to_date(self): return self._to_date @to_date.setter def to_date(self, value): self._to_date = value self.to_date_selector.setPythonDate(self.to_date) self.update_start_button_state() def setup_ui(self): # json file selector self.json_groupbox = QGroupBox("Export ODK Aggregate") layout = QGridLayout() self.json_select_button = PushButton("", self) self.json_select_button.clicked.connect(self.json_selector_clicked) layout.addWidget(self.json_select_button, 1, 0) self.json_groupbox.setLayout(layout) # destination folder selector self.destination_groupbox = QGroupBox("Destination") layout = QGridLayout() self.destination_select_button = PushButton(self.destination_folder, self) self.destination_select_button.clicked.connect( self.destination_selector_clicked) layout.addWidget(self.destination_select_button, 1, 0) self.destination_groupbox.setLayout(layout) # period calendars today = datetime.date.today() self.period_groupbox = QGroupBox("Période") layout = QGridLayout() self.from_date_selector = DateTimeEdit(QDate(self.from_date)) self.from_date_selector.dateChanged.connect(self.from_date_changed) self.from_date_selector.setMaximumDate(self.to_date) self.to_date_selector = DateTimeEdit(QDate(self.to_date)) self.to_date_selector.dateChanged.connect(self.to_date_changed) self.to_date_selector.setMinimumDate(self.from_date) self.to_date_selector.setMaximumDate(today) layout.addWidget(Label("Du"), 2, 0) layout.addWidget(self.from_date_selector, 3, 0) layout.addWidget(Label("Au"), 2, 1) layout.addWidget(self.to_date_selector, 3, 1) self.period_groupbox.setLayout(layout) # start button self.start_button = PushButton("Démarrer") self.start_button.setEnabled(False) self.start_button.setDefault(True) self.start_button.clicked.connect(self.export_requested) # cancel button self.cancel_button = CancelPushButton("Annuler") self.cancel_button.setEnabled(False) self.cancel_button.clicked.connect(self.cancel_export) # grid self.gridBox = QGridLayout() self.gridBox.addWidget(self.json_groupbox, 0, 0, 1, 2) self.gridBox.addWidget(self.destination_groupbox, 1, 0, 1, 2) self.gridBox.addWidget(self.period_groupbox, 2, 0, 1, 2) self.gridBox.addWidget(self.start_button, 3, 0) self.gridBox.addWidget(self.cancel_button, 3, 1) vBox = QVBoxLayout() vBox.addLayout(self.gridBox) self.setLayout(vBox) self.json_fpath = None def guess_destination(self, root_only=False): start_folder = os.path.join(os.path.expanduser("~"), 'Desktop') if root_only: return start_folder return os.path.join(start_folder, Constants.DEFAULT_FOLDER_NAME) def guess_dates(self): to = datetime.date.today() start = to - datetime.timedelta(days=15) return start, to def update_start_button_state(self): self.start_button.setEnabled( all([ self.json_fpath, self.destination_folder, self.from_date, self.to_date ])) def json_selector_clicked(self): # self.file_name_field.setText("Aucun fichier") self.start_button.setEnabled(False) fpath = QFileDialog.getOpenFileName( self, "Choisir le fichier d'export JSON", self.json_fpath or self.guess_destination(root_only=True), "Fichiers JSON (*.json)") self.json_fpath = os.path.abspath(fpath) if fpath else self.json_fpath def destination_selector_clicked(self): path = QFileDialog.getExistingDirectory(self, "Sélectionner le dossier", self.destination_folder) if path: self.destination_folder = os.path.abspath(path) def from_date_changed(self, new_date): self.from_date = new_date.toPyDate() def to_date_changed(self, new_date): self.to_date = new_date.toPyDate() def export_requested(self): logger.debug("export_requested") self.parentWidget().exporter.check_aggregate_presence() def display_missing_aggregate_confirmation(self): if MissingODKConfirmationWidget().exec_() == QDialog.Accepted: self.start_export() def start_export(self): logger.debug("Lancement ...") self.add_progressbar() self.start_button.setEnabled(False) self.cancel_button.setEnabled(True) self.parentWidget().exporter.parse( destination_folder=self.destination_folder, fname=self.json_fpath, from_date=self.from_date, to_date=self.to_date) def cancel_export(self): logger.debug("cancel") self.parentWidget().exporter.cancel() def update_progress_label(self, index): progression_label = "Export en cours... {index}/{total}" \ .format(index=index, total=self.nb_instances) self.progression_groupbox.setTitle(progression_label) def add_progressbar(self): self.progressbar = QProgressBar() self.progressbar.setMinimum(0) self.progressbar.setMaximum(100) self.progressbar.reset() self.progressbar.setTextVisible(False) self.progression_groupbox = QGroupBox("...") progress_layout = QHBoxLayout() progress_layout.addWidget(self.progressbar) self.progression_groupbox.setLayout(progress_layout) self.gridBox.addWidget(self.progression_groupbox, 4, 0, 1, 2) def remove_progressbar(self): self.progression_groupbox.deleteLater() self.progression_groupbox = None @pyqtSlot(bool, int, str) def parsing_ended(self, succeeded, nb_instances, error_message): if succeeded: self.nb_instances = nb_instances @pyqtSlot(str, int) def exporting_instance(self, ident, index): logger.debug("exporting_instance") self.update_progress_label(index) @pyqtSlot(bool, int) def instance_completed(self, succeeded, index): logger.debug("instance_completed") pc = index * 100 // self.nb_instances self.progressbar.setValue(pc) @pyqtSlot(int, int, int, int) def export_ended(self, nb_instances_successful, nb_instances_failed, nb_medias_successful, nb_medias_failed): self.cancel_button.setEnabled(False) self.start_button.setEnabled(True) @pyqtSlot() def export_canceled(self): self.remove_progressbar() self.cancel_button.setEnabled(False) self.start_button.setEnabled(True) QMessageBox.warning( self, "Export annulé !", "L'export en cours a été annulé.\n" "Tous les fichiers créés ont été supprimés", QMessageBox.Ok, QMessageBox.NoButton) if self.parentWidget().is_exiting: self.parentWidget().do_close()
class DocumentGeneratorDialog(QDialog, Ui_DocumentGeneratorDialog): """ Dialog that enables a user to generate documents by using configuration information for different entities. """ def __init__(self, iface, parent=None, plugin=None): QDialog.__init__(self, parent) self.setupUi(self) self._iface = iface self.plugin = plugin self._docTemplatePath = "" self._outputFilePath = "" self.curr_profile = current_profile() self.last_data_source = None self._config_mapping = OrderedDict() self._notif_bar = NotificationBar(self.vlNotification) self._doc_generator = DocumentGenerator(self._iface, self) self._data_source = "" enable_drag_sort(self.lstDocNaming) #Configure generate button generateBtn = self.buttonBox.button(QDialogButtonBox.Ok) if not generateBtn is None: generateBtn.setText(QApplication.translate("DocumentGeneratorDialog", "Generate")) #Load supported image types supportedImageTypes = QImageWriter.supportedImageFormats() for imageType in supportedImageTypes: imageTypeStr = imageType.data() self.cboImageType.addItem(imageTypeStr) self._init_progress_dialog() #Connect signals self.btnSelectTemplate.clicked.connect(self.onSelectTemplate) self.buttonBox.accepted.connect(self.onGenerate) self.chkUseOutputFolder.stateChanged.connect(self.onToggledOutputFolder) self.rbExpImage.toggled.connect(self.onToggleExportImage) self.tabWidget.currentChanged.connect(self.on_tab_index_changed) self.chk_template_datasource.stateChanged.connect(self.on_use_template_datasource) self.btnShowOutputFolder.clicked.connect(self.onShowOutputFolder) def _init_progress_dialog(self): """ Initializes the progress dialog. """ self.progress = QProgressBar(self) self.progress.resize(self.width(), 10) self.progress.setTextVisible(False) def add_entity_configuration(self, **kwargs): ent_config = EntityConfig(**kwargs) self.add_entity_config(ent_config) def add_entity_config(self, ent_config, progress_value=0): QApplication.processEvents() if not self._config_mapping.get(ent_config.title(), ""): fk_mapper = self._create_fk_mapper(ent_config) self.tabWidget.addTab(fk_mapper, ent_config.title()) self._config_mapping[ent_config.title()] = ent_config #Force list of column names to be loaded if self.tabWidget.currentIndex() != 0: self.tabWidget.setCurrentIndex(0) else: self.on_tab_index_changed(0) self.progress.setValue(progress_value) def on_tab_index_changed(self, index): if index == -1: return config = self.config(index) if not config is None: #Set data source name self._data_source = config.data_source() def on_use_template_datasource(self, state): if state == Qt.Checked: self.tabWidget.setEnabled(False) self.chkUseOutputFolder.setEnabled(False) self.chkUseOutputFolder.setChecked(False) elif state == Qt.Unchecked: self.tabWidget.setEnabled(True) self.chkUseOutputFolder.setEnabled(True) self.chkUseOutputFolder.setChecked(False) self.on_tab_index_changed(self.tabWidget.currentIndex()) def onShowOutputFolder(self): reg_config = RegistryConfig() path = reg_config.read([COMPOSER_OUTPUT]) output_path = path.get(COMPOSER_OUTPUT,'') # windows if sys.platform.startswith('win32'): os.startfile(output_path) # *nix systems if sys.platform.startswith('linux'): subprocess.Popen(['xdg-open', output_path]) # macOS if sys.platform.startswith('darwin'): subprocess.Popen(['open', output_path]) def notification_bar(self): """ :return: Returns an instance of the notification bar. :rtype: NotificationBar """ return self._notif_bar def config(self, index): """ Returns the configuration for the current mapper in the tab widget. """ tab_key = self.tabWidget.tabText(index) return self._config_mapping.get(tab_key, None) def current_config(self): """ Returns the configuration corresponding to the current widget in the tab. """ return self.config(self.tabWidget.currentIndex()) def _load_model_columns(self, config): """ Load model columns into the view for specifying file output name. Only those columns of display type variants will be used. """ model_attr_mapping = OrderedDict() for c in config.data_source_columns(): model_attr_mapping[c] = format_name(c) self.lstDocNaming.load_mapping(model_attr_mapping) def _load_data_source_columns(self, entity): """ Load the columns of a data source for use in the file naming. """ table_cols = entity_display_columns(entity, True) attr_mapping = OrderedDict() for c, header in table_cols.iteritems(): attr_mapping[c] = header self.lstDocNaming.load_mapping(attr_mapping) def _create_fk_mapper(self, config): fk_mapper = ForeignKeyMapper( config.ds_entity, self.tabWidget, self._notif_bar, enable_list=True, can_filter=True, plugin=self.plugin ) fk_mapper.setDatabaseModel(config.model()) fk_mapper.setSupportsList(True) fk_mapper.setDeleteonRemove(False) fk_mapper.setNotificationBar(self._notif_bar) return fk_mapper def onSelectTemplate(self): """ Slot raised to load the template selector dialog. """ current_config = self.current_config() if current_config is None: msg = QApplication.translate( 'DocumentGeneratorDialog', 'An error occured while trying to determine the data source ' 'for the current entity.\nPlease check your current profile ' 'settings.' ) QMessageBox.critical( self, QApplication.translate( 'DocumentGeneratorDialog', 'Template Selector' ), msg ) return #Set the template selector to only load those templates that # reference the current data source. filter_table = current_config.data_source() templateSelector = TemplateDocumentSelector( self, filter_data_source=filter_table ) if templateSelector.exec_() == QDialog.Accepted: docName,docPath = templateSelector.documentMapping() self.lblTemplateName.setText(docName) self._docTemplatePath = docPath if filter_table != self.last_data_source: #Load template data source fields self._load_template_datasource_fields() def _load_template_datasource_fields(self): #If using template data source template_doc, err_msg = self._doc_generator.template_document(self._docTemplatePath) if template_doc is None: QMessageBox.critical(self, "Error Generating documents", QApplication.translate("DocumentGeneratorDialog", "Error Generating documents - %s"%(err_msg))) return composer_ds, err_msg = self._doc_generator.composer_data_source(template_doc) if composer_ds is None: QMessageBox.critical(self, "Error Generating documents", QApplication.translate("DocumentGeneratorDialog", "Error Generating documents - %s"%(err_msg))) return #Load data source columns self._data_source = self.current_config().data_source() self.ds_entity = self.curr_profile.entity_by_name( self._data_source ) self._load_data_source_columns(self.ds_entity) def onToggledOutputFolder(self,state): """ Slot raised to enable/disable the generated output documents to be written to the plugin composer output folder using the specified naming convention. """ if state == Qt.Checked: self.gbDocNaming.setEnabled(True) elif state == Qt.Unchecked: self.gbDocNaming.setEnabled(False) def reset(self, success_status=False): """ Clears/resets the dialog from user-defined options. """ self._docTemplatePath = "" self._data_source = "" self.lblTemplateName.setText("") # reset form only if generation is successful if success_status: fk_table_view = self.tabWidget.currentWidget().\ findChild(QTableView) while fk_table_view.model().rowCount() > 0: fk_table_view.model().rowCount(0) fk_table_view.model().removeRow(0) if self.tabWidget.count() > 0 and \ not self.chk_template_datasource.isChecked(): self.on_tab_index_changed(0) if self.cboImageType.count() > 0: self.cboImageType.setCurrentIndex(0) def onToggleExportImage(self, state): """ Slot raised to enable/disable the image formats combobox. """ if state: self.cboImageType.setEnabled(True) else: self.cboImageType.setEnabled(False) def onGenerate(self): """ Slot raised to initiate the certificate generation process. """ self._notif_bar.clear() success_status = True config = self.current_config() self.last_data_source = config.data_source() if config is None: self._notif_bar.insertErrorNotification(QApplication.translate("DocumentGeneratorDialog", \ "The entity configuration could not be extracted.")) return #Get selected records and validate records = self.tabWidget.currentWidget().entities() if self.chk_template_datasource.isChecked(): records = self._dummy_template_records() if len(records) == 0: self._notif_bar.insertErrorNotification(QApplication.translate("DocumentGeneratorDialog", \ "Please load at least one entity record")) return if not self._docTemplatePath: self._notif_bar.insertErrorNotification(QApplication.translate("DocumentGeneratorDialog", \ "Please select a document template to use")) return documentNamingAttrs = self.lstDocNaming.selectedMappings() if self.chkUseOutputFolder.checkState() == Qt.Checked and len(documentNamingAttrs) == 0: self._notif_bar.insertErrorNotification(QApplication.translate("DocumentGeneratorDialog", \ "Please select at least one field for naming the output document")) return #Set output file properties if self.rbExpImage.isChecked(): outputMode = DocumentGenerator.Image fileExtension = self.cboImageType.currentText() saveAsText = "Image File" else: outputMode = DocumentGenerator.PDF fileExtension = "pdf" saveAsText = "PDF File" #Show save file dialog if not using output folder if self.chkUseOutputFolder.checkState() == Qt.Unchecked: docDir = source_document_location() if self._outputFilePath: fileInfo = QFileInfo(self._outputFilePath) docDir = fileInfo.dir().path() self._outputFilePath = QFileDialog.getSaveFileName(self, QApplication.translate("DocumentGeneratorDialog", "Save Document"), docDir, "{0} (*.{1})".format( QApplication.translate("DocumentGeneratorDialog", saveAsText), fileExtension)) if not self._outputFilePath: self._notif_bar.insertErrorNotification( QApplication.translate("DocumentGeneratorDialog", "Process aborted. No output file was specified.")) return #Include extension in file name self._outputFilePath = self._outputFilePath #+ "." + fileExtension else: #Multiple files to be generated. pass self._doc_generator.set_link_field(config.link_field()) self._doc_generator.clear_attr_value_formatters() if not self.chk_template_datasource.isChecked(): #Apply cell formatters for naming output files self._doc_generator.set_attr_value_formatters(config.formatters()) entity_field_name = "id" #Iterate through the selected records progressDlg = QProgressDialog(self) progressDlg.setMaximum(len(records)) try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) for i, record in enumerate(records): progressDlg.setValue(i) if progressDlg.wasCanceled(): success_status = False break #User-defined location if self.chkUseOutputFolder.checkState() == Qt.Unchecked: status,msg = self._doc_generator.run(self._docTemplatePath, entity_field_name, record.id, outputMode, filePath = self._outputFilePath) self._doc_generator.clear_temporary_layers() #Output folder location using custom naming else: status, msg = self._doc_generator.run(self._docTemplatePath, entity_field_name, record.id, outputMode, dataFields = documentNamingAttrs, fileExtension = fileExtension, data_source = self.ds_entity.name) self._doc_generator.clear_temporary_layers() if not status: result = QMessageBox.warning(self, QApplication.translate("DocumentGeneratorDialog", "Document Generate Error"), msg, QMessageBox.Ignore | QMessageBox.Abort) if result == QMessageBox.Abort: progressDlg.close() success_status = False #Restore cursor QApplication.restoreOverrideCursor() return #If its the last record and user has selected to ignore if i+1 == len(records): progressDlg.close() success_status = False #Restore cursor QApplication.restoreOverrideCursor() return else: progressDlg.setValue(len(records)) QApplication.restoreOverrideCursor() QMessageBox.information(self, QApplication.translate("DocumentGeneratorDialog", "Document Generation Complete"), QApplication.translate("DocumentGeneratorDialog", "Document generation has successfully completed.") ) except Exception as ex: LOGGER.debug(str(ex)) err_msg = sys.exc_info()[1] QApplication.restoreOverrideCursor() QMessageBox.critical( self, "STDM", QApplication.translate( "DocumentGeneratorDialog", "Error Generating documents - %s"%(err_msg) ) ) success_status = False #Reset UI self.reset(success_status) def _dummy_template_records(self): """ This is applied when records from a template data source are to be used to generate the documents where no related entity will be used to filter matching records in the data source. The iteration of the data source records will be done internally within the DocumentGenerator class. """ class _DummyRecord: id = 1 return [_DummyRecord()] def showEvent(self, event): """ Notifies if there are not entity configuration objects defined. :param event: Window event :type event: QShowEvent """ QTimer.singleShot(500, self.check_entity_config) return QDialog.showEvent(self, event) def check_entity_config(self): if len(self._config_mapping) == 0: self._notif_bar.clear() msg = QApplication.translate("DocumentGeneratorDialog", "Table " "configurations do not exist or have not been configured properly") self._notif_bar.insertErrorNotification(msg)
class Entity(QWidget): def __init__(self, base_image, size, hp=100, pos=(0, 0), parent=None): super().__init__(parent) self._base_label = QLabel(self) self._base_image = base_image self._size = size self._decor_label = None self._decor_pixmap = None self._hp_max = hp self.__pixmap = None """:type: PyQt4.QtGui.QPixmap""" self.__cord_x = pos[0] self.__cord_y = pos[1] self.__angle = 0 self.__hp_bar = QProgressBar(self) self.__hp_bar.setMaximum(self._hp_max) self.__hp_bar.setValue(self._hp_max) self.__hp_bar.setTextVisible(False) self.__hp_bar.setMaximumSize(size[0], 5) self.setAlignment(Qt.AlignCenter) self.updatePixmap() if _debugging: self.setStyleSheet("border: 1px solid black") @property def health(self): return self.__hp_bar.value() @health.setter def health(self, hp): if hp > self._hp_max: hp = self._hp_max elif hp < 0: hp = 0 self.__hp_bar.setValue(hp) @property def angle(self): return self.__angle @angle.setter def angle(self, angle): self.__angle = angle self.updatePixmap() @property def cord_x(self): return self.__cord_x @cord_x.setter def cord_x(self, cord): self.__cord_x = cord self.move(self.cord_x, self.cord_y) @property def cord_y(self): return self.__cord_y @cord_y.setter def cord_y(self, cord): self.__cord_y = cord self.move(self.cord_x, self.cord_y) def hide_hp_bar(self, bool=False): if bool: self.__hp_bar.hide() else: self.__hp_bar.show() def add_decoration(self, path): if path is None: self._decor_label.deleteLater() self._decor_label = None else: self._decor_label = QLabel(self) self._decor_pixmap = QPixmap(path) # self._decor_pixmap = self._decor_pixmap.scaled(self._size[0], self._size[1]) self._decor_pixmap = self._decor_pixmap.transformed( QTransform().rotate(self.angle)) self._decor_label.setPixmap(self._decor_pixmap) self._decor_label.setAlignment(Qt.AlignCenter) self._decor_label.show() def updatePixmap(self): path = get_asset_path(self._base_image) self.__pixmap = QPixmap(path) self.__pixmap = self.__pixmap.scaled(self._size[0], self._size[1]) self.__pixmap = self.__pixmap.transformed(QTransform().rotate( self.angle)) self._base_label.setPixmap(self.__pixmap) self._base_label.show() # self.setFixedSize(self.__pixmap.width(), self.__pixmap.height()) def setFixedSize(self, x, y): super().setFixedSize(x, y) self._base_label.setFixedSize(x, y) def setAlignment(self, alignment): self._base_label.setAlignment(alignment)
class Qt4SysTrayIcon: def __init__( self ): self.snapshots = snapshots.Snapshots() self.config = self.snapshots.config self.decode = None if len( sys.argv ) > 1: if not self.config.set_current_profile(sys.argv[1]): logger.warning("Failed to change Profile_ID %s" %sys.argv[1], self) self.qapp = qt4tools.create_qapplication(self.config.APP_NAME) translator = qt4tools.get_translator() self.qapp.installTranslator(translator) self.qapp.setQuitOnLastWindowClosed(False) import icon self.icon = icon self.qapp.setWindowIcon(icon.BIT_LOGO) self.status_icon = QSystemTrayIcon(icon.BIT_LOGO) #self.status_icon.actionCollection().clear() self.contextMenu = QMenu() self.menuProfileName = self.contextMenu.addAction(_('Profile: "%s"') % self.config.get_profile_name()) qt4tools.set_font_bold(self.menuProfileName) self.contextMenu.addSeparator() self.menuStatusMessage = self.contextMenu.addAction(_('Done')) self.menuProgress = self.contextMenu.addAction('') self.menuProgress.setVisible(False) self.contextMenu.addSeparator() self.btnDecode = self.contextMenu.addAction(icon.VIEW_SNAPSHOT_LOG, _('decode paths')) self.btnDecode.setCheckable(True) self.btnDecode.setVisible(self.config.get_snapshots_mode() == 'ssh_encfs') QObject.connect(self.btnDecode, SIGNAL('toggled(bool)'), self.onBtnDecode) self.openLog = self.contextMenu.addAction(icon.VIEW_LAST_LOG, _('View Last Log')) QObject.connect(self.openLog, SIGNAL('triggered()'), self.onOpenLog) self.startBIT = self.contextMenu.addAction(icon.BIT_LOGO, _('Start BackInTime')) QObject.connect(self.startBIT, SIGNAL('triggered()'), self.onStartBIT) self.status_icon.setContextMenu(self.contextMenu) self.pixmap = icon.BIT_LOGO.pixmap(24) self.progressBar = QProgressBar() self.progressBar.setMinimum(0) self.progressBar.setMaximum(100) self.progressBar.setValue(0) self.progressBar.setTextVisible(False) self.progressBar.resize(24, 6) self.progressBar.render(self.pixmap, sourceRegion = QRegion(0, -14, 24, 6), flags = QWidget.RenderFlags(QWidget.DrawChildren)) self.first_error = self.config.is_notify_enabled() self.popup = None self.last_message = None self.timer = QTimer() QObject.connect( self.timer, SIGNAL('timeout()'), self.update_info ) self.ppid = os.getppid() def prepare_exit( self ): self.timer.stop() if not self.status_icon is None: self.status_icon.hide() self.status_icon = None if not self.popup is None: self.popup.deleteLater() self.popup = None self.qapp.processEvents() def run( self ): self.status_icon.show() self.timer.start( 500 ) logger.info("[qt4systrayicon] begin loop", self) self.qapp.exec_() logger.info("[qt4systrayicon] end loop", self) self.prepare_exit() def update_info( self ): if not tools.is_process_alive( self.ppid ): self.prepare_exit() self.qapp.exit(0) return message = self.snapshots.get_take_snapshot_message() if message is None and self.last_message is None: message = ( 0, _('Working...') ) if not message is None: if message != self.last_message: self.last_message = message if self.decode: message = (message[0], self.decode.log(message[1])) self.menuStatusMessage.setText('\n'.join(tools.wrap_line(message[1],\ size = 80,\ delimiters = '',\ new_line_indicator = '') \ )) self.status_icon.setToolTip(message[1]) pg = progress.ProgressFile(self.config) if pg.isFileReadable(): pg.load() percent = pg.get_int_value('percent') if percent != self.progressBar.value(): self.progressBar.setValue(percent) self.progressBar.render(self.pixmap, sourceRegion = QRegion(0, -14, 24, 6), flags = QWidget.RenderFlags(QWidget.DrawChildren)) self.status_icon.setIcon(QIcon(self.pixmap)) self.menuProgress.setText(' | '.join(self.getMenuProgress(pg)) ) self.menuProgress.setVisible(True) else: self.status_icon.setIcon(self.icon.BIT_LOGO) self.menuProgress.setVisible(False) def getMenuProgress(self, pg): d = (('sent', _('Sent:')), \ ('speed', _('Speed:')),\ ('eta', _('ETA:')) ) for key, txt in d: value = pg.get_str_value(key, '') if not value: continue yield txt + ' ' + value def onStartBIT(self): profileID = self.config.get_current_profile() cmd = ['backintime-qt4',] if not profileID == '1': cmd += ['--profile-id', profileID] proc = subprocess.Popen(cmd) def onOpenLog(self): dlg = logviewdialog.LogViewDialog(self, systray = True) dlg.decode = self.decode dlg.cb_decode.setChecked(self.btnDecode.isChecked()) dlg.exec_() def onBtnDecode(self, checked): if checked: self.decode = encfstools.Decode(self.config) self.last_message = None self.update_info() else: self.decode = None
def __init__(self, parent=None): QWidget.__init__(self, parent) self.home_url = None self.zoom_factor = 1.0 self.webview = WebView(self) self.connect(self.webview, SIGNAL("loadFinished(bool)"), self.load_finished) self.connect(self.webview, SIGNAL("titleChanged(QString)"), self.setWindowTitle) self.connect(self.webview, SIGNAL("urlChanged(QUrl)"), self.url_changed) previous_button = create_toolbutton( self, get_icon("previous.png"), tip=self.tr("Previous"), triggered=self.webview.back ) next_button = create_toolbutton(self, get_icon("next.png"), tip=self.tr("Next"), triggered=self.webview.forward) home_button = create_toolbutton(self, get_icon("home.png"), tip=self.tr("Home"), triggered=self.go_home) zoom_out_button = create_toolbutton( self, get_icon("zoom_out.png"), tip=self.tr("Zoom out"), triggered=self.zoom_out ) zoom_in_button = create_toolbutton( self, get_icon("zoom_in.png"), tip=self.tr("Zoom in"), triggered=self.zoom_in ) refresh_button = create_toolbutton(self, get_icon("reload.png"), tip=self.tr("Reload"), triggered=self.reload) stop_button = create_toolbutton(self, get_icon("stop.png"), tip=self.tr("Stop"), triggered=self.webview.stop) stop_button.setEnabled(False) self.connect(self.webview, SIGNAL("loadStarted()"), lambda: stop_button.setEnabled(True)) self.connect(self.webview, SIGNAL("loadFinished(bool)"), lambda: stop_button.setEnabled(False)) progressbar = QProgressBar(self) progressbar.setTextVisible(False) progressbar.hide() self.connect(self.webview, SIGNAL("loadStarted()"), progressbar.show) self.connect(self.webview, SIGNAL("loadProgress(int)"), progressbar.setValue) self.connect(self.webview, SIGNAL("loadFinished(bool)"), progressbar.hide) label = QLabel(self.get_label()) self.url_combo = UrlComboBox(self) self.connect(self.url_combo, SIGNAL("valid(bool)"), self.url_combo_activated) self.connect(self.webview, SIGNAL("iconChanged()"), self.icon_changed) self.find_widget = FindReplace(self) self.find_widget.set_editor(self.webview) self.find_widget.hide() find_button = create_toolbutton( self, icon="find.png", tip=translate("FindReplace", "Find text"), toggled=self.toggle_find_widget ) self.connect(self.find_widget, SIGNAL("visibility_changed(bool)"), find_button.setChecked) hlayout = QHBoxLayout() for widget in ( previous_button, next_button, home_button, find_button, label, self.url_combo, zoom_out_button, zoom_in_button, refresh_button, progressbar, stop_button, ): hlayout.addWidget(widget) layout = QVBoxLayout() layout.addLayout(hlayout) layout.addWidget(self.webview) layout.addWidget(self.find_widget) self.setLayout(layout)
class ViewDataTools(QMainWindow): def __init__(self, parent=None): super(ViewDataTools, self).__init__(parent) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # DATATOOLS WINDOWS: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ self.setWindowTitle(ui_strings.DATATOOLS_TITLE) self._width = 680 self._height = 560 self._left_margin = 10 self.resize(self._width, self._height) size_policy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) size_policy.setHorizontalStretch(0) size_policy.setVerticalStretch(0) size_policy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) self.setSizePolicy(size_policy) self.setMinimumSize(QtCore.QSize(self._width, self._height)) self.setMaximumSize(QtCore.QSize(self._width, self._height)) self.setWindowIcon(QIcon(resources.ICON_LOGO)) # central widget self.central_widget = QWidget(self) # DataTools description self.lbl_description = QLabel(self.central_widget) self.lbl_description.setGeometry(QtCore.QRect(0, 0, self._width, 30)) self.lbl_description.setAlignment(QtCore.Qt.AlignCenter) self.lbl_description.setText(ui_strings.DATATOOLS_DESCRIPTION) # group input files self.group_input_file = QGroupBox(self.central_widget) self.group_input_file.setGeometry( QtCore.QRect(self._left_margin, 30, 660, 80)) self.group_input_file.setTitle(ui_strings.DATATOOLS_GROUP_INPUT) # frame input files self.frame_inputs = QFrame(self.group_input_file) self.frame_inputs.setGeometry( QtCore.QRect(self._left_margin, 0, 270, 80)) self.frame_inputs.setFrameShape(QFrame.StyledPanel) self.frame_inputs.setFrameShadow(QFrame.Raised) # label input type self.lbl_input_type = QLabel(self.frame_inputs) self.lbl_input_type.setGeometry(QtCore.QRect(20, 20, 60, 15)) self.lbl_input_type.setText(ui_strings.DATATOOLS_INPUT_TYPE) # button xls self.btn_xls = QToolButton(self.frame_inputs) self.btn_xls.setGeometry(QtCore.QRect(20, 35, 35, 35)) icon_xls = QIcon() icon_xls.addPixmap(QPixmap(resources.ICON_XLS), QIcon.Normal, QIcon.Off) self.btn_xls.setIcon(icon_xls) self.btn_xls.setIconSize(QtCore.QSize(24, 24)) self.btn_xls.setCheckable(True) self.btn_xls.setAutoExclusive(True) self.btn_xls.setObjectName("xls_button") # button csv self.btn_csv = QToolButton(self.frame_inputs) self.btn_csv.setGeometry(QtCore.QRect(60, 35, 35, 35)) icon_csv = QIcon() icon_csv.addPixmap(QPixmap(resources.ICON_CSV), QIcon.Normal, QIcon.Off) self.btn_csv.setIcon(icon_csv) self.btn_csv.setIconSize(QtCore.QSize(24, 24)) self.btn_csv.setCheckable(True) self.btn_csv.setAutoExclusive(True) self.btn_csv.setObjectName("csv_button") # checkbox csv with headers self.chk_csv_headers = QCheckBox(ui_strings.DATATOOLS_WITH_HEADERS, self.frame_inputs) self.chk_csv_headers.setGeometry(QtCore.QRect(100, 45, 110, 15)) self.chk_csv_headers.setEnabled(False) # TextEdit + PushButton (FindFolder) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # lbl sheet name self.lbl_file_path = QLabel(self.group_input_file) self.lbl_file_path.setGeometry(QtCore.QRect(250, 20, 120, 15)) self.lbl_file_path.setText(ui_strings.DATATOOLS_SELECT_FILE) self.txt_file = QLineEdit(self.group_input_file) self.txt_file.setGeometry(QtCore.QRect(250, 35, 160, 20)) self.txt_file.setReadOnly(True) self.btn_path = QPushButton(self.group_input_file) self.btn_path.setGeometry(QtCore.QRect(410, 34, 50, 22)) self.btn_path.setText(ui_strings.DATATOOLS_SELECT_BUTTON) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # lbl sheet name self.lbl_sheet_name = QLabel(self.group_input_file) self.lbl_sheet_name.setGeometry(QtCore.QRect(500, 20, 120, 15)) self.lbl_sheet_name.setText(ui_strings.DATATOOLS_SHEET_NAME) # Combobox select sheet - initially does not contain values self.cbo_sheet = QComboBox(self.group_input_file) self.cbo_sheet.setGeometry(QtCore.QRect(500, 35, 130, 20)) # data grid to visualize error messages self.tbl_errors = QTableWidget(self.central_widget) self.tbl_errors.setGeometry( QtCore.QRect(self._left_margin, 420, 660, 100)) # data grid to visualize those records with errors. self.tbl_uploaded_data = QTableWidget(self.central_widget) self.tbl_uploaded_data.setGeometry( QtCore.QRect(self._left_margin, 120, 500, 220)) # group run options self.group_run_options = QGroupBox(self.central_widget) self.group_run_options.setGeometry(QtCore.QRect(520, 120, 150, 220)) self.group_run_options.setTitle(ui_strings.DATATOOLS_GROUP_RUN) # Errors summary: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # group summary errors self.group_errors = QGroupBox(self.central_widget) self.group_errors.setGeometry( QtCore.QRect(self._left_margin, 350, 660, 60)) self.group_errors.setTitle(ui_strings.DATATOOLS_HEADER_ERRORS) # lbl records self.lbl_records = QLabel(self.group_errors) self.lbl_records.setGeometry(QtCore.QRect(165, 15, 80, 15)) self.lbl_records.setAlignment(QtCore.Qt.AlignCenter) self.lbl_records.setText(ui_strings.DATATOOLS_RECORDS) self.txt_records = QLineEdit(self.group_errors) self.txt_records.setGeometry(QtCore.QRect(165, 30, 80, 20)) self.txt_records.setAlignment(QtCore.Qt.AlignCenter) self.txt_records.setReadOnly(True) # lbl errors self.lbl_errors = QLabel(self.group_errors) self.lbl_errors.setGeometry(QtCore.QRect(275, 15, 80, 15)) self.lbl_errors.setAlignment(QtCore.Qt.AlignCenter) self.lbl_errors.setText(ui_strings.DATATOOLS_ERRORS) self.txt_errors = QLineEdit(self.group_errors) self.txt_errors.setGeometry(QtCore.QRect(275, 30, 80, 20)) self.txt_errors.setAlignment(QtCore.Qt.AlignCenter) self.txt_errors.setReadOnly(True) # lbl time self.lbl_time = QLabel(self.group_errors) self.lbl_time.setGeometry(QtCore.QRect(385, 15, 80, 15)) self.lbl_time.setAlignment(QtCore.Qt.AlignCenter) self.lbl_time.setText(ui_strings.DATATOOLS_TIME) self.txt_time = QLineEdit(self.group_errors) self.txt_time.setGeometry(QtCore.QRect(385, 30, 80, 20)) self.txt_time.setAlignment(QtCore.Qt.AlignCenter) self.txt_time.setReadOnly(True) # history button self.btn_history = QToolButton(self.group_errors) self.btn_history.setGeometry(QtCore.QRect(500, 25, 100, 25)) icon_history = QIcon() icon_history.addPixmap(QPixmap(resources.ICON_HISTORY), QIcon.Normal, QIcon.Off) self.btn_history.setIcon(icon_history) self.btn_history.setIconSize(QtCore.QSize(20, 20)) self.btn_history.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) self.btn_history.setText(ui_strings.DATATOOLS_HISTORY) self.btn_history.setCheckable(True) self.btn_history.setAutoExclusive(True) self.btn_history.setObjectName("history_button") # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # btn data uploader self.btn_data_uploader = QPushButton( ui_strings.DATATOOLS_DATA_UPLOADER, self.group_run_options) self.btn_data_uploader.setGeometry(QtCore.QRect(10, 120, 90, 25)) self.btn_data_uploader.setCheckable(True) self.btn_data_uploader.setAutoExclusive(True) self.btn_data_uploader.setFlat(False) # btn data testing self.btn_data_testing = QPushButton(ui_strings.DATATOOLS_DATA_TESTING, self.group_run_options) self.btn_data_testing.setEnabled(False) self.btn_data_testing.setGeometry(QtCore.QRect(10, 150, 90, 25)) self.btn_data_testing.setCheckable(True) self.btn_data_testing.setAutoExclusive(True) # btn data to database self.btn_data_db = QPushButton(ui_strings.DATATOOLS_DATA_DB, self.group_run_options) self.btn_data_db.setEnabled(False) self.btn_data_db.setGeometry(QtCore.QRect(10, 179, 91, 23)) self.btn_data_db.setCheckable(True) self.btn_data_db.setAutoExclusive(True) # frame run options self.frame_run = QFrame(self.group_run_options) self.frame_run.setGeometry(QtCore.QRect(10, 30, 130, 80)) self.frame_run.setFrameShape(QFrame.StyledPanel) self.frame_run.setFrameShadow(QFrame.Raised) # option process until first error self.rbtn_process_error = QRadioButton( ui_strings.DATATOOLS_PROCESS_ERROR, self.frame_run) self.rbtn_process_error.setGeometry(QtCore.QRect(0, 0, 150, 20)) # option process all data self.rbtn_process_all = QRadioButton(ui_strings.DATATOOLS_PROCESS_ALL, self.frame_run) self.rbtn_process_all.setGeometry(QtCore.QRect(0, 20, 150, 30)) # checkbox to filter by records with errors. #self.chk_filter_errors = QCheckBox(ui_strings.DATATOOLS_FILTER_ERRORS, self.frame_run) #self.chk_filter_errors.setGeometry(QtCore.QRect(0, 50, 100, 15)) #self.chk_filter_errors.setEnabled(False) # icons -> pass - error: Initially are empty labels # if not started -> ICON_MINI_WAIT # if error -> ICON_DELETE # if pass -> ICON_CHECK # state icon data uploader self.lbl_state_du = QLabel(self.group_run_options) self.lbl_state_du.setGeometry(QtCore.QRect(110, 120, 20, 20)) self.lbl_state_du.setPixmap(QPixmap(resources.ICON_MINI_WAIT)) self.lbl_state_du.setScaledContents(True) # state icon data to database self.lbl_state_dt = QLabel(self.group_run_options) self.lbl_state_dt.setGeometry(QtCore.QRect(110, 150, 20, 20)) self.lbl_state_dt.setPixmap(QPixmap(resources.ICON_MINI_WAIT)) self.lbl_state_dt.setScaledContents(True) # state icon data testing self.lbl_state_db = QLabel(self.group_run_options) self.lbl_state_db.setGeometry(QtCore.QRect(110, 180, 20, 20)) self.lbl_state_db.setPixmap(QPixmap(resources.ICON_MINI_WAIT)) self.lbl_state_db.setScaledContents(True) # progress bar self.progress_bar = QProgressBar(self.central_widget) self.progress_bar.setGeometry( QtCore.QRect(self._left_margin, 530, 660, 15)) self.progress_bar.setMaximum(100) self.progress_bar.setProperty("value", 0) self.progress_bar.setTextVisible(True) self.progress_bar.setOrientation(QtCore.Qt.Horizontal) self.progress_bar.setInvertedAppearance(False) self.progress_bar.setTextDirection(QProgressBar.TopToBottom) self.setCentralWidget(self.central_widget)
class HomeWidget(BaseWidget): def __init__(self, parent=0, *args, **kwargs): super(HomeWidget, self).__init__(parent=parent, *args, **kwargs) # inputs self._json_fpath = None self._destination_folder = self.guess_destination() self._from_date, self._to_date = self.guess_dates() self.nb_instances = 0 self.setup_ui() @property def json_fpath(self): return self._json_fpath @json_fpath.setter def json_fpath(self, value): self._json_fpath = value self.json_select_button.setText( value if value else "Sélection fichier JSON ODK Aggregate ...") self.update_start_button_state() @property def destination_folder(self): return self._destination_folder @destination_folder.setter def destination_folder(self, value): self._destination_folder = value self.destination_select_button.setText(self.destination_folder) self.update_start_button_state() @property def from_date(self): return self._from_date @from_date.setter def from_date(self, value): self._from_date = value self.from_date_selector.setPythonDate(self.from_date) self.update_start_button_state() @property def to_date(self): return self._to_date @to_date.setter def to_date(self, value): self._to_date = value self.to_date_selector.setPythonDate(self.to_date) self.update_start_button_state() def setup_ui(self): # json file selector self.json_groupbox = QGroupBox("Export ODK Aggregate") layout = QGridLayout() self.json_select_button = PushButton("", self) self.json_select_button.clicked.connect(self.json_selector_clicked) layout.addWidget(self.json_select_button, 1, 0) self.json_groupbox.setLayout(layout) # destination folder selector self.destination_groupbox = QGroupBox("Destination") layout = QGridLayout() self.destination_select_button = PushButton( self.destination_folder, self) self.destination_select_button.clicked.connect( self.destination_selector_clicked) layout.addWidget(self.destination_select_button, 1, 0) self.destination_groupbox.setLayout(layout) # period calendars today = datetime.date.today() self.period_groupbox = QGroupBox("Période") layout = QGridLayout() self.from_date_selector = DateTimeEdit(QDate(self.from_date)) self.from_date_selector.dateChanged.connect(self.from_date_changed) self.from_date_selector.setMaximumDate(self.to_date) self.to_date_selector = DateTimeEdit(QDate(self.to_date)) self.to_date_selector.dateChanged.connect(self.to_date_changed) self.to_date_selector.setMinimumDate(self.from_date) self.to_date_selector.setMaximumDate(today) layout.addWidget(Label("Du"), 2, 0) layout.addWidget(self.from_date_selector, 3, 0) layout.addWidget(Label("Au"), 2, 1) layout.addWidget(self.to_date_selector, 3, 1) self.period_groupbox.setLayout(layout) # start button self.start_button = PushButton("Démarrer") self.start_button.setEnabled(False) self.start_button.setDefault(True) self.start_button.clicked.connect(self.export_requested) # cancel button self.cancel_button = CancelPushButton("Annuler") self.cancel_button.setEnabled(False) self.cancel_button.clicked.connect(self.cancel_export) # grid self.gridBox = QGridLayout() self.gridBox.addWidget(self.json_groupbox, 0, 0, 1, 2) self.gridBox.addWidget(self.destination_groupbox, 1, 0, 1, 2) self.gridBox.addWidget(self.period_groupbox, 2, 0, 1, 2) self.gridBox.addWidget(self.start_button, 3, 0) self.gridBox.addWidget(self.cancel_button, 3, 1) vBox = QVBoxLayout() vBox.addLayout(self.gridBox) self.setLayout(vBox) self.json_fpath = None def guess_destination(self, root_only=False): start_folder = os.path.join(os.path.expanduser("~"), 'Desktop') if root_only: return start_folder return os.path.join(start_folder, Constants.DEFAULT_FOLDER_NAME) def guess_dates(self): to = datetime.date.today() start = to - datetime.timedelta(days=15) return start, to def update_start_button_state(self): self.start_button.setEnabled( all([self.json_fpath, self.destination_folder, self.from_date, self.to_date])) def json_selector_clicked(self): # self.file_name_field.setText("Aucun fichier") self.start_button.setEnabled(False) fpath = QFileDialog.getOpenFileName( self, "Choisir le fichier d'export JSON", self.json_fpath or self.guess_destination(root_only=True), "Fichiers JSON (*.json)") self.json_fpath = os.path.abspath(fpath) if fpath else self.json_fpath def destination_selector_clicked(self): path = QFileDialog.getExistingDirectory( self, "Sélectionner le dossier", self.destination_folder) if path: self.destination_folder = os.path.abspath(path) def from_date_changed(self, new_date): self.from_date = new_date.toPyDate() def to_date_changed(self, new_date): self.to_date = new_date.toPyDate() def export_requested(self): logger.debug("export_requested") self.parentWidget().exporter.check_aggregate_presence() def display_missing_aggregate_confirmation(self): if MissingODKConfirmationWidget().exec_() == QDialog.Accepted: self.start_export() def start_export(self): logger.debug("Lancement ...") self.add_progressbar() self.start_button.setEnabled(False) self.cancel_button.setEnabled(True) self.parentWidget().exporter.parse( destination_folder=self.destination_folder, fname=self.json_fpath, from_date=self.from_date, to_date=self.to_date) def cancel_export(self): logger.debug("cancel") self.parentWidget().exporter.cancel() def update_progress_label(self, index): progression_label = "Export en cours... {index}/{total}" \ .format(index=index, total=self.nb_instances) self.progression_groupbox.setTitle(progression_label) def add_progressbar(self): self.progressbar = QProgressBar() self.progressbar.setMinimum(0) self.progressbar.setMaximum(100) self.progressbar.reset() self.progressbar.setTextVisible(False) self.progression_groupbox = QGroupBox("...") progress_layout = QHBoxLayout() progress_layout.addWidget(self.progressbar) self.progression_groupbox.setLayout(progress_layout) self.gridBox.addWidget(self.progression_groupbox, 4, 0, 1, 2) def remove_progressbar(self): self.progression_groupbox.deleteLater() self.progression_groupbox = None @pyqtSlot(bool, int, str) def parsing_ended(self, succeeded, nb_instances, error_message): if succeeded: self.nb_instances = nb_instances @pyqtSlot(str, int) def exporting_instance(self, ident, index): logger.debug("exporting_instance") self.update_progress_label(index) @pyqtSlot(bool, int) def instance_completed(self, succeeded, index): logger.debug("instance_completed") pc = index * 100 // self.nb_instances self.progressbar.setValue(pc) @pyqtSlot(int, int, int, int) def export_ended(self, nb_instances_successful, nb_instances_failed, nb_medias_successful, nb_medias_failed): self.cancel_button.setEnabled(False) self.start_button.setEnabled(True) @pyqtSlot() def export_canceled(self): self.remove_progressbar() self.cancel_button.setEnabled(False) self.start_button.setEnabled(True) QMessageBox.warning(self, "Export annulé !", "L'export en cours a été annulé.\n" "Tous les fichiers créés ont été supprimés", QMessageBox.Ok, QMessageBox.NoButton) if self.parentWidget().is_exiting: self.parentWidget().do_close()
class Ui_RightWidget(object): def setupUi(self, RightWidget, server): RightWidget.setMinimumHeight(500) main_layout = QVBoxLayout(RightWidget) main_layout.setContentsMargins(0, 0, 0, 0) main_layout.setSpacing(10) # We hide all the main elements, to allow the proper viewer to enable # (only) the elements that uses. if hasattr(server, 'wild_chars'): self.text_map = QTextEdit() self.text_map.setObjectName('text_map') self.text_map.setVisible(False) self.text_map.setFocusPolicy(Qt.NoFocus) self.text_map.setAutoFillBackground(True) self.text_map.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.text_map.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.text_map.setUndoRedoEnabled(False) self.text_map.setReadOnly(True) # for some unknown reason, the fontmetrics of the text map is wrong # if the font is set with a global stylesheet, so we set it on the # specific widget. self.text_map.setStyleSheet("QTextEdit { font: 13px \"Courier\";}") main_layout.addWidget(self.text_map) # We calculate the map area size using the size of the font used. We # assume that the font is a monospace ones. font_metrics = self.text_map.fontMetrics() self.text_map.setFixedWidth(font_metrics.width('#' * server.map_width)) self.text_map.setFixedHeight(font_metrics.height() * server.map_height) # The rightwidget width is determined by the map area size RightWidget.setMinimumWidth(self.text_map.width()) else: RightWidget.setMinimumWidth(220) self.box_status = QWidget() self.box_status.setVisible(False) main_layout.addWidget(self.box_status) status_layout = QGridLayout(self.box_status) status_layout.setContentsMargins(5, 5, 5, 0) status_layout.setHorizontalSpacing(0) status_layout.setVerticalSpacing(15) label_health = QLabel() label_health.setMinimumWidth(80) label_health.setText(QApplication.translate("RightWidget", "Health")) status_layout.addWidget(label_health, 0, 0) self.bar_health = QProgressBar() self.bar_health.setObjectName("bar_health") self.bar_health.setFixedHeight(22) self.bar_health.setProperty("value", QVariant(100)) self.bar_health.setTextVisible(False) status_layout.addWidget(self.bar_health, 0, 1) label_mana = QLabel() label_mana.setMinimumWidth(80) label_mana.setText(QApplication.translate("RightWidget", "Mana")) status_layout.addWidget(label_mana, 1, 0) self.bar_mana = QProgressBar() self.bar_mana.setObjectName("bar_mana") self.bar_mana.setFixedHeight(22) self.bar_mana.setProperty("value", QVariant(100)) self.bar_mana.setTextVisible(False) status_layout.addWidget(self.bar_mana, 1, 1) label_movement = QLabel() label_movement.setMinimumWidth(80) label_movement.setText(QApplication.translate("RightWidget", "Movement")) status_layout.addWidget(label_movement, 2, 0) self.bar_movement = QProgressBar() self.bar_movement.setObjectName("bar_movement") self.bar_movement.setFixedHeight(22) self.bar_movement.setProperty("value", QVariant(100)) self.bar_movement.setTextVisible(False) status_layout.addWidget(self.bar_movement, 2, 1) main_layout.addStretch()