示例#1
2
class MenuWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.href = '/top/'
        self.file_name = FILE_NAME + '.json'
        self.window2 = None
        self.create_main_window()

    def create_main_window(self):

        lbl1 = QLabel("Choose needed section", self)
        lbl1.setGeometry(40, 0, 200, 35)

        self.sections_combo = QComboBox(self)
        for ref in _SECTIONS_REF:
            self.sections_combo.addItem(ref)
        self.sections_combo.setGeometry(40, 35, 200, 35)

        lbl2 = QLabel("Choose needed format", self)
        lbl2.setGeometry(40, 70, 200, 35)

        self.format_combo = QComboBox(self)
        for form in _FORMAT:
            self.format_combo.addItem(form)
        self.format_combo.setGeometry(40, 105, 200, 35)

        self.sections_combo.activated[str].connect(self.sections_combo_Activated)
        self.sections_combo.setCurrentIndex(int(self.sections_combo.findText('За сутки')))

        self.format_combo.activated[str].connect(self.format_combo_Activated)
        self.format_combo.setCurrentIndex(int(self.format_combo.findText('JSON')))

        btn1 = QPushButton("GO", self)
        btn1.setGeometry(40, 140, 200, 35)

        btn1.clicked.connect(self.buttonClicked)

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('Main')
        self.show()

    def buttonClicked(self):
        pars = Parser()

        if self.window2 is None:
            self.window2 = OutputWindow(str(pars.parse_site(self.href, self.file_name)))
        self.window2.show()
        self.close()

    def sections_combo_Activated(self, text):
        self.href = _SECTIONS_REF.get(text)

    def format_combo_Activated(self, text):
        self.file_name = FILE_NAME + _FORMAT.get(text)
示例#2
0
class FormComboWidget(QWidget):
    def __init__(self, datalist, comment="", parent=None):
        QWidget.__init__(self, parent)
        layout = QVBoxLayout()
        self.setLayout(layout)
        self.combobox = QComboBox()
        layout.addWidget(self.combobox)
        
        self.stackwidget = QStackedWidget(self)
        layout.addWidget(self.stackwidget)
        self.combobox.currentIndexChanged[int].connect(self.stackwidget,setCurrentIndex)
        
        self.widgetlist = []
        for data, title, comment in datalist:
            self.combobox.addItem(title)
            widget = FormWidget(data, comment=comment, parent=self)
            self.stackwidget.addWidget(widget)
            self.widgetlist.append(widget)
            
    def setup(self):
        for widget in self.widgetlist:
            widget.setup()

    def get(self):
        return [ widget.get() for widget in self.widgetlist]
示例#3
0
class DistanceUSV2(COMCUPluginBase):
    def __init__(self, *args):
        super().__init__(BrickletDistanceUSV2, *args)

        self.dist = self.device

        self.cbe_distance = CallbackEmulator(self.dist.get_distance,
                                             None,
                                             self.cb_distance,
                                             self.increase_error_count)

        self.current_distance = CurveValueWrapper()

        plots = [('Distance', Qt.red, self.current_distance, '{:.1f} cm'.format)]
        self.plot_widget = PlotWidget('Distance [cm]', plots, y_resolution=1.0)


        self.update_rate_label = QLabel('Update Rate:')
        self.update_rate_combo = QComboBox()
        self.update_rate_combo.addItem(" 2 Hz")
        self.update_rate_combo.addItem("10 Hz")

        self.update_rate_combo.currentIndexChanged.connect(self.new_update_rate)

        hlayout = QHBoxLayout()
        hlayout.addWidget(self.update_rate_label)
        hlayout.addWidget(self.update_rate_combo)
        hlayout.addStretch()

        layout = QVBoxLayout(self)
        layout.addWidget(self.plot_widget)
        layout.addLayout(hlayout)

    def new_update_rate(self):
        update_rate = self.update_rate_combo.currentIndex()
        self.dist.set_update_rate(update_rate)

    def get_update_rate_async(self, update_rate):
        self.update_rate_combo.setCurrentIndex(update_rate)

    def start(self):
        async_call(self.dist.get_update_rate, None, self.get_update_rate_async, self.increase_error_count)
        self.cbe_distance.set_period(100)

        self.plot_widget.stop = False

    def stop(self):
        self.cbe_distance.set_period(0)

        self.plot_widget.stop = True

    def destroy(self):
        pass

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletDistanceUSV2.DEVICE_IDENTIFIER

    def cb_distance(self, distance):
        self.current_distance.value = distance / 10.0
示例#4
0
 def createEditor(self, parent, option, index):
     if index.column() == 1:
         combo = QComboBox(parent)
         combo.addItem('')
         combo.addItems(self._action_list)
         return combo
     return super().createEditor(parent, option, index)
示例#5
0
	def _add_to_internal_dict(self, element, parent, num_row):
		QueueModel._add_to_internal_dict(self, element, parent, num_row)
		if element.tag == "item":
			# each row gets one combobox for the extension and one for the quality options
			format_combobox = QComboBox()  # see ComboBoxDelegate.createEditor()
			quality_combobox = QComboBox()  # see ComboBoxDelegate.createEditor()
			self.combo_boxes_format[element] = format_combobox
			self.combo_boxes_quality[element] = quality_combobox
			selected_extension = self.getSelectedExtension(element)
			selected_quality = self.getSelectedQuality(element, selected_extension)
			for format in element.findall("format"):
				format_combobox.addItem(format.get("extension"))
			for option in element.findall("format[@extension='%s']/option" % selected_extension):
				quality_combobox.addItem(option.get("quality"))
			format_combobox.setCurrentIndex(format_combobox.findText(selected_extension))
			quality_combobox.setCurrentIndex(quality_combobox.findText(selected_quality))

			# setup defaults for path and filename
			if "path" not in element.attrib:
				path = self.settings.value("DefaultDownloadFolder")
				element.attrib["path"] = path
			if "filename" not in element.attrib:
				filename = self.settings.value("DefaultFileName")
				# some of the template-filling will happen when an Item is moved to DownloadModel, as
				# quality and extension will most probably change until then
				mapping = dict(title=element.get("title"), url=element.get("url"), host=element.get("host"))
				element.attrib["filename"] = fill_filename_template(filename, mapping)
示例#6
0
class IconDropDown(QWidget):
    
    entrySelected = pyqtSignal(int)

    def __init__(self, parentWidget, iconName):
        QWidget.__init__(self, parentWidget)

        icon = QLabel(self)
        icon.setPixmap(QPixmap(iconName))

        self.dropdown = QComboBox(self)
        self.dropdown.activated.connect(self.entrySelected)

        hLayout = QVBoxLayout(self)
        hLayout.setContentsMargins(5, 5, 5, 5)
        
        self.setLayout(hLayout)
        hLayout.addWidget(icon, 0, Qt.AlignHCenter)
        hLayout.addWidget(self.dropdown)


    def addItem(self, title, tag):
        self.dropdown.addItem(title, tag)
        self.dropdown.setCurrentIndex(-1)   # TODO - can not set index to -1 before items have been added


    def setCurrentIndex(self, idx):
        self.dropdown.setCurrentIndex(idx)
示例#7
0
class GestionEleve(QWidget):
    def __init__(self,parent=None):
        super(GestionEleve,self).__init__(parent)
        
        #charge la classe en cour
        self.initClass()

        palette = QPalette()
        palette.setColor(QPalette.Text,QColor(128,128,128))    

        self.leNom = QLineEdit(self)
        self.leNom.setText("NOM..")
        self.leNom.setPalette(palette)
        
        self.lePrenom = QLineEdit(self)
        self.lePrenom.setText("PRENOM..")
        self.lePrenom.setPalette(palette)
        
        self.comboSex = QComboBox(self)
        self.comboSex.addItem("sexe..")
        self.comboSex.addItem("M")
        self.comboSex.addItem("F")
        
        self.comboClasse =  self.initComboClasse(["CE1","CE2"])
        
        self.buttonSave = QPushButton("Save")
        self.buttonSave.clicked.connect(self.saveEleve)

        layout = QHBoxLayout()
        layout.addStretch()
        layout.addWidget(self.leNom)
        layout.addWidget(self.lePrenom)
        layout.addWidget(self.comboSex)
        layout.addWidget(self.comboClasse)
        layout.addWidget(self.buttonSave)
        layout.addStretch()
        self.setLayout(layout)
    
    def initComboClasse(self,list):
        res = QComboBox()
        res.addItem("classe..")
        for elt in list:
            res.addItem(elt)
        return res
        
    def saveEleve(self):
        if (self.leNom.text == "NOM.."
            or self.lePrenom.text == "PRENOM.."
            or str(self.comboSex.currentText()) == "sexe.."
            or str(self.comboClasse.currentText()) == "classe.."
        ):
            pass
            #on enregistre pas
        else :
            pass
            #on enregistre
            
        
    def initClass(self):
        pass
示例#8
0
文件: gui.py 项目: kharyuk/astro
    def initUI(self):
        self.setAutoFillBackground(True)
        palette = self.palette()
        palette.setColor(self.backgroundRole(), QColor('white'))
        self.setPalette(palette)
        
        self.setFrameShape(_frameShape)
        self.setFrameShadow(_frameShadow)
        self.setLineWidth(_lineWidth)
        self.setMidLineWidth(_midLineWidth)
        return    
        combo = QComboBox(self)
        
        self.flist = self.load_list()
        self.lbl = QLabel('', self)
        self.descr = QLabel('', self)
        self.descr.setWordWrap(True)
        self.onActivated(0)

        for x in self.flist:
            combo.addItem(x['name'])
        
        combo.move(50, 50)
        self.lbl.move(50, 150)
        self.descr.move(150, 50)

        combo.activated[int].connect(self.onActivated) 
class Window(QWidget):
    """
    This part might be removed or included for main window application
    """

    def __init__(self, algorithms):
        super(Window, self).__init__()

        self.stackedWidget = QStackedWidget()
        self.orientationCombo = QComboBox()

        for category in categories:
            pass



        for algorithm in algorithms:
            self.orientationCombo.addItem(algorithm.get_name())
            self.stackedWidget.addWidget(GroupOfSliders(algorithm))

            layout = QBoxLayout(QBoxLayout.TopToBottom)

            settings_layout = QBoxLayout(QBoxLayout.TopToBottom)
            settings_layout.addWidget(self.stackedWidget)

            select_layout = QBoxLayout(QBoxLayout.TopToBottom)
            select_layout.addWidget(self.orientationCombo)

            layout.addItem(settings_layout)
            layout.addItem(select_layout)

            self.setLayout(layout)
            self.setWindowTitle(algorithm.get_name() + " Settings")
示例#10
0
class ModeSelectionToolbar(QToolBar):
    switch_mode = pyqtSignal(str)

    def __init__(self, network_handler):
        super().__init__("Mode selection")

        self._nh = network_handler

        mode_text = QLabel()
        mode_text.setText("Select mode:")

        self._mode_selection = QComboBox()
        self._mode_selection.setMinimumWidth(100)
        self._mode_selection.setMaximumWidth(140)
        self._mode_selection.addItem("RC")
        self._mode_selection.addItem("GPS")

        self.addWidget(mode_text)
        self.addWidget(self._mode_selection)

        self.addAction("Select", self._send_mode)

    @QtCore.pyqtSlot()
    def _send_mode(self):
        mode = self._mode_selection.currentText()
        self.switch_mode.emit(mode)

        if mode == "RC":
            command = "START_PROG_RC"
        elif mode == "GPS":
            command = "START_PROG_GPS"
        else:
            command = "START_PROG_RC"

        self._nh.send_command(command)
示例#11
0
文件: gui.py 项目: kharyuk/astro
    def initUI(self, parent):    
        combo = QComboBox(self)
        self.title = QLabel(u'Выбор каталога:', self)
        self.lbl = QLabel('', self)
        self.descr = QLabel('', self)
        self.descr.setWordWrap(True)
        self.descr.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
        self.onActivated(parent, parent.code_int)

        for x in parent.flist:
            combo.addItem(x['name'])
        
        combo.move(50, 50)
        self.title.move(5, 25)
        self.lbl.move(50, 100)
        self.descr.move(150, 50)
        
        def onact(ind):
            return self.onActivated(parent, ind)

        combo.activated[int].connect(onact) 
        
        self.setAutoFillBackground(True)
        palette = self.palette()
        palette.setColor(self.backgroundRole(), QColor('white'))
        self.setPalette(palette)
         
        self.setFrameShape(_frameShape)
        self.setFrameShadow(_frameShadow)
        self.setLineWidth(_lineWidth)
        self.setMidLineWidth(_midLineWidth)
示例#12
0
class AddItemDialog(QDialog):
    def __init__(self):
        super(AddItemDialog, self).__init__()
        self.setupUi(self)

    def setupUi(self, AddItemDialog):
        self.item_type_picker = QComboBox()

        self.item_properties_switch = QStackedWidget()

        for form in FORMS:
            self.item_type_picker.addItem(form.__name__.split('_')[0],
                                          FORMS.index(form))
            self.item_properties_switch.addWidget(form())

        self.item_type_picker.currentIndexChanged.connect(
            self.item_properties_switch.setCurrentIndex)

        self.add_button = QPushButton("Add")

        mainLayout = QVBoxLayout(self)
        mainLayout.addWidget(self.item_type_picker)
        mainLayout.addWidget(self.item_properties_switch, 1)
        mainLayout.addWidget(self.add_button)

        self.add_button.clicked.connect(self.add_item)

        self.setWindowIcon(QIcon(QPixmap('hotel_icon.jpg')))
        self.layout().setSizeConstraint(QLayout.SetFixedSize)
        self.setWindowTitle("Add Items")

    def add_item(self):
        self.item_properties_switch.currentWidget().add_button_click()
示例#13
0
    def __init__(self, parent=None):
        super(ConfigurationPage, self).__init__(parent)

        configGroup = QGroupBox("Server configuration")

        serverLabel = QLabel("Server:")
        serverCombo = QComboBox()
        serverCombo.addItem("Trolltech (Australia)")
        serverCombo.addItem("Trolltech (Germany)")
        serverCombo.addItem("Trolltech (Norway)")
        serverCombo.addItem("Trolltech (People's Republic of China)")
        serverCombo.addItem("Trolltech (USA)")

        serverLayout = QHBoxLayout()
        serverLayout.addWidget(serverLabel)
        serverLayout.addWidget(serverCombo)

        configLayout = QVBoxLayout()
        configLayout.addLayout(serverLayout)
        configGroup.setLayout(configLayout)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(configGroup)
        mainLayout.addStretch(1)

        self.setLayout(mainLayout)
示例#14
0
    def __init__(self, parent, configuration):
        QTableWidget.__init__(self, 5, 1, parent)
        self._configuration = configuration
        self._manual_change = True
        self.setVerticalHeaderLabels(
            ["Duration (cycles)", "Duration (ms)", "Cycles / ms",
             'RAM access time', 'Execution Time Model'])
        self.horizontalHeader().setStretchLastSection(True)
        self.horizontalHeader().hide()
        self.setItem(0, 0, QTableWidgetItem(str(configuration.duration)))
        self.setItem(1, 0, QTableWidgetItem(str(
            float(configuration.duration) / configuration.cycles_per_ms)))
        self.setItem(2, 0, QTableWidgetItem(str(configuration.cycles_per_ms)))
        self.setItem(
            3, 0, QTableWidgetItem(str(configuration.memory_access_time)))

        item = QComboBox(self)
        selected = 0
        for i, (etm_name, etm_code) in \
                enumerate(execution_time_model_names.items()):
            item.addItem(etm_name)
            if etm_code == configuration.etm:
                selected = i
        item.setCurrentIndex(selected)
        self.setCellWidget(4, 0, item)

        def activation_handler(x):
            configuration.etm = execution_time_model_names[str(x)]
            configuration.conf_changed()
        item.activated['QString'].connect(activation_handler)

#        self._update_observe_window()

        self.cellChanged.connect(self._cell_changed)
示例#15
0
    def initUI(self):

        # lineedit
        self.lbl = QLabel(self)
        qle = QLineEdit(self)

        qle.move(20, 30)
        self.lbl.move(20, 10)

        qle.textChanged[str].connect(self.onChanged)

        # combobox
        self.lbl1 = QLabel('ubuntu', self)

        combo = QComboBox(self)
        combo.addItem('ubuntu')
        combo.addItem('mandriva')
        combo.addItem('fedora')
        combo.addItem('arch')
        combo.addItem('gentoo')

        combo.move(20, 70)
        self.lbl1.move(20, 100)

        combo.activated[str].connect(self.onActivated)

        self.setGeometry(300, 300, 300, 250)
        self.setWindowTitle('widget 1')
        self.show()
示例#16
0
    def createDesktopOption(self, layout):
        hlayout = QHBoxLayout()
        layout.addLayout(hlayout)

        vlayout1 = QVBoxLayout()
        vlayout2 = QVBoxLayout()
        hlayout.addLayout(vlayout1)
        hlayout.addLayout(vlayout2)

        label1 = QLabel()
        label1.setText(self.tr("Desktop Type"))
        vlayout1.addWidget(label1)
        label2 = QLabel()
        label2.setText(self.tr("Number of Desktops"))
        vlayout2.addWidget(label2)

        comboBox = QComboBox()
        comboBox.addItem(self.tr("Desktop View"))
        comboBox.addItem(self.tr("Folder View"))
        comboBox.currentIndexChanged.connect(self.desktopTypeCreate)
        vlayout1.addWidget(comboBox)
        spinBox = QSpinBox()
        spinBox.setMinimum(1)
        spinBox.setMaximum(20)
        spinBox.valueChanged.connect(self.desktopCreate)
        vlayout2.addWidget(spinBox)
示例#17
0
class FileChooser(QWidget):
    fileOpened = pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.folderBox = QComboBox(self)
        self.explorerTree = FileTreeView(self)
        self.explorerTree.doubleClickCallback = self._fileOpened
        self.explorerModel = QFileSystemModel(self)
        self.explorerModel.setFilter(
            QDir.AllDirs | QDir.Files | QDir.NoDotAndDotDot)
        self.explorerModel.setNameFilters(["*.py"])
        self.explorerModel.setNameFilterDisables(False)
        self.explorerTree.setModel(self.explorerModel)
        for index in range(1, self.explorerModel.columnCount()):
            self.explorerTree.hideColumn(index)
        self.setCurrentFolder()
        self.folderBox.currentIndexChanged[int].connect(
            self.updateCurrentFolder)

        layout = QVBoxLayout(self)
        layout.addWidget(self.folderBox)
        layout.addWidget(self.explorerTree)
        layout.setContentsMargins(5, 5, 0, 0)

    def _fileOpened(self, modelIndex):
        path = self.explorerModel.filePath(modelIndex)
        if os.path.isfile(path):
            self.fileOpened.emit(path)

    def currentFolder(self):
        return self.explorerModel.rootPath()

    def setCurrentFolder(self, path=None):
        if path is None:
            app = QApplication.instance()
            path = app.getScriptsDirectory()
        else:
            assert os.path.isdir(path)
        self.explorerModel.setRootPath(path)
        self.explorerTree.setRootIndex(self.explorerModel.index(path))
        self.folderBox.blockSignals(True)
        self.folderBox.clear()
        style = self.style()
        dirIcon = style.standardIcon(style.SP_DirIcon)
        self.folderBox.addItem(dirIcon, os.path.basename(path))
        self.folderBox.insertSeparator(1)
        self.folderBox.addItem(self.tr("Browse…"))
        self.folderBox.setCurrentIndex(0)
        self.folderBox.blockSignals(False)

    def updateCurrentFolder(self, index):
        if index < self.folderBox.count() - 1:
            return
        path = QFileDialog.getExistingDirectory(
            self, self.tr("Choose Directory"), self.currentFolder(),
            QFileDialog.ShowDirsOnly)
        if path:
            QSettings().setValue("scripting/path", path)
            self.setCurrentFolder(path)
示例#18
0
	def initUI(self):
		self.setWindowTitle("QTableWidget 例子")
		self.resize(430,300);
		conLayout = QHBoxLayout()
		tableWidget = QTableWidget()
		tableWidget.setRowCount(4)
		tableWidget.setColumnCount(3)
		conLayout.addWidget(tableWidget )
		
		tableWidget.setHorizontalHeaderLabels(['姓名','性别','体重(kg)'])  
		  
		newItem = QTableWidgetItem("张三")  
		tableWidget.setItem(0, 0, newItem)  
		  
		comBox = QComboBox()
		comBox.addItem("男")
		comBox.addItem("女")
		comBox.setStyleSheet("QComboBox{margin:3px};")
		tableWidget.setCellWidget(0,1,comBox)
		
		searchBtn = QPushButton("修改")  
		searchBtn.setDown( True )
		searchBtn.setStyleSheet("QPushButton{margin:3px};")
		tableWidget.setCellWidget(0, 2, searchBtn) 
		 				
		self.setLayout(conLayout)
示例#19
0
 def initUI(self):
     
     self.setFixedSize(400, 260)
     
     self.setWindowTitle('Fomoire!')
     fomoire = QPixmap(os.path.join('./Pictures/', "fomoire.png"))
     logo = QLabel(self)
     logo.setPixmap(fomoire)
     logo.setFixedSize(fomoire.size())
     logo.move(400 / 2 - fomoire.width() / 2, 15)
     
     towerDefence = QLabel('A Tower Defence Game', self)
     towerDefence.move(130, 66)
     
     selectMap = QLabel('Select map:', self)
     selectMap.move(50, 105)
     
     mapList = QComboBox(self)
     mapList.addItem('No map selected')
     
     for mapFile in os.listdir('./Maps/'):
         mapList.addItem(mapFile)
     
     mapList.move(135, 102)
     mapList.activated[str].connect(self.selectMap)
     
     setSpeed = QLabel('Set game speed:', self)
     setSpeed.move(50, 140)
     
     slow = QLabel('Slow', self)
     slow.move(170, 140)
     
     slider = QSlider(Qt.Horizontal, self)
     slider.setFocusPolicy(Qt.NoFocus)
     slider.setSliderPosition(100 - self.gameSpeed)
     slider.setGeometry(210, 140, 100, 20)
     slider.valueChanged[int].connect(self.changeGameSpeed)
     
     fast = QLabel('Fast', self)
     fast.move(325, 140)
     
     start = QPushButton('Start game!', self)
     start.move(145, 175)
     start.clicked[bool].connect(self.startGame)
     
     quitButton = QPushButton('Quit', self)
     quitButton.move(168, 210)
     quitButton.clicked[bool].connect(qApp.quit)
     
     barbarian = QLabel(self)
     brbr = QPixmap(os.path.join('./Pictures/', "barbarian.png"))
     barbarian.setPixmap(brbr)
     barbarian.move(70, 185)
     
     berserker = QLabel(self)
     berber = QPixmap(os.path.join('./Pictures/', "berserker_left.png"))
     berserker.setPixmap(berber)
     berserker.move(290, 185)
     
     self.show()
示例#20
0
文件: app.py 项目: ipapi/ipap
    def initoptionspanel(self):
        label = QLabel('Filter')

        filtertype = QComboBox()
        filtertype.addItem('None')
        filtertype.addItem('Lowpass')
        filtertype.addItem('Highpass')
        filtertype.addItem('Bandreject')
        filtertype.addItem('Bandpass')
        filtertype.currentIndexChanged.connect(self.filtertypelistener)

        self.filterfunction = QComboBox()
        self.filterfunction.addItem('Ideal')
        self.filterfunction.addItem('Butterworth')
        self.filterfunction.addItem('Gaussian')
        self.filterfunction.currentIndexChanged.connect(self.filterfunctionlistener)
        self.filterfunction.setEnabled(False)

        self.filtercutoff = QDoubleSpinBox()
        self.filtercutoff.setValue(0.0)
        self.filtercutoff.setRange(0.0, 10000.0)
        self.filtercutoff.valueChanged.connect(self.filtercutofflistener)
        self.filtercutoff.setEnabled(False)

        self.filterbandwidth = QDoubleSpinBox()
        self.filterbandwidth.setValue(1.0)
        self.filterbandwidth.setRange(0.0, 10000.0)
        self.filterbandwidth.valueChanged.connect(self.filterbandwidthlistener)
        self.filterbandwidth.setEnabled(False)

        self.filterorder = QDoubleSpinBox()
        self.filterorder.setValue(1.0)
        self.filterorder.setRange(0.0, 10000.0)
        self.filterorder.valueChanged.connect(self.filterorderlistener)
        self.filterorder.setEnabled(False)

        loader = QMovie('loader.gif')
        loader.start()
        self.loadercontainer = QLabel()
        self.loadercontainer.setMovie(loader)
        self.loadercontainer.setVisible(False)

        formlayout = QFormLayout()
        formlayout.addRow('Type', filtertype)
        formlayout.addRow('Function', self.filterfunction)
        formlayout.addRow('Cut off', self.filtercutoff)
        formlayout.addRow('Bandwidth', self.filterbandwidth)
        formlayout.addRow('Order', self.filterorder)
        formlayout.addRow('', self.loadercontainer)

        filterbox = QGroupBox('Filter')
        filterbox.setLayout(formlayout)

        options = QDockWidget('Options')
        options.setFeatures(QDockWidget.DockWidgetFloatable)
        options.setFeatures(QDockWidget.DockWidgetMovable)
        options.setWidget(filterbox)
        self.addDockWidget(Qt.RightDockWidgetArea, options)
示例#21
0
class FindInFilesActions(QWidget):

    searchRequested = pyqtSignal('QString', bool, bool, bool)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Ignored)
        self._scope = QComboBox()
        self._scope.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.ninjaide = IDE.get_service('ide')
        self.ninjaide.filesAndProjectsLoaded.connect(
            self._update_combo_projects)

        main_layout = QVBoxLayout(self)
        hbox = QHBoxLayout()
        hbox.addWidget(QLabel(translations.TR_SEARCH_SCOPE))
        hbox.addWidget(self._scope)
        main_layout.addLayout(hbox)
        widgets_layout = QGridLayout()
        widgets_layout.setContentsMargins(0, 0, 0, 0)
        self._line_search = QLineEdit()
        self._line_search.setPlaceholderText(translations.TR_SEARCH_FOR)
        main_layout.addWidget(self._line_search)
        # TODO: replace
        self._check_cs = QCheckBox(translations.TR_SEARCH_CASE_SENSITIVE)
        self._check_cs.setChecked(True)
        widgets_layout.addWidget(self._check_cs, 2, 0)
        self._check_wo = QCheckBox(translations.TR_SEARCH_WHOLE_WORDS)
        widgets_layout.addWidget(self._check_wo, 2, 1)
        self._check_re = QCheckBox(translations.TR_SEARCH_REGEX)
        widgets_layout.addWidget(self._check_re, 3, 0)
        self._check_recursive = QCheckBox('Recursive')
        widgets_layout.addWidget(self._check_recursive, 3, 1)
        main_layout.addLayout(widgets_layout)
        main_layout.addStretch(1)

        # Connections
        self._line_search.returnPressed.connect(self.search_requested)

    def _update_combo_projects(self):
        projects = self.ninjaide.get_projects()
        for nproject in projects.values():
            self._scope.addItem(nproject.name, nproject.path)

    @property
    def current_project_path(self):
        """Returns NProject.path of current project"""
        return self._scope.itemData(self._scope.currentIndex())

    def search_requested(self):
        text = self._line_search.text()
        if not text.strip():
            return
        has_search = self._line_search.text()
        cs = self._check_cs.isChecked()
        regex = self._check_re.isChecked()
        wo = self._check_wo.isChecked()
        self.searchRequested.emit(has_search, cs, regex, wo)
示例#22
0
文件: pulppy.py 项目: bruino/pulppy
    def __init__(self, title, numVar, numCons, typeVar, objCrit, parent=None):
        super(InputTableModel, self).__init__(parent)
        self.problem = None
        self.problemTitle = title
        self.numVariables = numVar
        self.numConstraints = numCons
        self.objCriterion = objCrit
        self.typeVariable = typeVar
        self.tableModel = QTableWidget(self.numConstraints+1, self.numVariables+2)
        self.tableModel.setItemDelegate(Delegate(self))

        listVariables = []
        for m in range(self.numVariables):
            listVariables.append("X"+str(m))

        listVariables.extend(["Direction","R.H.S"])

        #Generar Filas
        listConstraints = ["Objetive"]
        for m in range(self.numConstraints):
            listConstraints.append("C"+str(m))
            combo = QComboBox()
            combo.addItem('<')
            combo.addItem('<=')
            combo.addItem('=')
            combo.addItem('>=')
            combo.addItem('>')
            self.tableModel.setCellWidget(m+1, self.numVariables, combo)

        #listConstraints.extend(["LowerBound","UpperBound", "VariableType"])

        self.tableModel.setCellWidget(0, self.numVariables, QLabel(""))

        self.tableModel.setHorizontalHeaderLabels(listVariables)
        self.tableModel.setVerticalHeaderLabels(listConstraints)

        buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        buttonBox.accepted.connect(self.verify)
        buttonBox.rejected.connect(self.reject)

        f = "Problem Title: "
        if self.objCriterion == True:
            f = f + self.problemTitle + " - Objetive: Maximitation"
        else:
            f = f + self.problemTitle + " - Objetive: Minimization"
        t = QLabel(f)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(t)
        mainLayout.addWidget(self.tableModel)
        mainLayout.addWidget(buttonBox)

        width = self.tableModel.columnWidth(1)*(self.tableModel.columnCount()+1)
        height = self.tableModel.rowHeight(0)*(self.tableModel.rowCount()+4)

        self.resize(QSize(width, height))
        self.setWindowTitle("Input Problem Model")
        self.setLayout(mainLayout)
示例#23
0
class SubFileDialog(QFileDialog):
    def __init__(self, parent = None, caption = "", directory = "", filter = ""):
        super().__init__(parent, caption, directory, filter)
        self.setOption(QFileDialog.DontUseNativeDialog)

    def _initAllSubFormats(self, formatList):
        self._formats = {}
        for f in formatList:
            self._formats[f.NAME] = f

    def _addEncodingsBox(self, row, addAuto):
        mainLayout = self.layout()

        encodingLabel = QLabel(_("File encoding:"), self)

        self._encodingBox = QComboBox(self)
        if addAuto is True:
            self._encodingBox.addItem(AUTO_ENCODING_STR)
        self._encodingBox.addItems(ALL_ENCODINGS)
        self._encodingBox.setToolTip(_("Change file encoding"))
        self._encodingBox.setEditable(True)

        mainLayout.addWidget(encodingLabel, row, 0)
        mainLayout.addWidget(self._encodingBox, row, 1)

    def _addFormatBox(self, row, formatList):
        self._initAllSubFormats(formatList)
        displayedFormats = list(self._formats.keys())
        displayedFormats.sort()

        mainLayout = self.layout()

        formatLabel = QLabel(_("Subtitle format:"), self)
        self._formatBox = QComboBox(self)
        self._formatBox.addItems(displayedFormats)

        mainLayout.addWidget(formatLabel, row, 0)
        mainLayout.addWidget(self._formatBox, row, 1)

    def getEncoding(self):
        encoding = self._encodingBox.currentText()
        if encoding == AUTO_ENCODING_STR:
            encoding = None
        return encoding

    def setEncoding(self, encoding):
        index = self._encodingBox.findText(encoding)
        self._encodingBox.setCurrentIndex(index)

    def getSubFormat(self):
        return self._formats.get(self._formatBox.currentText())

    def setSubFormat(self, subFormat):
        for key, val in self._formats.items():
            if val == subFormat:
                index = self._formatBox.findText(key)
                self._formatBox.setCurrentIndex(index)
                return
    def __init__(self, *args):
        COMCUPluginBase.__init__(self, BrickletIndustrialQuadRelayV2, *args)

        self.setupUi(self)

        self.iqr = self.device

        self.open_pixmap = load_masked_pixmap('plugin_system/plugins/industrial_quad_relay/relay_open.bmp')
        self.close_pixmap = load_masked_pixmap('plugin_system/plugins/industrial_quad_relay/relay_close.bmp')

        self.relay_buttons = [self.b0, self.b1, self.b2, self.b3]
        self.relay_button_icons = [self.b0_icon, self.b1_icon, self.b2_icon, self.b3_icon]
        self.relay_button_labels = [self.b0_label, self.b1_label, self.b2_label, self.b3_label]

        for icon in self.relay_button_icons:
            icon.setPixmap(self.open_pixmap)
            icon.show()

        for i in range(len(self.relay_buttons)):
            self.relay_buttons[i].clicked.connect(functools.partial(self.relay_button_clicked, i))

        self.monoflop_values = []
        self.monoflop_times = []

        for i in range(4):
            self.monoflop_channel.setItemData(i, i)

            monoflop_value = QComboBox()
            monoflop_value.addItem('On', True)
            monoflop_value.addItem('Off', False)

            self.monoflop_values.append(monoflop_value)
            self.monoflop_value_stack.addWidget(monoflop_value)

            monoflop_time = QSpinBox()
            monoflop_time.setRange(1, (1 << 31) - 1)
            monoflop_time.setValue(1000)

            self.monoflop_times.append(monoflop_time)
            self.monoflop_time_stack.addWidget(monoflop_time)

        self.monoflop = Monoflop(self.iqr,
                                 [0, 1, 2, 3],
                                 self.monoflop_values,
                                 self.cb_value_change_by_monoflop,
                                 self.monoflop_times,
                                 None,
                                 self)

        self.monoflop_channel.currentIndexChanged.connect(self.monoflop_channel_changed)
        self.monoflop_go.clicked.connect(self.monoflop_go_clicked)

        self.cbox_cs0_cfg.currentIndexChanged.connect(self.cbox_cs0_cfg_changed)
        self.cbox_cs1_cfg.currentIndexChanged.connect(self.cbox_cs1_cfg_changed)
        self.cbox_cs2_cfg.currentIndexChanged.connect(self.cbox_cs2_cfg_changed)
        self.cbox_cs3_cfg.currentIndexChanged.connect(self.cbox_cs3_cfg_changed)
    def createLegendBox(self):
        legendComboBox = QComboBox()

        legendComboBox.addItem("No Legend ", 0)
        legendComboBox.addItem("Legend Top", Qt.AlignTop)
        legendComboBox.addItem("Legend Bottom", Qt.AlignBottom)
        legendComboBox.addItem("Legend Left", Qt.AlignLeft)
        legendComboBox.addItem("Legend Right", Qt.AlignRight)

        return legendComboBox
示例#26
0
 def _createOptions(self, param, tooltip=""):
     combo = QComboBox()
     combo.addItem("Select option")
     combo.addItems(param.options)
     combo.setCurrentIndex(0)
     append = param.isVectorType()
     combo.currentTextChanged.connect(lambda text: self._optionSelected(param.name, append, text))
     row = self.findRow(param.name)
     if tooltip:
         combo.setToolTip(tooltip)
     self.setCellWidget(row, 2, combo)
class AddPlayerWidget(QWidget):
	def __init__(self):
		super(AddPlayerWidget, self).__init__()

		self.users = {}

		# self.setWindowTitle('Add Player')
		self.setStyleSheet(style.style_loader.stylesheet)

		self.label = QLabel('Enter Name:', self)

		self.label_widget = QWidget(self)
		label_layout = QBoxLayout(QBoxLayout.LeftToRight)
		label_layout.addWidget(self.label)
		self.label_widget.setLayout(label_layout)

		self.user_box = QComboBox(self)
		self.user_box.setFixedWidth(210)
		self.user_box.setFixedHeight(50)

		self.user_box_widget = QWidget(self)
		user_box_layout = QBoxLayout(QBoxLayout.LeftToRight)
		user_box_layout.addWidget(self.user_box)
		self.user_box_widget.setLayout(user_box_layout)

		self.submit_btn = QPushButton('Add Player', self)
		self.submit_btn.clicked.connect(self.submit)

		self.submit_btn_widget = QWidget(self)
		submit_btn_layout = QBoxLayout(QBoxLayout.LeftToRight)
		submit_btn_layout.addWidget(self.submit_btn)
		self.submit_btn_widget.setLayout(submit_btn_layout)

		layout = QFormLayout()
		layout.addRow(self.label_widget)
		layout.addRow(self.user_box_widget)
		layout.addRow(self.submit_btn_widget)
		self.setLayout(layout)

		self.show()
		self.setFixedHeight(self.height())
		self.setFixedWidth(self.width())
		self.close()

	def update(self):
		self.user_box.clear()
		self.users = um.users()
		for user in self.users:
			self.user_box.addItem(user.name + ' (' + str(user.id) + ')')

	def submit(self):
		user = self.users[self.user_box.currentIndex()]
		view.notifier.player_added(user.name, user)
		self.close()
示例#28
0
class DeleteForm(QDialog):
    def __init__(self):
        super(DeleteForm, self).__init__()
        self.initUI(self)

    def initUI(self, DeleteForm):
        layout = QGridLayout(self)

        self.delete_label = QLabel("Delete by:")
        self.delete_combo_box = QComboBox()
        self.delete_combo_box.addItem("ISBN")
        self.delete_combo_box.addItem("Title")
        self.delete_line_edit = QLineEdit()
        self.delete_button = QPushButton("Delete")

        layout.addWidget(self.delete_label, 0, 0)
        layout.addWidget(self.delete_combo_box, 0, 1)
        layout.addWidget(self.delete_line_edit, 0, 2)
        layout.addWidget(self.delete_button, 0, 3, 1, 2)

        self.setLayout(layout)
        self.delete_button.clicked.connect(self.delete_button_click)
        self.layout().setSizeConstraint(QLayout.SetFixedSize)
        self.setWindowTitle("Delete Book")
        self.setWindowIcon(QIcon(QPixmap('../images/delete.png')))

    def delete_button_click(self):
        search = self.delete_combo_box.currentText()
        text = self.delete_line_edit.text()
        if search == 'ISBN':
            if not(Validations.is_valid_isbn(text)):
                QMessageBox(QMessageBox.Critical, "Error",
                            "Invalid ISBN. Please correct it!").exec_()
            books = select_by_isbn(text)
            if books != []:
                delete_by_isbn(text)
                QMessageBox(QMessageBox.Information, "Information",
                            "You successfully deleted this book!").exec_()
                return
            else:
                QMessageBox(QMessageBox.Information, "No results",
                            "There is NO such book in the library!").exec_()
                return
        elif search == 'Title':
            books = select_by_title(string.capwords(text))
            if books != []:
                delete_by_title(string.capwords(text))
                QMessageBox(QMessageBox.Information, "Information",
                            "You successfully deleted this book!").exec_()
                return
            else:
                QMessageBox(QMessageBox.Information, "No results",
                            "There is NO such book in the library!").exec_()
                return
示例#29
0
    def createPaceSelector(self, pace_id=None):
        selector = QComboBox() # create a combo box

        for i in range(self.paceSelect.count()):
            selector.addItem(self.paceSelect.itemText(i))
        if pace_id == None:
            selector.setCurrentIndex(self.paceSelect.currentIndex())
        else:
            selector.setCurrentIndex(pace_id-1) # subtract 1 because comboboxes are indexed starting at 0

        selector.currentIndexChanged.connect(self.segmentPaceChanged) # connect to the function that deals with adding the change to the database
        return selector
示例#30
0
class PreviewForm(QDialog):
    def __init__(self, parent):
        super(PreviewForm, self).__init__(parent)

        self.encodingComboBox = QComboBox()
        encodingLabel = QLabel("&Encoding:")
        encodingLabel.setBuddy(self.encodingComboBox)

        self.textEdit = QTextEdit()
        self.textEdit.setLineWrapMode(QTextEdit.NoWrap)
        self.textEdit.setReadOnly(True)

        buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)

        self.encodingComboBox.activated.connect(self.updateTextEdit)
        buttonBox.accepted.connect(self.accept)
        buttonBox.rejected.connect(self.reject)

        mainLayout = QGridLayout()
        mainLayout.addWidget(encodingLabel, 0, 0)
        mainLayout.addWidget(self.encodingComboBox, 0, 1)
        mainLayout.addWidget(self.textEdit, 1, 0, 1, 2)
        mainLayout.addWidget(buttonBox, 2, 0, 1, 2)
        self.setLayout(mainLayout)

        self.setWindowTitle("Choose Encoding")
        self.resize(400, 300)

    def setCodecList(self, codecs):
        self.encodingComboBox.clear()
        for codec in codecs:
            self.encodingComboBox.addItem(codec_name(codec), codec.mibEnum())

    def setEncodedData(self, data):
        self.encodedData = data
        self.updateTextEdit()

    def decodedString(self):
        return self.decodedStr

    def updateTextEdit(self):
        mib = self.encodingComboBox.itemData(self.encodingComboBox.currentIndex())
        codec = QTextCodec.codecForMib(mib)

        data = QTextStream(self.encodedData)
        data.setAutoDetectUnicode(False)
        data.setCodec(codec)

        self.decodedStr = data.readAll()
        self.textEdit.setPlainText(self.decodedStr)
示例#31
0
    def __init__(self, layer):
        super().__init__()
        self.layer = layer
        self.unselectedStyleSheet = "QFrame#layer {border: 3px solid lightGray; background-color:lightGray; border-radius: 3px;}"
        self.selectedStyleSheet = "QFrame#layer {border: 3px solid rgb(0, 153, 255); background-color:lightGray; border-radius: 3px;}"
        self.setObjectName('layer')

        self.grid_layout = QGridLayout()

        cb = QCheckBox(self)
        cb.setStyleSheet("QCheckBox::indicator {width: 18px; height: 18px;}"
                         "QCheckBox::indicator:checked {image: url(" +
                         path_on + ");}")
        cb.setToolTip('Layer visibility')
        cb.setChecked(self.layer.visible)
        cb.stateChanged.connect(lambda state=cb: self.changeVisible(state))
        self.grid_layout.addWidget(cb, 0, 0)

        #self.grid_layout.insertSpacing(1, 5)

        textbox = QLineEdit(self)
        textbox.setStyleSheet('background-color:lightGray; border:none')
        textbox.setText(layer.name)
        textbox.setToolTip('Layer name')
        textbox.setFixedWidth(80)
        textbox.setAcceptDrops(False)
        textbox.editingFinished.connect(
            lambda text=textbox: self.changeText(text))
        self.grid_layout.addWidget(textbox, 0, 1)

        self.grid_layout.addWidget(QLabel('opacity:'), 1, 0)
        sld = QSlider(Qt.Horizontal, self)
        sld.setFocusPolicy(Qt.NoFocus)
        #sld.setInvertedAppearance(True)
        sld.setFixedWidth(75)
        sld.setMinimum(0)
        sld.setMaximum(100)
        sld.setSingleStep(1)
        sld.setValue(self.layer.opacity * 100)
        sld.valueChanged[int].connect(
            lambda value=sld: self.changeOpacity(value))
        self.grid_layout.addWidget(sld, 1, 1)

        blend_comboBox = QComboBox()
        for blend in self.layer._blending_modes:
            blend_comboBox.addItem(blend)
        index = blend_comboBox.findText(self.layer._blending,
                                        Qt.MatchFixedString)
        if index >= 0:
            blend_comboBox.setCurrentIndex(index)
        blend_comboBox.activated[str].connect(
            lambda text=blend_comboBox: self.changeBlending(text))
        self.grid_layout.addWidget(QLabel('blending:'), 2, 0)
        self.grid_layout.addWidget(blend_comboBox, 2, 1)

        self.setLayout(self.grid_layout)
        self.setToolTip(
            'Click to select\nDrag to rearrange\nDouble click to expand')
        self.setSelected(True)
        self.setExpanded(False)
        self.setFixedWidth(200)
        self.grid_layout.setColumnMinimumWidth(0, 100)
        self.grid_layout.setColumnMinimumWidth(1, 100)
示例#32
0
    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.setMinimumHeight(300)
        self.setMinimumWidth(300)

        # MENU BAR
        menu_bar = self.menuBar()
        _ = menu_bar.addMenu('&File')
        edit = menu_bar.addMenu('&Edit')

        copy = edit.addAction('&copy')
        copy.triggered.connect(self.text_edit.copy)
        paste = edit.addAction('&paste')
        paste.triggered.connect(self.text_edit.paste)
        select_all = edit.addAction('&select all')
        select_all.triggered.connect(self.text_edit.selectAll)
        undo = edit.addAction('&undo')
        undo.triggered.connect(self.text_edit.undo)
        redo = edit.addAction('&redo')
        redo.triggered.connect(self.text_edit.redo)

        window_layout = QVBoxLayout()
        window_layout.addWidget(menu_bar, 0)

        # TOOL BAR
        tool_bar = QToolBar()
        button = QAction(QIcon("icons/new-file.png"), "a", self)
        button.triggered.connect(self.new_file)
        tool_bar.addAction(button)
        button = QAction(QIcon("icons/open-archive.png"), "a", self)
        button.triggered.connect(self.getfile)
        tool_bar.addAction(button)
        button = QAction(QIcon("icons/save.png"), "a", self)
        button.triggered.connect(self.save_file)
        tool_bar.addAction(button)
        button = QAction(QIcon("icons/saveas.png"), "a", self)
        button.triggered.connect(self.save_as)
        tool_bar.addAction(button)
        tool_bar.addSeparator()
        button = QAction(QIcon("icons/undo.png"), "a", self)
        button.triggered.connect(self.text_edit.undo)
        tool_bar.addAction(button)
        button = QAction(QIcon("icons/redo.png"), "a", self)
        button.triggered.connect(self.text_edit.redo)
        tool_bar.addAction(button)
        tool_bar.addSeparator()
        button = QAction(QIcon("icons/copy.png"), "a", self)
        button.triggered.connect(self.text_edit.copy)
        tool_bar.addAction(button)
        button = QAction(QIcon("icons/paste.png"), "a", self)
        button.triggered.connect(self.text_edit.paste)
        tool_bar.addAction(button)
        button = QAction(QIcon("icons/selection.png"), "a", self)
        button.triggered.connect(self.text_edit.selectAll)
        tool_bar.addAction(button)
        window_layout.addWidget(tool_bar, 1)

        # SPLIT PANE
        window_layout.addWidget(self.split_pane, 2)

        # LEFT PANE
        w = QWidget()
        w.setLayout(self.left_v_box)
        w.setFixedWidth(250)
        self.split_pane.addWidget(w)

        # RIGHT PANE
        self.split_pane.addWidget(self.text_edit)

        # LEFT PANE FONT SIZE
        combo_box = QComboBox(self)
        combo_box.addItem("10")
        combo_box.addItem("12")
        combo_box.addItem("14")
        combo_box.addItem("16")
        combo_box.addItem("18")
        combo_box.activated[str].connect(self.change_font_size)
        self.left_v_box.addWidget(combo_box)

        # # LEFT PANE FONT STYLE
        # options = ['Times Nes Roman', 'Arial', 'Courier New']
        # cbg = QButtonGroup(self)
        # cbg.setExclusive(True)
        # for id, ch in enumerate(options):
        #     rb = QRadioButton(ch)
        #     cbg.addButton(rb)
        #     cbg.setId(rb, id)
        #     self.left_v_box.addWidget(rb)

        # LEFT PANE FONT STYLE
        options = ['Times Nes Roman', 'Arial', 'Courier New']
        rb = QRadioButton(options[0])
        rb.clicked.connect(self.set_font1)
        self.left_v_box.addWidget(rb)
        rb = QRadioButton(options[1])
        rb.pressed.connect(self.set_font2)
        self.left_v_box.addWidget(rb)
        rb = QRadioButton(options[2])
        rb.pressed.connect(self.set_font3)
        self.left_v_box.addWidget(rb)

        # LEFT PANE COLOR PALETTE
        pal_widget = QWidget()
        pal_widget.setFixedHeight(120)
        pal_widget.setFixedWidth(120)
        palette = QGridLayout()
        pal_widget.setLayout(palette)
        self.left_v_box.addWidget(pal_widget)
        colors = [
            '#000000', '#141923', '#414168', '#3a7fa7', '#35e3e3', '#8fd970',
            '#5ebb49', '#458352', '#dcd37b', '#fffee5', '#ffd035', '#cc9245',
            '#a15c3e', '#a42f3b', '#f45b7a', '#ffffff'
        ]
        row, col = 0, 0
        num_of_columns = 4
        for c in colors:
            b = _PaletteButton(c)
            b.clicked.connect(
                self.ColorChanger(c, self.pal, self.text_edit,
                                  self.statusBar()))
            palette.addWidget(b, row, col)
            col += 1
            if col == num_of_columns:
                col = 0
                row += 1

        # ALIGN LEFT PANE TO TOP
        self.left_v_box.addStretch(1)

        # SET MAIN WINDOW
        self.main_widget.setLayout(window_layout)
        self.setCentralWidget(self.main_widget)

        # STATUS BAR
        self.statusBar().showMessage("Status bar")

        self.show()
示例#33
0
class ReTextWindow(QMainWindow):
	def __init__(self, parent=None):
		QMainWindow.__init__(self, parent)
		self.resize(950, 700)
		screenRect = QDesktopWidget().screenGeometry()
		if globalSettings.windowGeometry:
			self.restoreGeometry(globalSettings.windowGeometry)
		else:
			self.move((screenRect.width()-self.width())/2, (screenRect.height()-self.height())/2)
			if not screenRect.contains(self.geometry()):
				self.showMaximized()
		if sys.platform.startswith('darwin'):
			# https://github.com/retext-project/retext/issues/198
			searchPaths = QIcon.themeSearchPaths()
			searchPaths.append('/opt/local/share/icons')
			searchPaths.append('/usr/local/share/icons')
			QIcon.setThemeSearchPaths(searchPaths)
		if globalSettings.iconTheme:
			QIcon.setThemeName(globalSettings.iconTheme)
		if QIcon.themeName() in ('hicolor', ''):
			if not QFile.exists(getBundledIcon('document-new')):
				QIcon.setThemeName(get_icon_theme())
		if QFile.exists(getBundledIcon('retext')):
			self.setWindowIcon(QIcon(getBundledIcon('retext')))
		elif QFile.exists('/usr/share/pixmaps/retext.png'):
			self.setWindowIcon(QIcon('/usr/share/pixmaps/retext.png'))
		else:
			self.setWindowIcon(QIcon.fromTheme('retext',
				QIcon.fromTheme('accessories-text-editor')))
		self.tabWidget = QTabWidget(self)
		self.initTabWidget()
		self.setCentralWidget(self.tabWidget)
		self.tabWidget.currentChanged.connect(self.changeIndex)
		self.tabWidget.tabCloseRequested.connect(self.closeTab)
		self.toolBar = QToolBar(self.tr('File toolbar'), self)
		self.addToolBar(Qt.TopToolBarArea, self.toolBar)
		self.editBar = QToolBar(self.tr('Edit toolbar'), self)
		self.addToolBar(Qt.TopToolBarArea, self.editBar)
		self.searchBar = QToolBar(self.tr('Search toolbar'), self)
		self.addToolBar(Qt.BottomToolBarArea, self.searchBar)
		self.toolBar.setVisible(not globalSettings.hideToolBar)
		self.editBar.setVisible(not globalSettings.hideToolBar)
		self.actionNew = self.act(self.tr('New'), 'document-new',
			self.createNew, shct=QKeySequence.New)
		self.actionNew.setPriority(QAction.LowPriority)
		self.actionOpen = self.act(self.tr('Open'), 'document-open',
			self.openFile, shct=QKeySequence.Open)
		self.actionOpen.setPriority(QAction.LowPriority)
		self.actionSetEncoding = self.act(self.tr('Set encoding'),
			trig=self.showEncodingDialog)
		self.actionSetEncoding.setEnabled(False)
		self.actionReload = self.act(self.tr('Reload'), 'view-refresh',
			lambda: self.currentTab.readTextFromFile())
		self.actionReload.setEnabled(False)
		self.actionSave = self.act(self.tr('Save'), 'document-save',
			self.saveFile, shct=QKeySequence.Save)
		self.actionSave.setEnabled(False)
		self.actionSave.setPriority(QAction.LowPriority)
		self.actionSaveAs = self.act(self.tr('Save as'), 'document-save-as',
			self.saveFileAs, shct=QKeySequence.SaveAs)
		self.actionNextTab = self.act(self.tr('Next tab'), 'go-next',
			lambda: self.switchTab(1), shct=Qt.CTRL+Qt.Key_PageDown)
		self.actionPrevTab = self.act(self.tr('Previous tab'), 'go-previous',
			lambda: self.switchTab(-1), shct=Qt.CTRL+Qt.Key_PageUp)
		self.actionCloseCurrentTab = self.act(self.tr('Close tab'), 'window-close',
			lambda: self.closeTab(self.ind), shct=QKeySequence.Close)
		self.actionPrint = self.act(self.tr('Print'), 'document-print',
			self.printFile, shct=QKeySequence.Print)
		self.actionPrint.setPriority(QAction.LowPriority)
		self.actionPrintPreview = self.act(self.tr('Print preview'), 'document-print-preview',
			self.printPreview)
		self.actionViewHtml = self.act(self.tr('View HTML code'), 'text-html', self.viewHtml)
		self.actionChangeEditorFont = self.act(self.tr('Change editor font'),
			trig=self.changeEditorFont)
		self.actionChangePreviewFont = self.act(self.tr('Change preview font'),
			trig=self.changePreviewFont)
		self.actionSearch = self.act(self.tr('Find text'), 'edit-find',
			self.search, shct=QKeySequence.Find)
		self.actionGoToLine = self.act(self.tr('Go to line'),
			trig=self.goToLine, shct=Qt.CTRL+Qt.Key_G)
		self.searchBar.visibilityChanged.connect(self.searchBarVisibilityChanged)
		self.actionPreview = self.act(self.tr('Preview'), shct=Qt.CTRL+Qt.Key_E,
			trigbool=self.preview)
		if QIcon.hasThemeIcon('document-preview'):
			self.actionPreview.setIcon(QIcon.fromTheme('document-preview'))
		elif QIcon.hasThemeIcon('preview-file'):
			self.actionPreview.setIcon(QIcon.fromTheme('preview-file'))
		elif QIcon.hasThemeIcon('x-office-document'):
			self.actionPreview.setIcon(QIcon.fromTheme('x-office-document'))
		else:
			self.actionPreview.setIcon(QIcon(getBundledIcon('document-preview')))
		self.actionLivePreview = self.act(self.tr('Live preview'), shct=Qt.CTRL+Qt.Key_L,
		trigbool=self.enableLivePreview)
		menuPreview = QMenu()
		menuPreview.addAction(self.actionLivePreview)
		self.actionPreview.setMenu(menuPreview)
		self.actionInsertTable = self.act(self.tr('Insert table'),
			trig=lambda: self.insertFormatting('table'))
		self.actionTableMode = self.act(self.tr('Table editing mode'),
			shct=Qt.CTRL+Qt.Key_T,
			trigbool=lambda x: self.currentTab.editBox.enableTableMode(x))
		if ReTextFakeVimHandler:
			self.actionFakeVimMode = self.act(self.tr('FakeVim mode'),
				shct=Qt.CTRL+Qt.ALT+Qt.Key_V, trigbool=self.enableFakeVimMode)
			if globalSettings.useFakeVim:
				self.actionFakeVimMode.setChecked(True)
				self.enableFakeVimMode(True)
		self.actionFullScreen = self.act(self.tr('Fullscreen mode'), 'view-fullscreen',
			shct=Qt.Key_F11, trigbool=self.enableFullScreen)
		self.actionFullScreen.setChecked(self.isFullScreen())
		self.actionFullScreen.setPriority(QAction.LowPriority)
		self.actionConfig = self.act(self.tr('Preferences'), icon='preferences-system',
			trig=self.openConfigDialog)
		self.actionConfig.setMenuRole(QAction.PreferencesRole)
		self.actionSaveHtml = self.act('HTML', 'text-html', self.saveFileHtml)
		self.actionPdf = self.act('PDF', 'application-pdf', self.savePdf)
		self.actionOdf = self.act('ODT', 'x-office-document', self.saveOdf)
		self.getExportExtensionsList()
		self.actionQuit = self.act(self.tr('Quit'), 'application-exit', shct=QKeySequence.Quit)
		self.actionQuit.setMenuRole(QAction.QuitRole)
		self.actionQuit.triggered.connect(self.close)
		self.actionUndo = self.act(self.tr('Undo'), 'edit-undo',
			lambda: self.currentTab.editBox.undo(), shct=QKeySequence.Undo)
		self.actionRedo = self.act(self.tr('Redo'), 'edit-redo',
			lambda: self.currentTab.editBox.redo(), shct=QKeySequence.Redo)
		self.actionCopy = self.act(self.tr('Copy'), 'edit-copy',
			lambda: self.currentTab.editBox.copy(), shct=QKeySequence.Copy)
		self.actionCut = self.act(self.tr('Cut'), 'edit-cut',
			lambda: self.currentTab.editBox.cut(), shct=QKeySequence.Cut)
		self.actionPaste = self.act(self.tr('Paste'), 'edit-paste',
			lambda: self.currentTab.editBox.paste(), shct=QKeySequence.Paste)
		self.actionPasteImage = self.act(self.tr('Paste image'), 'edit-paste',
			lambda: self.currentTab.editBox.pasteImage(), shct=Qt.CTRL+Qt.SHIFT+Qt.Key_V)
		self.actionMoveUp = self.act(self.tr('Move line up'), 'go-up',
			lambda: self.currentTab.editBox.moveLineUp(), shct=Qt.ALT+Qt.Key_Up)
		self.actionMoveDown = self.act(self.tr('Move line down'), 'go-down',
			lambda: self.currentTab.editBox.moveLineDown(), shct=Qt.ALT+Qt.Key_Down)
		self.actionUndo.setEnabled(False)
		self.actionRedo.setEnabled(False)
		self.actionCopy.setEnabled(False)
		self.actionCut.setEnabled(False)
		qApp = QApplication.instance()
		qApp.clipboard().dataChanged.connect(self.clipboardDataChanged)
		self.clipboardDataChanged()
		if enchant is not None:
			self.actionEnableSC = self.act(self.tr('Enable'), trigbool=self.enableSpellCheck)
			self.actionSetLocale = self.act(self.tr('Set locale'), trig=self.changeLocale)
		self.actionWebKit = self.act(self.tr('Use WebKit renderer'), trigbool=self.enableWebKit)
		if ReTextWebKitPreview is None:
			globalSettings.useWebKit = False
			self.actionWebKit.setEnabled(False)
		self.actionWebKit.setChecked(globalSettings.useWebKit)
		self.actionWebEngine = self.act(self.tr('Use WebEngine (Chromium) renderer'),
			trigbool=self.enableWebEngine)
		if ReTextWebEnginePreview is None:
			globalSettings.useWebEngine = False
		self.actionWebEngine.setChecked(globalSettings.useWebEngine)
		self.actionShow = self.act(self.tr('Show directory'), 'system-file-manager', self.showInDir)
		self.actionFind = self.act(self.tr('Next'), 'go-next', self.find,
			shct=QKeySequence.FindNext)
		self.actionFindPrev = self.act(self.tr('Previous'), 'go-previous',
			lambda: self.find(back=True), shct=QKeySequence.FindPrevious)
		self.actionReplace = self.act(self.tr('Replace'), 'edit-find-replace',
			lambda: self.find(replace=True))
		self.actionReplaceAll = self.act(self.tr('Replace all'), trig=self.replaceAll)
		menuReplace = QMenu()
		menuReplace.addAction(self.actionReplaceAll)
		self.actionReplace.setMenu(menuReplace)
		self.actionCloseSearch = self.act(self.tr('Close'), 'window-close',
			lambda: self.searchBar.setVisible(False),
			shct=QKeySequence.Cancel)
		self.actionCloseSearch.setPriority(QAction.LowPriority)
		self.actionHelp = self.act(self.tr('Get help online'), 'help-contents', self.openHelp)
		self.aboutWindowTitle = self.tr('About ReText')
		self.actionAbout = self.act(self.aboutWindowTitle, 'help-about', self.aboutDialog)
		self.actionAbout.setMenuRole(QAction.AboutRole)
		self.actionAboutQt = self.act(self.tr('About Qt'))
		self.actionAboutQt.setMenuRole(QAction.AboutQtRole)
		self.actionAboutQt.triggered.connect(qApp.aboutQt)
		availableMarkups = markups.get_available_markups()
		if not availableMarkups:
			print('Warning: no markups are available!')
		if len(availableMarkups) > 1:
			self.chooseGroup = QActionGroup(self)
			markupActions = []
			for markup in availableMarkups:
				markupAction = self.act(markup.name, trigbool=self.markupFunction(markup))
				if markup.name == globalSettings.defaultMarkup:
					markupAction.setChecked(True)
				self.chooseGroup.addAction(markupAction)
				markupActions.append(markupAction)
		self.actionBold = self.act(self.tr('Bold'), shct=QKeySequence.Bold,
			trig=lambda: self.insertFormatting('bold'))
		self.actionItalic = self.act(self.tr('Italic'), shct=QKeySequence.Italic,
			trig=lambda: self.insertFormatting('italic'))
		self.actionUnderline = self.act(self.tr('Underline'), shct=QKeySequence.Underline,
			trig=lambda: self.insertFormatting('underline'))
		self.usefulTags = ('header', 'italic', 'bold', 'underline', 'numbering',
			'bullets', 'image', 'link', 'inline code', 'code block', 'blockquote',
			'table')
		self.usefulChars = ('deg', 'divide', 'euro', 'hellip', 'laquo', 'larr',
			'lsquo', 'mdash', 'middot', 'minus', 'nbsp', 'ndash', 'raquo',
			'rarr', 'rsquo', 'times')
		self.formattingBox = QComboBox(self.editBar)
		self.formattingBox.addItem(self.tr('Formatting'))
		self.formattingBox.addItems(self.usefulTags)
		self.formattingBox.activated[str].connect(self.insertFormatting)
		self.symbolBox = QComboBox(self.editBar)
		self.symbolBox.addItem(self.tr('Symbols'))
		self.symbolBox.addItems(self.usefulChars)
		self.symbolBox.activated.connect(self.insertSymbol)
		self.updateStyleSheet()
		menubar = self.menuBar()
		menuFile = menubar.addMenu(self.tr('File'))
		menuEdit = menubar.addMenu(self.tr('Edit'))
		menuHelp = menubar.addMenu(self.tr('Help'))
		menuFile.addAction(self.actionNew)
		menuFile.addAction(self.actionOpen)
		self.menuRecentFiles = menuFile.addMenu(self.tr('Open recent'))
		self.menuRecentFiles.aboutToShow.connect(self.updateRecentFiles)
		menuFile.addAction(self.actionShow)
		menuFile.addAction(self.actionSetEncoding)
		menuFile.addAction(self.actionReload)
		menuFile.addSeparator()
		menuFile.addAction(self.actionSave)
		menuFile.addAction(self.actionSaveAs)
		menuFile.addSeparator()
		menuFile.addAction(self.actionNextTab)
		menuFile.addAction(self.actionPrevTab)
		menuFile.addAction(self.actionCloseCurrentTab)
		menuFile.addSeparator()
		menuExport = menuFile.addMenu(self.tr('Export'))
		menuExport.addAction(self.actionSaveHtml)
		menuExport.addAction(self.actionOdf)
		menuExport.addAction(self.actionPdf)
		if self.extensionActions:
			menuExport.addSeparator()
			for action, mimetype in self.extensionActions:
				menuExport.addAction(action)
			menuExport.aboutToShow.connect(self.updateExtensionsVisibility)
		menuFile.addAction(self.actionPrint)
		menuFile.addAction(self.actionPrintPreview)
		menuFile.addSeparator()
		menuFile.addAction(self.actionQuit)
		menuEdit.addAction(self.actionUndo)
		menuEdit.addAction(self.actionRedo)
		menuEdit.addSeparator()
		menuEdit.addAction(self.actionCut)
		menuEdit.addAction(self.actionCopy)
		menuEdit.addAction(self.actionPaste)
		menuEdit.addAction(self.actionPasteImage)
		menuEdit.addSeparator()
		menuEdit.addAction(self.actionMoveUp)
		menuEdit.addAction(self.actionMoveDown)
		menuEdit.addSeparator()
		if enchant is not None:
			menuSC = menuEdit.addMenu(self.tr('Spell check'))
			menuSC.addAction(self.actionEnableSC)
			menuSC.addAction(self.actionSetLocale)
		menuEdit.addAction(self.actionSearch)
		menuEdit.addAction(self.actionGoToLine)
		menuEdit.addAction(self.actionChangeEditorFont)
		menuEdit.addAction(self.actionChangePreviewFont)
		menuEdit.addSeparator()
		if len(availableMarkups) > 1:
			self.menuMode = menuEdit.addMenu(self.tr('Default markup'))
			for markupAction in markupActions:
				self.menuMode.addAction(markupAction)
		menuFormat = menuEdit.addMenu(self.tr('Formatting'))
		menuFormat.addAction(self.actionBold)
		menuFormat.addAction(self.actionItalic)
		menuFormat.addAction(self.actionUnderline)
		if ReTextWebKitPreview is not None or ReTextWebEnginePreview is None:
			menuEdit.addAction(self.actionWebKit)
		else:
			menuEdit.addAction(self.actionWebEngine)
		menuEdit.addSeparator()
		menuEdit.addAction(self.actionViewHtml)
		menuEdit.addAction(self.actionPreview)
		menuEdit.addAction(self.actionInsertTable)
		menuEdit.addAction(self.actionTableMode)
		if ReTextFakeVimHandler:
			menuEdit.addAction(self.actionFakeVimMode)
		menuEdit.addSeparator()
		menuEdit.addAction(self.actionFullScreen)
		menuEdit.addAction(self.actionConfig)
		menuHelp.addAction(self.actionHelp)
		menuHelp.addSeparator()
		menuHelp.addAction(self.actionAbout)
		menuHelp.addAction(self.actionAboutQt)
		self.toolBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
		self.toolBar.addAction(self.actionNew)
		self.toolBar.addSeparator()
		self.toolBar.addAction(self.actionOpen)
		self.toolBar.addAction(self.actionSave)
		self.toolBar.addAction(self.actionPrint)
		self.toolBar.addSeparator()
		self.toolBar.addAction(self.actionPreview)
		self.toolBar.addAction(self.actionFullScreen)
		self.editBar.addAction(self.actionUndo)
		self.editBar.addAction(self.actionRedo)
		self.editBar.addSeparator()
		self.editBar.addAction(self.actionCut)
		self.editBar.addAction(self.actionCopy)
		self.editBar.addAction(self.actionPaste)
		self.editBar.addSeparator()
		self.editBar.addWidget(self.formattingBox)
		self.editBar.addWidget(self.symbolBox)
		self.searchEdit = QLineEdit(self.searchBar)
		self.searchEdit.setPlaceholderText(self.tr('Search'))
		self.searchEdit.returnPressed.connect(self.find)
		self.replaceEdit = QLineEdit(self.searchBar)
		self.replaceEdit.setPlaceholderText(self.tr('Replace with'))
		self.replaceEdit.returnPressed.connect(self.find)
		self.csBox = QCheckBox(self.tr('Case sensitively'), self.searchBar)
		self.searchBar.addWidget(self.searchEdit)
		self.searchBar.addWidget(self.replaceEdit)
		self.searchBar.addSeparator()
		self.searchBar.addWidget(self.csBox)
		self.searchBar.addAction(self.actionFindPrev)
		self.searchBar.addAction(self.actionFind)
		self.searchBar.addAction(self.actionReplace)
		self.searchBar.addAction(self.actionCloseSearch)
		self.searchBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
		self.searchBar.setVisible(False)
		self.autoSaveEnabled = globalSettings.autoSave
		if self.autoSaveEnabled:
			timer = QTimer(self)
			timer.start(60000)
			timer.timeout.connect(self.saveAll)
		self.ind = None
		if enchant is not None:
			self.sl = globalSettings.spellCheckLocale
			try:
				enchant.Dict(self.sl or None)
			except enchant.errors.Error as e:
				warnings.warn(str(e), RuntimeWarning)
				globalSettings.spellCheck = False
			if globalSettings.spellCheck:
				self.actionEnableSC.setChecked(True)
		self.fileSystemWatcher = QFileSystemWatcher()
		self.fileSystemWatcher.fileChanged.connect(self.fileChanged)

	def restoreLastOpenedFiles(self):
		for file in readListFromSettings("lastFileList"):
			self.openFileWrapper(file)

		# Show the tab of last opened file
		lastTabIndex = globalSettings.lastTabIndex
		if lastTabIndex >= 0 and lastTabIndex < self.tabWidget.count():
			self.tabWidget.setCurrentIndex(lastTabIndex)

	def iterateTabs(self):
		for i in range(self.tabWidget.count()):
			yield self.tabWidget.widget(i)

	def updateStyleSheet(self):
		self.ss = None
		if globalSettings.styleSheet:
			sheetfile = QFile(globalSettings.styleSheet)
			sheetfile.open(QIODevice.ReadOnly)
			self.ss = QTextStream(sheetfile).readAll()
			sheetfile.close()

	def initTabWidget(self):
		def dragEnterEvent(e):
			e.acceptProposedAction()
		def dropEvent(e):
			fn = bytes(e.mimeData().data('text/plain')).decode().rstrip()
			if fn.startswith('file:'):
				fn = QUrl(fn).toLocalFile()
			self.openFileWrapper(fn)
		self.tabWidget.setTabsClosable(True)
		self.tabWidget.setAcceptDrops(True)
		self.tabWidget.setMovable(True)
		self.tabWidget.dragEnterEvent = dragEnterEvent
		self.tabWidget.dropEvent = dropEvent
		self.tabWidget.setTabBarAutoHide(globalSettings.tabBarAutoHide)

	def act(self, name, icon=None, trig=None, trigbool=None, shct=None):
		if not isinstance(shct, QKeySequence):
			shct = QKeySequence(shct)
		if icon:
			action = QAction(self.actIcon(icon), name, self)
		else:
			action = QAction(name, self)
		if trig:
			action.triggered.connect(trig)
		elif trigbool:
			action.setCheckable(True)
			action.triggered[bool].connect(trigbool)
		if shct:
			action.setShortcut(shct)
		return action

	def actIcon(self, name):
		return QIcon.fromTheme(name, QIcon(getBundledIcon(name)))

	def printError(self):
		import traceback
		print('Exception occurred while parsing document:', file=sys.stderr)
		traceback.print_exc()


	def tabFileNameChanged(self, tab):
		'''
		Perform all UI state changes that need to be done when the
		filename of the current tab has changed.
		'''
		if tab == self.currentTab:
			if tab.fileName:
				self.setWindowTitle("")
				if globalSettings.windowTitleFullPath:
					self.setWindowTitle(tab.fileName + '[*]')
				self.setWindowFilePath(tab.fileName)
				self.tabWidget.setTabText(self.ind, tab.getBaseName())
				self.tabWidget.setTabToolTip(self.ind, tab.fileName)
				QDir.setCurrent(QFileInfo(tab.fileName).dir().path())
			else:
				self.setWindowFilePath('')
				self.setWindowTitle(self.tr('New document') + '[*]')

			canReload = bool(tab.fileName) and not self.autoSaveActive(tab)
			self.actionSetEncoding.setEnabled(canReload)
			self.actionReload.setEnabled(canReload)

	def tabActiveMarkupChanged(self, tab):
		'''
		Perform all UI state changes that need to be done when the
		active markup class of the current tab has changed.
		'''
		if tab == self.currentTab:
			markupClass = tab.getActiveMarkupClass()
			dtMarkdown = (markupClass == markups.MarkdownMarkup)
			dtMkdOrReST = dtMarkdown or (markupClass == markups.ReStructuredTextMarkup)
			self.formattingBox.setEnabled(dtMarkdown)
			self.symbolBox.setEnabled(dtMarkdown)
			self.actionUnderline.setEnabled(dtMarkdown)
			self.actionBold.setEnabled(dtMkdOrReST)
			self.actionItalic.setEnabled(dtMkdOrReST)

	def tabModificationStateChanged(self, tab):
		'''
		Perform all UI state changes that need to be done when the
		modification state of the current tab has changed.
		'''
		if tab == self.currentTab:
			changed = tab.editBox.document().isModified()
			if self.autoSaveActive(tab):
				changed = False
			self.actionSave.setEnabled(changed)
			self.setWindowModified(changed)

	def createTab(self, fileName):
		previewStatesByName = {
			'editor': PreviewDisabled,
			'normal-preview': PreviewNormal,
			'live-preview': PreviewLive,
		}
		previewState = previewStatesByName.get(globalSettings.defaultPreviewState, PreviewDisabled)
		if previewState == PreviewNormal and not fileName:
			previewState = PreviewDisabled  # Opening empty document in preview mode makes no sense
		self.currentTab = ReTextTab(self, fileName, previewState)
		self.currentTab.fileNameChanged.connect(lambda: self.tabFileNameChanged(self.currentTab))
		self.currentTab.modificationStateChanged.connect(lambda: self.tabModificationStateChanged(self.currentTab))
		self.currentTab.activeMarkupChanged.connect(lambda: self.tabActiveMarkupChanged(self.currentTab))
		self.tabWidget.addTab(self.currentTab, self.tr("New document"))
		self.currentTab.updateBoxesVisibility()
		if previewState > 0:
			QTimer.singleShot(500, self.currentTab.triggerPreviewUpdate)

	def closeTab(self, ind):
		if self.maybeSave(ind):
			if self.tabWidget.count() == 1:
				self.createTab("")
			closedTab = self.tabWidget.widget(ind)
			if closedTab.fileName:
				self.fileSystemWatcher.removePath(closedTab.fileName)
			self.tabWidget.removeTab(ind)
			closedTab.deleteLater()

	def changeIndex(self, ind):
		'''
		This function is called when a different tab is selected.
		It changes the state of the window to mirror the current state
		of the newly selected tab. Future changes to this state will be
		done in response to signals emitted by the tab, to which the
		window was subscribed when the tab was created. The window is
		subscribed to all tabs like this, but only the active tab will
		logically generate these signals.
		Aside from the above this function also calls the handlers for
		the other changes that are implied by a tab switch: filename
		change, modification state change and active markup change.
		'''
		self.currentTab = self.tabWidget.currentWidget()
		editBox = self.currentTab.editBox
		previewState = self.currentTab.previewState
		self.actionUndo.setEnabled(editBox.document().isUndoAvailable())
		self.actionRedo.setEnabled(editBox.document().isRedoAvailable())
		self.actionCopy.setEnabled(editBox.textCursor().hasSelection())
		self.actionCut.setEnabled(editBox.textCursor().hasSelection())
		self.actionPreview.setChecked(previewState >= PreviewLive)
		self.actionLivePreview.setChecked(previewState == PreviewLive)
		self.actionTableMode.setChecked(editBox.tableModeEnabled)
		self.editBar.setEnabled(previewState < PreviewNormal)
		self.ind = ind
		editBox.setFocus(Qt.OtherFocusReason)

		self.tabFileNameChanged(self.currentTab)
		self.tabModificationStateChanged(self.currentTab)
		self.tabActiveMarkupChanged(self.currentTab)

	def changeEditorFont(self):
		font, ok = QFontDialog.getFont(globalSettings.editorFont, self)
		if ok:
			self.setEditorFont(font)

	def setEditorFont(self, font):
		globalSettings.editorFont = font
		for tab in self.iterateTabs():
			tab.editBox.updateFont()

	def changePreviewFont(self):
		font, ok = QFontDialog.getFont(globalSettings.font, self)
		if ok:
			self.setPreviewFont(font)

	def setPreviewFont(self, font):
		globalSettings.font = font
		for tab in self.iterateTabs():
			tab.triggerPreviewUpdate()

	def preview(self, viewmode):
		self.currentTab.previewState = viewmode * 2
		self.actionLivePreview.setChecked(False)
		self.editBar.setDisabled(viewmode)
		self.currentTab.updateBoxesVisibility()
		self.currentTab.triggerPreviewUpdate()

	def enableLivePreview(self, livemode):
		self.currentTab.previewState = int(livemode)
		self.actionPreview.setChecked(livemode)
		self.editBar.setEnabled(True)
		self.currentTab.updateBoxesVisibility()
		self.currentTab.triggerPreviewUpdate()

	def enableWebKit(self, enable):
		globalSettings.useWebKit = enable
		globalSettings.useWebEngine = False
		for tab in self.iterateTabs():
			tab.rebuildPreviewBox()

	def enableWebEngine(self, enable):
		globalSettings.useWebKit = False
		globalSettings.useWebEngine = enable
		for tab in self.iterateTabs():
			tab.rebuildPreviewBox()

	def enableCopy(self, copymode):
		self.actionCopy.setEnabled(copymode)
		self.actionCut.setEnabled(copymode)

	def enableFullScreen(self, yes):
		if yes:
			self.showFullScreen()
		else:
			self.showNormal()

	def openConfigDialog(self):
		dlg = ConfigDialog(self)
		dlg.setWindowTitle(self.tr('Preferences'))
		dlg.show()

	def enableFakeVimMode(self, yes):
		globalSettings.useFakeVim = yes
		if yes:
			FakeVimMode.init(self)
			for tab in self.iterateTabs():
				tab.editBox.installFakeVimHandler()
		else:
			FakeVimMode.exit(self)

	def enableSpellCheck(self, yes):
		try:
			dict = enchant.Dict(self.sl or None)
		except enchant.errors.Error as e:
			QMessageBox.warning(self, '', str(e))
			self.actionEnableSC.setChecked(False)
			yes = False
		self.setAllDictionaries(dict if yes else None)
		globalSettings.spellCheck = yes

	def setAllDictionaries(self, dictionary):
		for tab in self.iterateTabs():
			hl = tab.highlighter
			hl.dictionary = dictionary
			hl.rehighlight()

	def changeLocale(self):
		localedlg = LocaleDialog(self, defaultText=self.sl)
		if localedlg.exec() != QDialog.Accepted:
			return
		sl = localedlg.localeEdit.text()
		try:
			enchant.Dict(sl or None)
		except enchant.errors.Error as e:
			QMessageBox.warning(self, '', str(e))
		else:
			self.sl = sl or None
			self.enableSpellCheck(self.actionEnableSC.isChecked())
			if localedlg.checkBox.isChecked():
				globalSettings.spellCheckLocale = sl

	def search(self):
		self.searchBar.setVisible(True)
		self.searchEdit.setFocus(Qt.ShortcutFocusReason)

	def goToLine(self):
		line, ok = QInputDialog.getInt(self, self.tr("Go to line"), self.tr("Type the line number"))
		if ok:
			self.currentTab.goToLine(line-1)

	def searchBarVisibilityChanged(self, visible):
		if visible:
			self.searchEdit.setFocus(Qt.ShortcutFocusReason)

	def find(self, back=False, replace=False):
		flags = QTextDocument.FindFlags()
		if back:
			flags |= QTextDocument.FindBackward
		if self.csBox.isChecked():
			flags |= QTextDocument.FindCaseSensitively
		text = self.searchEdit.text()
		replaceText = self.replaceEdit.text() if replace else None
		found = self.currentTab.find(text, flags, replaceText=replaceText)
		self.setSearchEditColor(found)

	def replaceAll(self):
		text = self.searchEdit.text()
		replaceText = self.replaceEdit.text()
		found = self.currentTab.replaceAll(text, replaceText)
		self.setSearchEditColor(found)

	def setSearchEditColor(self, found):
		palette = self.searchEdit.palette()
		palette.setColor(QPalette.Active, QPalette.Base,
		                 Qt.white if found else QColor(255, 102, 102))
		self.searchEdit.setPalette(palette)

	def showInDir(self):
		if self.currentTab.fileName:
			path = QFileInfo(self.currentTab.fileName).path()
			QDesktopServices.openUrl(QUrl.fromLocalFile(path))
		else:
			QMessageBox.warning(self, '', self.tr("Please, save the file somewhere."))

	def moveToTopOfRecentFileList(self, fileName):
		if fileName:
			files = readListFromSettings("recentFileList")
			if fileName in files:
				files.remove(fileName)
			files.insert(0, fileName)
			recentCount = globalSettings.recentDocumentsCount
			if len(files) > recentCount:
				del files[recentCount:]
			writeListToSettings("recentFileList", files)

	def createNew(self, text=None):
		self.createTab("")
		self.ind = self.tabWidget.count()-1
		self.tabWidget.setCurrentIndex(self.ind)
		if text:
			self.currentTab.editBox.textCursor().insertText(text)

	def switchTab(self, shift=1):
		self.tabWidget.setCurrentIndex((self.ind + shift) % self.tabWidget.count())

	def updateRecentFiles(self):
		self.menuRecentFiles.clear()
		self.recentFilesActions = []
		filesOld = readListFromSettings("recentFileList")
		files = []
		for f in filesOld:
			if QFile.exists(f):
				files.append(f)
				self.recentFilesActions.append(self.act(f, trig=self.openFunction(f)))
		writeListToSettings("recentFileList", files)
		for action in self.recentFilesActions:
			self.menuRecentFiles.addAction(action)

	def markupFunction(self, markup):
		return lambda: self.setDefaultMarkup(markup)

	def openFunction(self, fileName):
		return lambda: self.openFileWrapper(fileName)

	def extensionFunction(self, data):
		return lambda: \
		self.runExtensionCommand(data['Exec'], data['FileFilter'], data['DefaultExtension'])

	def getExportExtensionsList(self):
		extensions = []
		for extsprefix in datadirs:
			extsdir = QDir(extsprefix+'/export-extensions/')
			if extsdir.exists():
				for fileInfo in extsdir.entryInfoList(['*.desktop', '*.ini'],
				QDir.Files | QDir.Readable):
					extensions.append(self.readExtension(fileInfo.filePath()))
		locale = QLocale.system().name()
		self.extensionActions = []
		for extension in extensions:
			try:
				if ('Name[%s]' % locale) in extension:
					name = extension['Name[%s]' % locale]
				elif ('Name[%s]' % locale.split('_')[0]) in extension:
					name = extension['Name[%s]' % locale.split('_')[0]]
				else:
					name = extension['Name']
				data = {}
				for prop in ('FileFilter', 'DefaultExtension', 'Exec'):
					if 'X-ReText-'+prop in extension:
						data[prop] = extension['X-ReText-'+prop]
					elif prop in extension:
						data[prop] = extension[prop]
					else:
						data[prop] = ''
				action = self.act(name, trig=self.extensionFunction(data))
				if 'Icon' in extension:
					action.setIcon(self.actIcon(extension['Icon']))
				mimetype = extension['MimeType'] if 'MimeType' in extension else None
			except KeyError:
				print('Failed to parse extension: Name is required', file=sys.stderr)
			else:
				self.extensionActions.append((action, mimetype))

	def updateExtensionsVisibility(self):
		markupClass = self.currentTab.getActiveMarkupClass()
		for action in self.extensionActions:
			if markupClass is None:
				action[0].setEnabled(False)
				continue
			mimetype = action[1]
			if mimetype is None:
				enabled = True
			elif markupClass == markups.MarkdownMarkup:
				enabled = (mimetype in ("text/x-retext-markdown", "text/x-markdown", "text/markdown"))
			elif markupClass == markups.ReStructuredTextMarkup:
				enabled = (mimetype in ("text/x-retext-rst", "text/x-rst"))
			else:
				enabled = False
			action[0].setEnabled(enabled)

	def readExtension(self, fileName):
		extFile = QFile(fileName)
		extFile.open(QIODevice.ReadOnly)
		extension = {}
		stream = QTextStream(extFile)
		while not stream.atEnd():
			line = stream.readLine()
			if '=' in line:
				index = line.index('=')
				extension[line[:index].rstrip()] = line[index+1:].lstrip()
		extFile.close()
		return extension

	def openFile(self):
		supportedExtensions = ['.txt']
		for markup in markups.get_all_markups():
			supportedExtensions += markup.file_extensions
		fileFilter = ' (' + str.join(' ', ['*'+ext for ext in supportedExtensions]) + ');;'
		fileNames = QFileDialog.getOpenFileNames(self,
			self.tr("Select one or several files to open"), QDir.currentPath(),
			self.tr("Supported files") + fileFilter + self.tr("All files (*)"))
		for fileName in fileNames[0]:
			self.openFileWrapper(fileName)

	@pyqtSlot(str)
	def openFileWrapper(self, fileName):
		if not fileName:
			return
		fileName = QFileInfo(fileName).canonicalFilePath()
		exists = False
		for i, tab in enumerate(self.iterateTabs()):
			if tab.fileName == fileName:
				exists = True
				ex = i
		if exists:
			self.tabWidget.setCurrentIndex(ex)
		elif QFile.exists(fileName):
			noEmptyTab = (
				(self.ind is None) or
				self.currentTab.fileName or
				self.currentTab.editBox.toPlainText() or
				self.currentTab.editBox.document().isModified()
			)
			if noEmptyTab:
				self.createTab(fileName)
				self.ind = self.tabWidget.count()-1
				self.tabWidget.setCurrentIndex(self.ind)
			if fileName:
				self.fileSystemWatcher.addPath(fileName)
			self.currentTab.readTextFromFile(fileName)
			self.moveToTopOfRecentFileList(self.currentTab.fileName)

	def showEncodingDialog(self):
		if not self.maybeSave(self.ind):
			return
		codecsSet = set(bytes(QTextCodec.codecForName(alias).name())
		                for alias in QTextCodec.availableCodecs())
		encoding, ok = QInputDialog.getItem(self, '',
			self.tr('Select file encoding from the list:'),
			[bytes(b).decode() for b in sorted(codecsSet)],
			0, False)
		if ok:
			self.currentTab.readTextFromFile(None, encoding)

	def saveFileAs(self):
		self.saveFile(dlg=True)

	def saveAll(self):
		for tab in self.iterateTabs():
			if (tab.fileName and tab.editBox.document().isModified()
				and QFileInfo(tab.fileName).isWritable()):
				tab.saveTextToFile()

	def saveFile(self, dlg=False):
		fileNameToSave = self.currentTab.fileName

		if (not fileNameToSave) or dlg:
			proposedFileName = ""
			markupClass = self.currentTab.getActiveMarkupClass()
			if (markupClass is None) or not hasattr(markupClass, 'default_extension'):
				defaultExt = self.tr("Plain text (*.txt)")
				ext = ".txt"
			else:
				defaultExt = self.tr('%s files',
					'Example of final string: Markdown files') \
					% markupClass.name + ' (' + str.join(' ',
					('*'+extension for extension in markupClass.file_extensions)) + ')'
				if markupClass == markups.MarkdownMarkup:
					ext = globalSettings.markdownDefaultFileExtension
				elif markupClass == markups.ReStructuredTextMarkup:
					ext = globalSettings.restDefaultFileExtension
				else:
					ext = markupClass.default_extension
			if fileNameToSave is not None:
				proposedFileName = fileNameToSave
			fileNameToSave = QFileDialog.getSaveFileName(self,
				self.tr("Save file"), proposedFileName, defaultExt)[0]
			if fileNameToSave:
				if not QFileInfo(fileNameToSave).suffix():
					fileNameToSave += ext
				# Make sure we don't overwrite a file opened in other tab
				for tab in self.iterateTabs():
					if tab is not self.currentTab and tab.fileName == fileNameToSave:
						QMessageBox.warning(self, "",
							self.tr("Cannot save to file which is open in another tab!"))
						return False
				self.actionSetEncoding.setDisabled(self.autoSaveActive())
		if fileNameToSave:
			if self.currentTab.saveTextToFile(fileNameToSave):
				self.moveToTopOfRecentFileList(self.currentTab.fileName)
				return True
			else:
				QMessageBox.warning(self, '',
				self.tr("Cannot save to file because it is read-only!"))
		return False

	def saveHtml(self, fileName):
		if not QFileInfo(fileName).suffix():
			fileName += ".html"
		try:
			_, htmltext, _ = self.currentTab.getDocumentForExport(webenv=True)
		except Exception:
			return self.printError()
		htmlFile = QFile(fileName)
		result = htmlFile.open(QIODevice.WriteOnly)
		if not result:
			QMessageBox.warning(self, '',
				self.tr("Cannot save to file because it is read-only!"))
			return
		html = QTextStream(htmlFile)
		if globalSettings.defaultCodec:
			html.setCodec(globalSettings.defaultCodec)
		html << htmltext
		htmlFile.close()

	def textDocument(self, title, htmltext):
		td = QTextDocument()
		td.setMetaInformation(QTextDocument.DocumentTitle, title)
		td.setHtml(htmltext)
		td.setDefaultFont(globalSettings.font)
		return td

	def saveOdf(self):
		title, htmltext, _ = self.currentTab.getDocumentForExport()
		try:
			document = self.textDocument(title, htmltext)
		except Exception:
			return self.printError()
		fileName = QFileDialog.getSaveFileName(self,
			self.tr("Export document to ODT"), self.currentTab.getBaseName() + ".odt",
			self.tr("OpenDocument text files (*.odt)"))[0]
		if not QFileInfo(fileName).suffix():
			fileName += ".odt"
		writer = QTextDocumentWriter(fileName)
		writer.setFormat(b"odf")
		writer.write(document)

	def saveFileHtml(self):
		fileName = QFileDialog.getSaveFileName(self,
			self.tr("Save file"), self.currentTab.getBaseName() + ".html",
			self.tr("HTML files (*.html *.htm)"))[0]
		if fileName:
			self.saveHtml(fileName)

	def getDocumentForPrint(self, title, htmltext, preview):
		if globalSettings.useWebKit:
			return preview
		try:
			return self.textDocument(title, htmltext)
		except Exception:
			self.printError()

	def standardPrinter(self, title):
		printer = QPrinter(QPrinter.HighResolution)
		printer.setDocName(title)
		printer.setCreator('ReText %s' % app_version)
		if globalSettings.paperSize:
			pageSize = self.getPageSizeByName(globalSettings.paperSize)
			if pageSize is not None:
				printer.setPaperSize(pageSize)
			else:
				QMessageBox.warning(self, '',
					self.tr('Unrecognized paperSize setting "%s".') %
					globalSettings.paperSize)
		return printer

	def getPageSizeByName(self, pageSizeName):
		""" Returns a validated PageSize instance corresponding to the given
		name. Returns None if the name is not a valid PageSize.
		"""
		pageSize = None

		lowerCaseNames = {pageSize.lower(): pageSize for pageSize in
		                  self.availablePageSizes()}
		if pageSizeName.lower() in lowerCaseNames:
			pageSize = getattr(QPagedPaintDevice, lowerCaseNames[pageSizeName.lower()])

		return pageSize

	def availablePageSizes(self):
		""" List available page sizes. """

		sizes = [x for x in dir(QPagedPaintDevice)
		         if type(getattr(QPagedPaintDevice, x)) == QPagedPaintDevice.PageSize]
		return sizes

	def savePdf(self):
		fileName = QFileDialog.getSaveFileName(self,
			self.tr("Export document to PDF"),
			self.currentTab.getBaseName() + ".pdf",
			self.tr("PDF files (*.pdf)"))[0]
		if fileName:
			if not QFileInfo(fileName).suffix():
				fileName += ".pdf"
			title, htmltext, preview = self.currentTab.getDocumentForExport()
			if globalSettings.useWebEngine and hasattr(preview.page(), "printToPdf"):
				pageSize = self.getPageSizeByName(globalSettings.paperSize)
				if pageSize is None:
					pageSize = QPageSize(QPageSize.A4)
				margins = QMarginsF(20, 20, 13, 20)  # left, top, right, bottom (in millimeters)
				layout = QPageLayout(pageSize, QPageLayout.Portrait, margins, QPageLayout.Millimeter)
				preview.page().printToPdf(fileName, layout)  # Available since Qt 5.7
				return
			printer = self.standardPrinter(title)
			printer.setOutputFormat(QPrinter.PdfFormat)
			printer.setOutputFileName(fileName)
			document = self.getDocumentForPrint(title, htmltext, preview)
			if document != None:
				document.print(printer)

	def printFile(self):
		title, htmltext, preview = self.currentTab.getDocumentForExport()
		printer = self.standardPrinter(title)
		dlg = QPrintDialog(printer, self)
		dlg.setWindowTitle(self.tr("Print document"))
		if (dlg.exec() == QDialog.Accepted):
			document = self.getDocumentForPrint(title, htmltext, preview)
			if document != None:
				document.print(printer)

	def printPreview(self):
		title, htmltext, preview = self.currentTab.getDocumentForExport()
		document = self.getDocumentForPrint(title, htmltext, preview)
		if document is None:
			return
		printer = self.standardPrinter(title)
		preview = QPrintPreviewDialog(printer, self)
		preview.paintRequested.connect(document.print)
		preview.exec()

	def runExtensionCommand(self, command, filefilter, defaultext):
		import shlex
		of = ('%of' in command)
		html = ('%html' in command)
		if of:
			if defaultext and not filefilter:
				filefilter = '*'+defaultext
			fileName = QFileDialog.getSaveFileName(self,
				self.tr('Export document'), '', filefilter)[0]
			if not fileName:
				return
			if defaultext and not QFileInfo(fileName).suffix():
				fileName += defaultext
		else:
			fileName = 'out' + defaultext
		basename = '.%s.retext-temp' % self.currentTab.getBaseName()
		if html:
			tmpname = basename+'.html'
			self.saveHtml(tmpname)
		else:
			tmpname = basename + self.currentTab.getActiveMarkupClass().default_extension
			self.currentTab.writeTextToFile(tmpname)
		command = command.replace('%of', shlex.quote(fileName))
		command = command.replace('%html' if html else '%if', shlex.quote(tmpname))
		try:
			Popen(str(command), shell=True).wait()
		except Exception as error:
			errorstr = str(error)
			QMessageBox.warning(self, '', self.tr('Failed to execute the command:')
			+ '\n' + errorstr)
		QFile(tmpname).remove()

	def autoSaveActive(self, tab=None):
		tab = tab if tab else self.currentTab
		return bool(self.autoSaveEnabled and tab.fileName and
			    QFileInfo(tab.fileName).isWritable())

	def clipboardDataChanged(self):
		mimeData = QApplication.instance().clipboard().mimeData()
		if mimeData is not None:
			self.actionPaste.setEnabled(mimeData.hasText())
			self.actionPasteImage.setEnabled(mimeData.hasImage())

	def insertFormatting(self, formatting):
		if formatting == 'table':
			dialog = InsertTableDialog(self)
			dialog.show()
			self.formattingBox.setCurrentIndex(0)
			return

		cursor = self.currentTab.editBox.textCursor()
		text = cursor.selectedText()
		moveCursorTo = None

		def c(cursor):
			nonlocal moveCursorTo
			moveCursorTo = cursor.position()

		def ensurenl(cursor):
			if not cursor.atBlockStart():
				cursor.insertText('\n\n')

		toinsert = {
			'header': (ensurenl, '# ', text),
			'italic': ('*', text, c, '*'),
			'bold': ('**', text, c, '**'),
			'underline': ('<u>', text, c, '</u>'),
			'numbering': (ensurenl, ' 1. ', text),
			'bullets': (ensurenl, '  * ', text),
			'image': ('![', text or self.tr('Alt text'), c, '](', self.tr('URL'), ')'),
			'link': ('[', text or self.tr('Link text'), c, '](', self.tr('URL'), ')'),
			'inline code': ('`', text, c, '`'),
			'code block': (ensurenl, '    ', text),
			'blockquote': (ensurenl, '> ', text),
		}

		if formatting not in toinsert:
			return

		cursor.beginEditBlock()
		for token in toinsert[formatting]:
			if callable(token):
				token(cursor)
			else:
				cursor.insertText(token)
		cursor.endEditBlock()

		self.formattingBox.setCurrentIndex(0)
		# Bring back the focus on the editor
		self.currentTab.editBox.setFocus(Qt.OtherFocusReason)

		if moveCursorTo:
			cursor.setPosition(moveCursorTo)
			self.currentTab.editBox.setTextCursor(cursor)

	def insertSymbol(self, num):
		if num:
			self.currentTab.editBox.insertPlainText('&'+self.usefulChars[num-1]+';')
		self.symbolBox.setCurrentIndex(0)

	def fileChanged(self, fileName):
		tab = None
		for testtab in self.iterateTabs():
			if testtab.fileName == fileName:
				tab = testtab
		if tab is None:
			self.fileSystemWatcher.removePath(fileName)
			return
		if not QFile.exists(fileName):
			self.tabWidget.setCurrentWidget(tab)
			tab.editBox.document().setModified(True)
			QMessageBox.warning(self, '', self.tr(
				'This file has been deleted by other application.\n'
				'Please make sure you save the file before exit.'))
		elif not tab.editBox.document().isModified():
			# File was not modified in ReText, reload silently
			tab.readTextFromFile()
		else:
			self.tabWidget.setCurrentWidget(tab)
			text = self.tr(
				'This document has been modified by other application.\n'
				'Do you want to reload the file (this will discard all '
				'your changes)?\n')
			if self.autoSaveEnabled:
				text += self.tr(
					'If you choose to not reload the file, auto save mode will '
					'be disabled for this session to prevent data loss.')
			messageBox = QMessageBox(QMessageBox.Warning, '', text)
			reloadButton = messageBox.addButton(self.tr('Reload'), QMessageBox.YesRole)
			messageBox.addButton(QMessageBox.Cancel)
			messageBox.exec()
			if messageBox.clickedButton() is reloadButton:
				tab.readTextFromFile()
			else:
				self.autoSaveEnabled = False
				tab.editBox.document().setModified(True)
		if fileName not in self.fileSystemWatcher.files():
			# https://github.com/retext-project/retext/issues/137
			self.fileSystemWatcher.addPath(fileName)

	def maybeSave(self, ind):
		tab = self.tabWidget.widget(ind)
		if self.autoSaveActive(tab):
			tab.saveTextToFile()
			return True
		if not tab.editBox.document().isModified():
			return True
		self.tabWidget.setCurrentIndex(ind)
		ret = QMessageBox.warning(self, '',
			self.tr("The document has been modified.\nDo you want to save your changes?"),
			QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel)
		if ret == QMessageBox.Save:
			return self.saveFile(False)
		elif ret == QMessageBox.Cancel:
			return False
		return True

	def closeEvent(self, closeevent):
		for ind in range(self.tabWidget.count()):
			if not self.maybeSave(ind):
				return closeevent.ignore()
		if globalSettings.saveWindowGeometry:
			globalSettings.windowGeometry = self.saveGeometry()
		if globalSettings.openLastFilesOnStartup:
			files = [tab.fileName for tab in self.iterateTabs()]
			writeListToSettings("lastFileList", files)
			globalSettings.lastTabIndex = self.tabWidget.currentIndex()
		closeevent.accept()

	def viewHtml(self):
		htmlDlg = HtmlDialog(self)
		try:
			_, htmltext, _ = self.currentTab.getDocumentForExport(includeStyleSheet=False)
		except Exception:
			return self.printError()
		winTitle = self.currentTab.getBaseName()
		htmlDlg.setWindowTitle(winTitle+" ("+self.tr("HTML code")+")")
		htmlDlg.textEdit.setPlainText(htmltext.rstrip())
		htmlDlg.hl.rehighlight()
		htmlDlg.show()
		htmlDlg.raise_()
		htmlDlg.activateWindow()

	def openHelp(self):
		QDesktopServices.openUrl(QUrl('https://github.com/retext-project/retext/wiki'))

	def aboutDialog(self):
		QMessageBox.about(self, self.aboutWindowTitle,
		'<p><b>' + (self.tr('ReText %s (using PyMarkups %s)') % (app_version, markups.__version__))
		+'</b></p>' + self.tr('Simple but powerful editor'
		' for Markdown and reStructuredText')
		+'</p><p>'+self.tr('Author: Dmitry Shachnev, 2011').replace('2011', '2011–2017')
		+'<br><a href="https://github.com/retext-project/retext">'+self.tr('Website')
		+'</a> | <a href="http://daringfireball.net/projects/markdown/syntax">'
		+self.tr('Markdown syntax')
		+'</a> | <a href="http://docutils.sourceforge.net/docs/user/rst/quickref.html">'
		+self.tr('reStructuredText syntax')+'</a></p>')

	def setDefaultMarkup(self, markupClass):
		globalSettings.defaultMarkup = markupClass.name
		for tab in self.iterateTabs():
			if not tab.fileName:
				tab.updateActiveMarkupClass()
示例#34
0
class DAT_GUI(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.initUI()

    def initUI(self):
        screen = QApplication.desktop().screenNumber(
            QApplication.desktop().cursor().pos())
        centerPoint = QApplication.desktop().screenGeometry(screen).center()

        # should fit in 1024x768 (old computer screens)
        window_width = 900
        window_height = 700
        self.setGeometry(
            QtCore.QRect(
                centerPoint.x() - int(window_width / 2),
                centerPoint.y() - int(window_height / 2), window_width,
                window_height))  # should I rather center on the screen

        # zoom parameters
        self.scale = 1.0
        self.min_scaling_factor = 0.1
        self.max_scaling_factor = 20
        self.zoom_increment = 0.05

        self.setWindowTitle(__NAME__ + ' v' + str(__VERSION__))

        self.paint = Createpaintwidget()

        # initiate 2D image for 2D display
        self.img = None

        self.list = QListWidget(
            self)  # a list that contains files to read or play with
        self.list.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.list.selectionModel().selectionChanged.connect(
            self.selectionChanged)  # connect it to sel change

        self.scrollArea = QScrollArea()
        self.scrollArea.setBackgroundRole(QPalette.Dark)
        self.scrollArea.setWidget(self.paint)
        self.paint.scrollArea = self.scrollArea

        self.table_widget = QWidget()
        table_widget_layout = QVBoxLayout()

        # Initialize tab screen
        self.tabs = QTabWidget(self)
        self.tab1 = QWidget()
        self.tab2 = QWidget()
        self.tab3 = QWidget()

        # Add tabs
        self.tabs.addTab(self.tab1, "Mask neuron")
        self.tabs.addTab(self.tab2, "Mask cell body")
        self.tabs.addTab(self.tab3, "Segment dendrites")

        # listen to tab changes
        self.tabs.currentChanged.connect(self._onTabChange)

        # Create first tab
        self.tab1.layout = QGridLayout()
        self.tab1.layout.setAlignment(Qt.AlignTop)
        self.tab1.layout.setHorizontalSpacing(3)
        self.tab1.layout.setVerticalSpacing(3)
        self.tab1.layout.setContentsMargins(0, 0, 0, 0)

        label1_tab1 = QLabel('Step 1:')
        self.tab1.layout.addWidget(label1_tab1, 0, 0)

        self.local_threshold = QPushButton("Local threshold")
        self.local_threshold.clicked.connect(self.run_threshold_neuron)
        self.tab1.layout.addWidget(self.local_threshold, 0, 1)
        self.global_threshold = QPushButton("Global threshold")
        self.global_threshold.clicked.connect(self.run_threshold_neuron)
        self.tab1.layout.addWidget(self.global_threshold, 0, 2)
        self.local_n_global_threshold = QPushButton(
            "Local AND Global threshold")
        self.local_n_global_threshold.clicked.connect(
            self.run_threshold_neuron)
        self.tab1.layout.addWidget(self.local_n_global_threshold, 0, 3)

        self.extra_value_for_threshold = QSpinBox()
        self.extra_value_for_threshold.setSingleStep(1)
        self.extra_value_for_threshold.setRange(0, 1_000_000)
        self.extra_value_for_threshold.setValue(6)
        self.tab1.layout.addWidget(self.extra_value_for_threshold, 0, 4)

        self.threshold_method = QComboBox()
        self.threshold_method.addItem('Mean')
        self.threshold_method.addItem('Median')
        self.tab1.layout.addWidget(self.threshold_method, 0, 5)

        label2_tab1 = QLabel('Step 2 (optional):')
        self.tab1.layout.addWidget(label2_tab1, 1, 0)

        self.remove_pixel_blobs_smaller_or_equal = QPushButton(
            "Remove pixel blobs smaller or equal to")
        self.remove_pixel_blobs_smaller_or_equal.clicked.connect(
            self.remove_blobs)
        self.tab1.layout.addWidget(self.remove_pixel_blobs_smaller_or_equal, 1,
                                   1)

        self.remove_blobs_size = QSpinBox()
        self.remove_blobs_size.setSingleStep(1)
        self.remove_blobs_size.setRange(0, 1_000_000)
        self.remove_blobs_size.setValue(1)
        self.tab1.layout.addWidget(self.remove_blobs_size, 1, 2)

        label3_tab1 = QLabel('Step 3: Save')
        self.tab1.layout.addWidget(label3_tab1, 2, 0)

        self.tab1.setLayout(self.tab1.layout)

        self.tab2.layout = QGridLayout()
        self.tab2.layout.setAlignment(Qt.AlignTop)
        self.tab2.layout.setHorizontalSpacing(3)
        self.tab2.layout.setVerticalSpacing(3)
        self.tab2.layout.setContentsMargins(0, 0, 0, 0)

        label1_tab2 = QLabel('Step 1:')
        self.tab2.layout.addWidget(label1_tab2, 0, 0)

        self.detect_cell_body = QPushButton("Detect cell body")
        self.detect_cell_body.clicked.connect(self.detect_neuronal_cell_body)
        self.tab2.layout.addWidget(self.detect_cell_body, 0, 1)

        self.extraCutOff_cell_body = QSpinBox()
        self.extraCutOff_cell_body.setSingleStep(1)
        self.extraCutOff_cell_body.setRange(0, 1_000_000)
        self.extraCutOff_cell_body.setValue(5)
        self.tab2.layout.addWidget(self.extraCutOff_cell_body, 0, 2)

        erosion_label = QLabel('erosion rounds')
        self.tab2.layout.addWidget(erosion_label, 0, 3)

        self.nb_erosion_cellbody = QSpinBox()
        self.nb_erosion_cellbody.setSingleStep(1)
        self.nb_erosion_cellbody.setRange(0, 1_000_000)
        self.nb_erosion_cellbody.setValue(2)
        self.tab2.layout.addWidget(self.nb_erosion_cellbody, 0, 4)

        min_object_size_label = QLabel('minimum object size')
        self.tab2.layout.addWidget(min_object_size_label, 0, 5)

        self.min_obj_size_px = QSpinBox()
        self.min_obj_size_px.setSingleStep(1)
        self.min_obj_size_px.setRange(0, 1_000_000)
        self.min_obj_size_px.setValue(600)
        self.tab2.layout.addWidget(self.min_obj_size_px, 0, 6)

        fill_label = QLabel('fill up to')
        self.tab2.layout.addWidget(fill_label, 0, 7)

        self.fill_holes_up_to = QSpinBox()
        self.fill_holes_up_to.setSingleStep(1)
        self.fill_holes_up_to.setRange(0, 1_000_000)
        self.fill_holes_up_to.setValue(600)
        self.tab2.layout.addWidget(self.fill_holes_up_to, 0, 8)

        nb_dilation_cell_body_label = QLabel('nb dilation cell body')
        self.tab2.layout.addWidget(nb_dilation_cell_body_label, 0, 9)

        self.nb_dilation_cellbody = QSpinBox()
        self.nb_dilation_cellbody.setSingleStep(1)
        self.nb_dilation_cellbody.setRange(0, 1_000_000)
        self.nb_dilation_cellbody.setValue(2)
        self.tab2.layout.addWidget(self.nb_dilation_cellbody, 0, 10)

        label2_tab2 = QLabel('Step 2: Save')
        self.tab2.layout.addWidget(label2_tab2, 6, 0)

        self.tab2.setLayout(self.tab2.layout)

        self.tab3.layout = QGridLayout()
        self.tab3.layout.setAlignment(Qt.AlignTop)
        self.tab3.layout.setHorizontalSpacing(3)
        self.tab3.layout.setVerticalSpacing(3)
        self.tab3.layout.setContentsMargins(0, 0, 0, 0)

        label1_tab3 = QLabel('Step 1:')
        self.tab3.layout.addWidget(label1_tab3, 0, 0)

        self.wshed = QPushButton("Watershed")
        self.wshed.clicked.connect(self.watershed_segment_the_neuron)
        self.tab3.layout.addWidget(self.wshed, 0, 1)

        self.whsed_big_blur = QDoubleSpinBox()
        self.whsed_big_blur.setSingleStep(0.1)
        self.whsed_big_blur.setRange(0, 100)
        self.whsed_big_blur.setValue(2.1)
        self.tab3.layout.addWidget(self.whsed_big_blur, 0, 2)

        self.whsed_small_blur = QDoubleSpinBox()
        self.whsed_small_blur.setSingleStep(0.1)
        self.whsed_small_blur.setRange(0, 100)
        self.whsed_small_blur.setValue(1.4)
        self.tab3.layout.addWidget(self.whsed_small_blur, 0, 3)

        self.wshed_rm_small_cells = QSpinBox()
        self.wshed_rm_small_cells.setSingleStep(1)
        self.wshed_rm_small_cells.setRange(0, 1_000_000)
        self.wshed_rm_small_cells.setValue(10)
        self.tab3.layout.addWidget(self.wshed_rm_small_cells, 0, 4)

        self.jSpinner11 = QSpinBox()
        self.jSpinner11.setSingleStep(1)
        self.jSpinner11.setRange(0, 1_000_000)
        self.jSpinner11.setValue(10)
        self.tab3.layout.addWidget(self.jSpinner11, 0, 5)

        label1_bis_tab3 = QLabel('Alternative Step 1:')
        self.tab3.layout.addWidget(label1_bis_tab3, 1, 0)

        self.skel = QPushButton("Skeletonize")
        self.skel.clicked.connect(self.skeletonize_mask)
        self.tab3.layout.addWidget(self.skel, 1, 1)

        label2_tab3 = QLabel('Step 2:')
        self.tab3.layout.addWidget(label2_tab3, 2, 0)

        self.apply_cell_body = QPushButton("Apply cell body")
        self.apply_cell_body.clicked.connect(
            self.apply_cell_body_to_skeletonized_mask)
        self.tab3.layout.addWidget(self.apply_cell_body, 2, 1)

        label3_tab3 = QLabel('Step 3 (Optional):')
        self.tab3.layout.addWidget(label3_tab3, 3, 0)

        self.prune = QPushButton("Prune")
        self.prune.clicked.connect(self.prune_dendrites)
        self.tab3.layout.addWidget(self.prune, 3, 1)

        self.prune_length = QSpinBox()
        self.prune_length.setSingleStep(1)
        self.prune_length.setRange(0, 1_000_000)
        self.prune_length.setValue(3)
        self.tab3.layout.addWidget(self.prune_length, 3, 2)

        label4_tab3 = QLabel('Step 4 (Optional):')
        self.tab3.layout.addWidget(label4_tab3, 4, 0)

        self.find_neurons = QPushButton("Find neurons")
        self.find_neurons.clicked.connect(self.find_neurons_in_mask)
        self.tab3.layout.addWidget(self.find_neurons, 4, 1)

        self.find_neurons_min_size = QSpinBox()
        self.find_neurons_min_size.setSingleStep(1)
        self.find_neurons_min_size.setRange(0, 1_000_000)
        self.find_neurons_min_size.setValue(45)
        self.tab3.layout.addWidget(self.find_neurons_min_size, 4, 2)

        self.prune_unconnected_segments = QPushButton(
            "Prune unconnected segments (run 'Find neurons' first)")
        self.prune_unconnected_segments.clicked.connect(
            self.prune_neuron_unconnected_segments)
        self.tab3.layout.addWidget(self.prune_unconnected_segments, 4, 3)

        label6_tab3 = QLabel('Step 5: Save')
        self.tab3.layout.addWidget(label6_tab3, 5, 0)

        label5_tab3 = QLabel('Step 6:')
        self.tab3.layout.addWidget(label5_tab3, 6, 0)

        self.create_n_save_bonds = QPushButton("Segment dendrites")
        self.create_n_save_bonds.clicked.connect(self.save_segmented_bonds)
        self.tab3.layout.addWidget(self.create_n_save_bonds, 6, 1)

        self.tab3.setLayout(self.tab3.layout)

        # Add tabs to widget
        table_widget_layout.addWidget(self.tabs)
        self.table_widget.setLayout(table_widget_layout)

        self.Stack = QStackedWidget(self)
        self.Stack.addWidget(self.scrollArea)

        # create a grid that will contain all the GUI interface
        self.grid = QGridLayout()
        self.grid.addWidget(self.Stack, 0, 0)
        self.grid.addWidget(self.list, 0, 1)
        # The first parameter of the rowStretch method is the row number, the second is the stretch factor. So you need two calls to rowStretch, like this: --> below the first row is occupying 80% and the second 20%
        self.grid.setRowStretch(0, 75)
        self.grid.setRowStretch(2, 25)

        # first col 75% second col 25% of total width
        self.grid.setColumnStretch(0, 75)
        self.grid.setColumnStretch(1, 25)

        # void QGridLayout::addLayout(QLayout * layout, int row, int column, int rowSpan, int columnSpan, Qt::Alignment alignment = 0)
        self.grid.addWidget(self.table_widget, 2, 0, 1,
                            2)  # spans over one row and 2 columns

        # BEGIN TOOLBAR
        # pen spin box and connect
        self.penSize = QSpinBox()
        self.penSize.setSingleStep(1)
        self.penSize.setRange(1, 256)
        self.penSize.setValue(3)
        self.penSize.valueChanged.connect(self.penSizechange)

        self.channels = QComboBox()
        self.channels.addItem("merge")
        self.channels.currentIndexChanged.connect(self.channelChange)

        tb_drawing_pane = QToolBar()

        save_button = QToolButton()
        save_button.setText("Save")
        save_button.clicked.connect(self.save_current_mask)
        tb_drawing_pane.addWidget(save_button)

        tb_drawing_pane.addWidget(QLabel("Channels"))
        tb_drawing_pane.addWidget(self.channels)

        # tb.addAction("Save")
        #
        tb_drawing_pane.addWidget(QLabel("Pen size"))
        tb_drawing_pane.addWidget(self.penSize)

        self.grid.addWidget(tb_drawing_pane, 1, 0)
        # END toolbar

        # toolbar for the list
        tb_list = QToolBar()

        del_button = QToolButton()
        del_button.setText("Delete selection from list")
        del_button.clicked.connect(self.delete_from_list)
        tb_list.addWidget(del_button)

        self.grid.addWidget(tb_list, 1, 1)

        # self.setCentralWidget(self.scrollArea)
        self.setCentralWidget(QFrame())
        self.centralWidget().setLayout(self.grid)

        # self.statusBar().showMessage('Ready')
        statusBar = self.statusBar(
        )  # sets an empty status bar --> then can add messages in it
        self.paint.statusBar = statusBar

        # add progress bar to status bar
        self.progress = QProgressBar(self)
        self.progress.setGeometry(200, 80, 250, 20)
        statusBar.addWidget(self.progress)

        # Set up menu bar
        self.mainMenu = self.menuBar()

        self.zoomInAct = QAction(
            "Zoom &In (25%)",
            self,  # shortcut="Ctrl++",
            enabled=True,
            triggered=self.zoomIn)
        self.zoomOutAct = QAction(
            "Zoom &Out (25%)",
            self,  # shortcut="Ctrl+-",
            enabled=True,
            triggered=self.zoomOut)
        self.normalSizeAct = QAction(
            "&Normal Size",
            self,  # shortcut="Ctrl+S",
            enabled=True,
            triggered=self.defaultSize)

        self.viewMenu = QMenu("&View", self)
        self.viewMenu.addAction(self.zoomInAct)
        self.viewMenu.addAction(self.zoomOutAct)
        self.viewMenu.addAction(self.normalSizeAct)

        self.menuBar().addMenu(self.viewMenu)

        self.setMenuBar(self.mainMenu)

        # set drawing window fullscreen
        fullScreenShortcut = QtWidgets.QShortcut(
            QtGui.QKeySequence(QtCore.Qt.Key_F), self)
        fullScreenShortcut.activated.connect(self.fullScreen)
        fullScreenShortcut.setContext(QtCore.Qt.ApplicationShortcut)

        escapeShortcut = QtWidgets.QShortcut(
            QtGui.QKeySequence(QtCore.Qt.Key_Escape), self)
        escapeShortcut.activated.connect(self.escape)
        escapeShortcut.setContext(QtCore.Qt.ApplicationShortcut)

        # Show/Hide the mask
        escapeShortcut = QtWidgets.QShortcut(
            QtGui.QKeySequence(QtCore.Qt.Key_H), self)
        escapeShortcut.activated.connect(self.showHideMask)
        escapeShortcut.setContext(QtCore.Qt.ApplicationShortcut)

        zoomPlus = QtWidgets.QShortcut("Ctrl+Shift+=", self)
        zoomPlus.activated.connect(self.zoomIn)
        zoomPlus.setContext(QtCore.Qt.ApplicationShortcut)

        zoomPlus2 = QtWidgets.QShortcut("Ctrl++", self)
        zoomPlus2.activated.connect(self.zoomIn)
        zoomPlus2.setContext(QtCore.Qt.ApplicationShortcut)

        zoomMinus = QtWidgets.QShortcut("Ctrl+Shift+-", self)
        zoomMinus.activated.connect(self.zoomOut)
        zoomMinus.setContext(QtCore.Qt.ApplicationShortcut)

        zoomMinus2 = QtWidgets.QShortcut("Ctrl+-", self)
        zoomMinus2.activated.connect(self.zoomOut)
        zoomMinus2.setContext(QtCore.Qt.ApplicationShortcut)

        spaceShortcut = QtWidgets.QShortcut(
            QtGui.QKeySequence(QtCore.Qt.Key_Space), self)
        spaceShortcut.activated.connect(self.nextFrame)
        spaceShortcut.setContext(QtCore.Qt.ApplicationShortcut)

        backspaceShortcut = QtWidgets.QShortcut(
            QtGui.QKeySequence(QtCore.Qt.Key_Backspace), self)
        backspaceShortcut.activated.connect(self.prevFrame)
        backspaceShortcut.setContext(QtCore.Qt.ApplicationShortcut)

        # connect enter keys to edit dendrites
        enterShortcut = QtWidgets.QShortcut(
            QtGui.QKeySequence(QtCore.Qt.Key_Return), self)
        enterShortcut.activated.connect(self.runSkel)
        enterShortcut.setContext(QtCore.Qt.ApplicationShortcut)
        enter2Shortcut = QtWidgets.QShortcut(
            QtGui.QKeySequence(QtCore.Qt.Key_Enter), self)
        enter2Shortcut.activated.connect(self.runSkel)
        enter2Shortcut.setContext(QtCore.Qt.ApplicationShortcut)

        #Qt.Key_Enter is the Enter located on the keypad:
        #Qt::Key_Return  0x01000004
        #Qt::Key_Enter   0x01000005  Typically located on the keypad.

        self.setAcceptDrops(True)  # KEEP IMPORTANT

    def __get_mask_img_from_overlay(self):
        if self.paint.imageDraw:
            channels_count = 4
            s = self.paint.imageDraw.bits().asstring(
                self.img.shape[0] * self.img.shape[1] * channels_count)
            arr = np.frombuffer(s, dtype=np.uint8).reshape(
                (self.img.shape[0], self.img.shape[1], channels_count))
            return Img(arr[..., 2].copy(), dimensions='hw')
        else:
            return None

    def __get_output_folder(self):
        selected_items = self.list.selectedItems()
        if selected_items:
            filename = selected_items[0].toolTip()
            filename0_without_ext = os.path.splitext(filename)[0]
            return filename0_without_ext
        else:
            return None

    def delete_from_list(self):
        list_items = self.list.selectedItems()
        # empty list --> nothing to do
        if not list_items:
            return
        for item in list_items:
            self.list.takeItem(self.list.row(item))

    def save_current_mask(self):
        output_folder = self.__get_output_folder()
        if output_folder is None:
            logger.error('No image is selected --> nothing to save')
            return
        mask = self.__get_mask_img_from_overlay()
        if mask is None:
            logger.error('No mask/overlay detected --> nothing to save')
            return
        if self.tabs.currentIndex() == 0:
            print('saving', os.path.join(output_folder, 'mask.tif'))
            mask.save(os.path.join(output_folder, 'mask.tif'))
        elif self.tabs.currentIndex() == 1:
            print('saving', os.path.join(output_folder, 'cellBodyMask.tif'))
            mask.save(os.path.join(output_folder, 'cellBodyMask.tif'))
        else:
            print('saving', os.path.join(output_folder, 'handCorrection.tif'))
            mask.save(os.path.join(output_folder, 'handCorrection.tif'))

    def detect_neuronal_cell_body(self):
        try:
            # get image and detect cell body
            mask = detect_cell_body(
                self.img,
                fillHoles=self.fill_holes_up_to.value(),
                denoise=self.min_obj_size_px.value(),
                nbOfErosions=self.nb_erosion_cellbody.value(),
                nbOfDilatations=self.nb_dilation_cellbody.value(),
                extraCutOff=self.extraCutOff_cell_body.value(),
                channel=self.channels.currentText())
            if mask is not None:
                self.paint.imageDraw = Img(self.createRGBA(mask),
                                           dimensions='hwc').getQimage()
                self.paint.update()
            else:
                logger.error('Cell body could not be detected')
        except:
            traceback.print_exc()

    def __get_neuronal_mask(self, warn=True):
        output_folder = self.__get_output_folder()
        if output_folder is None:
            if warn:
                logger.error('No image selected --> nothing to do')
            return None
        if os.path.exists(os.path.join(output_folder, 'mask.tif')):
            # NB should I check the nb of channels --> no I don't want to handle externally created files and want people to rely fully on my stuff that has
            return Img(os.path.join(output_folder, 'mask.tif'))
        else:
            if warn:
                logger.error(
                    'Neuronal mask not found --> Please create one in the "Mask neuron" tab first'
                )
        return None

    def __get_corrected_mask(self, warn=True):
        output_folder = self.__get_output_folder()
        if output_folder is None:
            if warn:
                logger.error('No image selected --> nothing to do')
            return None
        if os.path.exists(os.path.join(output_folder, 'handCorrection.tif')):
            return Img(os.path.join(output_folder, 'handCorrection.tif'))
        elif os.path.exists(os.path.join(output_folder,
                                         'mask.tif')) and not warn:
            return Img(os.path.join(output_folder, 'mask.tif'))
        return None

    def __get_cellbody_mask(self, warn=True):
        output_folder = self.__get_output_folder()
        if output_folder is None:
            if warn:
                logger.error('No image selected --> nothing to do')
            return None
        if os.path.exists(os.path.join(output_folder, 'cellBodyMask.tif')):
            # NB should I check the nb of channels --> no I don't want to handle externally created files and want people to rely fully on my stuff that has
            return Img(os.path.join(output_folder, 'cellBodyMask.tif'))
        else:
            if warn:
                logger.error(
                    'Cell body mask not found --> Please create one in the "Mask cell body" tab first'
                )
        return None

    # seems ok for now
    def watershed_segment_the_neuron(self):
        try:
            # get raw image and segment it using the watershed algorithm
            # make it load the neuronal mask
            neuronal_mask = self.__get_neuronal_mask()
            if neuronal_mask is None:
                return
            # TODO should I add autoskel or not
            mask = watershed_segment_neuron(
                self.img,
                neuronal_mask,
                fillSize=self.jSpinner11.value(),
                autoSkel=True,
                first_blur=self.whsed_big_blur.value(),
                second_blur=self.whsed_small_blur.value(),
                min_size=self.wshed_rm_small_cells.value(),
                channel=self.channels.currentText())
            if mask is not None:
                self.paint.imageDraw = Img(self.createRGBA(mask),
                                           dimensions='hwc').getQimage()
                self.paint.update()
            else:
                logger.error(
                    'Something went wrong, the neuron could not be segmented, sorry...'
                )
        except:
            traceback.print_exc()

    def save_segmented_bonds(self):
        output_folder = self.__get_output_folder()
        if output_folder is None:
            logger.error('No image is selected --> nothing to save')
            return
        # get mask the find neurons
        mask = self.__get_mask_img_from_overlay()
        if mask is None:
            logger.error('No mask/overlay detected --> nothing to do')
            return
        mask = detect_cell_bonds(mask)

        if mask is None:
            logger.error(
                'Could not find dendrites, are you sure a mask is overlayed over the neuron'
            )
            return

        # code for conversion of 24 bits numpy array to an RGB one --> keep and store in Img at some point cause useful
        # convert 24 bits array to RGB
        RGB_mask = np.zeros(shape=(*mask.shape, 3), dtype=np.uint8)
        RGB_mask[..., 2] = mask & 255
        RGB_mask[..., 1] = (mask >> 8) & 255
        RGB_mask[..., 0] = (mask >> 16) & 255

        Img(RGB_mask,
            dimensions='hwc').save(os.path.join(output_folder, 'bonds.tif'))

    def prune_neuron_unconnected_segments(self):
        # get mask the find neurons
        mask = self.__get_mask_img_from_overlay()
        if mask is None:
            logger.error('No mask/overlay detected --> nothing to do')
            return
        mask = find_neurons(
            mask,
            neuron_minimum_size_threshold=self.find_neurons_min_size.value(),
            return_unconnected=True)
        if mask is None:
            logger.error(
                'Could not find neurons, are you sure a mask is overlayed over the neuron'
            )
            return

        self.paint.imageDraw = Img(self.createRGBA(mask),
                                   dimensions='hwc').getQimage()
        self.paint.update()

    def apply_cell_body_to_skeletonized_mask(self):
        mask = self.__get_mask_img_from_overlay()
        if mask is None:
            logger.error('No mask/overlay detected --> nothing to do')
            return
        cell_body_mask = self.__get_cellbody_mask()
        if cell_body_mask is None:
            return
        cell_body_outline = get_cell_body_outline(cell_body_mask, mask)
        if cell_body_outline is None:
            logger.error(
                'Error could not add cell body outline to the neuronal mask...'
            )
            return
        self.paint.imageDraw = Img(self.createRGBA(cell_body_outline),
                                   dimensions='hwc').getQimage()
        self.paint.update()

    def find_neurons_in_mask(self):
        # get mask the find neurons
        mask = self.__get_mask_img_from_overlay()
        if mask is None:
            logger.error('No mask/overlay detected --> nothing to do')
            return
        mask_copy = mask.copy()
        mask = find_neurons(
            mask,
            neuron_minimum_size_threshold=self.find_neurons_min_size.value())
        if mask is None:
            logger.error(
                'Could not find neurons, are you sure a mask is overlayed over the neuron'
            )
            return

        # we set the red channel, the blue one, the alpha transparency (channel 4) and finally we only allow alpha channel in the two masks regions to keep the rest of the stuff
        final_overlay = np.zeros(shape=(*mask_copy.shape, 4), dtype=np.uint8)
        final_overlay[..., 0] = np.logical_xor(mask, mask_copy).astype(
            np.uint8) * 255  # blue channel
        final_overlay[mask == 0, 0] = 0
        final_overlay[..., 1] = final_overlay[
            ...,
            0]  # green channel # copy the channel to make the stuff appear cyan
        final_overlay[..., 2] = mask_copy  # red channel
        final_overlay[np.logical_or(mask, mask_copy) != 0,
                      3] = 255  # --> need set alpha transparency of the image

        self.paint.imageDraw = Img(final_overlay, dimensions='hwc').getQimage()
        self.paint.update()

    def prune_dendrites(self):

        prune_lgth = self.prune_length.value()
        if prune_lgth <= 0:
            logger.info('prune length is 0 --> nothing to do')
            return

        # get the mask from displayed image
        mask = self.__get_mask_img_from_overlay()
        if mask is None:
            logger.error('No mask/overlay detected --> nothing to do')
            return

        # see how to get the stuff ????
        mask = prune_dendrites(mask, prune_below=prune_lgth)

        if mask is None:
            logger.error(
                'Could not prune dendrites, are you sure there is a mask ovrlayed on the neuron'
            )
            return

        self.paint.imageDraw = Img(self.createRGBA(mask),
                                   dimensions='hwc').getQimage()
        self.paint.update()

    def skeletonize_mask(self):
        # get mask then skeletonize it then return it --> see exactly
        try:
            # get raw image and segment it using the skeletonize algorithm
            # make it load the neuronal mask
            neuronal_mask = self.__get_neuronal_mask()
            if neuronal_mask is None:
                return
            mask = skel_segment_neuronal_mask(neuronal_mask)
            if mask is not None:
                self.paint.imageDraw = Img(self.createRGBA(mask),
                                           dimensions='hwc').getQimage()
                self.paint.update()
            else:
                logger.error(
                    'Something went wrong, the neuron could not be sekeletonized, sorry...'
                )
        except:
            traceback.print_exc()

    def _onTabChange(self):
        # if tab is changed --> do stuff
        # load files or warn...
        if self.tabs.currentIndex() == 0:
            mask = self.__get_neuronal_mask(warn=False)
            if mask is not None:
                self.paint.imageDraw = Img(self.createRGBA(mask),
                                           dimensions='hwc').getQimage()
                self.paint.update()
        elif self.tabs.currentIndex() == 1:
            mask = self.__get_cellbody_mask(warn=False)
            if mask is not None:
                self.paint.imageDraw = Img(self.createRGBA(mask),
                                           dimensions='hwc').getQimage()
                self.paint.update()
        elif self.tabs.currentIndex() == 2:
            mask = self.__get_corrected_mask(warn=False)
            if mask is not None:
                self.paint.imageDraw = Img(self.createRGBA(mask),
                                           dimensions='hwc').getQimage()
                self.paint.update()

    def run_threshold_neuron(self):
        try:
            local_or_global = 'global'
            if self.sender() == self.local_threshold:
                local_or_global = 'local'
            elif self.sender() == self.local_n_global_threshold:
                local_or_global = 'local+global'

            mask = threshold_neuron(
                self.img,
                mode=local_or_global,
                blur_method=self.threshold_method.currentText(),
                spin_value=self.extra_value_for_threshold.value(),
                channel=self.channels.currentText())
            if mask is not None:
                self.paint.imageDraw = Img(self.createRGBA(mask),
                                           dimensions='hwc').getQimage()
                self.paint.update()
        except:
            traceback.print_exc()

    def channelChange(self, i):
        if self.Stack.currentIndex() == 0:
            if i == 0:
                self.paint.setImage(self.img)
            else:
                channel_img = self.img.imCopy(c=i - 1)
                self.paint.setImage(channel_img)
            self.paint.update()

    def penSizechange(self):
        self.paint.brushSize = self.penSize.value()

    def selectionChanged(self):
        self.paint.maskVisible = True
        selected_items = self.list.selectedItems()
        if selected_items:
            start = timer()
            if self.img is not None:
                # make sure we don't load the image twice
                if selected_items[0].toolTip() != self.img.metadata['path']:
                    self.img = Img(selected_items[0].toolTip())
                    logger.debug("took " + str(timer() - start) +
                                 " secs to load image")
                else:
                    logger.debug("image already loaded --> ignoring")
            else:
                self.img = Img(selected_items[0].toolTip())
                logger.debug("took " + str(timer() - start) +
                             " secs to load image")

        if self.img is not None:
            selection = self.channels.currentIndex()
            self.channels.disconnect()
            self.channels.clear()
            comboData = ['merge']
            if self.img.has_c():
                for i in range(self.img.get_dimension('c')):
                    comboData.append(str(i))
            logger.debug('channels found ' + str(comboData))
            self.channels.addItems(comboData)
            if selection != -1 and selection < self.channels.count():
                self.channels.setCurrentIndex(selection)
            else:
                self.channels.setCurrentIndex(0)
            self.channels.currentIndexChanged.connect(self.channelChange)

        if selected_items:
            self.statusBar().showMessage('Loading ' +
                                         selected_items[0].toolTip())
            selection = self.channels.currentIndex()
            if selection == 0:
                self.paint.setImage(self.img)
            else:
                self.paint.setImage(self.img.imCopy(c=selection - 1))
            self.scaleImage(0)
            self.update()
            self.paint.update()

            if self.list.currentItem() and self.list.currentItem().icon(
            ).isNull():
                logger.debug('Updating icon')
                icon = QIcon(QPixmap.fromImage(self.paint.image))
                pixmap = icon.pixmap(24, 24)
                icon = QIcon(pixmap)
                self.list.currentItem().setIcon(icon)
        else:
            logger.debug("Empty selection")
            self.paint.image = None
            self.scaleImage(0)
            self.update()
            self.paint.update()
            self.img = None
        # try update also the masks if they are available
        try:
            self._onTabChange()
        except:
            pass

    def clearlayout(self, layout):
        for i in reversed(range(layout.count())):
            layout.itemAt(i).widget().setParent(None)

    def showHideMask(self):
        self.paint.maskVisible = not self.paint.maskVisible
        self.paint.update()

    def escape(self):
        if self.Stack.isFullScreen():
            self.fullScreen()

    def fullScreen(self):
        if not self.Stack.isFullScreen():
            self.Stack.setWindowFlags(
                QtCore.Qt.Window | QtCore.Qt.CustomizeWindowHint |
                # QtCore.Qt.WindowTitleHint |
                # QtCore.Qt.WindowCloseButtonHint |
                QtCore.Qt.WindowStaysOnTopHint)
            self.Stack.showFullScreen()
        else:
            self.Stack.setWindowFlags(QtCore.Qt.Widget)
            self.grid.addWidget(self.Stack, 0, 0)
            # dirty hack to make it repaint properly --> obviously not all lines below are required but some are --> need test, the last line is key though
            self.grid.update()
            self.Stack.update()
            self.Stack.show()
            self.centralWidget().setLayout(self.grid)
            self.centralWidget().update()
            self.update()
            self.show()
            self.repaint()
            self.Stack.update()
            self.Stack.repaint()
            self.centralWidget().repaint()

    def nextFrame(self):
        idx = self.list.model().index(self.list.currentRow() + 1, 0)
        if idx.isValid():
            self.list.selectionModel().setCurrentIndex(
                idx, QItemSelectionModel.ClearAndSelect)  # SelectCurrent

    def remove_blobs(self):
        blob_size = self.remove_blobs_size.value()
        if blob_size <= 0:
            logger.info('blob size is 0 --> nothing to do')
            return

        # get the mask from displayed image
        mask = self.__get_mask_img_from_overlay()
        if mask is None:
            logger.error('No mask/overlay detected --> nothing to save')
            return

        mask = remove_small_objects(mask.astype(np.bool),
                                    min_size=blob_size,
                                    connectivity=2,
                                    in_place=False)
        # then place back pixels in the mask
        # now set the mask back
        # plt.imshow(mask)
        # plt.show()

        self.paint.imageDraw = Img(self.createRGBA(mask),
                                   dimensions='hwc').getQimage()
        self.paint.update()

    def runSkel(self):
        # only allow that for tab 3
        if self.tabs.currentIndex() == 2:
            mask = self.__get_mask_img_from_overlay()
            if mask is None:
                logger.error('No mask/overlay detected --> nothing to do')
                return
            # just skeletonize the image
            mask = skel_segment_neuronal_mask(
                mask, fill_holes=0)  # should I put it to 0 or other things ???
            if mask is None:
                logger.error('Could not skeletonize user edited mask...')
                return

            self.paint.imageDraw = Img(self.createRGBA(mask),
                                       dimensions='hwc').getQimage()
            self.paint.update()

    def createRGBA(self, handCorrection):
        # use pen color to display the mask
        # in fact I need to put the real color
        RGBA = np.zeros((handCorrection.shape[0], handCorrection.shape[1], 4),
                        dtype=np.uint8)
        red = self.paint.drawColor.red()
        green = self.paint.drawColor.green()
        blue = self.paint.drawColor.blue()

        # bug somewhere --> fix it some day --> due to bgra instead of RGBA
        RGBA[handCorrection != 0, 0] = blue  # b
        RGBA[handCorrection != 0, 1] = green  # g
        RGBA[handCorrection != 0, 2] = red  # r
        RGBA[..., 3] = 255  # alpha --> indeed alpha
        RGBA[handCorrection == 0, 3] = 0  # very complex fix some day

        return RGBA

    def prevFrame(self):
        idx = self.list.model().index(self.list.currentRow() - 1, 0)
        if idx.isValid():
            self.list.selectionModel().setCurrentIndex(
                idx, QItemSelectionModel.ClearAndSelect)

    def zoomIn(self):
        self.statusBar().showMessage('Zooming in', msecs=200)
        if self.Stack.currentIndex() == 0:
            self.scaleImage(self.zoom_increment)

    def zoomOut(self):
        self.statusBar().showMessage('Zooming out', msecs=200)
        if self.Stack.currentIndex() == 0:
            self.scaleImage(-self.zoom_increment)

    def defaultSize(self):
        self.paint.adjustSize()
        self.scale = 1.0
        self.scaleImage(0)

    def scaleImage(self, factor):
        self.scale += factor
        if self.paint.image is not None:
            self.paint.resize(self.scale * self.paint.image.size())
        else:
            # no image set size to 0, 0 --> scroll pane will auto adjust
            self.paint.resize(QSize(0, 0))
            self.scale -= factor  # reset zoom

        self.paint.scale = self.scale
        # self.paint.vdp.scale = self.scale

        self.zoomInAct.setEnabled(self.scale < self.max_scaling_factor)
        self.zoomOutAct.setEnabled(self.scale > self.min_scaling_factor)

        # allow DND

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls:
            event.accept()
        else:
            event.ignore()

    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls:
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()
        else:
            event.ignore()

        # handle DND on drop

    def dropEvent(self, event):
        if event.mimeData().hasUrls:
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()
            urls = []
            for url in event.mimeData().urls():
                urls.append(url.toLocalFile())

            for url in urls:
                import os
                item = QListWidgetItem(os.path.basename(url), self.list)
                item.setToolTip(url)
                self.list.addItem(item)
        else:
            event.ignore()
示例#35
0
class MainWindow(QWidget):
    __exit = False
    futures = None

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.title = "CryptoAlerts"
        self.left = 50
        self.top = 50
        self.width = 600
        self.height = 400
        self.ticker = "btcusdt"
        self.dlg = PriceAlertDialog()
        self.dlg.setWindowModality(Qt.WindowModality.WindowModal)

        self.InitUI()

        self.create_config()

        self.check_alerts = threading.Thread(target=self.check_prices)
        if self.futures:
            self.check_alerts.start()

    def create_config(self):
        """ Create new folder and config.json file in local appdata directory to store the api keys
        """
        config_dir = os.path.join(os.getenv("LOCALAPPDATA"), "CryptoAlerts")
        if not os.path.exists(config_dir) or not os.path.exists(
                os.path.join(config_dir, "config.json")):
            try:
                os.mkdir(config_dir)
            except:
                print(f"Couldn't create a directory in {config_dir}")

            input_d = APIInputDialog(config_dir)
            acc = input_d.exec()
            if acc == QDialog.Accepted:
                self.futures = Futures(True)
        else:
            self.futures = Futures(True)

    def InitUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.ticker_textbox = QLineEdit()
        self.ticker_textbox.returnPressed.connect(self.change_ticker)

        # Alert textbox
        self.alert_pricebox = QLineEdit()

        # Alert button
        alert_b = QPushButton("Set Alert")
        alert_b.clicked.connect(self.add_to_list)

        # Remove alert
        alert_rem_b = QPushButton("Remove Alert")
        alert_rem_b.clicked.connect(self.remove_from_list)

        # Alert dropdown
        self.alert_dropdown = QComboBox()
        self.alert_dropdown.addItem("Below")
        self.alert_dropdown.addItem("Above")

        # Alert layout
        alert_layout = QBoxLayout(QBoxLayout.Direction.LeftToRight)
        alert_layout.addWidget(self.alert_dropdown)
        alert_layout.addWidget(self.alert_pricebox)
        alert_layout.addWidget(alert_b)
        alert_layout.addWidget(alert_rem_b)

        self.ticker_price = QLabel("")
        self.ticker_l = QLabel(self.ticker.upper())

        # List of alerts
        self.alert_list = QTableWidget()
        self.alert_list.setColumnCount(4)
        self.alert_list.setHorizontalHeaderLabels(
            ["Ticker", "Alert Price", "Type", "Triggered"])

        # Main layout
        tickerlayout = QFormLayout()
        tickerlayout.addRow("Ticker", self.ticker_textbox)
        tickerlayout.addRow(self.ticker_l, self.ticker_price)
        tickerlayout.addRow("Alert when price is", alert_layout)
        tickerlayout.addRow(self.alert_list)

        grid = QGridLayout()

        self.setLayout(tickerlayout)

    def remove_from_list(self):
        """Removes a symbol from the list (which disables the alert)
        """
        for row in self.alert_list.selectedItems():
            self.alert_list.removeRow(row.row())

    def check_prices(self):
        """Constantly goes through a list of symbols and checks if price has reached a given number (runs in a thread)
        """
        while True:
            if self.__exit:
                break

            self.set_ticker_price()

            for row in range(self.alert_list.rowCount()):
                if self.alert_list.item(row, 3).text() == "False":
                    symbol = self.alert_list.item(row, 0).text().lower()
                    alert_price = self.alert_list.item(row, 1).text()
                    alert_type = self.alert_list.item(row, 2).text()
                    price = self.futures.get_price(symbol)

                    if alert_type == "Below" and price < float(alert_price):
                        self.alert_list.item(row, 3).setText("True")
                        self.dlg.set_ticker(symbol, alert_price, alert_type)
                        self.dlg.play_sound()
                        self.dlg.exec()
                    elif alert_type == "Above" and price > float(alert_price):
                        self.alert_list.item(row, 3).setText("True")
                        self.dlg.set_ticker(symbol, alert_price, alert_type)
                        self.dlg.play_sound()
                        self.dlg.exec()

            time.sleep(0.5)

    def add_to_list(self):
        """Adds an item to the list
        """
        self.alert_list.insertRow(self.alert_list.rowCount())

        tck = QTableWidgetItem()
        tck.setText(self.ticker.upper())
        price = QTableWidgetItem()
        price.setText(self.alert_pricebox.text())
        typ = QTableWidgetItem()
        alert_type = self.alert_dropdown.itemText(
            self.alert_dropdown.currentIndex())
        typ.setText(alert_type)
        triggered = QTableWidgetItem()
        triggered.setText("False")

        self.alert_list.setItem(self.alert_list.rowCount() - 1, 0, tck)
        self.alert_list.setItem(self.alert_list.rowCount() - 1, 1, price)
        self.alert_list.setItem(self.alert_list.rowCount() - 1, 2, typ)
        self.alert_list.setItem(self.alert_list.rowCount() - 1, 3, triggered)

    def change_ticker(self):
        self.ticker = self.ticker_textbox.text()
        self.ticker_l.setText(self.ticker.upper())

    def set_ticker_price(self):
        self.ticker_price.setText(str(self.futures.get_price(self.ticker)))

    def closeEvent(self, event):
        # Breaks the while loop to end the thread
        self.__exit = True
示例#36
0
class LedgerAuthDialog(QDialog):
    def __init__(self, handler, data):
        '''Ask user for 2nd factor authentication. Support text, security card and paired mobile methods.
        Use last method from settings, but support new pairing and downgrade.
        '''
        QDialog.__init__(self, handler.top_level_window())
        self.handler = handler
        self.txdata = data
        self.idxs = self.txdata[
            'keycardData'] if self.txdata['confirmationType'] > 1 else ''
        self.setMinimumWidth(650)
        self.setWindowTitle(_("Ledger Wallet Authentication"))
        self.cfg = copy.deepcopy(self.handler.win.wallet.get_keystore().cfg)
        self.dongle = self.handler.win.wallet.get_keystore().get_client(
        ).dongle
        self.ws = None
        self.pin = ''

        self.devmode = self.getDevice2FAMode()
        if self.devmode == 0x11 or self.txdata['confirmationType'] == 1:
            self.cfg['mode'] = 0

        vbox = QVBoxLayout()
        self.setLayout(vbox)

        def on_change_mode(idx):
            if idx < 2 and self.ws:
                self.ws.stop()
                self.ws = None
            self.cfg[
                'mode'] = 0 if self.devmode == 0x11 else idx if idx > 0 else 1
            if self.cfg['mode'] > 1 and self.cfg['pair'] and not self.ws:
                self.req_validation()
            if self.cfg['mode'] > 0:
                self.handler.win.wallet.get_keystore().cfg = self.cfg
                self.handler.win.wallet.save_keystore()
            self.update_dlg()

        def add_pairing():
            self.do_pairing()

        def return_pin():
            self.pin = self.pintxt.text(
            ) if self.txdata['confirmationType'] == 1 else self.cardtxt.text()
            if self.cfg['mode'] == 1:
                self.pin = ''.join(chr(int(str(i), 16)) for i in self.pin)
            self.accept()

        self.modebox = QWidget()
        modelayout = QHBoxLayout()
        self.modebox.setLayout(modelayout)
        modelayout.addWidget(QLabel(_("Method:")))
        self.modes = QComboBox()
        modelayout.addWidget(self.modes, 2)
        self.addPair = QPushButton(_("Pair"))
        self.addPair.setMaximumWidth(60)
        modelayout.addWidget(self.addPair)
        modelayout.addStretch(1)
        self.modebox.setMaximumHeight(50)
        vbox.addWidget(self.modebox)

        self.populate_modes()
        self.modes.currentIndexChanged.connect(on_change_mode)
        self.addPair.clicked.connect(add_pairing)

        self.helpmsg = QTextEdit()
        self.helpmsg.setStyleSheet(
            "QTextEdit { background-color: lightgray; }")
        self.helpmsg.setReadOnly(True)
        vbox.addWidget(self.helpmsg)

        self.pinbox = QWidget()
        pinlayout = QHBoxLayout()
        self.pinbox.setLayout(pinlayout)
        self.pintxt = QLineEdit()
        self.pintxt.setEchoMode(2)
        self.pintxt.setMaxLength(4)
        self.pintxt.returnPressed.connect(return_pin)
        pinlayout.addWidget(QLabel(_("Enter PIN:")))
        pinlayout.addWidget(self.pintxt)
        pinlayout.addWidget(QLabel(_("NOT DEVICE PIN - see above")))
        pinlayout.addStretch(1)
        self.pinbox.setVisible(self.cfg['mode'] == 0)
        vbox.addWidget(self.pinbox)

        self.cardbox = QWidget()
        card = QVBoxLayout()
        self.cardbox.setLayout(card)
        self.addrtext = QTextEdit()
        self.addrtext.setStyleSheet(
            "QTextEdit { color:blue; background-color:lightgray; padding:15px 10px; border:none; font-size:20pt; font-family:monospace; }"
        )
        self.addrtext.setReadOnly(True)
        self.addrtext.setMaximumHeight(130)
        card.addWidget(self.addrtext)

        def pin_changed(s):
            if len(s) < len(self.idxs):
                i = self.idxs[len(s)]
                addr = self.txdata['address']
                if not constants.net.TESTNET:
                    text = addr[:i] + '<u><b>' + addr[
                        i:i + 1] + '</u></b>' + addr[i + 1:]
                else:
                    # pin needs to be created from mainnet address
                    addr_mainnet = bitcoin.script_to_address(
                        bitcoin.address_to_script(addr),
                        net=constants.BitcoinMainnet)
                    addr_mainnet = addr_mainnet[:i] + '<u><b>' + addr_mainnet[
                        i:i + 1] + '</u></b>' + addr_mainnet[i + 1:]
                    text = str(addr) + '\n' + str(addr_mainnet)
                self.addrtext.setHtml(str(text))
            else:
                self.addrtext.setHtml(_("Press Enter"))

        pin_changed('')
        cardpin = QHBoxLayout()
        cardpin.addWidget(QLabel(_("Enter PIN:")))
        self.cardtxt = QLineEdit()
        self.cardtxt.setEchoMode(2)
        self.cardtxt.setMaxLength(len(self.idxs))
        self.cardtxt.textChanged.connect(pin_changed)
        self.cardtxt.returnPressed.connect(return_pin)
        cardpin.addWidget(self.cardtxt)
        cardpin.addWidget(QLabel(_("NOT DEVICE PIN - see above")))
        cardpin.addStretch(1)
        card.addLayout(cardpin)
        self.cardbox.setVisible(self.cfg['mode'] == 1)
        vbox.addWidget(self.cardbox)

        self.pairbox = QWidget()
        pairlayout = QVBoxLayout()
        self.pairbox.setLayout(pairlayout)
        pairhelp = QTextEdit(helpTxt[5])
        pairhelp.setStyleSheet("QTextEdit { background-color: lightgray; }")
        pairhelp.setReadOnly(True)
        pairlayout.addWidget(pairhelp, 1)
        self.pairqr = QRCodeWidget()
        pairlayout.addWidget(self.pairqr, 4)
        self.pairbox.setVisible(False)
        vbox.addWidget(self.pairbox)
        self.update_dlg()

        if self.cfg['mode'] > 1 and not self.ws:
            self.req_validation()

    def populate_modes(self):
        self.modes.blockSignals(True)
        self.modes.clear()
        self.modes.addItem(
            _("Summary Text PIN (requires dongle replugging)"
              ) if self.txdata['confirmationType'] ==
            1 else _("Summary Text PIN is Disabled"))
        if self.txdata['confirmationType'] > 1:
            self.modes.addItem(_("Security Card Challenge"))
            if not self.cfg['pair']:
                self.modes.addItem(_("Mobile - Not paired"))
            else:
                self.modes.addItem(
                    _("Mobile - {}").format(self.cfg['pair'][1]))
        self.modes.blockSignals(False)

    def update_dlg(self):
        self.modes.setCurrentIndex(self.cfg['mode'])
        self.modebox.setVisible(True)
        self.addPair.setText(
            _("Pair") if not self.cfg['pair'] else _("Re-Pair"))
        self.addPair.setVisible(self.txdata['confirmationType'] > 2)
        self.helpmsg.setText(
            helpTxt[self.cfg['mode'] if self.cfg['mode'] < 2 else 2 if self.
                    cfg['pair'] else 4])
        self.helpmsg.setMinimumHeight(180 if self.txdata['confirmationType'] ==
                                      1 else 100)
        self.pairbox.setVisible(False)
        self.helpmsg.setVisible(True)
        self.pinbox.setVisible(self.cfg['mode'] == 0)
        self.cardbox.setVisible(self.cfg['mode'] == 1)
        self.pintxt.setFocus(
            True) if self.cfg['mode'] == 0 else self.cardtxt.setFocus(True)
        self.setMaximumHeight(400)

    def do_pairing(self):
        rng = os.urandom(16)
        pairID = (hexlify(rng) +
                  hexlify(hashlib.sha256(rng).digest()[0:1])).decode('utf-8')
        self.pairqr.setData(pairID)
        self.modebox.setVisible(False)
        self.helpmsg.setVisible(False)
        self.pinbox.setVisible(False)
        self.cardbox.setVisible(False)
        self.pairbox.setVisible(True)
        self.pairqr.setMinimumSize(300, 300)
        if self.ws:
            self.ws.stop()
        self.ws = LedgerWebSocket(self, pairID)
        self.ws.pairing_done.connect(self.pairing_done)
        self.ws.start()

    def pairing_done(self, data):
        if data is not None:
            self.cfg['pair'] = [data['pairid'], data['name'], data['platform']]
            self.cfg['mode'] = 2
            self.handler.win.wallet.get_keystore().cfg = self.cfg
            self.handler.win.wallet.save_keystore()
        self.pin = 'paired'
        self.accept()

    def req_validation(self):
        if self.cfg['pair'] and 'secureScreenData' in self.txdata:
            if self.ws:
                self.ws.stop()
            self.ws = LedgerWebSocket(self, self.cfg['pair'][0], self.txdata)
            self.ws.req_updated.connect(self.req_updated)
            self.ws.start()

    def req_updated(self, pin):
        if pin == 'accepted':
            self.helpmsg.setText(helpTxt[3])
        else:
            self.pin = str(pin)
            self.accept()

    def getDevice2FAMode(self):
        apdu = [0xe0, 0x24, 0x01, 0x00, 0x00, 0x01]  # get 2fa mode
        try:
            mode = self.dongle.exchange(bytearray(apdu))
            return mode
        except BTChipException as e:
            debug_msg('Device getMode Failed')
        return 0x11

    def closeEvent(self, evnt):
        debug_msg("CLOSE - Stop WS")
        if self.ws:
            self.ws.stop()
        if self.pairbox.isVisible():
            evnt.ignore()
            self.update_dlg()
示例#37
0
class FileManager(QWidget, _HalWidgetBase):
    def __init__(self, parent=None):
        super(FileManager, self).__init__(parent)
        self.title = 'Qtvcp File System View'
        self.left = 10
        self.top = 10
        self.width = 640
        self.height = 480
        self._last = 0

        if INFO.PROGRAM_PREFIX is not None:
            self.user_path = os.path.expanduser(INFO.PROGRAM_PREFIX)
        else:
            self.user_path = (os.path.join(os.path.expanduser('~'),
                                           'linuxcnc/nc_files'))
        user = os.path.split(os.path.expanduser('~'))[-1]
        self.media_path = (os.path.join('/media', user))
        temp = [('User', self.user_path), ('Media', self.media_path)]
        self._jumpList = OrderedDict(temp)
        self.currentPath = None
        self.currentFolder = None
        self.PREFS_ = None
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        pasteBox = QHBoxLayout()
        self.textLine = QLineEdit()
        self.textLine.setToolTip('Current Director/selected File')
        self.pasteButton = QToolButton()
        self.pasteButton.setEnabled(False)
        self.pasteButton.setText('Paste')
        self.pasteButton.setToolTip(
            'Copy file from copy path to current directory/file')
        self.pasteButton.clicked.connect(self.paste)
        self.pasteButton.hide()
        pasteBox.addWidget(self.textLine)
        pasteBox.addWidget(self.pasteButton)

        self.copyBox = QFrame()
        hbox = QHBoxLayout()
        hbox.setContentsMargins(0, 0, 0, 0)
        self.copyLine = QLineEdit()
        self.copyLine.setToolTip('File path to copy from, when pasting')
        self.copyButton = QToolButton()
        self.copyButton.setText('Copy')
        self.copyButton.setToolTip('Record current file as copy path')
        self.copyButton.clicked.connect(self.recordCopyPath)
        hbox.addWidget(self.copyButton)
        hbox.addWidget(self.copyLine)
        self.copyBox.setLayout(hbox)
        self.copyBox.hide()

        self.model = QFileSystemModel()
        self.model.setRootPath(QDir.currentPath())
        self.model.setFilter(QDir.AllDirs | QDir.NoDot | QDir.Files)
        self.model.setNameFilterDisables(False)
        self.model.rootPathChanged.connect(self.folderChanged)

        self.list = QListView()
        self.list.setModel(self.model)
        self.list.resize(640, 480)
        self.list.clicked[QModelIndex].connect(self.listClicked)
        self.list.activated.connect(self._getPathActivated)
        self.list.setAlternatingRowColors(True)
        self.list.hide()

        self.table = QTableView()
        self.table.setModel(self.model)
        self.table.resize(640, 480)
        self.table.clicked[QModelIndex].connect(self.listClicked)
        self.table.activated.connect(self._getPathActivated)
        self.table.setAlternatingRowColors(True)

        header = self.table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.Stretch)
        header.setSectionResizeMode(1, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(3, QHeaderView.ResizeToContents)
        header.swapSections(1, 3)
        header.setSortIndicator(1, Qt.AscendingOrder)

        self.table.setSortingEnabled(True)
        self.table.setColumnHidden(2, True)  # type
        self.table.verticalHeader().setVisible(False)  # row count header

        self.cb = QComboBox()
        self.cb.currentIndexChanged.connect(self.filterChanged)
        self.fillCombobox(INFO.PROGRAM_FILTERS_EXTENSIONS)
        self.cb.setMinimumSize(200, 30)
        self.cb.setSizePolicy(QSizePolicy(QSizePolicy.Fixed,
                                          QSizePolicy.Fixed))

        self.button2 = QToolButton()
        self.button2.setText('User')
        self.button2.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button2.setMinimumSize(60, 30)
        self.button2.setToolTip(
            'Jump to User directory.\nLong press for Options.')
        self.button2.clicked.connect(self.onJumpClicked)

        self.button3 = QToolButton()
        self.button3.setText('Add Jump')
        self.button3.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button3.setMinimumSize(60, 30)
        self.button3.setToolTip('Add current directory to jump button list')
        self.button3.clicked.connect(self.onActionClicked)

        self.settingMenu = QMenu(self)
        self.button2.setMenu(self.settingMenu)

        hbox = QHBoxLayout()
        hbox.addWidget(self.button2)
        hbox.addWidget(self.button3)
        hbox.insertStretch(2, stretch=0)
        hbox.addWidget(self.cb)

        windowLayout = QVBoxLayout()
        windowLayout.addLayout(pasteBox)
        windowLayout.addWidget(self.copyBox)
        windowLayout.addWidget(self.list)
        windowLayout.addWidget(self.table)
        windowLayout.addLayout(hbox)
        self.setLayout(windowLayout)
        self.show()

    def _hal_init(self):
        if self.PREFS_:
            last_path = self.PREFS_.getpref('last_loaded_directory',
                                            self.user_path, str,
                                            'BOOK_KEEPING')
            LOG.debug("lAST FILE PATH: {}".format(last_path))
            if not last_path == '' and os.path.exists(last_path):
                self.updateDirectoryView(last_path)
            else:
                self.updateDirectoryView(self.user_path)

            # get all the saved jumplist paths
            temp = self.PREFS_.getall('FILEMANAGER_JUMPLIST')
            self._jumpList.update(temp)

        else:
            LOG.debug("lAST FILE PATH: {}".format(self.user_path))
            self.updateDirectoryView(self.user_path)

        # install jump paths into toolbutton menu
        for i in self._jumpList:
            self.addAction(i)

        # set recorded columns sort settings
        self.SETTINGS_.beginGroup("FileManager-{}".format(self.objectName()))
        sect = self.SETTINGS_.value('sortIndicatorSection', type=int)
        order = self.SETTINGS_.value('sortIndicatorOrder', type=int)
        self.SETTINGS_.endGroup()
        if not None in (sect, order):
            self.table.horizontalHeader().setSortIndicator(sect, order)

    # when qtvcp closes this gets called
    # record jump list paths
    def _hal_cleanup(self):
        if self.PREFS_:
            for i, key in enumerate(self._jumpList):
                if i in (0, 1):
                    continue
                self.PREFS_.putpref(key, self._jumpList.get(key), str,
                                    'FILEMANAGER_JUMPLIST')

        # record sorted columns
        h = self.table.horizontalHeader()
        self.SETTINGS_.beginGroup("FileManager-{}".format(self.objectName()))
        self.SETTINGS_.setValue('sortIndicatorSection',
                                h.sortIndicatorSection())
        self.SETTINGS_.setValue('sortIndicatorOrder', h.sortIndicatorOrder())
        self.SETTINGS_.endGroup()

    #########################
    # callbacks
    #########################

    # add shown text and hidden filter data from the INI
    def fillCombobox(self, data):
        for i in data:
            self.cb.addItem(i[0], i[1])

    def folderChanged(self, data):
        data = os.path.normpath(data)
        self.currentFolder = data
        self.textLine.setText(data)

    def updateDirectoryView(self, path, quiet=False):
        if os.path.exists(path):
            self.list.setRootIndex(self.model.setRootPath(path))
            self.table.setRootIndex(self.model.setRootPath(path))
        else:
            LOG.debug(
                "Set directory view error - no such path {}".format(path))
            if not quiet:
                STATUS.emit(
                    'error', LOW_ERROR,
                    "File Manager error - No such path: {}".format(path))

    # retrieve selected filter (it's held as QT.userData)
    def filterChanged(self, index):
        userdata = self.cb.itemData(index)
        self.model.setNameFilters(userdata)

    def listClicked(self, index):
        # the signal passes the index of the clicked item
        dir_path = os.path.normpath(self.model.filePath(index))
        if self.model.fileInfo(index).isFile():
            self.currentPath = dir_path
            self.textLine.setText(self.currentPath)
            return
        root_index = self.model.setRootPath(dir_path)
        self.list.setRootIndex(root_index)
        self.table.setRootIndex(root_index)

    def onUserClicked(self):
        self.showUserDir()

    def onMediaClicked(self):
        self.showMediaDir()

    # jump directly to a saved path shown on the button
    def onJumpClicked(self):
        data = self.button2.text()
        if data.upper() == 'MEDIA':
            self.showMediaDir()
        elif data.upper() == 'USER':
            self.showUserDir()
        else:
            temp = self._jumpList.get(data)
            if temp is not None:
                self.updateDirectoryView(temp)
            else:
                STATUS.emit('error', linuxcnc.OPERATOR_ERROR,
                            'file jumopath: {} not valid'.format(data))
                log.debug('file jumopath: {} not valid'.format(data))

    # jump directly to a saved path from the menu
    def jumpTriggered(self, data):
        if data.upper() == 'MEDIA':
            self.button2.setText('{}'.format(data))
            self.button2.setToolTip(
                'Jump to Media directory.\nLong press for Options.')
            self.showMediaDir()
        elif data.upper() == 'USER':
            self.button2.setText('{}'.format(data))
            self.button2.setToolTip(
                'Jump to User directory.\nLong press for Options.')
            self.showUserDir()
        else:
            self.button2.setText('{}'.format(data))
            self.button2.setToolTip('Jump to directory:\n{}'.format(
                self._jumpList.get(data)))
            self.updateDirectoryView(self._jumpList.get(data))

    # add a jump list path
    def onActionClicked(self):
        i = self.currentFolder
        try:
            self._jumpList[i] = i
        except Exception as e:
            print(e)
        button = QAction(QIcon.fromTheme('user-home'), i, self)
        # weird lambda i=i to work around 'function closure'
        button.triggered.connect(lambda state, i=i: self.jumpTriggered(i))
        self.settingMenu.addAction(button)

    # get current selection and update the path
    # then if the path is good load it into linuxcnc
    # record it in the preference file if available
    def _getPathActivated(self):
        if self.list.isVisible():
            row = self.list.selectionModel().currentIndex()
        else:
            row = self.table.selectionModel().currentIndex()
            self.listClicked(row)

        fname = self.currentPath
        if fname is None:
            return
        if fname:
            self.load(fname)

    def recordCopyPath(self):
        data, isFile = self.getCurrentSelected()
        if isFile:
            self.copyLine.setText(os.path.normpath(data))
            self.pasteButton.setEnabled(True)
        else:
            self.copyLine.setText('')
            self.pasteButton.setEnabled(False)
            STATUS.emit('error', OPERATOR_ERROR,
                        'Can only copy a file, not a folder')

    def paste(self):
        res = self.copyFile(self.copyLine.text(), self.textLine.text())
        if res:
            self.copyLine.setText('')
            self.pasteButton.setEnabled(False)

    ########################
    # helper functions
    ########################

    def addAction(self, i):
        axisButton = QAction(QIcon.fromTheme('user-home'), i, self)
        # weird lambda i=i to work around 'function closure'
        axisButton.triggered.connect(lambda state, i=i: self.jumpTriggered(i))
        self.settingMenu.addAction(axisButton)

    def showList(self, state=True):
        if state:
            self.table.hide()
            self.list.show()
        else:
            self.table.show()
            self.list.hide()

    def showTable(self, state=True):
        self.showList(not state)

    def showCopyControls(self, state):
        if state:
            self.copyBox.show()
            self.pasteButton.show()
        else:
            self.copyBox.hide()
            self.pasteButton.hide()

    def showMediaDir(self, quiet=False):
        self.updateDirectoryView(self.media_path, quiet)

    def showUserDir(self, quiet=False):
        self.updateDirectoryView(self.user_path, quiet)

    def copyFile(self, s, d):
        try:
            shutil.copy(s, d)
            return True
        except Exception as e:
            LOG.error("Copy file error: {}".format(e))
            STATUS.emit('error', OPERATOR_ERROR,
                        "Copy file error: {}".format(e))
            return False

    @pyqtSlot(float)
    @pyqtSlot(int)
    def scroll(self, data):
        if data > self._last:
            self.up()
        elif data < self._last:
            self.down()
        self._last = data

    # moves the selection up
    # used with MPG scrolling
    def up(self):
        self.select_row('up')

    # moves the selection down
    # used with MPG scrolling
    def down(self):
        self.select_row('down')

    def select_row(self, style='down'):
        style = style.lower()
        if self.list.isVisible():
            i = self.list.rootIndex()
            selectionModel = self.list.selectionModel()
        else:
            i = self.table.rootIndex()
            selectionModel = self.table.selectionModel()

        row = selectionModel.currentIndex().row()
        self.rows = self.model.rowCount(i)

        if style == 'last':
            row = self.rows
        elif style == 'up':
            if row > 0:
                row -= 1
            else:
                row = 0
        elif style == 'down':
            if row < self.rows - 1:
                row += 1
            else:
                row = self.rows - 1
        else:
            return
        top = self.model.index(row, 0, i)
        selectionModel.setCurrentIndex(
            top, QItemSelectionModel.Select | QItemSelectionModel.Rows)
        selection = QItemSelection(top, top)
        selectionModel.clearSelection()
        selectionModel.select(selection, QItemSelectionModel.Select)

    # returns the current highlighted (selected) path as well as
    # whether it's a file or not.
    def getCurrentSelected(self):
        if self.list.isVisible():
            selectionModel = self.list.selectionModel()
        else:
            selectionModel = self.table.selectionModel()
        index = selectionModel.currentIndex()
        dir_path = os.path.normpath(self.model.filePath(index))
        if self.model.fileInfo(index).isFile():
            return (dir_path, True)
        else:
            return (dir_path, False)

    # This can be class patched to do something else
    def load(self, fname=None):
        try:
            if fname is None:
                self._getPathActivated()
                return
            self.recordBookKeeping()
            ACTION.OPEN_PROGRAM(fname)
            STATUS.emit('update-machine-log', 'Loaded: ' + fname, 'TIME')
        except Exception as e:
            LOG.error("Load file error: {}".format(e))
            STATUS.emit('error', NML_ERROR, "Load file error: {}".format(e))

    # This can be class patched to do something else
    def recordBookKeeping(self):
        fname = self.currentPath
        if fname is None:
            return
        if self.PREFS_:
            self.PREFS_.putpref('last_loaded_directory', self.model.rootPath(),
                                str, 'BOOK_KEEPING')
            self.PREFS_.putpref('RecentPath_0', fname, str, 'BOOK_KEEPING')
示例#38
0
        def __init__(self, parent=None):
            super(Widget, self).__init__(parent)
            self.setWindowTitle("Keuze grafieken externe werken")
            self.setWindowIcon(QIcon('./images/logos/logo.jpg'))

            self.setFont(QFont('Arial', 10))

            self.Keuze = QLabel()
            kEdit = QComboBox()
            kEdit.setFixedWidth(300)
            kEdit.setFont(QFont("Arial", 10))
            kEdit.setStyleSheet("color: black;  background-color: gainsboro")
            kEdit.addItem('                  Keuze Grafieken')
            kEdit.addItem('1. Kosten totaal begroot-werkelijk')
            kEdit.addItem('2. Lonen begroot-werkelijk')
            kEdit.addItem('3. Materialen begroot-werkelijk')
            kEdit.addItem('4. Materiëel begroot-werkelijk')
            kEdit.addItem('5. Inhuur begroot-werkelijk')
            kEdit.addItem('6. Diensten begroot-werkelijk')
            kEdit.addItem('7. Projektkosten begroot-werkelijk')
            kEdit.addItem('8. Bruto winst - prognose / aktueel')
            kEdit.addItem('9. Onderhandenwerk - Betaald bedrag')
            kEdit.addItem('A. Opbrengsten - prognose / aktueel')
            kEdit.addItem('B. Bruto winst werkelijk\n     Meerminderwerk')

            kEdit.activated[str].connect(self.kChanged)

            self.Zoekterm = QLabel()
            zktermEdit = QLineEdit()
            zktermEdit.setFixedWidth(65)
            zktermEdit.setFont(QFont("Arial", 10))
            zktermEdit.textChanged.connect(self.zktermChanged)
            reg_ex = QRegExp("^[2]{1}[0-9]{3}[0-5]{1}[0-9]{1}$")
            input_validator = QRegExpValidator(reg_ex, zktermEdit)
            zktermEdit.setValidator(input_validator)

            grid = QGridLayout()
            grid.setSpacing(20)

            lbl = QLabel()
            pixmap = QPixmap('./images/logos/verbinding.jpg')
            lbl.setPixmap(pixmap)
            grid.addWidget(lbl, 0, 0, 1, 2)

            grid.addWidget(kEdit, 1, 0, 1, 2, Qt.AlignRight)
            lbl1 = QLabel('Jaarweek-uitdraai (jjjjww)')
            lbl1.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
            grid.addWidget(lbl1, 2, 0, 1, 2, Qt.AlignCenter)
            grid.addWidget(zktermEdit, 2, 1, 1, 1, Qt.AlignRight)

            self.setLayout(grid)
            self.setGeometry(500, 200, 150, 150)

            grid.addWidget(
                QLabel('\u00A9 2017 all rights reserved [email protected]'),
                4, 0, 1, 2, Qt.AlignRight)

            logo = QLabel()
            pixmap = QPixmap('./images/logos/logo.jpg')
            logo.setPixmap(pixmap)
            grid.addWidget(logo, 0, 1, 1, 1, Qt.AlignRight)

            applyBtn = QPushButton('Zoeken')
            applyBtn.clicked.connect(self.accept)

            sluitBtn = QPushButton('Sluiten')
            sluitBtn.clicked.connect(lambda: windowSluit(self, m_email))

            grid.addWidget(applyBtn, 3, 1, 1, 1, Qt.AlignRight)
            applyBtn.setFont(QFont("Arial", 10))
            applyBtn.setFixedWidth(100)
            applyBtn.setStyleSheet(
                "color: black;  background-color: gainsboro")

            grid.addWidget(sluitBtn, 3, 0, 1, 2, Qt.AlignCenter)
            sluitBtn.setFont(QFont("Arial", 10))
            sluitBtn.setFixedWidth(100)
            sluitBtn.setStyleSheet(
                "color: black;  background-color: gainsboro")
示例#39
0
class LCD20x4(PluginBase):
    MAX_LINE = 4
    MAX_POSITION = 20
    qtcb_pressed = pyqtSignal(int)
    qtcb_released = pyqtSignal(int)

    def __init__(self, *args):
        super().__init__(BrickletLCD20x4, *args)

        self.lcd = self.device

        # the firmware version of a EEPROM Bricklet can (under common circumstances)
        # not change during the lifetime of an EEPROM Bricklet plugin. therefore,
        # it's okay to make final decisions based on it here
        self.has_custom_character = self.firmware_version >= (2, 0, 1)

        self.qtcb_pressed.connect(self.cb_pressed)
        self.lcd.register_callback(self.lcd.CALLBACK_BUTTON_PRESSED,
                                   self.qtcb_pressed.emit)
        self.qtcb_released.connect(self.cb_released)
        self.lcd.register_callback(self.lcd.CALLBACK_BUTTON_RELEASED,
                                   self.qtcb_released.emit)

        self.line_label = QLabel('Line:')
        self.line_combo = QComboBox()

        for i  in range(LCD20x4.MAX_LINE):
            self.line_combo.addItem(str(i))

        self.pos_label = QLabel('Position:')
        self.pos_combo = QComboBox()

        for i in range(LCD20x4.MAX_POSITION):
            self.pos_combo.addItem(str(i))

        self.line_pos_layout = QHBoxLayout()
        self.line_pos_layout.addWidget(self.line_label)
        self.line_pos_layout.addWidget(self.line_combo)
        self.line_pos_layout.addWidget(self.pos_label)
        self.line_pos_layout.addWidget(self.pos_combo)
        self.line_pos_layout.addStretch()

        self.text_label = QLabel('Text:')
        self.text_edit = QLineEdit()
        self.text_edit.setMaxLength(LCD20x4.MAX_POSITION)
        self.text_button = QPushButton('Send Text')
        self.text_layout = QHBoxLayout()
        self.text_layout.addWidget(self.text_label)
        self.text_layout.addWidget(self.text_edit)
        self.text_layout.addWidget(self.text_button)

        self.clear_button = QPushButton("Clear Display")

        self.bl_button = QPushButton("Querying backlight status...")
        self.cursor_button = QPushButton("Querying cursor status...")
        self.blink_button = QPushButton("Querying blink status...")

        self.onofflayout = QHBoxLayout()
        self.onofflayout.addWidget(self.bl_button)
        self.onofflayout.addWidget(self.cursor_button)
        self.onofflayout.addWidget(self.blink_button)

        self.b0_label = QLabel('Button 0: Released,')
        self.b1_label = QLabel('Button 1: Released,')
        self.b2_label = QLabel('Button 2: Released,')
        self.b3_label = QLabel('Button 3: Released')

        self.buttonlayout = QHBoxLayout()
        self.buttonlayout.addWidget(self.b0_label)
        self.buttonlayout.addWidget(self.b1_label)
        self.buttonlayout.addWidget(self.b2_label)
        self.buttonlayout.addWidget(self.b3_label)

        self.cursor_button.clicked.connect(self.cursor_clicked)
        self.blink_button.clicked.connect(self.blink_clicked)
        self.clear_button.clicked.connect(self.clear_clicked)
        self.bl_button.clicked.connect(self.bl_clicked)
        self.text_button.clicked.connect(self.text_clicked)

        if self.has_custom_character:
            line = QFrame()
            line.setObjectName("line")
            line.setFrameShape(QFrame.HLine)
            line.setFrameShadow(QFrame.Sunken)

            self.scribble_widget = ScribbleWidget(5, 8, 25, QColor(Qt.white), QColor(Qt.blue))

            self.char_index_label = QLabel('Index:')
            self.char_index_combo = QComboBox()
            self.char_index_combo.currentIndexChanged.connect(self.char_index_changed)
            for i in range(8):
                self.char_index_combo.addItem(str(i))

            self.char_index_layout = QHBoxLayout()
            self.char_index_layout.addStretch()
            self.char_index_layout.addWidget(self.char_index_label)
            self.char_index_layout.addWidget(self.char_index_combo)
            self.char_index_layout.addStretch()

            self.char_index_save = QPushButton('Save Character')
            self.char_index_save.clicked.connect(self.char_index_save_clicked)
            self.char_show = QPushButton('Show all Custom Characters on LCD')
            self.char_show.clicked.connect(self.show_clicked)
            self.char_save_layout = QVBoxLayout()
            self.char_save_layout.addStretch()
            self.char_save_layout.addLayout(self.char_index_layout)
            self.char_save_layout.addWidget(self.char_index_save)
            self.char_save_layout.addWidget(self.char_show)

            help_label = QLabel('Use "\\0, \\1, ..., \\7" in text field to show custom characters.')
            help_label.setWordWrap(True)

            self.char_save_layout.addWidget(help_label)
            self.char_save_layout.addStretch()

            grid_stretch_layout = QHBoxLayout()
            grid_stretch_layout.addWidget(QLabel('Custom Character:'))
            grid_stretch_layout.addWidget(self.scribble_widget)
            grid_stretch_layout.addLayout(self.char_save_layout)
            grid_stretch_layout.addStretch()

            self.char_main_layout = QHBoxLayout()
            self.char_main_layout.addStretch()
            self.char_main_layout.addLayout(grid_stretch_layout)
            self.char_main_layout.addStretch()

        layout = QVBoxLayout(self)
        layout.addLayout(self.line_pos_layout)
        layout.addLayout(self.text_layout)
        layout.addWidget(self.clear_button)
        layout.addLayout(self.onofflayout)
        layout.addLayout(self.buttonlayout)

        if self.hardware_version <= (1, 1, 0):
            self.b3_label.hide()

        if self.has_custom_character:
            layout.addWidget(line)
            layout.addLayout(self.char_main_layout)

        layout.addStretch(1)

    def is_backlight_on_async(self, on):
        if on:
            self.bl_button.setText('Backlight Off')
        else:
            self.bl_button.setText('Backlight On')

    def get_config_async(self, config):
        cursor, blink = config
        if cursor:
            self.cursor_button.setText('Cursor Off')
        else:
            self.cursor_button.setText('Cursor On')

        if blink:
            self.blink_button.setText('Blink Off')
        else:
            self.blink_button.setText('Blink On')

    def start(self):
        async_call(self.lcd.is_backlight_on, None, self.is_backlight_on_async, self.increase_error_count)
        async_call(self.lcd.get_config, None, self.get_config_async, self.increase_error_count)

    def stop(self):
        pass

    def destroy(self):
        pass

    def get_url_part(self):
        # override normal get_url_part() function, because the URL part here
        # depends on the hardware version
        return 'lcd_20x4_v{0}{1}'.format(self.hardware_version[0], self.hardware_version[1])

    def is_hardware_version_relevant(self):
        return True

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletLCD20x4.DEVICE_IDENTIFIER

    def cb_pressed(self, button):
        if button == 0:
            self.b0_label.setText('Button 0: Pressed,')
        elif button == 1:
            self.b1_label.setText('Button 1: Pressed,')
        elif button == 2:
            self.b2_label.setText('Button 2: Pressed,')
        elif button == 3:
            self.b3_label.setText('Button 3: Pressed')

    def cb_released(self, button):
        if button == 0:
            self.b0_label.setText('Button 0: Released,')
        elif button == 1:
            self.b1_label.setText('Button 1: Released,')
        elif button == 2:
            self.b2_label.setText('Button 2: Released,')
        elif button == 3:
            self.b3_label.setText('Button 3: Released')

    def bl_clicked(self):
        if self.bl_button.text().replace('&', '') == 'Backlight On':
            async_call(self.lcd.backlight_on, None, None, self.increase_error_count)
            self.bl_button.setText('Backlight Off')
        else:
            async_call(self.lcd.backlight_off, None, None, self.increase_error_count)
            self.bl_button.setText('Backlight On')

    def get_config(self):
        cursor = self.cursor_button.text().replace('&', '') == 'Cursor Off'
        blink = self.blink_button.text().replace('&', '') == 'Blink Off'

        return (cursor, blink)

    def cursor_clicked(self):
        cursor, blink = self.get_config()

        async_call(self.lcd.set_config, (not cursor, blink), None, self.increase_error_count)

        if cursor:
            self.cursor_button.setText('Cursor On')
        else:
            self.cursor_button.setText('Cursor Off')

    def blink_clicked(self):
        cursor, blink = self.get_config()

        async_call(self.lcd.set_config, (cursor, not blink), None, self.increase_error_count)

        if blink:
            self.blink_button.setText('Blink On')
        else:
            self.blink_button.setText('Blink Off')

    def clear_clicked(self):
        async_call(self.lcd.clear_display, None, None, self.increase_error_count)

    def text_clicked(self):
        line = int(self.line_combo.currentText())
        position = int(self.pos_combo.currentText())
        text = self.text_edit.text()

        if self.has_custom_character:
            for i in range(8):
                text = text.replace('\\' + str(i), chr(i + 8))

        async_call(self.lcd.write_line, (line, position, unicode_to_ks0066u(text)), None, self.increase_error_count)

    def char_index_save_clicked(self):
        char = [0]*8
        img = self.scribble_widget.image()

        for j in range(img.height()):
            for i in range(img.width() - 1, -1, -1):
                if img.pixel(i, j) == self.scribble_widget.foreground_color().rgb():
                    char[j] |= 1 << (4 - i)

        index = int(self.char_index_combo.currentText())

        async_call(self.lcd.set_custom_character, (index, char), None, self.increase_error_count)

    def show_clicked(self):
        async_call(self.lcd.clear_display, None, None, self.increase_error_count)

        line1 = '0:{0} 1:{1} 2:{2} 3:{3}'.format(chr(8), chr(9), chr(10), chr(11))
        line2 = '4:{0} 5:{1} 6:{2} 7:{3}'.format(chr(12), chr(13), chr(14), chr(15))

        async_call(self.lcd.write_line, (0, 0, line1), None, self.increase_error_count)
        async_call(self.lcd.write_line, (1, 0, line2), None, self.increase_error_count)

    def custom_character_async(self, characters):
        r = []
        g = []
        b = []

        for j in range(self.scribble_widget.image().height()):
            for i in range(self.scribble_widget.image().width() - 1, -1, -1):
                if characters[j] & (1 << i):
                    r.append(255)
                    g.append(255)
                    b.append(255)
                else:
                    r.append(0)
                    g.append(0)
                    b.append(255)

        self.scribble_widget.array_draw(r, g, b)

    def char_index_changed(self, index):
        async_call(self.lcd.get_custom_character, index, self.custom_character_async, self.increase_error_count)
示例#40
0
class SunPlotPy(Spatial, QMainWindow):
    """ 
    The main frame of the application
    """
    title = 'sunplot(py)'

    # Plotting options
    autoclim = True
    showedges = False
    bgcolor = 'k'
    textcolor = 'w'
    cmap = 'RdBu'
    particlesize = 1.8
    particlecolor = 'm'

    # other flags
    collectiontype = 'cells'
    oldcollectiontype = 'cells'

    #
    tindex = 0
    depthlevs = [0., 10., 100., 200., 300., 400., 500.,\
        1000.,2000.,3000.,4000.,5000]

    _FillValue = 999999

    def __init__(self, parent=None):
        #wx.Frame.__init__(self, None, -1, self.title)
        QMainWindow.__init__(self, parent)
        #super(SunPlotPy, self).__init__(parent)

        self.create_menu()
        #self.create_status_bar()
        self.create_main_panel()

        #self.draw_figure()

    def create_menu(self):
        self.file_menu = self.menuBar().addMenu("&File")

        ###
        # File Menu
        ###
        # Load a hydro output file
        load_file_action = self.create_action("&Open file",\
                shortcut="ctrl-o", slot=self.on_open_file,
                tip="open netcdf file")

        load_grid_action = self.create_action("&Open grid",\
                shortcut="ctrl-g", slot=self.on_load_grid,
                tip="open suntans grid")

        save_anim_action = self.create_action("&Save animation",\
                shortcut="ctrl-a", slot=self.on_save_anim,
                tip="animate current scene")

        quit_action = self.create_action("&Exit",\
                shortcut="ctrl-x", slot=self.close,
                tip="Close the application")

        self.add_actions(self.file_menu,
                (load_file_action, load_grid_action,\
                save_anim_action, None, quit_action))

        #    self.Bind(wx.EVT_MENU, self.on_open_file, m_expt)
        ###
        # Tools menu
        ###
        self.tools_menu = self.menuBar().addMenu("&Tools")

        ###
        # File Menu
        ###
        # Load a hydro output file
        load_stat_action = self.create_action("&Plot grid size statistics",\
                slot=self.on_plot_gridstat,
                tip="grid stats")

        self.add_actions(self.tools_menu, (load_stat_action, ))

    #    # Load a grid file
    #    m_grid = menu_file.Append(-1, "&Load grid\tCtrl-G", "Load SUNTANS grid from folder")
    #    self.Bind(wx.EVT_MENU, self.on_load_grid, m_grid)

    #    # Load a particle file
    #    m_part = menu_file.Append(-1, "&Load PTM file\tCtrl-Shift-P", "Load a PTM file")
    #    self.Bind(wx.EVT_MENU, self.on_load_ptm, m_part)

    #    # Save current scene as an animation
    #    m_anim = menu_file.Append(-1,"&Save animation of current scene\tCtrl-S","Save animation")
    #    self.Bind(wx.EVT_MENU, self.on_save_anim, m_anim)

    #    # Save the current figure
    #    m_prin = menu_file.Append(-1,"&Print current scene\tCtrl-P","Save figure")
    #    self.Bind(wx.EVT_MENU, self.on_save_fig, m_prin)

    #    menu_file.AppendSeparator()
    #    # Exit
    #    m_exit = menu_file.Append(-1, "E&xit\tCtrl-X", "Exit")
    #    self.Bind(wx.EVT_MENU, self.on_exit, m_exit)

    #    ###
    #    # Tools menu
    #    ###
    #    menu_tools = wx.Menu()
    #    m_gridstat = menu_tools.Append(-1, "&Plot grid size statistics", "SUNTANS grid size")
    #    self.Bind(wx.EVT_MENU, self.on_plot_gridstat, m_gridstat)

    #    m_countcells = menu_tools.Append(-1, "&Count # grid cells", "Grid cell count")
    #    self.Bind(wx.EVT_MENU, self.on_count_cells, m_countcells)

    #    m_overlaybathy = menu_tools.Append(-1, "&Overlay depth contours", "Depth overlay")
    #    self.Bind(wx.EVT_MENU, self.on_overlay_bathy, m_overlaybathy)

    #
    #    ###
    #    # Help Menu
    #    ###
    #    menu_help = wx.Menu()
    #    m_about = menu_help.Append(-1, "&About\tF1", "About the demo")
    #    self.Bind(wx.EVT_MENU, self.on_about, m_about)
    #
    #
    #    # Add all of the menu bars
    #    self.menubar.Append(menu_file, "&File")
    #    self.menubar.Append(menu_tools, "&Tools")
    #    self.menubar.Append(menu_help, "&Help")
    #    self.SetMenuBar(self.menubar)

    def add_actions(self, target, actions):
        for action in actions:
            if action is None:
                target.addSeparator()
            else:
                target.addAction(action)

    def create_action(
        self,
        text,
        slot=None,
        shortcut=None,
        icon=None,
        tip=None,
        checkable=False,
    ):
        #signal="triggered()"):
        action = QAction(text, self)
        if icon is not None:
            action.setIcon(QIcon(":/%s.png" % icon))
        if shortcut is not None:
            action.setShortcut(shortcut)

        if tip is not None:
            action.setToolTip(tip)
            action.setStatusTip(tip)
        if slot is not None:
            #self.connect(action, SIGNAL(signal), slot)
            # Qt5 style
            action.triggered.connect(slot)
        if checkable:
            action.setCheckable(True)
        return action

    def create_main_panel(self):
        """ Creates the main panel with all the controls on it:
             * mpl canvas 
             * mpl navigation toolbar
             * Control panel for interaction
        """
        self.panel = QWidget()

        # Create the mpl Figure and FigCanvas objects.
        # 5x4 inches, 100 dots-per-inch
        #
        self.dpi = 100
        #self.fig = Figure((7.0, 6.0), dpi=self.dpi,facecolor=self.bgcolor)
        self.fig = Figure((7.0, 6.0), dpi=self.dpi)
        #self.canvas = FigCanvas(self.panel, -1, self.fig)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self.panel)

        # Since we have only one plot, we can use add_axes
        # instead of add_subplot, but then the subplot
        # configuration tool in the navigation toolbar wouldn't
        # work.
        #
        self.axes = self.fig.add_subplot(111)
        #SetAxColor(self.axes,self.textcolor,self.bgcolor)

        # Bind the 'pick' event for clicking on one of the bars
        #
        #self.canvas.mpl_connect('pick_event', self.on_pick)

        #########
        ## Create widgets
        #########
        self.variable_list = QComboBox()
        self.variable_list.addItem("Select a variable...")
        self.variable_list.activated[str].connect(self.on_select_variable)

        self.time_list = QComboBox()
        self.time_list.addItem("Select a time...")
        self.time_list.activated[int].connect(self.on_select_time)

        self.depthlayer_list = QComboBox()
        self.depthlayer_list.addItem("Select a vertical layer...")
        self.depthlayer_list.activated[int].connect(self.on_select_depth)

        self.show_edge_check = QCheckBox('Show Edges', self)
        #self.show_edge_check.toggle()
        self.show_edge_check.stateChanged.connect(self.on_show_edges)

        cmaps = list(matplotlib.cm.datad.keys())
        cmaps.sort()
        self.colormap_list = QComboBox()
        self.colormap_list.clear()
        self.colormap_list.addItems(cmaps)
        self.colormap_list.activated[str].connect(self.on_select_cmap)

        self.clim_check = QCheckBox('Manual color limits', self)
        #self.show_edge_check.toggle()
        self.clim_check.stateChanged.connect(self.on_clim_check)

        #self.clim_check = wx.CheckBox(self.panel, -1,
        #    "Manual color limits ",
        #    style=wx.ALIGN_RIGHT)
        #self.clim_check.Bind(wx.EVT_CHECKBOX, self.on_clim_check)

        self.climlow = QLineEdit()
        self.climlow.textChanged[str].connect(self.on_climlow)

        self.climhigh = QLineEdit()
        self.climhigh.textChanged[str].connect(self.on_climhigh)

        ## Labels
        #self.variable_label = wx.StaticText(self.panel, -1,"Variable:",size=(200,-1))
        #self.time_label = wx.StaticText(self.panel, -1,"Time step:",size=(200,-1))
        #self.depth_label = wx.StaticText(self.panel, -1,"Vertical level:",size=(200,-1))

        # Create the navigation toolbar, tied to the canvas
        #
        self.toolbar = NavigationToolbar(self.canvas, self)
        #self.toolbar.toolitems[8][3]='my_save_fig'

        #def my_save_fig(self,*args):
        #     print 'saving figure'
        ##    return "break"

        #########
        # Layout with box sizers
        #########
        hbox = QHBoxLayout()
        for w in [self.variable_list, self.time_list, self.depthlayer_list]:
            hbox.addWidget(w)
            hbox.setAlignment(w, Qt.AlignVCenter)

        hbox1 = QHBoxLayout()
        for w in [
                self.show_edge_check, self.colormap_list, self.clim_check,
                self.climlow, self.climhigh
        ]:
            hbox1.addWidget(w)
            hbox1.setAlignment(w, Qt.AlignVCenter)

        self.vbox = QVBoxLayout()
        self.vbox.addWidget(self.canvas)
        self.vbox.addWidget(self.toolbar)
        self.vbox.addLayout(hbox)
        self.vbox.addLayout(hbox1)

        self.panel.setLayout(self.vbox)
        self.setCentralWidget(self.panel)

#
###########
## Event functions
###########

    def create_figure(self):
        """ 
        Creates the figure
        """
        # Find the colorbar limits if unspecified
        if self.autoclim:
            self.clim = [self.data.min(), self.data.max()]
            self.climlow.setText('%3.1f' % self.clim[0])
            self.climhigh.setText('%3.1f' % self.clim[1])

        if 'collection' in self.__dict__:
            #self.collection.remove()
            self.axes.collections.remove(self.collection)
        else:
            # First call - set the axes limits
            self.axes.set_aspect('equal')
            self.axes.set_xlim(self.xlims)
            self.axes.set_ylim(self.ylims)

        if self.collectiontype == 'cells':
            self.collection = PolyCollection(self.xy, cmap=self.cmap)
            self.collection.set_array(np.array(self.data[:]))
            if not self.showedges:
                self.collection.set_edgecolors(
                    self.collection.to_rgba(np.array((self.data[:]))))
        elif self.collectiontype == 'edges':
            xylines = [self.xp[self.edges], self.yp[self.edges]]
            linesc = [
                list(zip(xylines[0][ii, :], xylines[1][ii, :]))
                for ii in range(self.Ne)
            ]
            self.collection = LineCollection(linesc,
                                             array=np.array(self.data[:]),
                                             cmap=self.cmap)

        self.collection.set_clim(vmin=self.clim[0], vmax=self.clim[1])

        self.axes.add_collection(self.collection)
        self.title = self.axes.set_title(self.genTitle(), color=self.textcolor)
        self.axes.set_xlabel('Easting [m]')
        self.axes.set_ylabel('Northing [m]')

        # create a colorbar

        if 'cbar' not in self.__dict__:
            self.cbar = self.fig.colorbar(self.collection)
            #SetAxColor(self.cbar.ax.axes,self.textcolor,self.bgcolor)
        else:
            #pass
            print('Updating colorbar...')
            #self.cbar.check_update(self.collection)
            self.cbar.on_mappable_changed(self.collection)

        self.canvas.draw()

    def update_figure(self):
        if self.autoclim:
            self.clim = [self.data.min(), self.data.max()]
            self.climlow.setText('%3.1f' % self.clim[0])
            self.climhigh.setText('%3.1f' % self.clim[1])
        else:
            self.clim = [float(self.climlow.text()),\
                float(self.climhigh.text())]

        # check whether it is cell or edge type
        if self.hasDim(self.variable, self.griddims['Ne']):
            self.collectiontype = 'edges'
        elif self.hasDim(self.variable, self.griddims['Nc']):
            self.collectiontype = 'cells'

        # Create a new figure if the variable has gone from cell to edge of vice
        # versa
        if not self.collectiontype == self.oldcollectiontype:
            self.create_figure()
            self.oldcollectiontype = self.collectiontype

        self.collection.set_array(np.array(self.data[:]))
        self.collection.set_clim(vmin=self.clim[0], vmax=self.clim[1])

        # Cells only
        if self.collectiontype == 'cells':
            if not self.showedges:
                self.collection.set_edgecolors(
                    self.collection.to_rgba(np.array((self.data[:]))))
            else:
                self.collection.set_edgecolors('k')
                self.collection.set_linewidths(0.2)

        # Update the title
        self.title = self.axes.set_title(self.genTitle(), color=self.textcolor)

        #Update the colorbar
        self.cbar.update_normal(self.collection)

        # redraw the figure
        self.canvas.draw()

    #def on_pick(self, event):
    #    # The event received here is of the type
    #    # matplotlib.backend_bases.PickEvent
    #    #
    #    # It carries lots of information, of which we're using
    #    # only a small amount here.
    #    #
    #    box_points = event.artist.get_bbox().get_points()
    #    msg = "You've clicked on a bar with coords:\n %s" % box_points
    #
    #    dlg = wx.MessageDialog(
    #        self,
    #        msg,
    #        "Click!",
    #        wx.OK | wx.ICON_INFORMATION)

    #    dlg.ShowModal()
    #    dlg.Destroy()
    #
    def on_select_variable(self, event):
        #vname = event.GetString()
        vname = event
        #self.flash_status_message("Selecting variable: %s"%vname)
        # update the spatial object and load the data
        self.variable = vname
        self.loadData(variable=self.variable)

        # Check if the variable has a depth coordinate
        depthstr = ['']
        # If so populate the vertical layer box
        if self.hasDim(self.variable, self.griddims['Nk']):
            depthstr = ['%3.1f' % self.z_r[k] for k in range(self.Nkmax)]
            depthstr += ['surface', 'seabed']

        elif self.hasDim(self.variable, 'Nkw'):
            depthstr = ['%3.1f' % self.z_w[k] for k in range(self.Nkmax + 1)]

        self.depthlayer_list.clear()
        self.depthlayer_list.addItems(depthstr)

        # Update the plot
        self.update_figure()

    def on_select_time(self, event):

        self.tindex = event  #
        # Update the object time index and reload the data
        #if self.plot_type=='hydro':
        if not self.tstep == self.tindex:
            self.tstep = self.tindex
            self.loadData()
            #self.flash_status_message("Selecting variable: %s..."%event.GetString())

            # Update the plot
            self.update_figure()
        #elif self.plot_type=='particles':
        #    self.PTM.plot(self.tindex,ax=self.axes,\
        #        xlims=self.axes.get_xlim(),ylims=self.axes.get_ylim())
        #
        #    self.canvas.draw()

    def on_select_depth(self, event):
        print(event)
        kindex = event
        if not self.klayer[0] == kindex:
            # Check if its the seabed or surface value
            if kindex >= self.Nkmax:
                kindex = event.GetString()
            self.klayer = [kindex]
            self.loadData()
            #self.flash_status_message("Selecting depth: %s..."%event.GetString())

            # Update the plot
            self.update_figure()

    def on_open_file(self, event):
        file_choices = "SUNTANS NetCDF (*.nc);;All Files (*.*)"

        dlg = QFileDialog.getOpenFileNames(self, "Open SUNTANS file...", "",
                                           file_choices)

        path = dlg[0]

        if len(path) == 0:
            return

        self.statusBar().showMessage("Opening SUNTANS file: %s" % path)
        try:
            Spatial.__init__(self, path, _FillValue=self._FillValue)
        except:
            Spatial.__init__(self, path, _FillValue=-999999)
        startvar = 'dv'

        self.statusBar().clearMessage()

        # Populate the drop down menus
        vnames = self.listCoordVars()
        self.variable_list.clear()
        self.variable_list.addItems(vnames)
        # Update the time drop down list
        if 'time' in self.__dict__:
            self.timestr = [
                datetime.strftime(tt, '%d-%b-%Y %H:%M:%S') for tt in self.time
            ]
        else:
            # Assume that it is a harmonic-type file
            self.timestr = self.nc.Constituent_Names.split()

        self.time_list.clear()
        self.time_list.addItems(self.timestr)

        # Draw the depth
        if startvar in vnames:
            self.variable = startvar
            self.loadData()
            self.create_figure()

    def on_load_grid(self, event):

        dir_ = QFileDialog.getExistingDirectory(None, 'Select a SUNTANS grid folder:',\
                '~/', QFileDialog.ShowDirsOnly)
        print(dir_)

        if dir_ is not None:
            path = dir_

            # Initialise the class
            #self.flash_status_message("Opening SUNTANS grid from folder: %s" % path)
            Grid.__init__(self, path)

            # Plot the Grid
            if 'collection' in self.__dict__:
                self.axes.collections.remove(self.collection)

            self.axes, self.collection = self.plotmesh(ax=self.axes,
                                                       edgecolors='y')

            # redraw the figure
            self.canvas.draw()

    #def on_load_ptm(self, event):
    #    file_choices = "PTM NetCDF (*.nc)|*.nc|PTM Binary (*_bin.out)|*_bin.out|All Files (*.*)|*.*"
    #
    #    dlg = wx.FileDialog(
    #        self,
    #        message="Open PTM file...",
    #        defaultDir=os.getcwd(),
    #        defaultFile="",
    #        wildcard=file_choices,
    #        style= wx.FD_MULTIPLE)
    #
    #    if dlg.ShowModal() == wx.ID_OK:
    #        self.plot_type = 'particles'
    #        path = dlg.GetPath()

    #        # Initialise the class
    #        if dlg.GetFilterIndex() == 0: #SUNTANS
    #            self.flash_status_message("Opening PTM netcdf file: %s" % path)
    #            self.PTM = PtmNC(path)
    #        elif dlg.GetFilterIndex() == 1: #PTM
    #            self.flash_status_message("Opening PTM binary file: %s" % path)
    #            self.PTM = PtmBin(path)

    #        self.Nt = self.PTM.nt
    #
    #        # Update the time drop down list
    #        self.timestr = [datetime.strftime(tt,'%d-%b-%Y %H:%M:%S') for tt in self.PTM.time]
    #        self.time_list.SetItems(self.timestr)

    #        # Plot the first time step
    #        if self.__dict__.has_key('xlims'):
    #            self.PTM.plot(self.PTM.nt-1,ax=self.axes,xlims=self.xlims,\
    #            ylims=self.ylims,color=self.particlecolor,\
    #            fontcolor='w',markersize=self.particlesize)
    #        else:
    #            self.PTM.plot(self.PTM.nt-1,ax=self.axes,fontcolor='w',\
    #                color=self.particlecolor,markersize=self.particlesize)
    #        # redraw the figure
    #        self.canvas.draw()

    #
    def on_show_edges(self, event):
        if event > 0:
            self.showedges = True
        else:
            self.showedges = False

        # Update the figure
        self.update_figure()

    def on_clim_check(self, event):
        if event > 0:
            self.autoclim = False
            self.update_figure()
        else:
            self.autoclim = True

    def on_climlow(self, event):
        try:
            self.clim[0] = float(event)
        except:
            return  # do nothing

    #    self.clim[0] = event.GetString()
    #    #self.update_figure()

    def on_climhigh(self, event):
        try:
            self.clim[1] = float(event)
        except:
            return  # do nothing

    #    print event
    #    self.clim[1] = event.GetString()
    #    #self.update_figure()

    def on_select_cmap(self, event):
        self.cmap = event
        self.collection.set_cmap(self.cmap)

        # Update the figure
        self.update_figure()

    #def on_save_fig(self,event):
    #    """
    #    Save a figure of the current scene to a file
    #    """
    #    file_choices = " (*.png)|*.png| (*.pdf)|*.pdf |(*.jpg)|*.jpg |(*.eps)|*eps "
    #    filters=['.png','.pdf','.png','.png']

    #
    #    dlg = wx.FileDialog(
    #        self,
    #        message="Save figure to file...",
    #        defaultDir=os.getcwd(),
    #        defaultFile="",
    #        wildcard=file_choices,
    #        style= wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)

    #    if dlg.ShowModal() == wx.ID_OK:

    #        path = dlg.GetPath()
    #        ext = filters[dlg.GetFilterIndex()]
    #        if ext in path:
    #            outfile=path
    #        else:
    #            outfile = path+ext

    #        self.fig.savefig(outfile)

    #

    def on_save_anim(self, event):
        """
        Save an animation of the current scene to a file
        """
        #file_choices = "Quicktime (*.mov)|*.mov| (*.gif)|*.gif| (*.avi)|*.avi |(*.mp4)|*.mp4 "
        #filters=['.mov','.gif','.avi','.mp4']
        filters = "Movie formats (*.mp4 *.avi *.gif);;All files (*.*)"


        dir_ = QFileDialog.getSaveFileName(None, 'Save animation to file:',\
                '~/', filters)
        print(dir_)

        #dlg = wx.FileDialog(
        #    self,
        #    message="Output animation file...",
        #    defaultDir=os.getcwd(),
        #    defaultFile="",
        #    wildcard=file_choices,
        #    style= wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)

        if dir_ is not None:

            outfile = dir_[0]
            ext = outfile[-4::]

            # Create the animation
            #self.tstep = range(self.Nt) # Use all time steps for animation
            #self.animate(cbar=self.cbar,cmap=self.cmap,\
            #    xlims=self.axes.get_xlim(),ylims=self.axes.get_ylim())
            def initanim():
                return (self.title, self.collection)
                #if not self.plot_type=='particles':
                #    return (self.title, self.collection)
                #else:
                #    return (self.PTM.title,self.PTM.p_handle)

            def updateScalar(i):
                self.tstep = [i]
                self.loadData()
                self.update_figure()
                return (self.title, self.collection)

                #if not self.plot_type=='particles':
                #    self.tstep=[i]
                #    self.loadData()
                #    self.update_figure()
                #    return (self.title,self.collection)
                #elif self.plot_type=='particles':
                #    self.PTM.plot(i,ax=self.axes,\
                #        xlims=self.axes.get_xlim(),ylims=self.axes.get_ylim())
                #    return (self.PTM.title,self.PTM.p_handle)

            self.anim = animation.FuncAnimation(self.fig, \
                updateScalar, init_func = initanim, frames=self.Nt, interval=50, blit=True)

            if ext == '.gif':
                self.anim.save(outfile, writer='imagemagick', fps=6)
            elif ext == '.mp4':
                print('Saving html5 video...')
                # Ensures html5 compatibility
                self.anim.save(outfile,fps=6,\
                    writer='ffmpeg',\
                    bitrate=3600,extra_args=['-vcodec','libx264'])
                #writer='mencoder',
                #bitrate=3600,extra_args=['-ovc','x264']) # mencoder options
            else:
                self.anim.save(outfile, writer='mencoder', fps=6, bitrate=3600)

            # Return the figure back to its status
            del self.anim
            self.tstep = self.tindex
            self.loadData()
            self.update_figure()
            print('Finished saving animation to %s' % outfile)
            print(72 * '#')

            #if not self.plot_type=='particles':
            #    self.loadData()
            #    self.update_figure()

            # Bring up a dialog box
            #dlg2= wx.MessageDialog(self, 'Animation complete.', "Done", wx.OK)
            #dlg2.ShowModal()
            #dlg2.Destroy()

    #def on_exit(self, event):
    #    self.Destroy()
    #
    #def on_about(self, event):
    #    msg = """ SUNTANS NetCDF visualization tool
    #
    #        *Author: Matt Rayson
    #        *Institution: Stanford University
    #        *Created: October 2013
    #    """
    #    dlg = wx.MessageDialog(self, msg, "About", wx.OK)
    #    dlg.ShowModal()
    #    dlg.Destroy()

    #def on_count_cells(self,eveny):
    #    msg = "Total 3-D grid cells = %d"%(self.count_cells())
    #    dlg = wx.MessageDialog(self, msg, "No. cells", wx.OK)
    #    dlg.ShowModal()
    #    dlg.Destroy()

    #def on_overlay_bathy(self,event):
    #    # Plot depth contours
    #    print 'Plotting contours...'
    #    self.contourf(z=self.dv, clevs=self.depthlevs,\
    #        ax=self.axes,\
    #        filled=False, colors='0.5', linewidths=0.5, zorder=1e6)
    #    print 'Done'

    def on_plot_gridstat(self, event):
        """
        Plot the grid size histogram in a new figure
        """
        matplotlib.pyplot.figure()
        self.plothist()
        matplotlib.pyplot.show()
示例#41
0
    def create_filters(self, parent, code, lang=False, area=False, sal=True):
        if sal:
            label_sal = QLabel(parent)
            label_sal.setText('Зарплата от')
            label_sal.resize(100, 15)
            label_sal.move(5, 125)

            label_sal_val = QLabel(parent)
            label_sal_val.move(FRAME_WIDTH - 50, 125)
            label_sal_val.resize(45, 15)
            label_sal_val.setAlignment(Qt.AlignRight)
            label_sal_val.setText(str(self.start_sal))

            sld_sal = QSlider(Qt.Horizontal, parent)
            sld_sal.setMinimum(int(self.start_sal / 5000))
            sld_sal.setMaximum(40)
            sld_sal.setPageStep(1)
            sld_sal.move(5, 145)
            sld_sal.resize(FRAME_WIDTH - 10, 20)
            sld_sal.valueChanged[int].connect(
                lambda val, tab=code: self.sld_action(val, tab))
        else:
            label_sal_val = None
            sld_sal = None

        if lang:
            combo_lang = QComboBox(parent)
            combo_lang.setMaxVisibleItems(20)
            combo_lang.addItem("Все языки")
            combo_lang.resize(FRAME_WIDTH - 10, 20)
            combo_lang.move(5, 10)
            combo_lang.addItems(LANGUAGES)
            combo_lang.activated.connect(
                lambda val, tab=code: self.refresh_plot(tab))
        else:
            combo_lang = None

        if area:
            combo_area = QComboBox(parent)
            combo_area.setMaxVisibleItems(20)
            combo_area.addItem("Все города")
            combo_area.resize(FRAME_WIDTH - 10, 20)
            combo_area.move(5, 10)
            combo_area.addItems(
                [work_with_data.decode_param(val) for val in AREA])
            combo_area.activated.connect(
                lambda val, tab=code: self.refresh_plot(tab))
        else:
            combo_area = None

        combo_sizecomp = QComboBox(parent)
        combo_sizecomp.setMaxVisibleItems(5)
        combo_sizecomp.addItem("Все компании")
        combo_sizecomp.resize(FRAME_WIDTH - 10, 20)
        combo_sizecomp.move(5, 40)
        combo_sizecomp.addItems([
            work_with_data.decode_param(size_comp)
            for size_comp in SIZE_COMPANY
        ])
        combo_sizecomp.activated.connect(
            lambda val, tab=code: self.refresh_plot(tab))

        combo_exp = QComboBox(parent)
        combo_exp.setMaxVisibleItems(10)
        combo_exp.addItem("Любой опыт")
        combo_exp.resize(FRAME_WIDTH - 10, 20)
        combo_exp.move(5, 70)
        combo_exp.addItems([
            work_with_data.decode_param(experience)
            for experience in EXPERIENCE
        ])
        combo_exp.activated.connect(
            lambda val, tab=code: self.refresh_plot(tab))

        combo_empl = QComboBox(parent)
        combo_empl.setMaxVisibleItems(10)
        combo_empl.addItem("Любой график")
        combo_empl.resize(FRAME_WIDTH - 10, 20)
        combo_empl.move(5, 100)
        combo_empl.addItems([
            work_with_data.decode_param(employment)
            for employment in EMPLOYMENT
        ])
        combo_empl.activated.connect(
            lambda val, tab=code: self.refresh_plot(tab))

        items = {
            'Lang': combo_lang,
            'Area': combo_area,
            'MinSal': sld_sal,
            'SizeComp': combo_sizecomp,
            'Employment': combo_empl,
            'Experience': combo_exp,
            'lbl_min': label_sal_val
        }
        return items
示例#42
0
class MLSVM_Predict(ElementMaster):

    pixmap_path = 'images/MLSVM_Predict.png'
    child_pos = (True, False)

    def __init__(self, row, column):
        self.row = row
        self.column = column

        # scale_option, scale_mean, scale_std, predict_val, filename, log_state

        scale_option = 0
        scale_mean = True
        scale_std = True
        predict_val = False
        filename = None
        rel_path = False
        log_state = False

        self.config = scale_option, scale_mean, scale_std, predict_val, filename, rel_path, log_state

        super().__init__(self.row, self.column, self.pixmap_path, True,
                         self.config)
        super().edit_sig.connect(self.edit)
        logging.debug(
            'MLSVM_Predict::__init__() called at row {}, column {}'.format(
                row, column))
        self.addFunction(MLSVM_PredictFunction)

    def __setstate__(self, state):
        logging.debug('MLSVM_Predict::__setstate__() called')
        self.row, self.column, self.config = state
        super().__init__(self.row, self.column, self.pixmap_path, True,
                         self.config)
        super().edit_sig.connect(self.edit)
        self.addFunction(MLSVM_PredictFunction)

    def __getstate__(self):
        logging.debug('MLSVM_Predict::__getstate__() called')
        return (self.row, self.column, self.config)

    def openEditor(self):
        logging.debug('MLSVM_Predict::openEditor() called')

    def edit(self):

        logging.debug('MLSVM_Predict::edit()')

        # scale_option, scale_mean, scale_std, predict_val, filename, log_state
        self.scale_option, self.scale_mean, self.scale_std, self.predict_val, \
                self.filename, self.rel_path, self.log_state = self.config

        self.home_dict = str(Path.home())

        self.scale_label = QLabel()
        self.scale_label.setText(QC.translate('', 'Scale n_samples ?'))
        self.scale_list = QComboBox()
        self.scale_list.addItem(QC.translate('', 'No'), QVariant(False))
        self.scale_list.addItem(QC.translate('', 'Yes'), QVariant(True))

        self.scale_center_input_line = QWidget()
        self.scale_center_input_line_layout = QHBoxLayout(
            self.scale_center_input_line)
        self.scale_center_label = QLabel()
        self.scale_center_label.setText(
            QC.translate('', 'Center data before scaling?'))
        self.scale_center_checkbox = QCheckBox()
        self.scale_center_input_line_layout.addWidget(self.scale_center_label)
        self.scale_center_input_line_layout.addWidget(
            self.scale_center_checkbox)

        self.scale_std_input_line = QWidget()
        self.scale_std_input_line_layout = QHBoxLayout(
            self.scale_std_input_line)
        self.scale_std_label = QLabel()
        self.scale_std_label.setText(
            QC.translate('', 'Scale data until variance?'))
        self.scale_std_checkbox = QCheckBox()
        self.scale_std_input_line_layout.addWidget(self.scale_std_label)
        self.scale_std_input_line_layout.addWidget(self.scale_std_checkbox)

        self.scale_input_area = QWidget()
        self.scale_input_area_layout = QVBoxLayout(self.scale_input_area)
        self.scale_input_area_layout.addWidget(self.scale_center_input_line)
        self.scale_input_area_layout.addWidget(self.scale_std_input_line)

        self.last_value_line = QWidget()
        self.last_value_line_layout = QHBoxLayout(self.last_value_line)
        self.last_value_label = QLabel()
        self.last_value_label.setText(
            QC.translate('', 'Predict only last value [-1]?'))
        self.last_value_checkbox = QCheckBox()

        self.last_value_line_layout.addWidget(self.last_value_label)
        self.last_value_line_layout.addWidget(self.last_value_checkbox)

        self.conn_rest_layout = QVBoxLayout()
        self.confirm_button = QPushButton(QC.translate('', 'Ok'))
        """
        self.filename_text = QLabel()
        self.filename_text.setWordWrap(True)
        
        self.file_button = QPushButton(QC.translate('', 'Select model file'))
        self.file_button.clicked.connect(self.openFileNameDialog)
        """

        self.filename_text = QLabel()
        self.filename_text.setWordWrap(True)

        self.file_button = QPushButton(
            QC.translate('', 'Select model output file'))
        self.file_button.clicked.connect(self.openFileNameDialog)

        self.relative_file_check = QWidget()
        self.relative_file_check_layout = QHBoxLayout(self.relative_file_check)

        self.relative_file_label = QLabel()
        self.relative_file_label.setText(
            QC.translate('', 'Filename relative to $HOME.'))
        self.relative_file_checkbox = QCheckBox()
        self.relative_file_check_layout.addWidget(self.relative_file_checkbox)
        self.relative_file_check_layout.addWidget(self.relative_file_label)
        self.relative_file_check_layout.addStretch(1)

        self.relative_filepath_input = QLineEdit()
        self.relative_filepath_input.setPlaceholderText('my_folder/my_file')

        self.file_input = QWidget()
        self.file_input_layout = QVBoxLayout(self.file_input)
        self.file_input_layout.addWidget(self.filename_text)
        self.file_input_layout.addWidget(self.file_button)
        self.file_input_layout.addWidget(self.relative_file_check)
        self.file_input_layout.addWidget(self.relative_filepath_input)
        """
        output: prediction quality
        """
        self.help_text_1 = QLabel()
        self.help_text_1.setText(
            QC.translate('', 'Expects an array of samples as input.'))

        self.help_text_2 = QLabel()
        self.help_text_2.setText(
            QC.translate('', 'Outputs a single value or an array.'))

        # hier logging option einfügen
        self.log_line = QWidget()
        self.ask_for_logging = QLabel()
        self.ask_for_logging.setText(QC.translate('', 'Log output?'))
        self.log_checkbox = QCheckBox()
        self.log_line_layout = QHBoxLayout(self.log_line)
        self.log_line_layout.addWidget(self.ask_for_logging)
        self.log_line_layout.addWidget(self.log_checkbox)
        self.log_line_layout.addStretch(1)

        self.ml_svm_predict_edit = ElementEditor(self)
        self.ml_svm_predict_edit.setWindowTitle(
            QC.translate('', 'Support Vector Machine Prediction'))
        self.ml_svm_predict_edit.setMinimumHeight(450)

        # signals and slots
        self.relative_file_checkbox.stateChanged.connect(self.toggleFileInput)
        self.scale_list.currentIndexChanged.connect(self.scaledIndexChanged)
        self.confirm_button.clicked.connect(
            self.ml_svm_predict_edit.closeEvent)
        self.ml_svm_predict_edit.window_closed.connect(self.edit_done)

        # load config
        self.loadLastConfig()

        self.conn_rest_layout.addWidget(self.help_text_1)
        self.conn_rest_layout.addWidget(
            self.scale_label)  # scale: copy = false
        self.conn_rest_layout.addWidget(self.scale_list)
        self.conn_rest_layout.addWidget(self.scale_input_area)
        self.conn_rest_layout.addWidget(self.last_value_line)
        self.conn_rest_layout.addWidget(self.file_input)
        self.conn_rest_layout.addStretch(1)
        self.conn_rest_layout.addWidget(self.help_text_2)
        self.conn_rest_layout.addWidget(self.log_line)
        self.conn_rest_layout.addWidget(self.confirm_button)
        self.ml_svm_predict_edit.setLayout(self.conn_rest_layout)
        self.ml_svm_predict_edit.show()

    def loadLastConfig(self):

        logging.debug('MLSVM_Predict::loadLastConfig() called')

        self.scale_list.setCurrentIndex(self.scale_option)
        self.scaledIndexChanged(self.scale_option)
        self.scale_center_checkbox.setChecked(self.scale_mean)
        self.scale_std_checkbox.setChecked(self.scale_std)
        self.last_value_checkbox.setChecked(self.predict_val)
        self.log_checkbox.setChecked(self.log_state)
        self.relative_file_checkbox.setChecked(self.rel_path)

        if self.rel_path:
            self.toggleFileInput(2)
            if self.filename:
                self.relative_filepath_input.setText(self.filename)
        else:
            self.toggleFileInput(0)
            if self.filename:
                self.filename_text.setText(self.filename)

    def toggleFileInput(self, event):
        logging.debug('MLSVM::toggleFileInput() called: {}'.format(event))
        # 0 = FALSE, 2 = TRUE
        if event:  # TRUE
            self.file_button.setDisabled(True)
            self.relative_filepath_input.setDisabled(False)
            self.filename_text.setText('')
        else:
            self.file_button.setDisabled(False)
            self.relative_filepath_input.clear()
            self.relative_filepath_input.setDisabled(True)
            self.relative_filepath_input.setPlaceholderText(
                'my_folder/my_file')

    def scaledIndexChanged(self, event):

        current_index = event
        logging.debug(
            'MLSVM_Predict::scaledIndexChanged() called: {}'.format(event))
        if event == 1:
            self.scale_input_area.setVisible(True)
        else:
            self.scale_input_area.setVisible(False)

    def openFileNameDialog(self, event):
        options = QFileDialog.Options()
        #options |= QFileDialog.DontUseNativeDialog

        fileName, _ = QFileDialog.getOpenFileName(
            self,
            QC.translate('', 'Open SVM model file'),
            self.home_dict,
            "All Files (*);;Pythonic Files (*.pyc)",
            options=options)
        if fileName:
            logging.debug(
                'MLSVM_Predict::openFileNameDialog() called with filename: {}'.
                format(fileName))
            self.filename = fileName
            self.filename_text.setText(self.filename)

    def edit_done(self):

        logging.debug('MLSVM_Predict::edit_done() called')
        # scale_option, scale_mean, scale_std, predict_val, filename, log_state

        scale_option = self.scale_list.currentIndex()
        scale_mean = self.scale_center_checkbox.isChecked()
        scale_std = self.scale_std_checkbox.isChecked()
        predict_val = self.last_value_checkbox.isChecked()
        log_state = self.log_checkbox.isChecked()
        rel_path = self.relative_file_checkbox.isChecked()
        if rel_path:
            filename = self.relative_filepath_input.text()
        else:
            filename = self.filename

        if filename == '':
            filename = None

        self.config = scale_option, scale_mean, scale_std, predict_val, filename, rel_path, log_state

        self.addFunction(MLSVM_PredictFunction)
示例#43
0
class MainWindow(QMainWindow):
    """Main Window Class

    Following class contains several public functions to implement GUI of the app.

    """
    def __init__(self):
        """Initialize Function

        Following function creates main window and executes all other initialization functions.

        Args:
            QMainWindow object: main window of the app.

        Returns:
            None

        """

        super().__init__()

        self.resize(600, 200)
        self.init_ui()
        self.setStyleSheet(__style__)

        self.show()

    def init_ui(self):
        """Initialize User Interface Function

        Following function executes all other initialization functions, defining whole look of the app.

        Args:
            QMainWindow object: main window of the app.

        Returns:
            None

        """

        self.init_combo_box()
        self.init_text_edit()
        self.init_push_button()

    def init_combo_box(self):
        """Initialize Combo Boxes Function

        Following function defines all of the combo boxes of the app.

        Args:
            QMainWindow object: main window of the app.

        Returns:
            None

        """

        self.adjust_query = QComboBox(self)
        self.adjust_query.resize(200, 40)
        self.adjust_query.move(150, 140)

    def init_text_edit(self):
        """Initialize Text Edits Function

        Following function defines all of the text edits of the app.

        Args:
            QMainWindow object: main window of the app.

        Returns:
            None

        """

        self.russian_text_edit = QTextEdit(self)
        self.russian_text_edit.setPlaceholderText('Введите термин')
        self.russian_text_edit.setStyleSheet(__style__)
        self.russian_text_edit.resize(250, 100)
        self.russian_text_edit.move(20, 20)

        self.english_text_edit = QTextEdit(self)
        self.english_text_edit.setPlaceholderText('Enter term')
        self.english_text_edit.setStyleSheet(__style__)
        self.english_text_edit.resize(250, 100)
        self.english_text_edit.move(330, 20)

    def init_push_button(self):
        """Initialize Buttons Function

        Following function defines all of the buttons of the app.

        Args:
            QMainWindow object: main window of the app.

        Returns:
            None

        """

        self.translate_to_english_button = QPushButton('>', self)
        self.translate_to_english_button.clicked.connect(
            self.translate_to_english_button_clicked)
        self.translate_to_english_button.resize(20, 20)
        self.translate_to_english_button.move(290, 40)

        self.translate_to_russian_button = QPushButton('<', self)
        self.translate_to_russian_button.clicked.connect(
            self.translate_to_russian_button_clicked)
        self.translate_to_russian_button.resize(20, 20)
        self.translate_to_russian_button.move(290, 80)

        self.adjust_query_button = QPushButton('Adjust query', self)
        self.adjust_query_button.clicked.connect(
            self.adjust_query_button_clicked)
        self.adjust_query_button.resize(100, 30)
        self.adjust_query_button.move(370, 140)

    def translate_to_english_button_clicked(self):
        """Translate to English Button Clicked Function

        Following function implements logic, executing when user wants to translate term into English.

        Args:
            QMainWindow object: main window of the app.

        Returns:
            None

        """

        term = self.russian_text_edit.toPlainText()
        self.language = 'ru'
        search_result = Translator.search_user_term(term, self.language)

        if Translator.translate_user_term(term, self.language)[0] == '0':
            self.adjust_query.clear()
            for i in range(len(search_result)):
                self.adjust_query.addItem(search_result[i])
            term = self.adjust_query.currentText()
            self.english_text_edit.setText(
                Translator.translate_user_term(term, self.language)[1:])
        else:
            QMessageBox.warning(
                self, 'Error',
                Translator.translate_user_term(term, self.language)[1:],
                QMessageBox.Ok)

    def translate_to_russian_button_clicked(self):
        """Translate to Russian Button Clicked Function

        Following function implements logic, executing when user wants to translate term into Russian.

        Args:
            QMainWindow object: main window of the app.

        Returns:
            None

        """

        term = self.english_text_edit.toPlainText()
        self.language = 'en'
        search_result = Translator.search_user_term(term, self.language)

        if Translator.translate_user_term(term, self.language)[0] == '0':
            self.adjust_query.clear()
            for i in range(len(search_result)):
                self.adjust_query.addItem(search_result[i])
            term = self.adjust_query.currentText()
            self.russian_text_edit.setText(
                Translator.translate_user_term(term, self.language)[1:])
        else:
            QMessageBox.warning(
                self, 'Error',
                Translator.translate_user_term(term, self.language)[1:],
                QMessageBox.Ok)

    def adjust_query_button_clicked(self):
        """Adjust Query Button Clicked Function

        Following function implements logic, executing when user wants to adjust query.

        Args:
            QMainWindow object: main window of the app.

        Returns:
            None

        """

        try:
            term = self.adjust_query.currentText()
            adjust_language = self.language
            search_result = Translator.search_user_term(term, adjust_language)

            if Translator.translate_user_term(term, adjust_language)[0] == '0':
                if adjust_language == 'en':
                    self.russian_text_edit.setText(
                        Translator.translate_user_term(term,
                                                       adjust_language)[1:])
                else:
                    self.english_text_edit.setText(
                        Translator.translate_user_term(term,
                                                       adjust_language)[1:])
            else:
                QMessageBox.warning(
                    self, 'Error',
                    Translator.translate_user_term(term, adjust_language)[1:],
                    QMessageBox.Ok)
        except UnboundLocalError:
            QMessageBox.warning(self, 'Error', 'Input term to translate first',
                                QMessageBox.Ok)
示例#44
0
class TeqCustomQueryWidget(QWidget):
    def __init__(self):
        super(QWidget, self).__init__()
        self._setup_widget()

    def _setup_widget(self):
        self.query = QTextEdit(self)

        self.submit1 = QPushButton("Execute Query")
        self.submit1.clicked.connect(self.run_query)

        self.export1 = QPushButton("Export Data")
        self.export1.clicked.connect(self.export_data)

        self._setup_export_combobox()
        self.table1 = QTableWidget()

        # set layouts
        self.layout = QGridLayout(self)
        self.layout.setColumnStretch(0, 3)

        # add "Query" label
        self.layout.addWidget(QLabel("Query:"), 0, 0)
        # add query textbox
        self.layout.addWidget(self.query, 1, 0)
        # add "Execute Query" button
        self.layout.addWidget(self.submit1, 1, 1)
        # add "Output" label
        self.layout.addWidget(QLabel("Query Output:"), 2, 0)
        # add file option combobox
        self.layout.addWidget(self.export_combobox, 2, 1)
        # add query output result table
        self.layout.addWidget(self.table1, 3, 0)
        self.layout.addWidget(self.export1, 3, 1)

        self.setLayout(self.layout)

    def _setup_export_combobox(self):
        self.export_options = {
                "csv": exportCSV.ExportCSV(),
                "pdf": exportPDF.ExportPDF()
                }
        self.export_combobox = QComboBox()
        for key in self.export_options:
            self.export_combobox.addItem(key)

    @pyqtSlot()
    def run_query(self):
        query = self.query.toPlainText()
        if (len(query) == 0):
            gui_helper.prompt_error("Please enter a query")
            return
        try:
            dict_values = database.execute_query_result(query)
            if (dict_values):
                self.populateTable(dict_values)
            gui_helper.prompt_information("query executed successfully")
        except Exception as e:
            gui_helper.prompt_error("Failed to run Query: " + repr(e))

    def populateTable(self, column_values):
        self.table1.clearContents()

        self.table1.setColumnCount(len(column_values))
        for key in column_values:
            self.table1.setRowCount(len(column_values[key]))
            break
        for i, key in enumerate(column_values):
            self.table1.setHorizontalHeaderItem(i, QTableWidgetItem(key))
            col_vals = column_values[key]
            for j, val in enumerate(col_vals):
                self.table1.setItem(j, i, QTableWidgetItem(str(val)))

    @pyqtSlot()
    def export_data(self):
        query_text = self.query.toPlainText()
        if (len(query_text) == 0):
            gui_helper.prompt_error("Please enter a query")
            return

        export_option = self.export_options[self.export_combobox.currentText()]
        file_path = gui_helper.prompt_file_save()
        if (not file_path):
            return

        try:
            export_option.export(file_path, query_text)
            gui_helper.prompt_information("Data has been succesfully exported!")
        except Exception as e:
            gui_helper.prompt_error("Failed to export data: " + repr(e))

    @pyqtSlot()
    def add_graph(self):
        graph_type = self.export_combobox.currentText()
        query_text = self.query.toPlainText()

        if (len(query_text) == 0):
            gui_helper.prompt_error("Please enter a query")
            return

        row_count = self.report_table.rowCount()
        self.report_table.insertRow(row_count)
        self.report_table.setItem(row_count, 0, QTableWidgetItem(graph_type))
        self.report_table.setItem(row_count, 1, QTableWidgetItem(query_text))
示例#45
0
class TeqGraphGenerationWidget(QWidget):
    def __init__(self):
        super(QWidget, self).__init__()
        self._setup_widget()

    def _setup_widget(self):
        self.query = QTextEdit(self)

        self.addtoreport = QPushButton("Add Graph to Report")
        self.addtoreport.clicked.connect(self.add_graph)

        self.submit1 = QPushButton("Execute Query")
        self.submit1.clicked.connect(self.run_query)

        self.export1 = QPushButton("Export Graphs")
        self.export1.clicked.connect(self.export_data)

        self.clear1 = QPushButton("Clear Graphs")
        self.clear1.clicked.connect(self.clear_graphs)

        self._setup_graph_export_combobox()
        self._setup_report_queue_table()

        self.table1 = QTableWidget()

        # set layouts
        self.layout = QGridLayout(self)
        self.layout.setColumnStretch(0, 3)

        self.layout.addWidget(QLabel("Query:"), 0, 0)
        # add query textbox
        self.layout.addWidget(self.query, 1, 0)
        self.layout.addWidget(self.submit1, 1, 1)

        self.layout.addWidget(QLabel("In Current Report:"), 2, 0)
        # add file option combobox
        self.layout.addWidget(self.export_combobox, 2, 1)
        # add query output result table

        self.layout.addWidget(self.report_table, 3, 0)
        self.layout.addWidget(self.addtoreport, 3, 1)

        self.layout.addWidget(QLabel("Query Output:"), 4, 0)
        self.layout.addWidget(self.clear1, 4, 1)

        self.layout.addWidget(self.table1, 5, 0)
        self.layout.addWidget(self.export1, 5, 1)

        self.setLayout(self.layout)

    def _setup_graph_export_combobox(self):
        self.export_graph_options = {
                "bar": graph.bar_chart,
                "line": graph.line_chart,
                "pie": graph.pie_chart
                }
        self.export_combobox = QComboBox()
        for key in self.export_graph_options:
            self.export_combobox.addItem(key)

    def _setup_report_queue_table(self):
        self.report_table = QTableWidget()
        self.report_table.setColumnCount(2)
        header = self.report_table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(1, QHeaderView.ResizeToContents)
        self.report_table.setHorizontalHeaderItem(0, QTableWidgetItem("Graph Type"))
        self.report_table.setHorizontalHeaderItem(1, QTableWidgetItem("Query"))

    @pyqtSlot()
    def run_query(self):
        query = self.query.toPlainText()
        if (len(query) == 0):
            gui_helper.prompt_error("Please enter a query")
            return
        try:
            dict_values = database.execute_query_result(query)
            if (dict_values):
                self.populateTable(dict_values)
            gui_helper.prompt_information("query executed successfully")
        except Exception as e:
            gui_helper.prompt_error("Failed to run Query: " + repr(e))

    def populateTable(self, column_values):
        self.table1.clearContents()

        self.table1.setColumnCount(len(column_values))
        for key in column_values:
            self.table1.setRowCount(len(column_values[key]))
            break
        for i, key in enumerate(column_values):
            self.table1.setHorizontalHeaderItem(i, QTableWidgetItem(key))
            col_vals = column_values[key]
            for j, val in enumerate(col_vals):
                self.table1.setItem(j, i, QTableWidgetItem(str(val)))

    @pyqtSlot()
    def add_graph(self):
        graph_type = self.export_combobox.currentText()
        query_text = self.query.toPlainText()

        if (len(query_text) == 0):
            gui_helper.prompt_error("Please enter a query")
            return

        row_count = self.report_table.rowCount()
        self.report_table.insertRow(row_count)
        self.report_table.setItem(row_count, 0, QTableWidgetItem(graph_type))
        self.report_table.setItem(row_count, 1, QTableWidgetItem(query_text))

    @pyqtSlot()
    def clear_graphs(self):
        self.report_table.setRowCount(0)

    @pyqtSlot()
    def export_data(self):
        query_text = self.query.toPlainText()
        if (len(query_text) == 0):
            gui_helper.prompt_error("Please enter a query")
            return

        file_path = gui_helper.prompt_file_save()

        if (not file_path):
            return

        with PdfPages(file_path) as pdf:
            conn = database.get_db_connection()
            for i in range(self.report_table.rowCount()):
                query_text = self.report_table.item(i, 1).text()
                graph_type = self.report_table.item(i, 0).text()

                dict_values = query.manual_sql_query(conn, query_text)
                try:
                    plt = self.export_graph_options[graph_type](graph_type, dict_values)

                    fig = plt.gcf()
                    pdf.savefig()
                    plt.close(fig)
                except Exception as e:
                    gui_helper.prompt_error("Failed to export graph {}: ".format(i) + repr(e))
            conn.close()
            gui_helper.prompt_information("Graphs has been successfully exported")
示例#46
0
class SettingsDialogGeneral(QWidget):
    def __init__(self, dialog):
        super().__init__()

        layout = QVBoxLayout()
        layout.setAlignment(Qt.AlignTop)

        self.__language_gb = QGroupBox()
        layout.addWidget(self.__language_gb)

        self.__language_selector = QComboBox()

        configured_language_id = Application().config.language
        current_language_id = Application().language.current_language

        for no, (lang_id, label) in enumerate(AVAILABLE_LANGUAGES):
            self.__language_selector.addItem(label)
            if lang_id == configured_language_id:
                self.__language_selector.setCurrentIndex(no)
            elif configured_language_id is None and lang_id != current_language_id:
                self.__language_selector.setCurrentIndex(no)

        self.__use_system = QRadioButton()
        self.__use_custom = QRadioButton()
        self.__use_custom.toggled.connect(self.__use_custom_changed)

        if configured_language_id is None:
            self.__use_system.setChecked(True)
            self.__language_selector.setEnabled(False)
        else:
            self.__use_custom.setChecked(True)

        language_layout = QFormLayout()
        language_layout.addRow(self.__use_system)
        language_layout.addRow(self.__use_custom, self.__language_selector)

        self.__language_gb.setLayout(language_layout)

        self.setLayout(layout)

        self.reload_texts()

    def __use_custom_changed(self, checked):
        self.__language_selector.setEnabled(checked)

    @staticmethod
    def get_name():
        return _("General")

    def apply_settings(self):
        if self.__use_system.isChecked():
            Application().language.change_language(None)
        else:
            selected_no = self.__language_selector.currentIndex()

            Application().language.change_language(
                AVAILABLE_LANGUAGES[selected_no][0])

    def reload_texts(self):
        self.__use_system.setText(_("Use system language"))
        self.__use_custom.setText(_("Custom language"))
        self.__language_gb.setTitle(_("Application language"))
示例#47
0
class App(QMainWindow):
    def __init__(self):
        super().__init__()
        #        QMainWindow.__init__(self)
        #        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        #        self.left = 100
        #        self.top = 100
        self.title = 'PyQt5 matplotlib example - pythonspot.com'
        #        self.width = 800
        #        self.height = 600
        self.initUI()

    def initUI(self):
        global df, df1, df2
        #import data
        # def parse_dates(x):
        #     return datetime.strptime(x, "%Y.%m.%d")
        dateparse = lambda x: datetime.strptime(x, '%Y.%m.%d')
        df = pd.read_csv('LianJia.csv',
                         encoding='ANSI',
                         index_col=0,
                         parse_dates=['成交日期'],
                         date_parser=dateparse)  #注意编码格式和索引
        df.set_index('成交日期', inplace=True)  #利用 '时间' 为index
        #        Select_XiaoQu = App.getcombo1Information #self.combo1.currentText()
        #        print(Select_XiaoQu)
        #        if Select_XiaoQu == None:
        #            Select_XiaoQu='瀚盛家园'
        Select_XiaoQu = '瀚盛家园'
        df1 = df[df['小区'] == Select_XiaoQu]

        df2 = df[df['板块'] == '唐镇'].groupby(['小区']).count()
        #        df2.groupby(['小区']).count().index
        #        df2.groupby(['小区']).count()['单价']

        self.setWindowTitle(self.title)
        #        self.setGeometry(self.left, self.top, self.width, self.height)
        self.file_menu = QMenu('&File', self)
        self.file_menu.addAction('&Quit', self.fileQuit,
                                 QtCore.Qt.CTRL + QtCore.Qt.Key_Q)
        self.menuBar().addMenu(self.file_menu)

        self.help_menu = QMenu('&Help', self)
        self.menuBar().addSeparator()
        self.menuBar().addMenu(self.help_menu)

        self.help_menu.addAction('&About', self.about)

        self.main_widget = QWidget(self)
        l = QVBoxLayout(self.main_widget)
        self.m = PlotCanvas(self.main_widget, width=8, height=4, dpi=100)
        self.n = PlotCount(self.main_widget, width=8, height=4, dpi=100)
        #m.move(0,0)

        self.main_widget.setFocus()
        self.setCentralWidget(self.main_widget)

        self.combo = QComboBox(self)
        self.combo1 = QComboBox(self)
        l.addWidget(self.combo)
        l.addWidget(self.combo1)
        l.addWidget(self.m)
        l.addWidget(self.n)
        self.combo1.addItem('瀚盛家园')
        #self.combo.move(500, 30)
        for ListItem in df['板块'].unique():
            self.combo.addItem(ListItem)
        self.combo.currentTextChanged.connect(self.comboChanged)
        self.combo.activated.connect(self.BanKuaiChanged)
        self.combo1.activated.connect(self.XiaoQuChanged)

        #self.combo.activated.connect(self.comboChanged)
        #self.roomBox.activated.connect(self.m.plot)

        #self.combo1.move(600, 30)
        #self.combo1.activated.connect(m.plot())

        #button = QPushButton('PyQt5 button', self)
        #button.setToolTip('This s an example button')
        #button.move(500,0)
        #button.resize(140,100)

        #combo.activated[str].connect(self.onActivated)

        #self.show()

    def comboChanged(self, text):
        #self.mediaBox.setEnabled(True)
        global df, df1
        Select_XiaoQu = self.combo.currentText()
        #print(Select_XiaoQu)
        self.combo1.clear()
        df1 = df[df['板块'] == Select_XiaoQu]
        #print(df1['小区'].unique())
        for ListItem in df1['小区'].unique():
            self.combo1.addItem(ListItem)

    def XiaoQuChanged(self, text):
        global df, df1
        #self.mediaBox.setEnabled(True)
        Select_XiaoQu = self.combo1.currentText()
        df1 = df[df['小区'] == Select_XiaoQu]
        self.m.update_figure()

    def BanKuaiChanged(self, text):
        global df, df2
        #self.mediaBox.setEnabled(True)
        Select_XiaoQu = self.combo.currentText()
        df2 = df[df['板块'] == Select_XiaoQu].groupby(['小区']).count()
        self.n.update_figure()

    def getcombo1Information(self):
        textMedia = self.combo1.currentText()
        #print(textMedia)
        return textMedia

    def fileQuit(self):
        self.close()

    def closeEvent(self, ce):
        self.fileQuit()

    def about(self):
        QMessageBox.about(
            self, "About", """embedding_in_qt5.py example
Copyright 2005 Fand qt5""")
示例#48
0
class MainWindow(QMainWindow):
    
    def __init__(self, parent=None):

        super(MainWindow, self).__init__(parent)
        centralWidget = QWidget()
        self.mainLayout = QVBoxLayout()
        buttonLayout = QHBoxLayout()
        foldersLayout = QHBoxLayout()
        backupFolderLayout = QHBoxLayout()
        self.usbDevicesChooser = QComboBox()
        
        usb_util = Utils()
        self.usbDevices = usb_util.get_storage_device()

        for device in self.usbDevices:
            self.usbDevicesChooser.addItem(device.__str__())

        self.pathToFolders = QLineEdit()
        self.pathToFolders.setPlaceholderText("Path to folders you want to backup")
        self.pathToBackupFolder = QLineEdit()
        self.pathToBackupFolder.setPlaceholderText("Path to backup destination folder")

        self.browseFoldersButton = QPushButton("Browse...")
        self.browseFoldersButton.clicked.connect(self.on_browseFolders_clicked)
        self.browseBackupFolderButton = QPushButton("Browse...")
        self.browseBackupFolderButton.clicked.connect(self.on_browseBackupFolder_clicked)

        foldersLayout.addWidget(self.pathToFolders)
        foldersLayout.addWidget(self.browseFoldersButton)
        foldersLayout.setSpacing(5)

        backupFolderLayout.addWidget(self.pathToBackupFolder)
        backupFolderLayout.addWidget(self.browseBackupFolderButton)
        backupFolderLayout.setSpacing(5)

        self.startBackupButton = QPushButton("Start Backup")
        self.startBackupButton.clicked.connect(self.on_startBackup_clicked)

        self.exitButton = QPushButton("Exit")
        self.exitButton.clicked.connect(self.on_exit_clicked)

        buttonLayout.addWidget(self.startBackupButton)
        buttonLayout.addWidget(self.exitButton)
        buttonLayout.setSpacing(10)

        self.mainLayout.addWidget(self.usbDevicesChooser)
        self.mainLayout.addLayout(backupFolderLayout)
        self.mainLayout.addLayout(foldersLayout)
        self.mainLayout.addLayout(buttonLayout)

        centralWidget.setLayout(self.mainLayout)
        self.setCentralWidget(centralWidget)
        self.setWindowTitle("Nice Backup")
        self.setMinimumSize(600, 200)

    def on_exit_clicked(self, widget):
        sys.exit()

    def on_browseFolders_clicked(self, widget):
        index = self.usbDevicesChooser.currentIndex()
        file_dialog = QFileDialog()
        file_dialog.setFileMode(QFileDialog.DirectoryOnly)
        file_dialog.setOption(QFileDialog.DontUseNativeDialog, True)
        file_view = file_dialog.findChild(QListView, 'listView')

        if file_view:
            file_view.setSelectionMode(QAbstractItemView.MultiSelection)

        ftree_view = file_dialog.findChild(QTreeView)

        if ftree_view:
            ftree_view.setSelectionMode(QAbstractItemView.MultiSelection)

        file_dialog.setDirectory(self.usbDevices[index].getPath())

        if file_dialog.exec():
            paths = file_dialog.selectedFiles()

        self.pathToFolders.setText(";".join(paths))

    def on_browseBackupFolder_clicked(self, widget):
        fname = QFileDialog.getExistingDirectory(self.window(), 'Open file', '/home/{}'.format(getpass.getuser()))
        self.pathToBackupFolder.setText(fname)

    def on_startBackup_clicked(self, widget):
        print("Starting backup")
        backuper = Backuper.Backuper()
        sources = self.pathToFolders.text().split(";")
        destination = self.pathToBackupFolder.text()

        progress = QProgressBar()
        progress.setMinimum(0)
        progress.setMaximum(len(sources))
        self.mainLayout.addWidget(progress)

        for source in sources:
            backuper.make_backup(source, destination)
            progress.setValue(sources.index(source))
            QApplication.processEvents()
        doneDialog = QMessageBox()

        doneDialog.setIcon(QMessageBox.Information)
        doneDialog.setText("Copying data is completed")
        doneDialog.setWindowTitle("Copy event")
        doneDialog.setStandardButtons(QMessageBox.Ok)

        index = self.mainLayout.indexOf(progress)
        self.mainLayout.itemAt(index).widget().setParent(None)

        doneDialog.exec()
示例#49
0
class Example(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):

        self.gridGroupBox = QGroupBox("參數設定", self)
        layout = QGridLayout()

        self.manLabel = QLabel("測試人員", self)
        self.manLabel.resize(50, 250)
        self.combo001 = QComboBox(self)
        self.combo001.addItem('男性')
        self.combo001.addItem('女性')
        self.combo001.resize(50, 400)

        self.hightLabel = QLabel("身高(cm)", self)

        self.combo002 = QComboBox(self)
        self.combo002.addItem('150')
        self.combo002.addItem('160')
        self.combo002.addItem('170')
        self.combo002.addItem('180')
        self.combo002.addItem('190')

        self.strainLabel = QLabel("拉伸應變(%)", self)
        self.combo003 = QComboBox(self)

        self.combo003.addItem('5%')
        self.combo003.addItem('7.5%')
        self.combo003.addItem('10%')
        self.combo003.addItem('12.5%')
        self.combo003.addItem('15%')
        #        self.combo003.activated[str].connect(self.onActivated)

        layout.setSpacing(20)
        layout.addWidget(self.manLabel, 1, 0)
        layout.addWidget(self.combo001, 1, 1)

        layout.addWidget(self.hightLabel, 2, 0)
        layout.addWidget(self.combo002, 2, 1)

        layout.addWidget(self.strainLabel, 3, 0)
        #        layout.addWidget(self.emitLineEdit,2,1)
        layout.addWidget(self.combo003, 3, 1)

        self.noLabel1 = QLabel("案例編號", self)
        self.noLineEdit1 = QLineEdit("POC-", self)
        self.caseLabel1 = QLabel("案例名稱", self)
        self.caseLineEdit1 = QLineEdit(" ", self)
        self.dateLabel1 = QLabel("更新日期", self)
        self.dateLineEdit1 = QLineEdit("2021-01-", self)

        layout.setSpacing(20)
        layout.addWidget(self.noLabel1, 4, 0)
        layout.addWidget(self.noLineEdit1, 4, 1)
        layout.addWidget(self.caseLabel1, 5, 0)
        layout.addWidget(self.caseLineEdit1, 5, 1)
        layout.addWidget(self.dateLabel1, 6, 0)
        layout.addWidget(self.dateLineEdit1, 6, 1)

        self.pushButton_A01 = QPushButton()
        ###        self.pushButton_A01.setGeometry(QtCore.QRect(10, 30, 45, 35))
        self.pushButton_A01.setObjectName("pushButton_014")
        self.pushButton_A01.setStyleSheet(
            "background-color: #1F1F1F; color: white;font: 100 10pt \"Arial Narrow\""
        )
        self.pushButton_A01.setText("存檔")
        # self.pushButton_014.setFont(QFont('Arial', 5))
        #   self.pushButton_A01.scaled(20,15, Qt.KeepAspectRatio, Qt.SmoothTransformation)
        self.pushButton_A01.setStyleSheet(
            "QPushButton{color:white}"
            "QPushButton:hover{color:yellow}"
            ##                                 "QPushButton{border-image: url(/FHEUI/fig/max1.png)}"
            #                                 "QPushButton{background-image: url(/FHEUI/fig/max1.png)}"
            "QPushButton{background-color:#1E1E1E}"
            #                                 "QPushButton:hover{background-image:url(/FHEUI/fig/max2.png)}"
            "QPushButton{border:1px}"
            "QPushButton{border-radius:2px}"
            "QPushButton{font: 10pt} "
            "QPushButton{padding:2px 4px}")

        self.pushButton_A01.clicked.connect(self.saveas001)

        self.pushButton_A02 = QPushButton()
        ###        self.pushButton_A01.setGeometry(QtCore.QRect(10, 30, 45, 35))
        self.pushButton_A02.setObjectName("pushButton_014")
        self.pushButton_A02.setStyleSheet(
            "background-color: #1F1F1F; color: white;font: 100 10pt \"Arial Narrow\""
        )
        self.pushButton_A02.setText("修改")
        # self.pushButton_014.setFont(QFont('Arial', 5))
        #   self.pushButton_A01.scaled(20,15, Qt.KeepAspectRatio, Qt.SmoothTransformation)
        self.pushButton_A02.setStyleSheet(
            "QPushButton{color:white}"
            "QPushButton:hover{color:yellow}"
            ##                                 "QPushButton{border-image: url(/FHEUI/fig/max1.png)}"
            #                                 "QPushButton{background-image: url(/FHEUI/fig/max1.png)}"
            "QPushButton{background-color:#1E1E1E}"
            #                                "QPushButton:hover{background-image:url(/FHEUI/fig/max2.png)}"
            "QPushButton{border:1px}"
            "QPushButton{border-radius:2px}"
            "QPushButton{font: 10pt} "
            "QPushButton{padding:2px 4px}")

        self.pushButton_A02.clicked.connect(self.modify001)

        layout.addWidget(self.pushButton_A01, 7, 0)
        layout.addWidget(self.pushButton_A02, 7, 1)

        layout.setColumnStretch(1, 1)
        self.gridGroupBox.setLayout(layout)
        self.gridGroupBox.resize(400, 450)

        self.setWindowTitle('智慧褲線路佈局')
        self.setWindowIcon(QIcon('fig\itrilogo.png'))
        self.setGeometry(475, 200, 400, 450)

        self.show()

    def modify001(self):

        self.noLineEdit1.clear()
        self.caseLineEdit1.setText(" ")
        self.dateLineEdit1.setText(" ")

    def saveas001(self, text):

        text001 = str(self.noLineEdit1.text())

        text002 = str(self.caseLineEdit1.text())

        text003 = str(self.dateLineEdit1.text())

        text004 = "FHE ID_001"

        text005 = str(self.combo001.currentText())
        text006 = str(self.combo002.currentText())
        text007 = str(self.combo003.currentText())

        # print(text001)
        filename, filetype = QFileDialog.getSaveFileName(
            self, "Save File", "*.txt")
        with open(filename, 'w', encoding='utf-8-sig') as f:

            print(filename)
            f.write(text001 + '\n')
            f.write(text002 + '\n')
            f.write(text003 + '\n')
            f.write(text004 + '\n')
            f.write(text005 + '\n')
            f.write(text006 + '\n')
            f.write(text007)
            f.close()
示例#50
0
class WidgetGallery(QDialog):
    def __init__(self, parent=None):
        super(WidgetGallery, self).__init__(parent)
        self.AREA_LIST = [1261, 1, 1308, 1051, 1530]
        self.URL = r'https://api.hh.ru/vacancies/'
        self.messages = Message.MessageWindow()
        self.request_vacancy = Request.RequestVacancy(self.URL)
        self.save_vacancy = Save.SaveVacancy()
        self.clear_vacancy = Clear.ClearVacancy()

        self.create_top_left_group_box()
        self.create_top_right_group_box()
        self.create_bottom_left_tab_widget()
        self.create_bottom_right_group_box()

        main_layout = QGridLayout()
        main_layout.addWidget(self.top_left_group_box, 2, 0)
        main_layout.addWidget(self.top_right_group_box, 3, 0)
        main_layout.addWidget(self.bottom_left_tab_widget, 1, 1, 3, 3)
        main_layout.addWidget(self.bottom_right_group_box, 1, 0)
        main_layout.setRowStretch(1, 1)
        main_layout.setRowStretch(2, 1)
        main_layout.setColumnStretch(0, 1)
        main_layout.setColumnStretch(1, 1)
        self.setLayout(main_layout)

        self.setWindowTitle("HH API")
        self.setMinimumSize(800, 600)
        self.setWindowIcon(QIcon(r'Images\Иконка.png'))
        self.setWindowFlags(self.windowFlags()
                            | QtCore.Qt.WindowMinimizeButtonHint
                            | QtCore.Qt.WindowMaximizeButtonHint)

    def create_top_left_group_box(self):
        self.top_left_group_box = QGroupBox("Сохранение")

        name_str = QLabel()
        name_str.setText("Имя файла:")
        self.save_name_input = QLineEdit()
        self.save_name_input.setPlaceholderText("Имя")
        name_str_form = QLabel()
        name_str_form.setText("Формат:")
        self.format_branch_input = QComboBox()
        self.format_branch_input.addItem("CSV")
        self.format_branch_input.addItem("JSON")
        self.format_branch_input.addItem("XLSX")

        button_save = QPushButton("Сохранить")
        button_save.clicked.connect(self.add_save)
        layout = QVBoxLayout()
        layout.addWidget(name_str)
        layout.addWidget(self.save_name_input)
        layout.addWidget(name_str_form)
        layout.addWidget(self.format_branch_input)
        layout.addWidget(button_save)
        layout.addStretch(1)
        self.top_left_group_box.setLayout(layout)

    def create_top_right_group_box(self):
        self.top_right_group_box = QGroupBox()

        default_push_button = QPushButton("Помощь")
        default_push_button.clicked.connect(self.about)

        layout = QVBoxLayout()
        layout.addWidget(default_push_button)
        layout.addStretch(1)
        self.top_right_group_box.setLayout(layout)

    def create_bottom_left_tab_widget(self):
        self.connect_ = sqlite3.connect(r'Result.db')
        self.cursor = self.connect_.cursor()
        self.cursor.execute(
            "CREATE TABLE IF NOT EXISTS Result(id TEXT, name TEXT,area TEXT,employer TEXT,keySkills TEXT)"
        )
        self.cursor.close()
        self.bottom_left_tab_widget = QGroupBox()
        self.bottom_left_tab_widget.setSizePolicy(QSizePolicy.Preferred,
                                                  QSizePolicy.Ignored)

        self.table_widget = QTableWidget()
        self.table_widget.setAlternatingRowColors(True)
        self.table_widget.setColumnCount(5)
        self.table_widget.horizontalHeader().setCascadingSectionResizes(True)
        self.table_widget.horizontalHeader().setSortIndicatorShown(False)
        self.table_widget.horizontalHeader().setStretchLastSection(True)
        self.table_widget.verticalHeader().Stretch
        self.table_widget.verticalHeader().ResizeToContents
        self.table_widget.verticalHeader().setSectionResizeMode(
            QHeaderView.ResizeToContents)
        self.table_widget.verticalHeader().setVisible(True)
        self.table_widget.verticalHeader().setCascadingSectionResizes(True)
        self.table_widget.verticalHeader().setStretchLastSection(False)
        self.table_widget.setHorizontalHeaderLabels(
            ("ID", "Название", "Город", "Компания", "Ключевые навыки"))
        self.load_data()
        table_h_box = QHBoxLayout()
        table_h_box.addWidget(self.table_widget)
        self.bottom_left_tab_widget.setLayout(table_h_box)

    def create_bottom_right_group_box(self):
        self.bottom_right_group_box = QGroupBox("Добавить вакансии")

        self.vacancy_name_input = QLineEdit()
        self.vacancy_name_input.setPlaceholderText("Название")

        self.region_branch_input = QComboBox()
        self.region_branch_input.addItem("Свердловкая область")
        self.region_branch_input.addItem("Москва")
        self.region_branch_input.addItem("Ростовская область")
        self.region_branch_input.addItem("Курская область")
        self.region_branch_input.addItem("Новгородская область")

        button_add_work = QPushButton("Добавить")
        button_add_work.clicked.connect(self.add_work)
        push_button = QPushButton("Удалить все")
        push_button.clicked.connect(self.delete_all_works)

        layout = QGridLayout()
        layout.addWidget(self.vacancy_name_input, 0, 0, 1, 2)
        layout.addWidget(self.region_branch_input, 1, 0, 1, 2)
        layout.addWidget(button_add_work, 2, 0, 1, 2)
        layout.addWidget(push_button, 3, 0, 1, 2)
        layout.setRowStretch(5, 1)
        self.bottom_right_group_box.setLayout(layout)

    def delete_all_works(self):
        if self.clear_vacancy.clear():
            self.load_data()

    def add_work(self):
        self.request_vacancy.request(
            self.vacancy_name_input.text(),
            self.AREA_LIST[self.region_branch_input.currentIndex()])
        self.load_data()

    def add_save(self):
        _name = self.save_name_input.text()
        _branch = self.format_branch_input.itemText(
            self.format_branch_input.currentIndex())
        self.save_vacancy.save(
            self.save_name_input.text(),
            self.format_branch_input.itemText(
                self.format_branch_input.currentIndex()))

    def about(self):
        dialog = Help.AboutDialog()
        dialog.exec()

    def load_data(self):
        self.connect_ = sqlite3.connect(r'Result.db')
        _result = self.connect_.execute("SELECT * FROM Result")
        self.table_widget.setRowCount(0)
        for row_number, row_data in enumerate(_result):
            self.table_widget.insertRow(row_number)
            for column_number, data in enumerate(row_data):
                self.table_widget.setItem(row_number, column_number,
                                          QTableWidgetItem(str(data)))
        self.connect_.close()
示例#51
0
class Flasher(QDialog):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("ESP32 Flasher 1.0")
        self.setMinimumWidth(480)
        self.mode = 0  # BIN file
        self.bin_file = os.getcwd() + "\\firmware.bin"
        self.release_data = b""
        self.createUI()
        self.refreshPorts()
        self.jsonStart = False
        self.jsonBuffer = ""

    def createUI(self):
        vl = VLayout()
        self.setLayout(vl)

        # Port groupbox
        gbPort = GroupBoxH("Select port", 3)
        self.cbxPort = QComboBox()
        pbRefreshPorts = QPushButton("Refresh")
        gbPort.addWidget(self.cbxPort)
        gbPort.addWidget(pbRefreshPorts)
        gbPort.layout().setStretch(0, 4)
        gbPort.layout().setStretch(1, 1)

        # Firmware groupbox
        gbFW = GroupBoxV("Select image", 3)

        self.wFile = QWidget()
        hl_file = HLayout(0)
        self.file = QLineEdit()
        self.file.setReadOnly(True)

        self.file.setText(self.bin_file)
        pbFile = QPushButton("Open")
        hl_file.addWidgets([self.file, pbFile])
        self.wFile.setLayout(hl_file)
        gbFW.addWidgets([self.wFile])

        # Buttons
        self.pbFlash = QPushButton("Flash!")
        self.pbFlash.setFixedHeight(50)
        self.pbFlash.setStyleSheet("background-color: #223579;")
        self.pbConfig = QPushButton("Setup WIFI")
        self.pbConfig.setStyleSheet("background-color: #571054;")
        self.pbConfig.setFixedHeight(50)
        self.pbQuit = QPushButton("Quit")
        self.pbQuit.setStyleSheet("background-color: #c91017;")
        self.pbQuit.setFixedSize(QSize(50, 50))
        hl_btns = HLayout([50, 3, 50, 3])
        hl_btns.addWidgets([self.pbFlash, self.pbConfig, self.pbQuit])
        vl.addWidgets([gbPort, gbFW])
        vl.addLayout(hl_btns)
        pbRefreshPorts.clicked.connect(self.refreshPorts)
        pbFile.clicked.connect(self.openBinFile)
        self.pbFlash.clicked.connect(self.start_process)
        self.pbConfig.clicked.connect(self.send_config)
        self.pbQuit.clicked.connect(self.reject)

    def refreshPorts(self):
        self.cbxPort.clear()
        ports = reversed(
            sorted(port.portName()
                   for port in QSerialPortInfo.availablePorts()))
        for p in ports:
            port = QSerialPortInfo(p)
            self.cbxPort.addItem(port.portName(), port.systemLocation())

    def setBinMode(self, radio):
        self.mode = radio
        self.wFile.setVisible(self.mode == 0)

    def appendReleaseInfo(self):
        self.release_data += self.release_reply.readAll()

    def openBinFile(self):
        file, ok = QFileDialog.getOpenFileName(self,
                                               "Select Firmware image",
                                               self.bin_file,
                                               filter="BIN files (*.bin)")
        if ok:
            self.file.setText(file)

    def send_config(self):
        dlg = SendConfigDialog()
        if dlg.exec_() == QDialog.Accepted:
            if dlg.commands:
                try:
                    self.serial = QSerialPort(self.cbxPort.currentData())
                    self.serial.setBaudRate(115200)
                    self.serial.open(QIODevice.ReadWrite)
                    self.serial.readyRead.connect(self.on_serial_read)
                    bytes_sent = self.serial.write(bytes(dlg.commands, 'utf8'))
                except Exception as e:
                    QMessageBox.critical(self, "COM Port error", e)
            else:
                QMessageBox.information(self, "Done", "Nothing to send")

    def on_serial_read(self):
        self.process_bytes(bytes(self.serial.readAll()))

    def process_bytes(self, bs):
        text = bs.decode('ascii')
        # print("!Received: " + text)
        try:
            for b in text:
                if b == '{':  # start json
                    self.jsonStart = True
                    # print("start JSON")
                if self.jsonStart == True:
                    self.jsonBuffer += b
                if b == '}':  # end json
                    self.jsonStart = False
                    # print("found JSON")
                    print(self.jsonBuffer)
                    obj = json.loads(self.jsonBuffer)
                    url = "http://" + obj["IP"]
                    print("Device IP: {0} ".format(url))
                    txt = "******* Use admin/{0} to enter configuration page *******".format(
                        obj["ApPassword"])
                    print(txt)
                    webbrowser.get().open(url)
                    self.serial.close()

        except Exception as e:
            print("JSON error", e)

    def start_process(self):
        ok = True

        if self.mode == 0:
            if len(self.file.text()) > 0:
                self.bin_file = self.file.text()
            else:
                ok = False
                QMessageBox.information(
                    self, "Nothing to do...",
                    "Select a local BIN file or select which one to download.")

        if ok:
            dlg = FlashingDialog(self)
            if dlg.exec_() == QDialog.Accepted:
                QMessageBox.information(
                    self, "Done",
                    "Flashing successful! Press the reset button.")
            else:
                if dlg.error_msg:
                    QMessageBox.critical(self, "Error", dlg.error_msg)
                else:
                    QMessageBox.critical(
                        self, "Flashing aborted",
                        "Flashing process has been aborted by the user.")

    def mousePressEvent(self, e):
        self.old_pos = e.globalPos()

    def mouseMoveEvent(self, e):
        delta = e.globalPos() - self.old_pos
        self.move(self.x() + delta.x(), self.y() + delta.y())
        self.old_pos = e.globalPos()
示例#52
0
class Settings(QWidget):
    """settings window"""
    def __init__(self, lang, main, settings):
        """

        :param lang: dict, current locale
        :param main: core.gui.gui.Main object
        :param settings: dict, current settings
        """
        super().__init__()
        self.lang = lang['SETTINGS']
        self.orig_lang = lang
        self.main = main
        self.settings = settings
        self._loc_items = {}
        self._changed = False
        self.del_widgets_win = None
        # setup window
        self.setWindowTitle(self.lang['title'])
        self.setWindowIcon(QIcon(SETTINGS))
        self.resize(290, 200)
        self.setWindowFlags(Qt.WindowMinimizeButtonHint
                            | Qt.WindowCloseButtonHint)
        # setup 'Languages' lebel
        self.label_loc = QLabel(self.lang['label_loc'], self)
        self.label_loc.setAlignment(Qt.AlignCenter)
        # setup languages list
        self.language = QComboBox(self)
        self.language.setToolTip(self.lang['language_tt'])
        self.language.activated.connect(self._change_settings)
        self._langs_box_fill()
        # setup log level label
        self.label_log = QLabel(self.lang['label_log'])
        self.label_log.setAlignment(Qt.AlignCenter)
        # setup levels list
        self.log_levels = QComboBox(self)
        self.log_levels.setToolTip(self.lang['levels_tt'])
        self.log_levels.activated.connect(self._change_settings)
        self._logs_box_fill()
        # setup 'Load placed' checkbox
        self.load_placed = QCheckBox(self.lang['load_placed'], self)
        self.load_placed.setToolTip(self.lang['load_placed_tt'])
        if strtobool(settings['MAIN']['load_placed']):
            self.load_placed.setChecked(True)
        self.load_placed.stateChanged.connect(self._change_settings)
        # setup widgets delete button
        self.del_button = QPushButton(self.lang['del_button'], self)
        self.del_button.setToolTip(self.lang['del_button_tt'])
        self.del_button.clicked.connect(self._show_del_widgets)
        # setup 'Save' button
        self.save_button = QPushButton(self.lang['save_button'], self)
        self.save_button.setToolTip(self.lang['save_button_tt'])
        self.save_button.clicked.connect(self._save)
        # setup 'Cancel' button
        self.cancel_button = QPushButton(self.lang['cancel_button'], self)
        self.cancel_button.setToolTip(self.lang['cancel_button_tt'])
        self.cancel_button.clicked.connect(self._cancel)
        # setup h box layout
        self.h_box = QHBoxLayout()
        self.h_box.addWidget(self.save_button)
        self.h_box.addWidget(self.cancel_button)
        # setup grid layout
        self.grid = QGridLayout(self)
        self.grid.addWidget(self.label_loc, 0, 0)
        self.grid.addWidget(self.language, 0, 1)
        self.grid.addWidget(self.label_log, 1, 0)
        self.grid.addWidget(self.log_levels, 1, 1)
        self.grid.addWidget(self.load_placed, 2, 0, 1, 2)
        self.grid.addWidget(self.del_button, 3, 0, 1, 2)
        self.grid.addLayout(self.h_box, 4, 0, 1, 2)
        self.setLayout(self.grid)
        # show
        self.show()

    def _change_settings(self):
        self._changed = True

    def _langs_box_fill(self):
        for name in get_locales():
            try:
                conf = get_locale(name)
                item = conf['LANG']['name'] + ' ('
                item += conf['LANG']['description'] + ')'
                self.language.addItem(item)
                if name == self.settings['MAIN']['locale']:
                    self.language.setCurrentText(item)
                self._loc_items[item] = name
            except:
                print_stack_trace()()

    @try_except()
    def _logs_box_fill(self):
        for key in LogLevel.get_keys():
            try:
                self.log_levels.addItem(key)
            except:
                print_stack_trace()()
        self.log_levels.setCurrentText(
            LogLevel.from_int(int(self.settings['LOGS']['log_level'])))

    @try_except()
    def _save(self, checked):
        self.settings['MAIN']['locale'] = \
            self._loc_items[self.language.currentText()]
        self.settings['MAIN']['load_placed'] = \
            str(self.load_placed.isChecked())
        self.settings['LOGS']['log_level'] = \
            str(LogLevel.from_string(self.log_levels.currentText()))
        properties.write_settings(self.settings)
        if self._changed:
            self._show_warn()
        self.main._list_fill()
        self.close()

    @try_except()
    def _cancel(self, checked):
        self.main._list_fill()
        self.close()

    def _show_warn(self):
        mbox = QMessageBox(QMessageBox.Warning, self.lang['warn_title'],
                           self.lang['warn_text'], QMessageBox.Ok, self)
        mbox.setWindowIcon(QIcon(SUCCESS))
        ok = mbox.button(QMessageBox.Ok)
        ok.setText(self.lang['warn_ok_button'])
        ok.setToolTip(self.lang['warn_ok_button_tt'])
        mbox.exec()

    @try_except()
    def _show_del_widgets(self, checked):
        self.del_widgets_win = Delete(self.orig_lang,
                                      sys.modules['core.gui.gui'].manager)
示例#53
0
    def __init__(self, **kwargs):
        super().__init__()
        main_layout = QHBoxLayout()
        main_layout.setContentsMargins(20, 0, 20,
                                       0)  #(left, top, right, bottom)
        main_layout.setSpacing(0)
        h_options = [
            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"
        ]
        h_select = QComboBox()
        for option in h_options:
            h_select.addItem(option)
        m_options = [
            "00", "05", "10", "15", "20", "25", "30", "35", "40", "45", "50",
            "55"
        ]
        m_select = QComboBox()
        for option in m_options:
            m_select.addItem(option)

        space_item = QSpacerItem(20, 20, QSizePolicy.Expanding)
        am_pm = QComboBox()
        am_pm.addItem("ص")
        am_pm.addItem("م")
        separator = QLabel(" : ")

        if "value" in kwargs:
            time_parts = kwargs["value"].split(":")
            hour = int(time_parts[0])
            minute = int(time_parts[1])
            minute = self.myround(minute)
            the_hour, the_period = self.handle_am_pm(hour)

            ShortTimeWidget.hour_value = str(the_hour)
            ShortTimeWidget.minute_value = str(minute)
            ShortTimeWidget.am_pm_value = the_period

            h_select.setCurrentText(str(the_hour))
            m_select.setCurrentText(str(minute))
            am_pm.setCurrentText(the_period)
        else:
            current_hour = datetime.datetime.now().hour
            current_minute = datetime.datetime.now().minute
            current_minute = self.myround(current_minute)
            the_hour, the_period = self.handle_am_pm(current_hour)
            h_select.setCurrentText(str(the_hour))
            m_select.setCurrentText(str(current_minute))
            am_pm.setCurrentText(the_period)

            ShortTimeWidget.hour_value = str(the_hour)
            ShortTimeWidget.minute_value = str(current_minute)
            ShortTimeWidget.am_pm_value = the_period

        h_select.activated[str].connect(self.update_hour)
        m_select.activated[str].connect(self.update_minute)
        am_pm.activated[str].connect(self.update_am_pm)

        main_layout.addWidget(m_select)
        main_layout.addWidget(separator)
        main_layout.addWidget(h_select)
        main_layout.addSpacerItem(space_item)
        main_layout.addWidget(am_pm)

        self.setLayout(main_layout)
        self.setFixedWidth(200)
        self.setFixedHeight(37)
        self.setLayoutDirection(Qt.RightToLeft)
示例#54
0
class Window(QWidget):
    NumRenderAreas = 9

    def __init__(self):
        super(Window, self).__init__()

        rectPath = QPainterPath()
        rectPath.moveTo(20.0, 30.0)
        rectPath.lineTo(80.0, 30.0)
        rectPath.lineTo(80.0, 70.0)
        rectPath.lineTo(20.0, 70.0)
        rectPath.closeSubpath()

        roundRectPath = QPainterPath()
        roundRectPath.moveTo(80.0, 35.0)
        roundRectPath.arcTo(70.0, 30.0, 10.0, 10.0, 0.0, 90.0)
        roundRectPath.lineTo(25.0, 30.0)
        roundRectPath.arcTo(20.0, 30.0, 10.0, 10.0, 90.0, 90.0)
        roundRectPath.lineTo(20.0, 65.0)
        roundRectPath.arcTo(20.0, 60.0, 10.0, 10.0, 180.0, 90.0)
        roundRectPath.lineTo(75.0, 70.0)
        roundRectPath.arcTo(70.0, 60.0, 10.0, 10.0, 270.0, 90.0)
        roundRectPath.closeSubpath()

        ellipsePath = QPainterPath()
        ellipsePath.moveTo(80.0, 50.0)
        ellipsePath.arcTo(20.0, 30.0, 60.0, 40.0, 0.0, 360.0)

        piePath = QPainterPath()
        piePath.moveTo(50.0, 50.0)
        piePath.lineTo(65.0, 32.6795)
        piePath.arcTo(20.0, 30.0, 60.0, 40.0, 60.0, 240.0)
        piePath.closeSubpath()

        polygonPath = QPainterPath()
        polygonPath.moveTo(10.0, 80.0)
        polygonPath.lineTo(20.0, 10.0)
        polygonPath.lineTo(80.0, 30.0)
        polygonPath.lineTo(90.0, 70.0)
        polygonPath.closeSubpath()

        groupPath = QPainterPath()
        groupPath.moveTo(60.0, 40.0)
        groupPath.arcTo(20.0, 20.0, 40.0, 40.0, 0.0, 360.0)
        groupPath.moveTo(40.0, 40.0)
        groupPath.lineTo(40.0, 80.0)
        groupPath.lineTo(80.0, 80.0)
        groupPath.lineTo(80.0, 40.0)
        groupPath.closeSubpath()

        textPath = QPainterPath()
        timesFont = QFont("Times", 50)
        timesFont.setStyleStrategy(QFont.ForceOutline)
        textPath.addText(10, 70, timesFont, "Qt")

        bezierPath = QPainterPath()
        bezierPath.moveTo(20, 30)
        bezierPath.cubicTo(80, 0, 50, 50, 80, 80)

        starPath = QPainterPath()
        starPath.moveTo(90, 50)
        for i in range(1, 5):
            starPath.lineTo(50 + 40 * cos(0.8 * i * pi),
                            50 + 40 * sin(0.8 * i * pi))
        starPath.closeSubpath()

        self.renderAreas = [
            RenderArea(rectPath),
            RenderArea(roundRectPath),
            RenderArea(ellipsePath),
            RenderArea(piePath),
            RenderArea(polygonPath),
            RenderArea(groupPath),
            RenderArea(textPath),
            RenderArea(bezierPath),
            RenderArea(starPath),
        ]
        assert len(self.renderAreas) == 9

        self.fillRuleComboBox = QComboBox()
        self.fillRuleComboBox.addItem("Odd Even", Qt.OddEvenFill)
        self.fillRuleComboBox.addItem("Winding", Qt.WindingFill)

        fillRuleLabel = QLabel("Fill &Rule:")
        fillRuleLabel.setBuddy(self.fillRuleComboBox)

        self.fillColor1ComboBox = QComboBox()
        self.populateWithColors(self.fillColor1ComboBox)
        self.fillColor1ComboBox.setCurrentIndex(
            self.fillColor1ComboBox.findText("mediumslateblue"))

        self.fillColor2ComboBox = QComboBox()
        self.populateWithColors(self.fillColor2ComboBox)
        self.fillColor2ComboBox.setCurrentIndex(
            self.fillColor2ComboBox.findText("cornsilk"))

        fillGradientLabel = QLabel("&Fill Gradient:")
        fillGradientLabel.setBuddy(self.fillColor1ComboBox)

        fillToLabel = QLabel("to")
        fillToLabel.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

        self.penWidthSpinBox = QSpinBox()
        self.penWidthSpinBox.setRange(0, 20)

        penWidthLabel = QLabel("&Pen Width:")
        penWidthLabel.setBuddy(self.penWidthSpinBox)

        self.penColorComboBox = QComboBox()
        self.populateWithColors(self.penColorComboBox)
        self.penColorComboBox.setCurrentIndex(
            self.penColorComboBox.findText("darkslateblue"))

        penColorLabel = QLabel("Pen &Color:")
        penColorLabel.setBuddy(self.penColorComboBox)

        self.rotationAngleSpinBox = QSpinBox()
        self.rotationAngleSpinBox.setRange(0, 359)
        self.rotationAngleSpinBox.setWrapping(True)
        self.rotationAngleSpinBox.setSuffix(u"\N{DEGREE SIGN}")

        rotationAngleLabel = QLabel("&Rotation Angle:")
        rotationAngleLabel.setBuddy(self.rotationAngleSpinBox)

        self.fillRuleComboBox.activated.connect(self.fillRuleChanged)
        self.fillColor1ComboBox.activated.connect(self.fillGradientChanged)
        self.fillColor2ComboBox.activated.connect(self.fillGradientChanged)
        self.penColorComboBox.activated.connect(self.penColorChanged)

        for i in range(Window.NumRenderAreas):
            self.penWidthSpinBox.valueChanged.connect(
                self.renderAreas[i].setPenWidth)
            self.rotationAngleSpinBox.valueChanged.connect(
                self.renderAreas[i].setRotationAngle)

        topLayout = QGridLayout()
        for i in range(Window.NumRenderAreas):
            topLayout.addWidget(self.renderAreas[i], i / 3, i % 3)

        mainLayout = QGridLayout()
        mainLayout.addLayout(topLayout, 0, 0, 1, 4)
        mainLayout.addWidget(fillRuleLabel, 1, 0)
        mainLayout.addWidget(self.fillRuleComboBox, 1, 1, 1, 3)
        mainLayout.addWidget(fillGradientLabel, 2, 0)
        mainLayout.addWidget(self.fillColor1ComboBox, 2, 1)
        mainLayout.addWidget(fillToLabel, 2, 2)
        mainLayout.addWidget(self.fillColor2ComboBox, 2, 3)
        mainLayout.addWidget(penWidthLabel, 3, 0)
        mainLayout.addWidget(self.penWidthSpinBox, 3, 1, 1, 3)
        mainLayout.addWidget(penColorLabel, 4, 0)
        mainLayout.addWidget(self.penColorComboBox, 4, 1, 1, 3)
        mainLayout.addWidget(rotationAngleLabel, 5, 0)
        mainLayout.addWidget(self.rotationAngleSpinBox, 5, 1, 1, 3)
        self.setLayout(mainLayout)

        self.fillRuleChanged()
        self.fillGradientChanged()
        self.penColorChanged()
        self.penWidthSpinBox.setValue(2)

        self.setWindowTitle("Painter Paths")

    def fillRuleChanged(self):
        rule = Qt.FillRule(self.currentItemData(self.fillRuleComboBox))

        for i in range(Window.NumRenderAreas):
            self.renderAreas[i].setFillRule(rule)

    def fillGradientChanged(self):
        color1 = QColor(self.currentItemData(self.fillColor1ComboBox))
        color2 = QColor(self.currentItemData(self.fillColor2ComboBox))

        for i in range(Window.NumRenderAreas):
            self.renderAreas[i].setFillGradient(color1, color2)

    def penColorChanged(self):
        color = QColor(self.currentItemData(self.penColorComboBox))

        for i in range(Window.NumRenderAreas):
            self.renderAreas[i].setPenColor(color)

    def populateWithColors(self, comboBox):
        colorNames = QColor.colorNames()
        for name in colorNames:
            comboBox.addItem(name, name)

    def currentItemData(self, comboBox):
        return comboBox.itemData(comboBox.currentIndex())
示例#55
0
class MainTab(QWidget):
    WELCOMEGROUP = 1
    FORMGROUP = 2
    FIRSTSTANDARD = 3

    def __init__(self, tabs, *args) -> None:
        super().__init__(*args)

        self.tabs = tabs
        self.opt = None

        self.main_layout = QHBoxLayout()
        self.createBar()
        self.createFormGroupBox()
        self.createWelcome()
        self.main_layout.addWidget(self.barGroup)
        self.main_layout.addWidget(self.welcomeGroup)

        self.setLayout(self.main_layout)

    def createWelcome(self):
        self.welcomeGroup = QGroupBox("Welcome")

        self.qb = QVBoxLayout()
        lb1 = QLabel("Welcome")
        self.qb.addWidget(lb1)

        self.welcomeGroup.setLayout(self.qb)

    def createBar(self):
        self.barGroup = QGroupBox('Menu')
        self.btn1 = CustomBtn('Welcome')
        self.btn2 = CustomBtn("Selecting Files")
        self.btn3 = CustomBtn("First Standard")

        self.btn2.clicked.connect(
            lambda: self.handelFormBtn(MainTab.FORMGROUP))
        self.btn1.clicked.connect(
            lambda: self.handelFormBtn(MainTab.WELCOMEGROUP))
        self.btn3.clicked.connect(lambda x: self.handelStandards(x, 1))

        self.hb = QVBoxLayout()
        self.hb.addWidget(self.btn1)
        self.hb.addWidget(self.btn2)
        self.hb.addWidget(self.btn3)
        self.hb.addStretch(1)
        self.hb.setAlignment(Qt.AlignTop)
        self.barGroup.setMaximumWidth(150)

        self.barGroup.setLayout(self.hb)

    def handelFormBtn(self, clearOpt):
        self.clearLayoutAndSetNewOne(clearOpt)

    def handelStandards(self, _, number):
        self.exels_files = []
        self.exels_files.append(
            str(
                os.path.join(os.path.dirname(__file__), 'data',
                             f'standard_{number}.xlsx')))
        print(self.exels_files)
        for path in self.exels_files:
            if not os.path.exists(path):
                MainWindow.errorHandler(f"directory_{path} not exits")
                return

        self.createTabs(None)

    def clearLayoutAndSetNewOne(self, clearOpt):
        if self.opt != clearOpt:
            item = None
            if self.layout() is not None:
                for i in range(1, self.layout().count()):
                    item = self.layout().itemAt(i).widget()
                    item.setParent(None)
            item.close()
            if clearOpt == MainTab.FORMGROUP:
                self.createFormGroupBox()
                self.main_layout.addWidget(self.formGroupBox)
                self.opt = MainTab.FORMGROUP
            elif clearOpt == MainTab.WELCOMEGROUP:
                self.createWelcome()
                self.main_layout.addWidget(self.welcomeGroup)
                self.opt = MainTab.WELCOMEGROUP

    def setComobox(self):
        self.options = {}
        for i in range(1, 11):
            self.options[f'{i} file'] = {
                'value': i,
                'label': f'Insert Address of file {i}'
            }

    def createFormGroupBox(self):
        self.formGroupBox = QGroupBox("Form layout")
        self.formLayout = QFormLayout()
        self.combo = QComboBox(self)
        self.combo.setStyleSheet("""background: #275efe;
                                 border-radius: 10px;
                                 width:100%;""")
        self.combo.addItem('select')
        self.setComobox()

        for val in self.options:
            self.combo.addItem(val,
                               userData=QtCore.QVariant(
                                   str(self.options[val]['value'])))

        self.filebtn = QPushButton('Select File', self)
        self.filebtn.setStyleSheet("""background: #275efe;
                                   border-radius: 10px;
                                   width: 100%; padding: 2px""")
        self.filebtn.clicked.connect(self.fileBtnHandler)
        self.tabCreatorBtn = QPushButton('create Tabs', self)
        self.tabCreatorBtn.setStyleSheet("""background: #275efe;
                                         border-radius: 10px;
                                         width:100%; padding: 2px;""")

        self.formLayout.addRow(
            QLabel('Enter The Folder Which Contains The Execl Files.'),
            self.filebtn)
        self.formLayout.addRow(
            QLabel(
                "Enter the number of files you want to load from directory"),
            self.combo)
        self.formLayout.addRow(QLabel('Create Tabs For Execl files.'),
                               self.tabCreatorBtn)

        self.tabCreatorBtn.clicked.connect(self.createTabs)
        self.combo.currentIndexChanged.connect(self.comboHandler)
        self.formGroupBox.setLayout(self.formLayout)

    def fileBtnHandler(self, x):
        """
            Handling directory which selected by user if directory was not selected the send error msg
            in QMessage window if everything was good it sets file_path for directories; 
            parameter:
                x: clicked or not
            returns: 
                void
        """
        self.file_path = str(
            QFileDialog.getExistingDirectory(self, 'select Directory'))

        if self.file_path == None or self.file_path == " " or len(
                self.file_path) == 0:
            self.file_path = " "
            MainWindow.errorHandler(
                "Directory Not Selected!\n\nplease select directory.")
            return

        self.exels_files = []
        files = os.listdir(self.file_path)

        for file in files:
            if os.path.splitext(file)[1] == ".xlsx":
                self.exels_files.append(path.join(self.file_path, file))

        if len(self.exels_files) == 0:
            MainWindow.errorHandler("Directory Contains No .xlsx files.",
                                    "Directory Execl file")
            return

        foundedFiles = "["
        lbl = QLabel()

        for file in self.exels_files:
            foundedFiles += str(file).split('/')[-1] + ', '

        lbl.setText(foundedFiles + ']')
        self.formLayout.addRow(QLabel("Founded Files"), lbl)

    def comboHandler(self, value):
        self.combo_value = value

        if getattr(self, 'exels_files', None) == None or len(
                self.exels_files) == 0:
            MainWindow.errorHandler("please select Directory First.")
            return

        if value >= len(self.exels_files):
            self.combo_value = len(self.exels_files)

        itemValue = self.combo.itemData(value)
        itemText = self.combo.itemText(value)
        print(itemValue, "====", itemText, "====", value)

    def keyPressEvent(self, a0: QtGui.QKeyEvent) -> None:
        if a0.key() == QKeySequence("Ctrl+Q"):
            sys.exit(1)

        if a0.key() == QKeySequence('Command+Q'):
            sys.exit(1)

    def createTabs(self, _=None):
        if getattr(self, 'exels_files', None) == None or len(
                self.exels_files) == 0:
            MainWindow.errorHandler("please Select Directory First.")
            return

        if getattr(self, 'combo_value', None) == None:
            self.combo_value = len(self.exels_files)

        for file in self.exels_files[:self.combo_value]:
            tab = ExeclTab(file)
            tab.setMaximumWidth(self.width())
            self.tabs.addTab(tab, str(file).split('/')[-1])
            self.tabs.setCurrentWidget(tab)

        self.exels_files = None
        del self.exels_files
示例#56
0
class Compass(COMCUPluginBase):
    def __init__(self, *args):
        super().__init__(BrickletCompass, *args)

        self.compass = self.device

        self.cbe_mfd = CallbackEmulator(self.compass.get_magnetic_flux_density,
                                        None, self.cb_mfd,
                                        self.increase_error_count)

        self.calibration = None

        self.compass_widget = CompassWidget()

        self.current_mfd_x = CurveValueWrapper()  # int, µT
        self.current_mfd_y = CurveValueWrapper()  # int, µT
        self.current_mfd_z = CurveValueWrapper()  # int, µT

        self.heading_label = HeadingLabel()
        self.inclination_label = InclinationLabel()

        self.label_widget = QWidget()
        self.label_layout = QVBoxLayout()
        self.label_layout.addWidget(self.heading_label)
        self.label_layout.addWidget(self.inclination_label)
        self.label_widget.setLayout(self.label_layout)

        plots = [('X', Qt.red, self.current_mfd_x, '{0} µT'.format),
                 ('Y', Qt.darkGreen, self.current_mfd_y, '{0} µT'.format),
                 ('Z', Qt.blue, self.current_mfd_z, '{0} µT'.format)]
        self.plot_widget = PlotWidget(
            'Magnetic Flux Density [µT]',
            plots,
            extra_key_widgets=[self.compass_widget, self.label_widget],
            update_interval=0.1,
            y_resolution=1)

        self.dr_label = QLabel('Data Rate:')
        self.dr_combo = QComboBox()
        self.dr_combo.addItem("100 Hz")
        self.dr_combo.addItem("200 Hz")
        self.dr_combo.addItem("400 Hz")
        self.dr_combo.addItem("600 Hz")

        self.dr_combo.currentIndexChanged.connect(self.new_config)

        self.button_calibration = QPushButton('Calibrate')
        self.button_calibration.clicked.connect(self.calibration_clicked)

        hlayout = QHBoxLayout()
        hlayout.addStretch()
        hlayout.addWidget(self.dr_label)
        hlayout.addWidget(self.dr_combo)
        hlayout.addStretch()
        hlayout.addWidget(self.button_calibration)
        hlayout.addStretch()

        line = QFrame()
        line.setObjectName("line")
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)

        layout = QVBoxLayout(self)
        layout.addWidget(self.plot_widget)
        layout.addWidget(line)
        layout.addLayout(hlayout)

    def calibration_clicked(self):
        if self.calibration == None:
            self.calibration = Calibration(self)

        self.button_calibration.setEnabled(False)
        self.calibration.show()

    def new_config(self):
        dr = self.dr_combo.currentIndex()
        self.compass.set_configuration(dr, True)

    def cb_mfd(self, data):
        x, y, z = data
        inclination = round(180 / math.pi * math.atan2(z, math.hypot(y, x)))
        heading = math.atan2(y, x) * 180 / math.pi

        if heading < 0:
            heading += 360

        self.current_mfd_x.value = round(x / 100.0)
        self.current_mfd_y.value = round(y / 100.0)
        self.current_mfd_z.value = round(z / 100.0)
        self.heading_label.setText(round(heading))
        self.compass_widget.set_angle(heading)
        self.inclination_label.setText(inclination)

    def get_configuration_async(self, conf):
        self.dr_combo.setCurrentIndex(conf.data_rate)

    def start(self):
        async_call(self.compass.get_configuration, None,
                   self.get_configuration_async, self.increase_error_count)
        self.cbe_mfd.set_period(50)

        self.plot_widget.stop = False

    def stop(self):
        self.cbe_mfd.set_period(0)

        self.plot_widget.stop = True

    def destroy(self):
        pass

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletCompass.DEVICE_IDENTIFIER
class ControllerWindow(QWidget):
    def __init__(self):
        super(ControllerWindow, self).__init__()

        self.setWindowTitle("Controller")
        self.setGeometry(1060, 100, 240, 540)

        self.initUI()
        self.show()

    def initUI(self):

        self.wHLayoutWidget = QWidget(self)
        self.wHLayoutWidget.setGeometry(0, 0, 240, 50)
        self.wHLayout = QHBoxLayout(self.wHLayoutWidget)
        self.wHLayout.setContentsMargins(5, 5, 5, 5)

        self.btnStepBackward = QToolButton(self.wHLayoutWidget)
        self.btnStepBackward.setIcon(QIcon("./assets/icons/step-backward.svg"))
        self.btnStepBackward.setToolTip("Quay lại bước trước")
        self.btnStepBackward.clicked.connect(controller.debugStepBackward)
        self.wHLayout.addWidget(self.btnStepBackward)

        self.iconPlay = QIcon("./assets/icons/play.svg")
        self.iconPause = QIcon("./assets/icons/pause.svg")

        self.btnToggleRun = QToolButton(self.wHLayoutWidget)
        self.btnToggleRun.setIcon(self.iconPlay)
        self.btnToggleRun.setToolTip("Bắt đầu/Dừng quá trình tìm kiếm")
        self.btnToggleRun.clicked.connect(self.toggleRun)
        self.wHLayout.addWidget(self.btnToggleRun)

        self.btnStepForward = QToolButton(self.wHLayoutWidget)
        self.btnStepForward.setIcon(QIcon("./assets/icons/step-forward.svg"))
        self.btnStepForward.setToolTip("Bước tới một bước")
        self.btnStepForward.clicked.connect(controller.debugStepForward)
        self.wHLayout.addWidget(self.btnStepForward)

        self.btnStop = QToolButton(self.wHLayoutWidget)
        self.btnStop.setIcon(QIcon("./assets/icons/times.svg"))
        self.btnStop.setToolTip("Dừng chương trình")
        self.btnStop.clicked.connect(QCoreApplication.instance().quit)
        self.wHLayout.addWidget(self.btnStop)

        self.controlSeperator = QFrame(self)
        self.controlSeperator.setGeometry(0, 45, 240, 5)
        self.controlSeperator.setFrameShape(QFrame.HLine)
        self.controlSeperator.setFrameShadow(QFrame.Sunken)

        self.wFormLayoutWidget = QWidget(self)
        self.wFormLayoutWidget.setGeometry(0, 50, 240, 165)
        self.wFormLayout = QFormLayout(self.wFormLayoutWidget)
        self.wFormLayout.setContentsMargins(5, 5, 5, 5)

        self.labelAlg = QLabel(self.wFormLayoutWidget)
        self.labelAlg.setText("Chọn thuật toán")
        self.wFormLayout.setWidget(0, QFormLayout.LabelRole, self.labelAlg)

        self.algorithmChoice = QComboBox(self.wFormLayoutWidget)

        for algo in controller.algorithms:
            self.algorithmChoice.addItem(algo['name'])

        self.algorithmChoice.currentIndexChanged.connect(self.changeAlgo)

        self.wFormLayout.setWidget(0, QFormLayout.FieldRole,
                                   self.algorithmChoice)

        self.labelWidth, self.inpWidth = self._createLineInput(
            1, "Số ô ngang", QIntValidator(1, 9999999), self.wFormLayout,
            self.wFormLayoutWidget)

        self.labelHeight, self.inpHeight = self._createLineInput(
            2, "Số ô dọc", QIntValidator(1, 9999999), self.wFormLayout,
            self.wFormLayoutWidget)

        self.labelDelayTime, self.delayTime = self._createLineInput(
            3, "Thời gian đợi", QIntValidator(20, 9999999), self.wFormLayout,
            self.wFormLayoutWidget)

        self.labelInput = QLabel(self.wFormLayoutWidget)
        self.labelInput.setText("Input")
        self.wFormLayout.setWidget(4, QFormLayout.LabelRole, self.labelInput)

        self.chooseInputFile = QPushButton(self.wFormLayoutWidget)
        self.chooseInputFile.setText("Chọn File")
        self.chooseInputFile.clicked.connect(self.pick_input)
        self.wFormLayout.setWidget(4, QFormLayout.FieldRole,
                                   self.chooseInputFile)

        self.btnApply = QPushButton(self)
        self.btnApply.setText("Áp dụng")
        self.btnApply.setGeometry(5, 220, 230, 25)
        self.btnApply.clicked.connect(self.applySettings)

        self.infoSeperator = QFrame(self)
        self.infoSeperator.setGeometry(0, 250, 240, 5)
        self.infoSeperator.setFrameShape(QFrame.HLine)
        self.infoSeperator.setFrameShadow(QFrame.Sunken)

        self.wInfoLayoutWidget = QWidget(self)
        self.wInfoLayoutWidget.setGeometry(0, 260, 240, 300)
        self.wInfoLayout = QFormLayout(self.wInfoLayoutWidget)
        self.wInfoLayout.setContentsMargins(5, 5, 5, 5)

        self.labelCost, self.valCost = self._createInfo(
            0, "Cost", "_", self.wInfoLayout, self.wInfoLayoutWidget)

        self.labelTimeCost, self.valTimeCost = self._createInfo(
            1, "Duration", "_", self.wInfoLayout, self.wInfoLayoutWidget)

        # self.btnToggle3D = QPushButton(self)
        # self.btnToggle3D.setText("Đổi sang chế độ 3D")
        # self.btnToggle3D.setGeometry(5, 510, 230, 25)
        # self.btnToggle3D.clicked.connect(self.toggle_3D)

        self.updateValuesFromState()

    def updateValuesFromState(self):
        self.inpWidth.setText(str(controller.map.width))
        self.inpHeight.setText(str(controller.map.height))
        self.delayTime.setText(str(controller.delayTime))

        if controller.running:
            self.btnToggleRun.setIcon(self.iconPause)
        else:
            self.btnToggleRun.setIcon(self.iconPlay)

    def applySettings(self):
        controller.delayTime = int(self.delayTime.text())
        controller.setMapWidth(int(self.inpWidth.text()))
        controller.setMapHeight(int(self.inpHeight.text()))
        controller.winRenderer.update()

    def changeAlgo(self, v):
        controller.currentAlgo = int(v)

    def toggleRun(self):
        newV = not controller.running

        if newV:
            self.btnToggleRun.setIcon(self.iconPause)
        else:
            self.btnToggleRun.setIcon(self.iconPlay)

        controller.running = newV
        if newV and controller.started:
            controller.update()

        if not controller.started and newV is True:
            controller.pfStart()

    def pick_input(self):

        filename, _ = QFileDialog.getOpenFileName(
            None, "Chọn file Input", "", "All Files (*);;Text Files (*.txt)")
        if filename:
            inp = open(filename, "r")

            controller.setNewInput(''.join([line for line in inp.readlines()]))

            self.updateValuesFromState()
            controller.winRenderer.update()

    def setPfResult(self, cost, time):
        self.valCost.setText(str(cost))
        self.valTimeCost.setText(str(time))

    def _createInfo(self, index, text, valText, parent, container):
        label = QLabel(container)
        label.setText(text)
        parent.setWidget(index, QFormLayout.LabelRole, label)

        val = QLabel(container)
        val.setText(valText)
        val.setAlignment(Qt.AlignRight)
        parent.setWidget(index, QFormLayout.FieldRole, val)

        return label, val

    def _createLineInput(self, index, text, validator, parent, container):
        label = QLabel(container)
        label.setText(text)
        parent.setWidget(index, QFormLayout.LabelRole, label)

        inp = QLineEdit(container)
        inp.setAlignment(Qt.AlignRight)
        inp.setValidator(validator)
        parent.setWidget(index, QFormLayout.FieldRole, inp)

        return label, inp
示例#58
0
class ToolBar:
    def __init__(self, window):
        self.window = window
        self.tool_bar = self.window.addToolBar('Toolbar')
        self.tool_bar.setFixedHeight(50)
        self.tool_bar.layout().setSpacing(10)
        self.tool_bar.setMovable(False)

        self.view = None
        self.add_button = None
        self.del_button = None

        self.populate_tool_bar()

    def populate_tool_bar(self):
        self.view = QComboBox(self.window)
        self.view.addItem('CHURCH')
        self.view.addItem('EXAM')
        self.view.addItem('PRIZE')
        self.view.setFixedHeight(30)
        self.view.setFixedWidth(100)
        self.tool_bar.addWidget(self.view)
        self.add_button = ToolButton('Add',
                                     self.add,
                                     self.window,
                                     short_cut='',
                                     status_tip='Add Church')
        self.tool_bar.addAction(self.add_button.button)

        self.del_button = ToolButton('Delete',
                                     self.delete,
                                     self.window,
                                     short_cut='',
                                     status_tip='Delete all Church')
        self.tool_bar.addAction(self.del_button.button)

        self.add_spacer()
        self.add_spacer()
        self.add_spacer()
        self.add_spacer()
        self.add_spacer()
        self.add_spacer()
        self.add_spacer()

        search_label = QLabel()
        search_label.setText('Search')
        self.tool_bar.addWidget(search_label)

        self.add_search_bar()

    def add_spacer(self):
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.tool_bar.addWidget(spacer)

    def add_search_bar(self):
        line_edit = QLineEdit(self.window)
        str_list = ['test', 'complete']
        completer = QCompleter(str_list, line_edit)
        line_edit.setCompleter(completer)
        line_edit.setFocusPolicy(Qt.ClickFocus)
        line_edit.editingFinished.connect(self.set_focus)
        line_edit.focusNextChild()
        self.window.focusWidget()
        self.tool_bar.addWidget(line_edit)

    def add(self):
        self.window.add_window()

    def delete(self):
        self.window.delete()

    def set_focus(self):
        self.window.setFocus()

    def set_text(self, text):
        self.view.setCurrentText(text)
示例#59
0
class App(QWidget):
    def __init__(self):
        super().__init__()
        self.title = 'Extract Videos App'
        self.left = 10
        self.top = 10
        self.width = 600
        self.height = 300
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.labl = QLabel(self)
        # self.labl.setText('abc')

        self.all_label = QLabel(self)

        self.video_label = QLabel(self)

        self.ann_label = QLabel(self)

        button = QPushButton('Select annotation file', self)
        button.move(0, 10)
        button.resize(180, 32)
        button.clicked.connect(self.on_click)

        button_video = QPushButton('Select video file', self)
        button_video.move(0, 50)
        button_video.resize(180, 32)
        button_video.clicked.connect(self.video_click)

        self.info_label1 = QLabel(self)
        self.info_label1.move(15, 130)
        self.info_label1.setText(
            "Select tier from which you want to extract the annotations")

        button_all = QPushButton('Extract all annotations from tier', self)
        button_all.move(200, 150)
        button_all.resize(230, 32)
        button_all.clicked.connect(self.all_annotations)

        button_one = QPushButton('Extract one annotation', self)
        button_one.move(200, 198)
        button_one.resize(230, 32)
        button_one.clicked.connect(self.extract_one)

        self.combo = QComboBox(self)
        # combo.addItem("Apple")
        self.combo.move(10, 150)
        self.combo.activated[str].connect(self.to_print)

        self.combo_annotations = QComboBox(self)
        # combo.addItem("Apple")
        self.combo_annotations.move(10, 200)
        self.combo_annotations.activated[str].connect(self.only_one_annotation)

        self.show()

    @pyqtSlot()
    def on_click(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(
            None,
            "Choose a file",
            "",
            "All Files (*);;Python Files (*.py)",
            options=options)
        if fileName:
            self.combo.clear()
            self.labl.setText(str(fileName))
            self.labl.adjustSize()
            self.labl.move(190, 16)
            self.file_eaf = pympi.Eaf(file_path=fileName)
            self.tier_names = self.file_eaf.get_tier_names()
            for tier_name in self.tier_names:
                self.combo.addItem(str(tier_name))

    def video_click(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(
            None,
            "Choose a file",
            "",
            "All Files (*);;Python Files (*.py)",
            options=options)
        if fileName:
            self.video_label.setText(str(fileName))
            self.video_label.adjustSize()
            self.video_label.move(190, 57)

    def to_print(self, text):
        self.all_label.setText(str(text))
        self.all_label.adjustSize()
        self.all_label.move(200, 150)
        self.all_label.hide()

        # add all the annotations to the other combo box
        my_file = pympi.Eaf(file_path=self.labl.text())
        my_annotations = my_file.get_annotation_data_for_tier(str(text))
        self.combo_annotations.clear()
        for annotatio in my_annotations:
            self.combo_annotations.addItem(str(annotatio[2]))

    def all_annotations(self):
        # print(self.all_label.text())
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        path = QFileDialog.getExistingDirectory(
            parent=self,
            caption='Select directory to save extracted videos',
        )
        if path:
            print(path)
        selected_file = pympi.Eaf(file_path=self.labl.text())
        annotations = selected_file.get_annotation_data_for_tier(
            self.all_label.text())
        video_name = self.video_label.text()
        count = 0
        for annotation in annotations:
            # t1 = annotation[0]/1000
            # t2 = annotation[1]/1000
            # input_video_path = video_name
            # output_video_path = path+'/'+str(annotation[0])+".mp4"
            # print(output_video_path)

            # with VideoFileClip(input_video_path) as video:
            #     new = video.subclip(t_start= t1)
            #     new.write_videofile(filename=output_video_path, audio_codec='aac')

            start = annotation[0]
            end = annotation[1]
            print(start / 1000, end / 1000)

            ffmpeg_extract_subclip(video_name,
                                   start / 1000,
                                   end / 1000,
                                   targetname=path + '/' + str(annotation[2]) +
                                   '_' + str(count) + ".mp4")
            # Comment next line if you don't want to extract the frames for each video
            # video_to_frames("Data/"+str(gloss)+"/Videos/"+"%#05d.mp4" % (count+1), "Data/"+str(gloss)+"/"+"%#05d" % (count+1) )
            count = count + 1
        print("FINISHED")

    def only_one_annotation(self, text):
        self.ann_label.setText(str(text))
        self.ann_label.adjustSize()
        self.ann_label.move(200, 350)
        self.ann_label.hide()

    def extract_one(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        path = QFileDialog.getExistingDirectory(
            parent=self,
            caption='Select directory to save extracted video',
        )
        if path:
            print(path)
        selected_file = pympi.Eaf(file_path=self.labl.text())
        annotations2 = selected_file.get_annotation_data_for_tier(
            self.all_label.text())
        video_name = self.video_label.text()
        for annotation in annotations2:
            # print(self.ann_label.text())
            if annotation[2] == self.ann_label.text():
                start = annotation[0]
                end = annotation[1]
                # print(start/1000,end/1000)

                ffmpeg_extract_subclip(video_name,
                                       start / 1000,
                                       end / 1000,
                                       targetname=path + '/' +
                                       str(self.ann_label.text()) + ".mp4")
示例#60
0
class MainWindow(QWidget):
    def __init__(self, inList):
        super().__init__()
        self.inList = inList
        self.nameFrom = 'Folder'
        self.codec = 'utvideo'
        self.alpha = False
        self.frameRate = 24
        self.defaulStyle = ''
        self.initUI()

    def initUI(self):

        #self.hbox = QVBoxLayout(self)
        self.gridLayout = QGridLayout(self)
        self.gridLayout.setContentsMargins(11, 11, 11, 11)

        self.lblCodec = QLabel("Codec", self)
        self.lblAlpha = QLabel("Alpha", self)
        self.lblFrameRate = QLabel("Frame Rate", self)
        self.gridLayout.addWidget(self.lblCodec, 0, 0, 1, 1)
        self.gridLayout.addWidget(self.lblAlpha, 0, 1, 1, 1)
        self.gridLayout.addWidget(self.lblFrameRate, 0, 2, 1, 1)

        self.comboCodec = QComboBox(self)
        self.comboCodec.setMinimumWidth(80)
        self.comboCodec.addItem("UT Video")

        self.comboAlpha = QComboBox(self)
        self.comboAlpha.setMinimumWidth(80)
        self.comboAlpha.addItem("No Alpha")
        self.comboAlpha.addItem("with Alpha")

        self.comboFrameRate = QComboBox(self)
        self.comboFrameRate.setMinimumWidth(80)
        self.comboFrameRate.addItem("24.00")
        self.comboFrameRate.addItem("30.00")

        self.buttonCompress = QPushButton("Compress", self)
        self.buttonCompress.clicked[bool].connect(self.compressPress)

        self.gridLayout.addWidget(self.comboCodec, 1, 0, 1, 1)
        self.gridLayout.addWidget(self.comboAlpha, 1, 1, 1, 1)
        self.gridLayout.addWidget(self.comboFrameRate, 1, 2, 1, 1)
        self.gridLayout.addWidget(self.buttonCompress, 1, 3, 1, 1)

        self.groupBox = QButtonGroup(self)

        self.radio1 = QRadioButton('Output file name from Folder name', self)
        self.radio2 = QRadioButton('Output file name from File name', self)
        self.groupBox.addButton(self.radio1, 1)
        self.groupBox.addButton(self.radio2, 2)
        self.radio1.setChecked(True)

        self.gridLayout.addWidget(self.radio1, 2, 0, 1, 2)
        self.gridLayout.addWidget(self.radio2, 2, 2, 1, 2)

        self.groupBox.buttonClicked[int].connect(self.radioBtnState)

        self.pbList = []

        for i in range(len(self.inList)):
            self.tempPB = QProgressBar(self)
            self.tempPB.setMinimum(0)
            self.tempPB.setMaximum(100)
            self.tempPB.setTextVisible(True)
            self.tempPB.setFormat(str(self.inList[i]) + " %p%")
            self.tempPB.setAlignment(Qt.AlignCenter)
            self.tempPB.setValue(0)
            if i == 0:
                self.defaulStyle = self.tempPB.styleSheet()

            self.gridLayout.addWidget(self.tempPB, i + 3, 0, 1, 4)
            self.pbList.append(self.tempPB)

        self.errorLlb = QLabel("Output", self)
        self.gridLayout.addWidget(self.errorLlb, len(self.inList) + 4, 0, 1, 4)

        self.errorText = QPlainTextEdit('', self)
        self.gridLayout.addWidget(self.errorText,
                                  len(self.inList) + 5, 0, 1, 4)

        self.spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                      QSizePolicy.Expanding)
        self.gridLayout.addItem(self.spacerItem, len(self.inList) + 6, 0, 1, 1)

        self.comboCodec.activated[str].connect(self.chooseCodec)
        self.comboAlpha.activated[str].connect(self.chooseAlpha)
        self.comboFrameRate.activated[str].connect(self.chooseFrameRate)

        self.setGeometry(300, 300, 750, 100)
        #self.gridLayout.setGeometry(QRect(19, 19, 581, 100))
        self.setWindowTitle('FFMpeg Python Compressor')
        self.show()

        self.threadpool = QThreadPool()
        self.threadpool.setMaxThreadCount(1)
        print("Multithreading with maximum %d threads" %
              self.threadpool.maxThreadCount())

    '''
	Button Functions
	'''

    def chooseAlpha(self, text):
        switcher = {"No Alpha": False, "with Alpha": True}
        self.alpha = switcher.get(text, "Invalid day of week")
        #print (self.alpha)

    def chooseCodec(self, text):
        switcher = {"UT Video": "utvideo"}
        self.codec = switcher.get(text, "Invalid day of week")
        #print (self.codec)

    def chooseFrameRate(self, text):
        self.frameRate = float(text)
        #print (self.frameRate)

    def currentData(self, widget):
        return widget.currentText()

    def radioBtnState(self, text):
        switcher = {1: 'Folder', 2: 'File'}
        self.nameFrom = switcher.get(text, "Invalid day of week")
        #print(self.nameFrom)

    '''
	Execution Functions
	'''

    def execute_this_fn(self, path, codec, alpha, frameRate, progress_callback,
                        errorFFMPEG_callback):
        #print(path)
        pyCompression = pyFFMEGCompress(path, codec, alpha, frameRate)
        ffProcess = pyCompression.ffmpegCompress()

        #with kwargs
        kwargs = {
            'progress_callback': progress_callback,
            'errorFFMPEG_callback': errorFFMPEG_callback
        }
        pyCompression.printProcess(ffProcess, **kwargs)

        return pyCompression.debugString

    def printOutput(self, s):
        print("Printing output " + str(s))

    def threadComplete(self, r):
        print("THREAD COMPLETE! WITH ERROR " + str(r))

    def errorPB(self, err):
        for o in self.pbList:
            if o.format() == err:
                o.setValue(100)
                o.setStyleSheet(
                    "QProgressBar::chunk {background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #FF0350,stop: 0.4999 #FF0020,stop: 0.5 #FF0019,stop: 1 #FF0000 );border-radius: 3px; border: 1px solid #a60233;}QProgressBar{color:white}"
                )  #("QProgressBar::chunk { background-color: red; }")
                #pb.setStyleSheet("QProgressBar::chunk { background-color: red; }")
                o.setFormat(o.format() + " - Error")

    def resetProgressBar(self, pb, text):
        pb.setValue(0)
        pb.setFormat(text + ' %p%')
        pb.setStyleSheet(self.defaulStyle)

    def compressPress(self):
        for i in range(len(self.pbList)):
            self.resetProgressBar(self.pbList[i], self.inList[i])

            worker = Worker(
                self.execute_this_fn, self.inList[i], self.codec, self.alpha,
                self.frameRate
            )  # Any other args, kwargs are passed to the run function
            #worker.signals.result.connect(self.printOutput)
            worker.signals.result.connect(self.errorText.appendPlainText)
            worker.signals.progress.connect(self.pbList[i].setValue)
            worker.signals.errorFFMPEG.connect(self.errorPB)
            worker.signals.error.connect(self.errorPB)
            worker.signals.finished.connect(self.threadComplete)
            #worker.signals.finished.connect(self.errorText.appendPlainText)

            # Execute
            self.threadpool.start(worker)