Exemplo n.º 1
0
class DocumentTab(QWidget):
    def __init__(self, parent):
        self.parent = parent
        super(DocumentTab, self).__init__(parent)
        self.name = 'Documents'
        self.formats = config.document_formats

        convertQL = QLabel(self.tr('Convert to:'))
        self.extQCB = QComboBox()
        final_layout = utils.add_to_layout('h', convertQL, self.extQCB, None)
        self.setLayout(final_layout)

    def fill_extension_combobox(self, extraformats):
        self.extQCB.clear()
        self.extQCB.addItems(sorted(self.formats + extraformats))

    def ok_to_continue(self):
        """
        Check if everything is ok with documenttab to continue conversion.

        Checks if:
        - unoconv is missing.

        Return True if all tests pass, else False.
        """
        if not self.parent.unoconv:
            QMessageBox.warning(self, 'FF Multi Converter - ' + self.tr('Error!'),
                    self.tr('Unocov is not installed!'))
            return False
        return True
Exemplo n.º 2
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)
Exemplo n.º 3
0
class StartSession(preferences.Group):
    def __init__(self, page):
        super(StartSession, self).__init__(page)
        
        grid = QGridLayout()
        self.setLayout(grid)
        
        def changed():
            self.changed.emit()
            self.combo.setEnabled(self.custom.isChecked())
        
        self.none = QRadioButton(toggled=changed)
        self.lastused = QRadioButton(toggled=changed)
        self.custom = QRadioButton(toggled=changed)
        self.combo = QComboBox(currentIndexChanged=changed)
        
        grid.addWidget(self.none, 0, 0, 1, 2)
        grid.addWidget(self.lastused, 1, 0, 1, 2)
        grid.addWidget(self.custom, 2, 0, 1, 1)
        grid.addWidget(self.combo, 2, 1, 1, 1)

        app.translateUI(self)
        
    def translateUI(self):
        self.setTitle(_("Session to load if Frescobaldi is started without arguments"))
        self.none.setText(_("Start with no session"))
        self.lastused.setText(_("Start with last used session"))
        self.custom.setText(_("Start with session:"))
        
    def loadSettings(self):
        s = QSettings()
        s.beginGroup("session")
        startup = s.value("startup", "none", str)
        if startup ==  "lastused":
            self.lastused.setChecked(True)
        elif startup == "custom":
            self.custom.setChecked(True)
        else:
            self.none.setChecked(True)
        sessionNames = sessions.sessionNames()
        self.combo.clear()
        self.combo.addItems(sessionNames)
        custom = s.value("custom", "", str)
        if custom in sessionNames:
            self.combo.setCurrentIndex(sessionNames.index(custom))

    def saveSettings(self):
        s = QSettings()
        s.beginGroup("session")
        s.setValue("custom", self.combo.currentText())
        if self.custom.isChecked():
            startup = "custom"
        elif self.lastused.isChecked():
            startup = "lastused"
        else:
            startup = "none"
        s.setValue("startup", startup)
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()
Exemplo n.º 5
0
class AreaOperation(QWidget):
    
    # - add objects to an area
    # - remove objects from an area
    
    @update_paths
    def __init__(self, mode, obj, AS=set(), controller=None):
        super().__init__()
        
        title = 'Add to area' if mode == 'add' else 'Remove from area'
        self.setWindowTitle(title)

        values = tuple(map(str, AS))
        
        # list of existing AS
        self.AS_list = QComboBox()
        self.AS_list.addItems(values)
        self.AS_list.activated.connect(self.update_value)
        
        # list of areas
        self.area_list = QComboBox()
        self.update_value()
        
        # confirmation button
        button_area_operation = QPushButton()
        button_area_operation.setText('OK')
        button_area_operation.clicked.connect(lambda: self.area_operation(mode, *obj))
        
        # position in the grid
        layout = QGridLayout()
        layout.addWidget(self.AS_list, 0, 0, 1, 2)
        layout.addWidget(self.area_list, 1, 0, 1, 2)
        layout.addWidget(button_area_operation, 2, 0, 1, 1)
        layout.addWidget(cancel_button, 2, 1, 1, 1)
        self.setLayout(layout)
        
    def update_value(self, index):
        self.area_list.clear()
        selected_AS = self.network.AS_factory(name=self.AS_list.currentText())
        self.area_list.addItems(tuple(map(str, selected_AS.areas)))
        
    def area_operation(self, mode, *objects):
        selected_AS = self.network.AS_factory(name=self.AS_list.currentText())
        selected_area = self.area_list.currentText()

        if mode == 'add':
            selected_AS.management.add_to_area(selected_area, *objects)
        else:
            selected_AS.management.remove_from_area(selected_area, *objects)
            
        self.close()
Exemplo n.º 6
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)
Exemplo n.º 7
0
def update_ComboBox(combobox: QComboBox, init_text: str, texts: List[str]):
    """
    Updates a combo box content using a list of strings.

    :param combobox: the combobox to be updated
    :param init_text: the initial updated combo box element
    :param texts: the list of the texts used to fill the combo box
    :return:
    """

    combobox.clear()

    if len(texts) == 0:
        return

    if init_text:
        combobox.addItem(init_text)

    combobox.addItems(texts)
Exemplo n.º 8
0
class ChooseDefaultDict( ChoiceWidget ):
    def __init__( self, explainer ) :
        super().__init__( _TR( 'Preference item title line',
                               'Choose the dictionary for any new book' ),
                          explainer )
        self.dcb = QComboBox()
        self.layout().addWidget(self.dcb)
        self.dcb.activated[str].connect( self.choice_made )
        self.reset() # load the combobox
        paths.notify_me( self.path_changed )
        self.explanation = _TR( 'Preference item details',
'''Choose the spell-check dictionary to be used when a book is opened for the first time.

If the dictionary that you want is not in the list, you may need to choose the path to the dictionaries folder, above, and click Apply.

You can change the dictionary for any book by right-clicking in its Edit panel.''' )

    def choice_made( self, dic_tag ) :
        self.choice = dic_tag

    def path_changed( self, which ):
        # some path preference changed; if "dicts" reload the menu
        if which == "dicts" :
            self.reload_menu()

    def reload_menu( self ) :
        # refresh the combobox with the available tags.
        dict_dict = dictionaries.get_tag_list()
        self.dcb.clear()
        self.dcb.addItems( list( dict_dict.keys() ) )
        self.dcb.setCurrentText ( self.choice )

    def reset(self) :
        self.choice = dictionaries.get_default_tag()
        self.reload_menu()

    def apply(self):
        dictionaries.set_default_tag( self.choice )
Exemplo n.º 9
0
class Actividad7(QWidget):
	def __init__(self):
		super().__init__()
		self.ventana()
		
	def ventana(self):
		#Etiquetas
		self.entrada = QLineEdit("Numero de datos", self)
		self.entrada.move(5,5)
		self.combo = QComboBox(self)
		self.combo.move(160,5)
		x= QLabel("X:", self)
		x.move(5,40)
		btn= QPushButton("Calcular", self)
		btn.move(190,35)
		y = QLabel("f(X):", self)
		y.move(5,70)
		self.entradax = QLineEdit(self)
		self.entradax.move(35,35)
		self.entraday = QLineEdit(self)
		self.entraday.move(35,65)
		btn2= QPushButton("Borrar Todo", self)
		btn2.move(190,65)
		self.valor = QLineEdit("Valor a estimar en",self)
		self.valor.move(5,95)
		self.ecuacion= QLabel("Y=",self)
		self.ecuacion.move(5,130)

		#Eventos
		self.entrada.textChanged[str].connect(self.combobox)
		self.combo.activated[str].connect(self.cambio)
		self.entradax.textChanged[str].connect(self.x)
		self.entraday.textChanged[str].connect(self.y)
		btn.clicked.connect(self.boton)
		self.entrada.selectionChanged.connect(self.sel1)
		self.entradax.selectionChanged.connect(self.sel2)
		self.entraday.selectionChanged.connect(self.sel3)
		self.valor.selectionChanged.connect(self.sel4)
		btn2.clicked.connect(self.borrar)
		#Ventana
		self.setGeometry(300, 300, 310, 150)
		self.setWindowTitle("Polinomios de interpolacion de Langrange")
		self.show()
	
	def combobox(self, text):
		self.combo.clear()
		self.entradax.clear()
		self.entraday.clear()
		if text =='':
			text='0'
		for c in range(int(text)):
			self.combo.addItem(str(c+1))
			if len(xl)<= c:
				xl.append(0.0)
				yl.append(0.0)
		if text != "0":
			self.entradax.setText(str(xl[self.combo.currentIndex()]))
			self.entraday.setText(str(yl[self.combo.currentIndex()]))
			
	def cambio(self, text):
		self.entradax.setText(str(xl[int(text)-1]))
		self.entraday.setText(str(yl[int(text)-1]))
	def x(self, text):
		if text == "" or text == '-':
			text= "0"
		xl[self.combo.currentIndex()]= float(text)
	def y(self, text):
		if text == "" or text == '-':
			text= "0"
		yl[self.combo.currentIndex()]= float(text)
	def boton(self):
		if self.valor.text() == "": #Si el usuario deja en blanco el valor a conocer se conocera que es 0
			self.valor.setText("0")
		datos= int(self.entrada.text()) #datos es el numero de datos ingresados por el usuario
		cx= float(self.valor.text())#cx sera el valor que el usuario quiera conocer
		suma=0 #Se declara la sumatoria
		for c in range(datos): #Este for funciona para movernos en I
			pro=1 #Se declara la variable producto
			for c2 in range(datos):#Este for funciona para movernos en J
				if c2!=c: #Si I es diferente a J se realizara la operacion producto 
					pro*= (cx-xl[c2])/(xl[c]-xl[c2]) #Producto de
			pro*= yl[c] #Al final de pasar por cada J se multiplica por f(X) en el cual I esta actualmente
			suma+= pro #pro pasa a ser parte de la Sumatoria
		self.ecuacion.setText("Y= " + str(suma)) #Al final se imprime la Sumatoria
		self.ecuacion.adjustSize()
	def sel1(self):
		self.entrada.clear()
	def sel2(self):
		self.entradax.clear()
	def sel3(self):
		self.entraday.clear()
	def sel4(self):
		self.valor.clear()
	def borrar(self):
		for c in range(len(xl)):
			xl[c]= 0.0
			yl[c]= 0.0
		self.sel1()
		self.sel2()
		self.sel3()
		self.sel4()
Exemplo n.º 10
0
class Example(QWidget):
	def __init__(self):
		super().__init__()
		self.initUI()

	def initUI(self):
		mainBox = QVBoxLayout()
		fileBox = QHBoxLayout()
		menuBox = QHBoxLayout()
		resBox = QHBoxLayout()
		self.outEdit = QTextEdit()
		toolBox = QVBoxLayout()

		mainBox.addLayout(fileBox)
		mainBox.addLayout(menuBox)
		mainBox.addLayout(resBox)
		resBox.addWidget(self.outEdit)
		resBox.addLayout(toolBox)

		openFileBtn = QPushButton('1.选择文件')
		self.fileNameEdit = QLineEdit()
		parseFileBtn = QPushButton('2.开始解析')
		fileBox.addWidget(openFileBtn)
		fileBox.addWidget(self.fileNameEdit)
		fileBox.addWidget(parseFileBtn)

		label1 = QLabel('3.筛选:')
		levelLabel = QLabel('log级别')
		self.levelCombo = QComboBox()
		self.levelCombo.setMinimumWidth(100)
		modLabel = QLabel('log模块')
		self.modCombo = QComboBox()
		self.modCombo.setMinimumWidth(100)
		funLabel = QLabel('功能')
		self.funCombo = QComboBox()
		self.funCombo.setMinimumWidth(100)
		menuBox.addWidget(label1)
		menuBox.addWidget(levelLabel)
		menuBox.addWidget(self.levelCombo)
		menuBox.addSpacing(15)
		menuBox.addWidget(modLabel)
		menuBox.addWidget(self.modCombo)
		menuBox.addSpacing(15)
		menuBox.addWidget(funLabel)
		menuBox.addWidget(self.funCombo)
		menuBox.addStretch()

		toolBtn1 = QPushButton('复制')
		toolBtn2 = QPushButton('保存')
		toolBtn3 = QPushButton('')
		toolBtn4 = QPushButton('')
		self.statusLabel = QLabel('')
		toolBox.addWidget(toolBtn1)
		toolBox.addWidget(toolBtn2)
		# toolBox.addWidget(toolBtn3)
		# toolBox.addWidget(toolBtn4)
		toolBox.addStretch()
		toolBox.addWidget(self.statusLabel)

		self.setLayout(mainBox)

		# 按钮连接到槽
		openFileBtn.clicked.connect(self.open_file)
		parseFileBtn.clicked.connect(self.parse_file)

		self.levelCombo.activated.connect(self.show_lines)
		self.modCombo.activated.connect(self.show_lines)
		self.funCombo.activated.connect(self.show_lines)

		toolBtn1.clicked.connect(self.copy_result)
		toolBtn2.clicked.connect(self.save_result)

		self.setGeometry(200, 300, 700, 500)
		self.setWindowTitle('log解析工具')
		self.show()

	def open_file(self):
		file = QFileDialog.getOpenFileName(self, '选择log文件', '')
		filename = file[0]
		self.fileNameEdit.setText(filename)

	def parse_file(self):
		self.please_wait()
		filename = self.fileNameEdit.text()

		start = time.time() # 计时开始

		self.L = plo.Parser(filename)
		for line_no in range(0,self.L.lines): # 遍历所有log
			try:
				self.L.parse_log_level(line_no) # log级别
				self.L.parse_log_mod(line_no) # log模块
				self.L.parse_log_all_func(line_no) # 其他功能
			except Exception as e:
				print(e)
			if line_no%1000 == 0 or line_no == self.L.lines - 1: # 每100行和最后一行执行一次刷新,可大大加快解析速度!
				self.outEdit.setText('解析中,请等待...('+str(line_no)+'/'+str(self.L.lines)+')')
				QApplication.processEvents()

		end = time.time() # 计时结束

		# log级别
		log_levels = self.L.get_levels()
		self.levelCombo.clear()
		self.levelCombo.addItem('全部')
		self.levelCombo.addItems(log_levels.keys())

		# log模块
		log_mods = self.L.get_mods()
		self.modCombo.clear()
		self.modCombo.addItem('全部')
		self.modCombo.addItems(log_mods.keys())

		# log功能
		log_funcs = self.L.get_funcs()
		self.funCombo.clear()
		self.funCombo.addItem('全部')
		self.funCombo.addItems(log_funcs.keys())

		# 输出结果
		print_log = ''
		print_log += '解析时间:%.2fs\n' % (end-start)
		print_log += ('各级别log统计结果:\n')
		for level_name in log_levels.keys():
			print_log += (level_name + ': ' + str(len(log_levels.get(level_name, []))) + '\n')
		print_log += '\n'
		print_log += ('各模块log统计结果:\n')
		for mod_name in log_mods.keys():
			print_log += (mod_name + ': ' + str(len(log_mods.get(mod_name, []))) + '\n')
		print_log += '\n'
		print_log += ('各功能统计结果:\n')
		for func_name in log_funcs.keys():
			print_log += (func_name + ': ' + str(len(log_funcs.get(func_name, []))) + '\n')
		self.parse_result = print_log # 保存解析结果
		self.outEdit.setText(print_log)

	def show_lines(self):
		'''
		筛选框操作后,显示结果
		'''
		selLevel = self.levelCombo.currentText()
		selMod = self.modCombo.currentText()
		selFun = self.funCombo.currentText()

		if(selLevel == '全部' and selMod == '全部' and selFun == '全部'): # 不要显示全部log
			self.outEdit.setText(self.parse_result)
			return

		self.please_wait()

		if (selLevel != '全部'):
			resLevel = self.L.get_log_lines(selLevel)

		if (selMod != '全部'):
			resMod = self.L.get_log_lines(selMod)

		if (selFun != '全部'):
			resFun = self.L.get_log_lines(selFun)

		# 逐行显示
		self.outEdit.clear()
		lines_num = 0
		for i in range(0, self.L.lines):
			if (selLevel != '全部' and i not in resLevel): # 不满足等级筛选条件
				continue
			if (selMod != '全部' and i not in resMod): # 不满足模块筛选条件
				continue
			if (selFun != '全部' and i not in resFun): # 不满足功能筛选条件
				continue
			# i满足所有筛选条件
			self.outEdit.moveCursor(QTextCursor.End) # 使用insertPlainText需保证cursor在末尾
			self.outEdit.insertPlainText(self.L.log[i])
			lines_num = lines_num + 1
			self.show_status('当前' + str(lines_num) + '条')
			QApplication.processEvents()
		self.show_status('共' + str(lines_num) + '条')

	def please_wait(self):
		self.outEdit.setText('解析中,请等待...')
		QApplication.processEvents()
		self.show_status('')

	def show_status(self, status):
		self.statusLabel.setText(status)
		QApplication.processEvents()

	def copy_result(self):
		clipboard = QApplication.clipboard()
		clipboard.setText(self.outEdit.toPlainText())
		self.show_status('复制成功')

	def save_result(self):
		file = QFileDialog.getSaveFileName(self, '保存log文件', '')
		filename = file[0]
		try:
			with open(filename, 'w+') as f:
				result = self.outEdit.toPlainText()
				f.write(result)
			self.show_status('保存成功')
		except Exception as e:
			print(e)
			self.show_status('保存失败')
Exemplo n.º 11
0
    class preferences(QWidget):
        def __init__(self, scale_factor):
            try:
                super().__init__()
            except TypeError:
                super(self.__class__, self).__init__()  # port to python2

            self.scale_factor = scale_factor
            self.config = ConfigParser.RawConfigParser()
            self.configurations = config_manager()
            self.configf = self.configurations.configf
            if os.path.exists(self.configf) is False:
                print('Config file does not exist!')
                self.configurations.config_defaults()
            self.read_defaults()
            self.initUI()

        def initUI(self):
            self.backend()
            self.codec()
            self.bitrate()
            self.samplerates()
            self.iconcolors()
            self.notifications()
            self.searchatlaunch()
            if platform == 'Linux':
                self.alsadevice()
            self.buttons()
            self.window()

        def backend(self):
            """
            Backend
            """
            backends_supported = ['node', 'ffmpeg', 'avconv', 'parec',
                                  'gstreamer']
            self.backends = []
            if platform == 'Darwin':
                for item in backends_supported:
                    if (is_installed(item, PATH, debug) is True and
                       item != 'avconv' and item != 'gstreamer'):
                        self.backends.append(item)
            else:
                for item in backends_supported:
                    if (is_installed(item, PATH, debug) is True and
                       item != 'node' and item != 'gstreamer'):
                        self.backends.append(item)
                    # hardcoded gst-launch-1.0 for gstreamer
                    elif (is_installed('gst-launch-1.0', PATH, debug) is
                          True and item == 'gstreamer'):
                        self.backends.append(item)
            try:
                backend_index = self.backends.index(self.backend_conf)
            except ValueError:
                # No backend found
                backend_index = None
                pass
            self.backend = QLabel('Select Backend', self)
            self.backend.move(20 * self.scale_factor, 24 * self.scale_factor)
            self.qcbackend = QComboBox(self)
            self.qcbackend.move(180 * self.scale_factor,
                                20 * self.scale_factor)
            self.qcbackend.setMinimumContentsLength(7)
            for item in self.backends:
                self.qcbackend.addItem(item)

            if backend_index:
                self.qcbackend.setCurrentIndex(backend_index)

            self.qcbackend.activated[str].connect(self.onActivatedbk)

        def codec(self):
            """
            Codec
            """
            self.codec = QLabel('Audio Coding Format', self)
            self.codec.move(20 * self.scale_factor, 56 * self.scale_factor)
            self.qccodec = QComboBox(self)
            self.qccodec.clear()
            if self.backend_conf == 'node':
                self.codecs = ['mp3']
            else:
                self.codecs = [
                    'mp3',
                    'ogg',
                    'aac',
                    'wav',
                    'flac'
                    ]
            if debug is True:
                print(self.codecs)
            codecindex = self.codecs.index(self.codecconf)
            self.qccodec.move(180 * self.scale_factor, 54 * self.scale_factor)
            self.qccodec.setMinimumContentsLength(7)
            for item in self.codecs:
                self.qccodec.addItem(item)
            self.qccodec.setCurrentIndex(codecindex)
            self.qccodec.activated[str].connect(self.onActivatedcc)

        def bitrate(self):
            """
            Bitrate
            """
            self.bitrate = QLabel('Select Bitrate (kbit/s)', self)
            self.bitrate.move(20 * self.scale_factor, 88 * self.scale_factor)
            self.qcbitrate = QComboBox(self)
            self.qcbitrate.clear()
            self.qcbitrate.move(180 * self.scale_factor,
                                88 * self.scale_factor)
            self.qcbitrate.setMinimumContentsLength(7)
            if self.codecconf == 'wav':
                self.bitrates = ['None']
                bitrateindex = 0
            else:
                self.bitrates = [
                    '128',
                    '160',
                    '192',
                    '224',
                    '256',
                    '320',
                    '500'
                    ]
                bitrateindex = self.bitrates.index(self.bitrateconf)
            for item in self.bitrates:
                self.qcbitrate.addItem(item)
            self.qcbitrate.setCurrentIndex(bitrateindex)
            self.qcbitrate.activated[str].connect(self.onActivatedbt)

        def samplerates(self):
            """
            Sample rate
            """
            self.samplerates = [
                '192000',
                '176400',
                '96000',
                '88200',
                '48000',
                '44100',
                '32000',
                '22050'
                ]
            sampleratesindex = self.samplerates.index(self.samplerateconf)
            self.samplerate = QLabel('Sample Rate (Hz)', self)
            self.samplerate.move(20 * self.scale_factor,
                                 120 * self.scale_factor)
            self.qcsamplerate = QComboBox(self)
            self.qcsamplerate.move(180 * self.scale_factor,
                                   120 * self.scale_factor)
            self.qcsamplerate.setMinimumContentsLength(7)
            for item in self.samplerates:
                self.qcsamplerate.addItem(item)
            self.qcsamplerate.setCurrentIndex(sampleratesindex)
            self.qcsamplerate.activated[str].connect(self.onActivatedsr)

        def iconcolors(self):
            """
            Icon colors
            """
            self.colors_list = [
                'black',
                'blue',
                'white'
                ]
            colorsindex = self.colors_list.index(self.searchcolorsconf)
            self.colors = QLabel('Icon Colors', self)
            self.colors.move(20 * self.scale_factor,
                             152 * self.scale_factor)
            self.qccolors = QComboBox(self)
            self.qccolors.move(180 * self.scale_factor,
                               152 * self.scale_factor)
            self.qccolors.setMinimumContentsLength(7)
            for item in self.colors_list:
                self.qccolors.addItem(item)
            self.qccolors.setCurrentIndex(colorsindex)
            self.qccolors.activated[str].connect(self.onActivatedcolors)

        def notifications(self):
            """
            Notifications
            """
            self.notifications_list = [
                'enabled',
                'disabled'
                ]
            notindex = self.notifications_list.index(self.notifconf)
            self.notifications = QLabel('Notifications', self)
            self.notifications.move(20 * self.scale_factor,
                                    184 * self.scale_factor)
            self.qcnotifications = QComboBox(self)
            self.qcnotifications.move(180 * self.scale_factor,
                                      184 * self.scale_factor)
            self.qcnotifications.setMinimumContentsLength(7)
            for item in self.notifications_list:
                self.qcnotifications.addItem(item)
            self.qcnotifications.setCurrentIndex(notindex)
            self.qcnotifications.activated[str].connect(self.onActivatednotify)

        def searchatlaunch(self):
            """
            Search at launch
            """
            self.atlaunch_list = [
                'enabled',
                'disabled'
                ]
            launchindex = self.atlaunch_list.index(self.satlaunchconf)
            self.atlaunch = QLabel('Search At Launch', self)
            self.atlaunch.move(20 * self.scale_factor,
                               214 * self.scale_factor)
            self.qcatlaunch = QComboBox(self)
            self.qcatlaunch.move(180 * self.scale_factor,
                                 214 * self.scale_factor)
            self.qcatlaunch.setMinimumContentsLength(7)
            for item in self.atlaunch_list:
                self.qcatlaunch.addItem(item)
            self.qcatlaunch.setCurrentIndex(launchindex)
            self.qcatlaunch.activated[str].connect(self.onActivatedatlaunch)

        def alsadevice(self):
            """
            Set the ALSA Device
            """
            self.alsadevice = QLabel('ALSA Device', self)
            self.alsadevice.move(20 * self.scale_factor,
                                 244 * self.scale_factor)
            self.qle = QLineEdit(self)
            self.qle.move(179 * self.scale_factor,
                          244 * self.scale_factor)
            self.qle.setFixedWidth(84*self.scale_factor)
            self.read_defaults()
            if self.alsadeviceconf is not None:
                self.qle.setText(self.alsadeviceconf)
            self.qle.textChanged[str].connect(self.onActivatedalsadevice)

        def buttons(self):
            """
            Buttons
            """
            resetbtn = QPushButton("Reset Settings", self)
            resetbtn.move(10 * self.scale_factor, 274 * self.scale_factor)
            resetbtn.clicked.connect(self.reset_configuration)

            faqbtn = QPushButton("FAQ", self)
            faqbtn.move(138 * self.scale_factor, 274 * self.scale_factor)
            faqbtn.clicked.connect(lambda: webbrowser.open('https://github.com/muammar/mkchromecast/wiki/FAQ'))

            donbtn = QPushButton("Donate :)", self)
            donbtn.move(204 * self.scale_factor, 274 * self.scale_factor)
            donbtn.clicked.connect(lambda: webbrowser.open('https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=RZLF7TDCAXT9Q&lc=US&item_name=mkchromecast&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted'))

        def window(self):
            """
            Geometry and window's title
            """
            self.setGeometry(300 * self.scale_factor,
                             300 * self.scale_factor,
                             300 * self.scale_factor,
                             200 * self.scale_factor)
            if platform == 'Darwin':
                # This is to fix the size of the window
                self.setFixedSize(310 * self.scale_factor,
                                  320 * self.scale_factor)
            else:
                # This is to fix the size of the window
                self.setFixedSize(282 * self.scale_factor,
                                  320 * self.scale_factor)
            self.setWindowFlags(QtCore.Qt.WindowCloseButtonHint |
                                QtCore.Qt.WindowMinimizeButtonHint |
                                QtCore.Qt.WindowStaysOnTopHint)
            self.setWindowTitle('Mkchromecast Preferences')

            """
            Methods
            """
        def reset_configuration(self):
            self.configurations.write_defaults()
            self.reset_indexes()

        def reset_indexes(self):
            self.read_defaults()
            """
            Indexes of QCombo boxes are reset
            """
            backend_index = self.backends.index(self.backend_conf)
            codecindex = self.codecs.index(self.codecconf)
            self.bitrates = [
                '128',
                '160',
                '192',
                '224',
                '256',
                '320',
                '500'
                ]
            bitrateindex = self.bitrates.index(self.bitrateconf)
            self.qcbitrate.clear()
            for item in self.bitrates:
                self.qcbitrate.addItem(item)
            sampleratesindex = self.samplerates.index(self.samplerateconf)
            colorsindex = self.colors_list.index(self.searchcolorsconf)
            notindex = self.notifications_list.index(self.notifconf)
            launchindex = self.atlaunch_list.index(self.satlaunchconf)
            self.qcbackend.setCurrentIndex(backend_index)
            self.qccodec.setCurrentIndex(codecindex)
            self.qcbitrate.setCurrentIndex(bitrateindex)
            self.qcsamplerate.setCurrentIndex(sampleratesindex)
            self.qccolors.setCurrentIndex(colorsindex)
            self.qcnotifications.setCurrentIndex(notindex)
            self.qcatlaunch.setCurrentIndex(launchindex)

        def onActivatedbk(self, text):
            self.config.read(self.configf)
            self.config.set('settings', 'backend', text)
            self.write_config()
            self.read_defaults()
            self.qccodec.clear()
            if self.backend_conf == 'node':
                codecs = ['mp3']
                self.config.read(self.configf)
                self.config.set('settings', 'codec', 'mp3')
                self.write_config()
            else:
                codecs = [
                    'mp3',
                    'ogg',
                    'aac',
                    'wav',
                    'flac'
                    ]
            if debug is True:
                print('Codecs: %s.' % codecs)
            codecindex = codecs.index(self.codecconf)
            self.qccodec.move(180 * self.scale_factor, 54 * self.scale_factor)
            self.qccodec.setMinimumContentsLength(7)
            for item in codecs:
                self.qccodec.addItem(item)
            self.qccodec.setCurrentIndex(codecindex)
            self.qccodec.activated[str].connect(self.onActivatedcc)

        def onActivatedcc(self, text):
            self.config.read(self.configf)
            self.config.set('settings', 'codec', text)
            self.write_config()
            self.read_defaults()
            self.qcbitrate.clear()
            if self.codecconf == 'wav':
                bitrates = ['None']
                bitrateindex = 0
            else:
                self.configurations.chk_config()
                self.read_defaults()
                bitrates = [
                    '128',
                    '160',
                    '192',
                    '224',
                    '256',
                    '320',
                    '500'
                    ]
                bitrateindex = bitrates.index(self.bitrateconf)
            self.qcbitrate.move(180 * self.scale_factor,
                                88 * self.scale_factor)
            for item in bitrates:
                self.qcbitrate.addItem(item)
            self.qcbitrate.setCurrentIndex(bitrateindex)
            self.qcbitrate.activated[str].connect(self.onActivatedbt)

        def onActivatedbt(self, text):
            self.config.read(self.configf)
            self.config.set('settings', 'bitrate', text)
            self.write_config()
            self.read_defaults()

        def onActivatedsr(self, text):
            self.config.read(self.configf)
            self.config.set('settings', 'samplerate', text)
            self.write_config()
            self.read_defaults()

        def onActivatednotify(self, text):
            self.config.read(self.configf)
            self.config.set('settings', 'notifications', text)
            self.write_config()
            self.read_defaults()

        def onActivatedcolors(self, text):
            self.config.read(self.configf)
            self.config.set('settings', 'colors', text)
            self.write_config()
            self.read_defaults()

        def onActivatedatlaunch(self, text):
            self.config.read(self.configf)
            self.config.set('settings', 'searchatlaunch', text)
            self.write_config()
            self.read_defaults()

        def onActivatedalsadevice(self, text):
            self.config.read(self.configf)
            if not text:
                self.config.set('settings', 'alsadevice', None)
            else:
                self.config.set('settings', 'alsadevice', text)
            self.write_config()
            self.read_defaults()

        def read_defaults(self):
            self.backend_conf = ConfigSectionMap('settings')['backend']
            self.codecconf = ConfigSectionMap('settings')['codec']
            if self.backend_conf == 'node' and self.codecconf != 'mp3':
                self.config.read(self.configf)
                self.config.set('settings', 'codec', 'mp3')
                self.write_config()
                self.codecconf = ConfigSectionMap('settings')['codec']
            self.bitrateconf = ConfigSectionMap('settings')['bitrate']
            self.samplerateconf = ConfigSectionMap('settings')['samplerate']
            self.notifconf = ConfigSectionMap('settings')['notifications']
            self.searchcolorsconf = ConfigSectionMap('settings')['colors']
            self.satlaunchconf = ConfigSectionMap('settings')['searchatlaunch']
            self.alsadeviceconf = ConfigSectionMap('settings')['alsadevice']
            if debug is True:
                print(self.backend_conf, self.codecconf, self.bitrateconf,
                      self.samplerateconf, self.notifconf,
                      self.satlaunchconf, self.searchcolorsconf,
                      self.alsadeviceconf)

        def write_config(self):
            """This method writes to configfile"""
            with open(self.configf, 'w') as configfile:
                    self.config.write(configfile)
Exemplo n.º 12
0
class MazeWalkerWidget(cw.CustomWidget):
    def __init__(self, parent=None):
        """
        Constructor
        """
        idp_hooks.register_rename_callback(self._rename_hook)

        cw.CustomWidget.__init__(self)
        self.name = "Execution Tree"
        self.parent = parent
        self.icon = QIcon(Config().icons_path + 'radar-icon.png')

        # Functionality associated with this widget
        self.ma = parent.maze_analysis

        self._createGui()

    def _createGui(self):

        self._createLayout()
        self._createToolBar('Maze')
        self._createToolBarActions()
        self._createExecutionTree()

        # Output Layout
        self.main_splitter.addWidget(self.ExecutionTreeWG)

    def _createLayout(self):
        """
        This creates the basic layout:
        Buttons & Outputs
        """

        # Layouts (This is a common disposition)
        main_layout = QtWidgets.QHBoxLayout()

        # Output Layout Inner (QSplitter)
        self.main_splitter = QSplitter(QtCore.Qt.Horizontal)

        # Nested layouts
        main_layout.addWidget(self.main_splitter)

        self.central_widget.setLayout(main_layout)

    def _createExecutionTree(self):

        layout = QtWidgets.QVBoxLayout()
        self.ExecutionTreeWG = QtWidgets.QWidget()
        self.ExecutionTreeWG.setLayout(layout)

        self.filter_qbox = QComboBox()
        self.filter_qbox.setSizeAdjustPolicy(QComboBox.AdjustToContents)
        self.filter_qbox.currentIndexChanged.connect(self._tag_filter)

        self.execution_tree = Maze()
        maze = self._load_maze_from_idb()
        if maze is not None:
            self.execution_tree.init_maze(json.loads(maze)[0], True)
            for tag in self.execution_tree.tags:
                self.filter_qbox.addItem(tag)

        layout.addWidget(self.filter_qbox)
        layout.addWidget(self.execution_tree)

    def _createToolBarActions(self):

        self.addMazeLog = QtWidgets.QAction(QIcon(Config().icons_path +
                                                  'add-icon.png'),
                                            '&Open Maze Log',
                                            self,
                                            triggered=self._addMazeLog)

        self.reloadMazeLog = QtWidgets.QAction(QIcon(Config().icons_path +
                                                     'arrow-rotate.png'),
                                               '&Reload Maze Log',
                                               self,
                                               triggered=self._ReloadMazeLog)

        self.toolbar.addAction(self.addMazeLog)
        self.toolbar.addAction(self.reloadMazeLog)

    def _store_maze_in_idb(self, maze):
        name = "$ com.mazewalker"
        store = idaapi.netnode(name, 0, True)
        store.setblob(maze, 0, "N")

    def _load_maze_from_idb(self):
        name = "$ com.mazewalker"
        store = idaapi.netnode(name, 0, True)
        return store.getblob(0, 'N')

    def _addMazeLog(self):
        maze_file = idc.AskFile(0, '*.json', 'Select the Maze...')
        if maze_file is not None:
            with open(maze_file, 'r') as fd:
                maze = fd.read()
                self._store_maze_in_idb(maze)
                self.filter_qbox.clear()

                self.execution_tree.init_maze(json.loads(maze)[0])
                for tag in self.execution_tree.tags:
                    self.filter_qbox.addItem(tag)

    def _ReloadMazeLog(self):
        self.execution_tree.reload_tree()

    def _tag_filter(self, index):
        self.execution_tree.fileter_by_tag(
            str(self.filter_qbox.itemText(index)))

    def _rename_execution_tree_node(self, root, new_name, old_name):
        if root.text(0) == old_name:
            root.setText(0, new_name)
        count = root.childCount()
        for i in range(count):
            self._rename_execution_tree_node(root.child(i), new_name, old_name)

    def _rename_hook(self, ea, new_name):
        if len(new_name) > 0:
            fname = idc.GetFunctionName(ea)
            if len(fname) == 0:
                fname = "0x%x" % ea
            root = self.execution_tree.invisibleRootItem()
            self._rename_execution_tree_node(root, new_name, fname)
            return 1
Exemplo n.º 13
0
class Set(QDialog):
    def __init__(self, father):
        super().__init__(father, Qt.WindowCloseButtonHint)
        self.father = father

        self.setObjectName('set')
        self.setWindowTitle('设置')
        self.setWindowIcon(QIcon('image/set.ico'))
        self.move_pos = [
            self.father.desktop_resolving[0] // 2 - 300,
            self.father.desktop_resolving[1] // 2 - 200
        ]
        self.size_ = [600, 400]
        self.setGeometry(*self.move_pos, *self.size_)

        combobox_frame = QFrame(self)
        api_label = QLabel('接口', combobox_frame)
        api_label.setProperty('cate', 'combo_label')
        api_label.setAlignment(Qt.AlignCenter)
        self.api_choose = QComboBox(self)
        self.api_choose.setToolTip('选择寻找壁纸的网站')
        self.api_choose.currentTextChanged.connect(
            lambda: self.set_change('api'))
        api_list_view = QListView()
        api_list_view.entered.connect(self.show_name)
        self.api_choose.setView(api_list_view)

        category_label = QLabel('分类', combobox_frame)
        category_label.setProperty('cate', 'combo_label')
        category_label.setAlignment(Qt.AlignCenter)
        self.category_choose = QComboBox(self)
        self.category_choose.setToolTip('选择壁纸类型')
        self.category_choose.currentTextChanged.connect(
            lambda: self.set_change('cate'))
        category_list_view = QListView()
        category_list_view.entered.connect(self.show_name)
        self.category_choose.setView(category_list_view)

        grid_1 = QGridLayout()
        grid_1.setContentsMargins(0, 30, 0, 30)
        grid_1.setSpacing(0)
        grid_1.addWidget(api_label, 0, 0, 1, 1)
        grid_1.addWidget(category_label, 0, 1, 1, 1)
        grid_1.addWidget(self.api_choose, 1, 0, 1, 1)
        grid_1.addWidget(self.category_choose, 1, 1, 1, 1)
        combobox_frame.setLayout(grid_1)

        remain_frame = QFrame(self)

        switch_label = QLabel('自动切换', remain_frame)
        switch_label.setProperty('cate', 'indicate_label')
        self.switch_list = [
            "从不", "30秒", "1分钟", "5分钟", "10分钟", "30分钟", "1小时", "2小时", "5小时",
            "10小时"
        ]
        self.true_switch_list = [
            0, 30, 60, 300, 600, 1800, 3600, 7200, 18000, 36000
        ]
        self.switch_slider = QSlider(Qt.Horizontal, self)
        self.switch_slider.setToolTip('自动切换壁纸')
        self.switch_slider.setMaximum(9)
        self.switch_slider.setValue(
            self.true_switch_list.index(self.father.config['switch']))
        self.switch_slider.valueChanged.connect(
            lambda: self.set_change('switch'))
        self.switch_show = QLabel(
            self.switch_list[self.true_switch_list.index(
                self.father.config['switch'])], remain_frame)

        size_label = QLabel('大小限制', remain_frame)
        size_label.setProperty('cate', 'indicate_label')
        self.size_list = ["不限制", "500K", "1M", "2M", "5M", "10M", "20M"]
        self.true_size_list = [0, 500, 1000, 2000, 5000, 10000, 20000]
        self.size_slider = QSlider(Qt.Horizontal, self)
        self.size_slider.setToolTip('限制图片大小')
        self.size_slider.setMaximum(6)
        self.size_slider.setValue(
            self.true_size_list.index(self.father.config['length']))
        self.size_slider.valueChanged.connect(lambda: self.set_change('size'))
        self.size_show = QLabel(
            self.size_list[self.true_size_list.index(
                self.father.config['length'])], remain_frame)

        self.show_windmill = QCheckBox('桌面显示风车', self)
        self.show_windmill.setToolTip('桌面显示切换风车')
        self.show_windmill.setCheckState(self.father.config['show_windmill'])
        self.show_windmill.stateChanged.connect(
            lambda: self.set_change('show_windmill'))

        random_switch_frame = QFrame(self)
        random_switch_label = QLabel('随机切换', random_switch_frame)
        random_switch_label.setAlignment(Qt.AlignCenter)
        random_switch_label.setProperty('cate', 'head_label')
        self.random_switch = PartFrame(self, self.father, 'random_switch',
                                       random_switch_frame)
        self.random_switch.setToolTip('随机切换壁纸')
        self.random_switch.set_part([
            [
                '从不', '顺序切换',
                'border-right: 1px solid;border-top-left-radius: 10px;border-top-right-radius: 0;border-bottom-right-radius: 0;border-bottom-left-radius: 10px;'
            ],
            [
                '一类', '每一次切换都是随机分类(仅分类选项为随机时可用)',
                'border-right: 1px solid;border-radius: 0;'
            ],
            [
                '一页', '每一页的壁纸顺序都被打乱',
                'border: 0px solid;border-top-left-radius: 0;border-top-right-radius: 10px;border-bottom-right-radius: 10px;border-bottom-left-radius: 0;'
            ]
        ])
        random_switch_frame.setFixedSize(122, 57)
        self.random_switch.move(0, 25)

        play_what_frame = QFrame(self)
        play_what_label = QLabel('选壁纸源', play_what_frame)
        play_what_label.setAlignment(Qt.AlignCenter)
        play_what_label.setProperty('cate', 'head_label')
        self.play_what = PartFrame(self, self.father, 'play_what',
                                   play_what_frame)
        self.play_what.setToolTip('选择壁纸源')
        self.play_what.set_part([
            [
                '网络', '网络壁纸',
                'border-right: 1px solid;border-top-left-radius: 10px;border-top-right-radius: 0;border-bottom-right-radius: 0;border-bottom-left-radius: 10px;'
            ], ['收藏', '已收藏的壁纸', 'border-right: 1px solid;border-radius: 0;'],
            [
                '本地', '本地壁纸(右键选择文件夹)',
                'border-left: 0px solid;border-top-left-radius: 0;border-top-right-radius: 10px;border-bottom-right-radius: 10px;border-bottom-left-radius: 0;'
            ]
        ])
        play_what_frame.setFixedSize(122, 57)
        self.play_what.move(0, 25)

        self.auto_start = QCheckBox('开机自动启动', self)
        self.auto_start.setToolTip('设置软件开机自启')
        self.auto_start.setCheckState(self.father.config['auto_start'])
        self.auto_start.stateChanged.connect(
            lambda: self.set_change('auto_start'))

        grid_2 = QGridLayout()
        grid_2.addWidget(switch_label, 0, 0, 1, 1)
        grid_2.addWidget(size_label, 1, 0, 1, 1)
        grid_2.addWidget(self.switch_slider, 0, 1, 1, 2)
        grid_2.addWidget(self.size_slider, 1, 1, 1, 2)
        grid_2.addWidget(self.switch_show, 0, 3, 1, 1)
        grid_2.addWidget(self.size_show, 1, 3, 1, 1)

        grid_2.addWidget(self.show_windmill, 2, 0, 1, 2)
        grid_2.addWidget(self.auto_start, 2, 2, 1, 2)
        grid_2.addWidget(random_switch_frame, 3, 0, 1, 2)
        grid_2.addWidget(play_what_frame, 3, 2, 1, 2)
        remain_frame.setLayout(grid_2)

        right_frame = QFrame(self)

        self.logo_label = AnimalLabel(self, self.father)
        self.logo_label.setToolTip('随机选项')
        self.logo_label.setObjectName('logo')

        resolution_label = QLabel('分辨率', right_frame)
        resolution_label.setStyleSheet('QLabel{max-width: 1000px;}')
        resolution_label.setAlignment(Qt.AlignCenter)
        resolution_label.setToolTip('依据这个最小分辨率筛选')
        self.width_edit = QLineEdit(str(self.father.config['resolving'][0]),
                                    right_frame)
        self.width_edit.setMaxLength(5)
        self.width_edit.setAlignment(Qt.AlignCenter)
        self.width_edit.editingFinished.connect(self.submit_resolution)
        self.height_edit = QLineEdit(str(self.father.config['resolving'][1]),
                                     right_frame)
        self.height_edit.setMaxLength(5)
        self.height_edit.setAlignment(Qt.AlignCenter)
        self.height_edit.editingFinished.connect(self.submit_resolution)
        resolution_mid = QLabel('x', right_frame)
        resolution_mid.setStyleSheet('QLabel{max-width: 1000px;}')
        resolution_mid.setAlignment(Qt.AlignCenter)

        clear_button = QPushButton('清空黑名单', right_frame)
        clear_button.setToolTip('清空不喜欢的图片')
        clear_button.clicked.connect(self.clear_list)
        self.update_button = QPushButton('更新接口', right_frame)
        self.update_button.setToolTip('更新可用网站')
        self.update_button.clicked.connect(self.check_update)

        # 状态文字
        self.status_label = QLabel('', self)
        self.status_timer = 0
        self.status_label.setFont(QFont('微软雅黑', 14, QFont.Bold))
        self.status_label.setStyleSheet(
            'QLabel{max-width: 200px;min-width: 200px;color: #A55;}')
        # GitHub
        git_btn = GitLabel(self)

        grid_3 = QGridLayout()
        grid_3.setRowStretch(3, 2)
        grid_3.addWidget(self.logo_label, 0, 2, 1, 6)
        grid_3.addWidget(resolution_label, 1, 0, 2, 2)
        grid_3.addWidget(self.width_edit, 1, 2, 2, 2)
        grid_3.addWidget(resolution_mid, 1, 4, 2, 1)
        grid_3.addWidget(self.height_edit, 1, 5, 2, 2)
        grid_3.addWidget(clear_button, 3, 2, 2, 3)
        grid_3.addWidget(self.update_button, 3, 5, 2, 3)
        grid_3.addWidget(self.status_label, 5, 0, 1, 6)
        grid_3.addWidget(git_btn, 5, 6, 1, 1)
        grid_3.setAlignment(Qt.AlignCenter)
        right_frame.setLayout(grid_3)

        mid_label_0 = QLabel('', self)
        mid_label_0.setStyleSheet(
            'QLabel{background: qlineargradient(x1: 0, y1: 0,x2: 1,y2: 0, stop: 0 #FF0000, stop: 1 #0000FF);;max-height: 3px;min-height: 3px;max-width: 10000px;}'
        )
        mid_label_1 = QLabel('', self)
        mid_label_1.setStyleSheet(
            'QLabel{background: qlineargradient(x1: 0, y1: 0,x2: 0,y2: 1, stop: 0 #F0F, stop: 1 #FAA);;max-width: 3px;min-width: 3px;max-height: 10000px;}'
        )

        main_grid = QGridLayout()
        main_grid.setColumnStretch(0, 1)
        main_grid.setColumnStretch(1, 1)
        main_grid.setColumnStretch(2, 1)
        main_grid.setContentsMargins(0, 0, 0, 0)
        main_grid.setSpacing(0)

        main_grid.addWidget(combobox_frame, 0, 0, 1, 1)
        main_grid.addWidget(mid_label_0, 1, 0, 1, 1)
        main_grid.addWidget(remain_frame, 2, 0, 2, 1)
        main_grid.addWidget(mid_label_1, 0, 1, 4, 1)
        main_grid.addWidget(right_frame, 0, 2, 4, 1)
        self.setLayout(main_grid)

        self.timer = QTimer()
        self.interval = 13
        self.timer.setInterval(self.interval)
        self.timer.start()
        self.timer.timeout.connect(self.rotate)

        self.remain_cate_random = False
        self.load_api()

    def load_api(self):
        for api in self.father.all_api:
            pix = QPixmap()
            if api == '随机':
                pix.loadFromData(
                    QByteArray.fromBase64(
                        b'iVBORw0KGgoAAAANSUhEUgAAADEAAAAxCAYAAABznEEcAAAJk0lEQVRoge2ZC4yU1RXHf+ebbx7s8lwW1FUR8AUoWqIg1keDUWyqaKk1TYltpUTbao1N2rS2xlhNrCFWrcRaaa2Vttr6SCvah1DEBwq1UKSgBhTBCvJeYd87j+87zb33m5lvl2F3ZwU1qWczOzPf3O/e//+cc8/53xk+sY+JCbeqQXIScDNwDpAqQdMYSKlwrb8m/biv6z1twEPAj4HQByYAi4GGLsO6gz0Y4LvP1R8yzuqAm4AxwJWGxF29EjhUplUQqTz2CmCRB5z5kRCIr9fXNSuP+6whUehl0Idj/SdS8D4WBD6geR8rAhrlRb6627w+jKkORDU53t0COGtMwNQxAeTc+wOuEzPvA0VBewDeHzIFOHd0wLNf7WDuRVkOH6SQNZ2g59vK6XSoUqqvc0fjOvNCwhOumZzn2dntXHt2jlQCFxntNj4yr4sni/mYjR656Fq4/2JVk9bYcyGau7hOvjxnceqWnDCiVvnJ+VkWXtHG9HEFl14V9otc/kS+8VuTC3XGA805oSMv7GoTtjS5x6a9wqZ9QltrRMa0x0Q/CETO8GvgmCHKuHo4ZqgyeqhSX6M2dTRUGgaHjBoakg+UUM0tStoPCVVZuN7nnuUZXt+WcBh8O/sC/+ghyrRRAe2BR8IDTzz7mSAWc0dB2NIsrH5PWLLJY9FGYVtjlIjJPoDPu8XOHqvMHK9MG6OMGaYMSSsShccALRjAquQCJRsIIm4CsSnmoRIyc3yB88a28ttXU9z3Spo9zR6kwS+EkFOho+CAe2KIiO3wHmKJHT8MxtUpsyYG7GoXHn9NmL/KY93WHiKTdzLhslOU66YqZ49SEuJA50LoLBjwYoFbOqr2vSolchL9F1FUhdYc+KJcO7WTSydkuWdFhofXZPDNQMNa7GApyRP7Sox3xC5aJDWiBq6dArMnhdy3UrjteWGfSbV0jEAnnNgAP70w5OIT3KVCNI/avHfADVjPRlwtCLGEHB4D2qyp4qJRxJkQF+H32z32dri65KcSYrOiJomNAtY70SaLRJfESOVDN/mAJHzv08pFJ8C3/yIs3RARycHMU2H+JcqIGufpoFQEnFdRE3FHw0uojbxaQtARiI2SJShF0ga8MDAV8t8mj/tfyfDg6jS5rFvTX79H+NMGn4wP6QQMzQjDB8CQDAxLl+NigASRd8zDRMjY+Hr46xXKVU8Jv18BV58L82dEuW4BSCk9jCU9KZWqlhzsaYH3WoS2vLCnDY6rD5lQb/ZFcWUYlIKWPPz632l+tjzF1kbP7cdUcczN2khAnc1rgWQCBqehboCrIJMOU84bC1OOhAGuGlgyxJSxZyMEC9cLM8ep3UdhrAQ7T7oLm/fBoo2wdLOwbjfsbBX2dkSD2uE75wfcOT3P3qza/pDwQp7Z6HH7CylWvRtVpfgeFBb4NoZeuY7nA2hsg8YW4a0d8PRa4dYkTBwJs05Rrp6s1GXKYS563Hj4ixPcrFqC7vLYTG8ifvuLsHCD0NQSeSARrV0MbxL8hLs0JA3/2Snc+XKaP6zzXY9IUdH8GCO6vI6rKoV1O+CHW4UHVwtzp5ty6YZpdGP33ueKhLs6fxXcsFjY1xIBScfW6WY1vtKah7kvJZn3zwTNbeLu6aGcC7doY3Tc69mKKKOOeeN5cMs0tykrTwymfH93McxbRqU02N8COHN0SHNWeH2LOOC9NVabTtVa0hG67e/YpnTHBfufHIt8b1gC85YAA/t4DE3Ais1RCqR7G1y2vkvxOIgcHDESLjy251suOBYOG1Hd+SBVBH8gGV7BqjtPBK6RfeY4eHGOcv7Yrroubua9Ibnk68qEI9x9vYrGHHzjtIB5MwoMzej+yrVfJDQSfTkH4sghcNclsOhrynF1TutUuiX++uQRjvCcqVEV6YycUQmcQm0arptcYNlVOeacUSAp0fqVLMoO34IMqOxSH4bXwmkNyhfGYQXcyFrKXd0MVy3JlbBrtbafmdemeT5wqfLNycpDrwrPvC283Rj7iqKYqjnoyLt5jEj8+cU5vnxKgVueS7JsU8KNq7CL/REDnaoclHar1w2AhkFw1GBl0uFwwnDl6MFSWslUHJHyuhJ1hpe2CD/4G9w9Q5nS0LXZOdmhnN4ApzcoTbmQtduF1TthaxO89b7r3obUuHq1jbOzoFYVTDky5M+zOnn0tQR3v5xi4w7PldxYDsn1i/KNd0/P13UEnlPXCSERg2iCFIRdZGEkxsSJMeCJN2DOk0JzExxRD499yajWOIFyVIrdu9jBzRXj+UKoRlLZc4SR4+bPpKt1hig1yZDtrfDAqiTzV6bL/UNY4BXTwOl4aMsbnaK0FaC9YK7vn/tGVhgQzVn4/j+Ey/8oNJtcr4XtzXDBQ8IvVjmGFmyMgPlvotkRuPnNOuYYYBRuruA+c6SLFJUwhKZOIwCVG87N8vRXWrnsUzkyCScbPI0OJe4UFfNYlAJxeZHylKSntOVgwRrhjF8JdzxP/JRl+0hnANc8CRf+Tli+xZFOGuKeloCVNqC61AvVRU1jn5dHaYl8U1Y4sT7gNzNbuWlau8Xkd68nxTRJWMAmtVwry4fKul0eT22AR9Z6vLE9ystKTSnqzovXw3ObPT4/Xpk9STlrFAxOldcz3rd7LHJWMe2KwFXLGq3YUAelQna0Cr9cVcMja9PkQsE3gitpzwduI5mbOgpqW/+uVuHNRmH1dmHle8LKbUK+IwJ5ADHWxdKQV3h8jTsNjq2Hc0aFTD3KSPiQ0cOMYnZqdYCvNiNM+przRDwi5qkmqTbCj72W4q7lGd7eGclxD+T4e4PGk0dqnQllS9YdAU3+7W53z2E2coMXpUx/v47XqJQXO3ESRg6CYRllcAYOH6hoQZlxUsCsiQWbsoaUSd9kQnnhHY+5y9Isf8fvXmoX+G/t9qzktiaxuBUlcl883hcrLlxcXGFXM+xqirxiSlMWRteH+KeC5ym1vrKhUbj3lRQPr0mRz1fG4++nLoGK3fRgm1ReN+1DRkJ2F4R7VphvNZLsbYnKaa/nibgdzJ+2qjWFJ9/0uXFJije2eQ5hpuc5zG92PZ8nDjWRbhq+vlbZYxpZEHNxz/twQe8qtv+/q/Vu3ecW2NNaUnV9W18OlE4VBlr7MH45jbu1jw6srmhWOr5VY9VEtS9jnf7yfPe1Wz9y5sNMs4pjSr8j29/sHi1f+IhNqiVAM3C/ado/Apa6Lzw/QjJ9jWxXjNeD/svsiX0gl4BeCXwO0XSX9JJDWGarTckygXdBHgVddPBBfWL/zwb8D/vnGgJlpdTcAAAAAElFTkSuQmCC'
                    ))
            else:
                pix.loadFromData(
                    QByteArray.fromBase64(eval('self.father.%s.b64_data' %
                                               api)))
            ico = QIcon(pix)
            ico.actualSize(QSize(22, 22))
            self.api_choose.addItem(ico, api)
        self.api_choose.setCurrentText(self.father.config['api'])

        if self.father.config['api'] != '随机':
            self.father.api = eval('self.father.%s' %
                                   self.father.config['api'])
            self.category_choose.addItems(self.father.api.cate)
            self.category_choose.setCurrentText(self.father.config['category'])
            if self.father.config['play_what'] != '网络':
                self.api_choose.setEnabled(False)
                self.category_choose.setEnabled(False)
        else:
            self.category_choose.addItem('随机')
            self.category_choose.setCurrentText('随机')

    def rotate(self):
        if self.status_timer > 0:
            self.status_timer -= 1
        elif not self.status_label.isHidden() and self.status_timer != -1:
            self.status_label.setText('')
        if self.logo_label.add == 0:
            return
        elif self.logo_label.add == 1:
            if self.interval > 2.5:
                self.interval -= 0.5
                self.timer.setInterval(self.interval)
        else:
            if self.interval < 15.5:
                self.interval += 0.5
                self.timer.setInterval(self.interval)
            else:
                self.logo_label.add = 0
        self.logo_label.angle = (self.logo_label.angle - 1) % 360
        self.logo_label.update()

    def set_change(self, what):
        if not self.father.initializing:
            if what == 'api':
                self.father.config['api'] = self.api_choose.currentText()
                if self.api_choose.currentText() != '随机':
                    # 保持一类随机
                    if self.father.config['random_switch'] == '一类':
                        self.remain_cate_random = True
                    else:
                        self.remain_cate_random = False
                    # 选择新api
                    exec('self.father.api = self.father.' +
                         self.api_choose.currentText())
                    self.category_choose.clear()
                    self.category_choose.addItems(self.father.api.cate)
                else:
                    self.category_choose.clear()
                    self.category_choose.addItem('随机')
                    self.category_choose.setCurrentText('随机')
            elif what == 'cate':
                self.father.config[
                    'category'] = self.category_choose.currentText()
                if self.category_choose.currentText(
                ) != '随机' and self.father.config[
                        'random_switch'] == '一类' and not self.remain_cate_random:
                    self.father.config['random_switch'] = '一页'
                    for c in self.random_switch.children():
                        if c.name == '一页':
                            c.set_active()
                try:
                    # 选择新的分类
                    self.father.api.img_set, self.father.api.img_idx = [], 0
                except:
                    pass
            elif what == 'switch':
                value = self.switch_slider.value()
                self.switch_show.setText(self.switch_list[value])
                self.father.config['switch'] = self.true_switch_list[value]
                self.father.switch_frame.step_time = 0
            elif what == 'size':
                value = self.size_slider.value()
                self.size_show.setText(self.size_list[value])
                self.father.config['length'] = self.true_size_list[value]
            elif what == 'show_windmill':
                self.father.config[
                    'show_windmill'] = self.show_windmill.checkState()
                if self.show_windmill.checkState() == 0:
                    self.father.hide()
                else:
                    self.father.show()
            elif what == 'auto_start':
                if auto_start(int(self.auto_start.checkState()),
                              self.father.my_path):
                    self.father.config[
                        'auto_start'] = self.auto_start.checkState()

            self.father.dump_data('config')

    def clear_list(self):
        for api in self.father.data['api']:
            self.father.data['api'][api]['hate_list'] = []
        self.father.dump_data('data')
        self.status_label.setText('清理完成')
        self.status_timer = 200

    def check_update(self):
        self.status_label.setText('检查中...')
        self.status_timer = -1
        self.update_button.setEnabled(False)
        Thread(target=self.check_update_main).start()

    def check_update_main(self):
        try:
            r = ''.join(
                get('https://github.com/yunyuyuan/invoker/tree/master/pyqt/wallpaper%20switcher/api'
                    ).content.decode().split())
            api_list = findall(
                r'<aclass="js-navigation-open"title="(.*?)\.py"', r)
        except:
            dump_log('检查更新' + '--->' + ':失败')
            self.status_label.setText('检查失败')
            self.status_timer = 200
            return
        self.not_download = []
        for new in api_list:
            if new not in self.father.all_api and new not in [
                    '__init__', 'LocalWallpaper_'
            ]:
                self.not_download.append(new)
        # 下载
        if self.not_download:
            self.status_label.setText('%s个更新,下载中-0个' %
                                      str(len(self.not_download)))
            self.status_timer = -1
            for api in self.not_download:
                Thread(target=self.download_api, args=(api, )).start()
        else:
            self.status_label.setText('暂无更新')
            self.status_timer = 200
            self.update_button.setEnabled(True)

    def download_api(self, api, err_count=0):
        r = get(
            'https://raw.githubusercontent.com/yunyuyuan/invoker/master/pyqt/wallpaper%%20switcher/api/%s.py'
            % api)
        if r.ok:
            with open('api/%s.py' % api, 'wb') as fp:
                fp.write(r.content)
                fp.close()
                self.father.data['api'][api] = {}
                self.father.data['api'][api]['ignore_list'] = []
                self.father.data['api'][api]['like_list'] = []
                self.father.data['api'][api]['hate_list'] = []
                self.father.dump_data('data')
                lock.acquire()
                num = int(
                    search('下载中.(\d*)个',
                           self.status_label.text()).group(1)) + 1
                self.status_label.setText('%s个更新,下载中-%s个' %
                                          (str(len(self.not_download)), num))
                self.status_timer = -1
                if num == len(self.not_download):
                    self.status_label.setText('下载完成,重启软件生效')
                    self.status_timer = 200
                    self.update_button.setEnabled(True)
                lock.release()
        elif err_count < 5:
            dump_log('更新api' + '--->' + ':出错')
            self.download_api(api, err_count + 1)

    def submit_resolution(self):
        try:
            w, h = int(self.width_edit.text()), int(self.height_edit.text())
            if 100 <= w <= 10000 and 100 <= h <= 10000:
                self.father.resolving = [w, h]
                self.father.config['resolving'] = self.father.resolving
                self.father.dump_data('config')
                self.status_label.setText('更新成功!')
                self.status_timer = 200
            else:
                raise ValueError
        except ValueError:
            self.status_label.setText('请输入3-5位数字!')
            self.status_timer = 200

    # 显示选择的api和分类
    def show_name(self, idx):
        self.status_label.setText(idx.data())
        self.status_timer = 200
Exemplo n.º 14
0
class MusicPreviewWidget(QWidget):
    def __init__(self, parent=None):
        super(MusicPreviewWidget, self).__init__(parent)
        self._lastbuildtime = 10.0
        self._running = None
        self._current = None

        self._chooserLabel = QLabel()
        self._chooser = QComboBox(self, activated=self.selectDocument)
        self._log = log.Log()
        self._view = popplerview.View()
        self._progress = widgets.progressbar.TimedProgressBar()

        self._stack = QStackedLayout()
        self._top = QWidget()

        layout = QVBoxLayout()
        self.setLayout(layout)

        layout.addWidget(self._top)
        layout.addLayout(self._stack)
        layout.addWidget(self._progress)

        top = QHBoxLayout()
        top.setContentsMargins(0, 0, 0, 0)
        top.setSpacing(2)
        self._top.setLayout(top)
        top.addWidget(self._chooserLabel)
        top.addWidget(self._chooser)
        top.addStretch(1)

        self._stack.addWidget(self._log)
        self._stack.addWidget(self._view)

        self._top.hide()
        app.aboutToQuit.connect(self.cleanup)
        app.translateUI(self)

    def translateUI(self):
        self._chooserLabel.setText(_("Document:"))

    def preview(self, text, title=None):
        """Runs LilyPond on the given text and shows the resulting PDF."""
        j = self._running = MusicPreviewJob(text, title)
        j.done.connect(self._done)
        self._log.clear()
        self._log.connectJob(j)
        j.start()
        self._progress.start(self._lastbuildtime)

    def _done(self, success):
        self._progress.stop(False)
        pdfs = self._running.resultfiles()
        self.setDocuments(pdfs)
        if not pdfs:
            self._stack.setCurrentWidget(self._log)
            return
        self._lastbuildtime = self._running.elapsed_time()
        self._stack.setCurrentWidget(self._view)
        if self._current:
            self._current.cleanup()
        self._current = self._running # keep the tempdir
        self._running = None

    def setDocuments(self, pdfs):
        """Loads the given PDF path names in the UI."""
        self._documents = [popplertools.Document(name) for name in pdfs]
        self._chooser.clear()
        self._chooser.addItems([d.name() for d in self._documents])
        self._top.setVisible(len(self._documents) > 1)
        if pdfs:
            self._chooser.setCurrentIndex(0)
            self.selectDocument(0)
        else:
            self._view.clear()

    def selectDocument(self, index):
        doc = self._documents[index].document()
        if doc:
            self._view.load(doc)

    def cleanup(self):
        if self._running:
            self._running.abort()
            self._running.cleanup()
            self._running = None
        if self._current:
            self._current.cleanup()
            self._current = None
        self._stack.setCurrentWidget(self._log)
        self._top.hide()
        self._view.clear()

    def print_(self):
        """Prints the currently displayed document."""
        if self._documents:
            doc = self._documents[self._chooser.currentIndex()]
            import popplerprint
            popplerprint.printDocument(doc, self)
Exemplo n.º 15
0
class SqliteDbTableEditer(QWidget):
    #Db=sqlite3.connect("test.db")
    def __init__(self,dbPath,tblName='',parent=None):

        self.app=QApplication(sys.argv)
        self.SqliteDbTypes=['integer','real','text','blob']
        self.DbPath,self.CurrentTable=dbPath,tblName
        #连接数据库
        self.Db=sqlite3.connect(self.DbPath)
        #构建Gui组件
        super(SqliteDbTableEditer,self).__init__(parent)
        self.setWindowTitle('Sqlite数据库表修改器')
        screen=QDesktopWidget().availableGeometry(0)
        self.setGeometry(screen.width()/3/2-1,
                         screen.height()/5/2-1,
                         screen.width()*2/3,
                         screen.height()*4/5
                         )
        #lay
        lay=QVBoxLayout()
        self.setLayout(lay)
        #数据库表设置控件
        ##layDb
        layDb=QHBoxLayout()
        lay.addLayout(layDb)
        ###lblDb
        lblDb=QLabel('数据库:')
        layDb.addWidget(lblDb)
        ###self.leDb
        self.leDb=QLineEdit()
        self.leDb.setText(self.DbPath)
        layDb.addWidget(self.leDb)
        ###btnDb
        btnChangeDb=QPushButton('浏览')
        btnChangeDb.clicked.connect(self.btnChangeDb_Clicked)
        layDb.addWidget(btnChangeDb)
        ###lblTbl
        lblTbl=QLabel('数据表:')
        layDb.addWidget(lblTbl)
        ###self.cbbTbls
        self.cbbTbls=QComboBox()
        tbls=list(map(lambda x:x[1],
                      list(filter(lambda x:x[0]=='table',
                                  self.Db.execute(
                                      'Select * From sqlite_master'
                                      ).fetchall()
                                  )
                           )
                      )
                  )
        self.cbbTbls.addItems(tbls)
        if self.CurrentTable!='' :
            self.cbbTbls.setCurrentIndex(tbls.index(self.CurrentTable))
        else:
            self.CurrentTable=tbls[0]
            self.makeTableInfo()
            self.cbbTbls.setCurrentIndex(0)
        layDb.addWidget(self.cbbTbls)
        ###lblRename
        lblRename=QLabel('重命名为:')
        layDb.addWidget(lblRename)
        ###self.leRename
        self.leRename=QLineEdit()
        self.leRename.setFixedWidth(100)
        layDb.addWidget(self.leRename)
        ###btnRename
        btnRenameTable=QPushButton('重命名')
        btnRenameTable.clicked.connect(self.btnRenameTable_Clicked)
        layDb.addWidget(btnRenameTable)
        ###btnDeleteTable
        btnDeleteTable=QPushButton('删除表')
        btnDeleteTable.clicked.connect(self.btnDeleteTable_Clicked)
        layDb.addWidget(btnDeleteTable)
        ###btnShow
        self.btnShow=QPushButton('查看表结构')
        self.btnShow.clicked.connect(self.btnShow_Clicked)
        layDb.addWidget(self.btnShow)
        ###设置TableView控件self.tv,以呈现表数据
        self.tv=QTableView()
        lay.addWidget(self.tv)
        ###self.model基本初始化
        self.model=QSqlTableModel(self,QSqlDatabase.addDatabase('QSQLITE'))
        self.model.setEditStrategy(QSqlTableModel.OnFieldChange)
        ###self.tv链接到数据源
        self.tv.setModel(self.model)
        ###self.model数据初始化
        self.model.database().setDatabaseName(self.DbPath)
        self.model.database().open()
        self.model.setTable(self.CurrentTable)
        self.model.select()
        self.cbbTbls.currentIndexChanged.connect(self.changeTable)
        ##layBtns
        layBtns=QHBoxLayout()
        lay.addLayout(layBtns)
        ###btnAddColumn
        btnAddColumn=QPushButton('添加列')
        btnAddColumn.setToolTip('给当前表添加列')
        btnAddColumn.clicked.connect(self.btnAddColumn_Clicked)
        layBtns.addWidget(btnAddColumn)
        ###btnDeleteColumn
        btnDeleteColumn=QPushButton('删除列')
        btnDeleteColumn.setToolTip('删除当前表的列')
        btnDeleteColumn.clicked.connect(self.btnDeleteColumn_Clicked)
        layBtns.addWidget(btnDeleteColumn)
        ###btnRenameColumn
        btnRenameColumn=QPushButton('重命名列')
        btnRenameColumn.setToolTip('重命名当前表的列')
        btnRenameColumn.clicked.connect(self.btnRenameColumn_Clicked)
        layBtns.addWidget(btnRenameColumn)
        ###btnModifyColumnType
        btnModifyColumnType=QPushButton('修改列数据类型')
        btnModifyColumnType.setToolTip('修改当前表的列的数据类型')
        btnModifyColumnType.clicked.connect(self.btnModifyColumnType_Clicked)
        layBtns.addWidget(btnModifyColumnType)
        ###btnModifyColumnConstraint
        btnModifyColumnConstraint=QPushButton('修改列约束')
        btnModifyColumnConstraint.setToolTip('修改当前表的列的约束')
        btnModifyColumnConstraint.clicked.connect(
            self.btnModifyColumnConstraint_Clicked)
        layBtns.addWidget(btnModifyColumnConstraint)
        ###btnOrderColumns
        btnOrderColumns=QPushButton('调整列顺序')
        btnOrderColumns.setToolTip('调整当前表的列的顺序')
        btnOrderColumns.clicked.connect(self.btnOrderColumns_Clicked)
        layBtns.addWidget(btnOrderColumns)
        ###btnModifyTableStruct
        btnModifyTableStruct=QPushButton('修改表结构')
        btnModifyTableStruct.setToolTip('功能:1.增加列;2.删除列;'
                                        +'3.修改列名;4.修改列类型;'
                                        +'5.修改列约束;6.调整列顺序'
                                        )
        btnModifyTableStruct.clicked.connect(self.btnModifyTableStruct_Clicked)
        layBtns.addWidget(btnModifyTableStruct)
        ###btnInsertRow
        btnInsertRow=QPushButton('插入行')
        btnInsertRow.setToolTip('将在数据表最后增加一行新记录')
        btnInsertRow.clicked.connect(self.btnInsertRow_Clicked)
        layBtns.addWidget(btnInsertRow)
        ###btnDeleteRows
        btnDeleteRows=QPushButton('删除行')
        btnDeleteRows.setToolTip('删除所有选中项所在的行')
        btnDeleteRows.clicked.connect(self.btnDeleteRows_Clicked)
        layBtns.addWidget(btnDeleteRows)
        ###btnQuery
        btnQuery=QPushButton('查询数据')
        btnQuery.setToolTip('对当前表或数据库进行查询,查询语句将被直接链接到self.model上')
        btnQuery.clicked.connect(self.btnQuery_Clicked)
        layBtns.addWidget(btnQuery)

        self.show()
        self.app.exec_()

    def __del__(self):
        #销毁多余数据库连接
        #self.Db.commit()
        self.Db.close()
    #----------------------------------------------------------------
    def makeTableInfo(self):
        #table_info=self.Db.execute('pragma table_info(%s)'%self.CurrentTable).fetchall()
        paragmastr="pragma table_info( '" + self.CurrentTable + "' ) "
        table_info=self.Db.execute(paragmastr).fetchall()
        self.columnsCount=len(table_info)
        self.columnsName=list(map(lambda x:x[1],table_info))
        self.columnsType=list(map(lambda x:x[2],table_info))
        dbinfo=self.Db.execute('select * from sqlite_master').fetchall()
        for x in dbinfo:
            if x[0]=='table' and x[1]==self.CurrentTable:
                self.sqlStr=x[4]
                break
    def DeleteColumn(self,tableName,columnName,tempName=''):
        if tempName=='':
            #tempName==''表示直接删除对应的列并提交数据库更改
            tempName=tableName+'temp'
            sqlite_master_sql="select * from sqlite_master"
            sqlite_master=self.Db.execute(sqlite_master_sql).fetchall()
            createStr=filter(lambda x:x[0]=='table' and x[1]==tableName,
                             self.Db.execute('select * from sqlite_master').fetchall())[0][4]
            createStr=','.join(filter(lambda x:x.find(columnName)==-1,createStr.split(',')))
            newColumns=','.join(map(lambda x:x[1],self.Db.execute('Pragma table_info(%s)'%tableName).fetchall()))
            #将旧表重命名为临时表名
            self.Db.execute("Alter Table %s Rename To %s"%(tableName,tempName))
            #新建删除了指定列的数据表
            self.Db.execute(createStr)
            #将旧表的数据导入新表
            self.Db.execute('Insert Into %s Select %s From %s'%
                            (tableName,newColumns,tempName))
            #删除旧表
            self.Db.execute('Drop Table %s'%tempName)
    #----------------------------------------------------------------
    def btnChangeDb_Clicked(self,event):
        pt=QFileDialog.getOpenFileName(
            caption='请选择一个sqlite数据库文件:',
            filter='sqlite数据库文件 (*.db)',
            directory=os.path.dirname(self.DbPath)
            )
        p=pt[0]
        if platform.system()=='Windows':
            p=p.replace('/','\\')
        if os.path.exists(p):
            self.DbPath=p
            self.Db=sqlite3.connect(self.DbPath)
            tbls=map(lambda x:x[1],
                 filter(lambda x:x[0]=='table',
                        self.Db.execute(
                            'Select * From sqlite_master'
                            ).fetchall()
                        )
                 )
            self.cbbTbls.currentIndexChanged.disconnect(self.changeTable)
            self.cbbTbls.clear()
            self.cbbTbls.addItems(tbls)
            self.cbbTbls.currentIndexChanged.connect(self.changeTable)
            self.CurrentTable=tbls[0]
            self.cbbTbls.setCurrentIndex(0)
            self.leDb.setText(p)
            self.model.database().setDatabaseName(self.DbPath)
            self.model.database().open()
            self.model.setTable(self.CurrentTable)
            self.model.select()
    def changeTable(self,event):
        if self.CurrentTable!=self.cbbTbls.itemText(event):
            self.CurrentTable=self.cbbTbls.itemText(event)
            self.model.setTable(self.CurrentTable)
            self.model.select()
            self.makeTableInfo()
            self.btnShow.setText('查看表结构')
    def btnDeleteTable_Clicked(self,event):
        self.Db.execute('Drop Table %s'%self.CurrentTable)
        for i in range(self.cbbTbls.count()-1,-1,-1):
            if self.cbbTbls.itemText(i)==self.CurrentTable:
                self.cbbTbls.removeItem(i)
                break
        self.CurrentTable=self.cbbTbls.itemText(0)
        self.model.setTable(self.CurrentTable)
        self.model.select()
    def btnRenameTable_Clicked(self,event):
        if self.leRename.text()!='':
            if self.leRename.text()!=self.CurrentTable:
                try:
                    self.Db.execute('Alter Table %s Rename To %s'%
                                (self.CurrentTable,self.leRename.text())
                                )
                except sqlite3.OperationalError as e:
                    if e.message=='there is already another table or index with this name: %s'%self.leRename.text():
                        QMessageBox.information(self,'错误',
                            '抱歉,本数据库中以“'+self.leRename.text()+
                            '”为名称的表或索引已经存在,无法完'+
                            '成重命名,请重新输入一个名称',
                            '知道了')
                    else:
                        QMessageBox.information(self,'错误',
                            '抱歉,可能是因表名包含非法字符,故'+
                            '无法完成重命名,请重新输入表名',
                            '知道了')
                    self.leRename.setText('')
                    return
                self.CurrentTable=self.leRename.text()
                self.cbbTbls.setItemText(self.cbbTbls.currentIndex(),
                                         self.CurrentTable
                                         )
                self.model.clear()
                self.model.setQuery(QSqlQuery(
                    'Select * From %s'%self.CurrentTable))
                self.model.select()
                self.leRename.setText('')
        else:
            QMessageBox.information(self,'注意',
                '抱歉,你还没有输入当前表要修改成的表名\n\n'+
                '请先在文本框里输入当前表要重命名成的名字,再点击我',
                '知道了')
    def btnShow_Clicked(self,event):
        if self.btnShow.text()=='查看表结构':
            self.model.setTable('')
            self.model.setQuery(QSqlQuery(
                'pragma table_info(%s)'%self.CurrentTable))
            self.model.select()
            self.btnShow.setText('查看表数据')
        else:
            self.model.setTable(self.CurrentTable)
            self.model.select()
            self.btnShow.setText('查看表结构')
    #----------------------------------------------------------------
    def btnInsertRow_Clicked(self,event):
        self.dlg_InsertRow_Values=[]
        #self.dlg
        self.dlg=QDialog()
        self.dlg.setWindowTitle('插入数据行:')
        #lay
        lay=QVBoxLayout()
        self.dlg.setLayout(lay)
        #lblprompt
        lblprompt=QLabel(
            '请参照创建此表的Sql字符串:\n'+self.sqlStr+
            '\n设置各个字段的数据:')
        lay.addWidget(lblprompt)
        #layG
        layG=QGridLayout()
        lay.addLayout(layG)
        for i in range(len(self.columnsName)):
            #lbl
            lbl=QLabel(self.columnsName[i]+'('+self.columnsType[i]+'):')
            lbl.setAlignment(Qt.AlignRight)
            layG.addWidget(lbl,i,0)
            #le
            le=QLineEdit()
            layG.addWidget(le,i,1)
            if self.columnsType[i].lower() not in self.SqliteDbTypes:
                #cbb
                cbb=QComboBox()
                cbb.addItems(self.SqliteDbTypes)
                cbb.setCurrentIndex(2)
                cbb.setToolTip(
                    '此字段的数据类型不是sqlite标准数据'+
                    '类型,请设置其存储时的使用的sqlite数据类型')
                layG.addWidget(cbb,i,2)
                self.dlg_InsertRow_Values.append((le,cbb))
            else:
                self.dlg_InsertRow_Values.append((le,self.columnsType[i]))
        layG.setColumnStretch(1,1)
        #layH
        layH=QHBoxLayout()
        lay.addLayout(layH)
        #btnOk
        btnOk=QPushButton('确定')
        btnOk.clicked.connect(self.dlg_InsertRow_btnOk_Clicked)
        layH.addWidget(btnOk)
        #btnCancel
        btnCancel=QPushButton('取消')
        btnCancel.clicked.connect(self.dlg.close)
        layH.addWidget(btnCancel)
        self.dlg.show()
    def dlg_InsertRow_btnOk_Clicked(self,event):
        sqlStr="Insert Into %s Values("%self.CurrentTable
        for item in self.dlg_InsertRow_Values:
            if item[0].text()!='':
                if type(item[1])==QComboBox:
                    print (item[0].text(),item[1].currentText())
                else:
                    print (item[0].text(),item[1])
            else:
                pass
    def btnDeleteRows_Clicked(self,event):
        rs=list(map(lambda x:x.row(),self.tv.selectedIndexes()))
        if len(rs)==0:
            QMessageBox.information(self,'提醒','请先选中至少一行,再点击此按钮!')
            return
        for i in reversed(rs):
            self.model.removeRows(i,1)
        self.model.submitAll()
    def btnQuery_Clicked(self,event):
        sqltxt,ok=QInputDialog.getText(self,'查询语句设置',
           '参照创建此表的Sql字符串:\n'+self.sqlStr+
           '\n请输入要设置到self.model的查询语句:')
        if ok:
            self.model.setTable('')
            self.model.setQuery(QSqlQuery(sqltxt))
            self.model.select()
    #----------------------------------------------------------------
    def btnAddColumn_Clicked(self,event):
        self.dlgMake_AddColumn()
    def dlgMake_AddColumn(self,lay=None):
        if lay is None:
            self.dlg=QDialog(self)
            self.dlg.setWindowTitle('添加列:')
        else:
            ##self.grpAddColumn
            self.grpAddColumn=QGroupBox('添加列:')
            self.grpAddColumn.setCheckable(True)
            self.grpAddColumn.setChecked(True)
            lay.addWidget(self.grpAddColumn)
	###layAddColumn
        layAddColumn=QVBoxLayout()
        if lay is None:
            self.dlg.setLayout(layAddColumn)
        else:
            self.grpAddColumn.setLayout(layAddColumn)
        ####self.grpAddColumn_ByCmdArgs
        self.grpAddColumn_ByCmdArgs=QGroupBox('使用参数创建列:')
        self.grpAddColumn_ByCmdArgs.setCheckable(True)
        self.grpAddColumn_ByCmdArgs.setChecked(True)
        self.PreviousChecked=0
        self.grpAddColumn_ByCmdArgs.toggled.connect(
            self.grpAddColumn_ByCmd_toggled)
        layAddColumn.addWidget(self.grpAddColumn_ByCmdArgs)
        #####layAddColumn_ByCmdArgs
        layAddColumn_ByCmdArgs=QHBoxLayout()
        self.grpAddColumn_ByCmdArgs.setLayout(layAddColumn_ByCmdArgs)
        ####lblAddColumn_select
        lblAddColumn_name=QLabel('列名:')
        layAddColumn_ByCmdArgs.addWidget(lblAddColumn_name)
        ####self.leAddColumn_name
        self.leAddColumn_name=QLineEdit()
        self.leAddColumn_name.setFixedWidth(100)
        layAddColumn_ByCmdArgs.addWidget(self.leAddColumn_name)
        ######lblAddColumn_type
        lblAddColumn_type=QLabel('类型:')
        layAddColumn_ByCmdArgs.addWidget(lblAddColumn_type)
        ######self.cbbAddColumn_type
        self.cbbAddColumn_type=QComboBox()
        self.cbbAddColumn_type.addItems(self.SqliteDbTypes)
        self.cbbAddColumn_type.setCurrentIndex(0)
        self.cbbAddColumn_type.setEditable(True)
        layAddColumn_ByCmdArgs.addWidget(self.cbbAddColumn_type)
        ######lblAddColumn_constraint
        lblAddColumn_constraint=QLabel('约束字符串:')
        layAddColumn_ByCmdArgs.addWidget(lblAddColumn_constraint)
        ######self.leAddColumn_constraint
        self.leAddColumn_constraint=QLineEdit()
        layAddColumn_ByCmdArgs.addWidget(self.leAddColumn_constraint)
        ####self.grpAddColumn_ByCmdStr
        self.grpAddColumn_ByCmdStr=QGroupBox('使用sql字符串创建列:')
        self.grpAddColumn_ByCmdStr.setCheckable(True)
        self.grpAddColumn_ByCmdStr.setChecked(False)
        self.grpAddColumn_ByCmdStr.toggled.connect(
            self.grpAddColumn_ByCmd_toggled)
        layAddColumn.addWidget(self.grpAddColumn_ByCmdStr)
        #####layAddColumn_ByCmdStr
        layAddColumn_ByCmdStr=QHBoxLayout()
        self.grpAddColumn_ByCmdStr.setLayout(layAddColumn_ByCmdStr)
        ######lblAddColumn_cmdstr
        lblAddColumn_cmdstr=QLabel('用来增加列的部分或完整Sql字符串:')
        layAddColumn_ByCmdStr.addWidget(lblAddColumn_cmdstr)
        ######self.leAddColumn_cmdstr
        self.leAddColumn_cmdstr=QLineEdit()
        layAddColumn_ByCmdStr.addWidget(self.leAddColumn_cmdstr)
        if lay is None:
            self.dlg.show()
    def grpAddColumn_ByCmd_toggled(self,event):
        if self.PreviousChecked==0:
            self.grpAddColumn_ByCmdStr.setChecked(True)
            self.grpAddColumn_ByCmdArgs.setChecked(False)
            self.PreviousChecked=1
        else:
            self.grpAddColumn_ByCmdArgs.setChecked(True)
            self.grpAddColumn_ByCmdStr.setChecked(False)
            self.PreviousChecked=0
    #----------------------------------------------------------------
    def btnDeleteColumn_Clicked(self,event):
        self.dlgMake_DeleteColumn()
    def dlgMake_DeleteColumn(self,lay=None):
        if lay is None:
            self.dlg=QDialog(self)
            self.dlg.setWindowTitle('删除列:')
        else:
            ##self.grpDeleteColumn
            self.grpDeleteColumn=QGroupBox('删除列:')
            self.grpDeleteColumn.setCheckable(True)
            self.grpDeleteColumn.setChecked(False)
            lay.addWidget(self.grpDeleteColumn)
        ###layDeleteColumn
        layDeleteColumn=QHBoxLayout()
        if lay is None:
            self.dlg.setLayout(layDeleteColumn)
        else:
            self.grpDeleteColumn.setLayout(layDeleteColumn)
        ###layColumnList
        layColumnList=QVBoxLayout()
        layDeleteColumn.addLayout(layColumnList)
        ####lblDeleteColumn
        lblDeleteColumn=QLabel('原有的所有列:')
        layColumnList.addWidget(lblDeleteColumn)
        ####self.lstColumnList
        self.lstColumnList=QListWidget()
        self.lstColumnList.addItems(self.columnsName)
        self.lstColumnList.setFixedWidth(150)
        layColumnList.addWidget(self.lstColumnList)
        ###layDeleteBtns
        layDeleteBtns=QVBoxLayout()
        layDeleteColumn.addLayout(layDeleteBtns)
        ####btnDeleteColumn_Store
        btnDeleteColumn_Store=QPushButton('>>')
        btnDeleteColumn_Store.setFixedWidth(50)
        layDeleteBtns.addWidget(btnDeleteColumn_Store)
        ####btnDeleteColumn_Unstore
        btnDeleteColumn_Unstore=QPushButton('<<')
        btnDeleteColumn_Unstore.setFixedWidth(50)
        layDeleteBtns.addWidget(btnDeleteColumn_Unstore)
        ###layColumnsToDelete
        layColumnsToDelete=QVBoxLayout()
        layDeleteColumn.addLayout(layColumnsToDelete)
        ####lblColumnsToDelete
        lblColumnsToDelete=QLabel('要删除的列:')
        layColumnsToDelete.addWidget(lblColumnsToDelete)
        ####self.lstColumnsToDelete
        self.lstColumnsToDelete=QListWidget()
        self.lstColumnsToDelete.setFixedWidth(150)
        layColumnsToDelete.addWidget(self.lstColumnsToDelete)
        if lay is None:
            self.dlg.show()
    #----------------------------------------------------------------
    def btnRenameColumn_Clicked(self,event):
        self.dlgMake_RenameColumn()
    def dlgMake_RenameColumn(self,lay=None):
        if lay is None:
            self.dlg=QDialog(self)
            self.dlg.setWindowTitle('重命名列:')
        else:
            ##self.grpRenameColumn
            self.grpRenameColumn=QGroupBox('重命名列:')
            self.grpRenameColumn.setCheckable(True)
            self.grpRenameColumn.setChecked(False)
            lay.addWidget(self.grpRenameColumn)
        ###layRenameColumn
        layRenameColumn=QHBoxLayout()
        if lay is None:
            self.dlg.setLayout(layRenameColumn)
        else:
            self.grpRenameColumn.setLayout(layRenameColumn)
        ####lblRenameColumn_select
        lblRenameColumn_select=QLabel('选择列:')
        layRenameColumn.addWidget(lblRenameColumn_select)
        ####self.cbbRenameColumn_select
        self.cbbRenameColumn_select=QComboBox()
        self.cbbRenameColumn_select.addItems(self.columnsName)
        layRenameColumn.addWidget(self.cbbRenameColumn_select)
        ####lblRenameColumn_renameto
        lblRenameColumn_renameto=QLabel('重命名为:')
        layRenameColumn.addWidget(lblRenameColumn_renameto)
        ####self.leRenameColumn_renameto
        self.leRenameColumn_renameto=QLineEdit()
        self.leRenameColumn_renameto.setFixedWidth(80)
        layRenameColumn.addWidget(self.leRenameColumn_renameto)
        ####btnRenameColumn_Store
        btnRenameColumn_Store=QPushButton('标记 >>')
        layRenameColumn.addWidget(btnRenameColumn_Store)
        ####self.cbbRenameColumn_Store
        self.cbbRenameColumn_Store=QComboBox()
        layRenameColumn.addWidget(self.cbbRenameColumn_Store,1)
        if lay is None:
            self.dlg.show()
    #----------------------------------------------------------------
    def btnModifyColumnType_Clicked(self,event):
        self.dlgMake_ModifyColumnType()
    def dlgMake_ModifyColumnType(self,lay=None):
        if lay is None:
            self.dlg=QDialog(self)
            self.dlg.setWindowTitle('修改列数据类型:')
        else:
            ##self.grpModifyColumnType
            self.grpModifyColumnType=QGroupBox('修改列数据类型:')
            self.grpModifyColumnType.setCheckable(True)
            self.grpModifyColumnType.setChecked(False)
            lay.addWidget(self.grpModifyColumnType)
        ###layModifyColumnType
        layModifyColumnType=QHBoxLayout()
        if lay is None:
            self.dlg.setLayout(layModifyColumnType)
        else:
            self.grpModifyColumnType.setLayout(layModifyColumnType)
        ####lblModifyColumnType_select
        lblModifyColumnType_select=QLabel('选择列:')
        layModifyColumnType.addWidget(lblModifyColumnType_select)
        ####self.cbbModifyColumnType_select
        self.cbbModifyColumnType_select=QComboBox()
        self.cbbModifyColumnType_select.addItems(self.columnsName)
        layModifyColumnType.addWidget(self.cbbModifyColumnType_select)
        ####lblModifyColumnType_modifyto
        lblModifyColumnType_modifyto=QLabel('改类型为:')
        layModifyColumnType.addWidget(lblModifyColumnType_modifyto)
        ####self.cbbModifyColumnType_modifyto
        self.cbbModifyColumnType_modifyto=QComboBox()
        self.cbbModifyColumnType_modifyto.setEditable(True)
        self.cbbModifyColumnType_modifyto.addItems(self.SqliteDbTypes)
        self.cbbModifyColumnType_modifyto.setCurrentIndex(2)
        self.cbbModifyColumnType_modifyto.setFixedWidth(80)
        layModifyColumnType.addWidget(self.cbbModifyColumnType_modifyto)
        ####btnModifyColumnType_Store
        btnModifyColumnType_Store=QPushButton('标记 >>')
        layModifyColumnType.addWidget(btnModifyColumnType_Store)
        ####self.cbbModifyColumnType_Store
        self.cbbModifyColumnType_Store=QComboBox()
        layModifyColumnType.addWidget(self.cbbModifyColumnType_Store,1)
        if lay is None:
            self.dlg.show()
    #----------------------------------------------------------------
    def btnModifyColumnConstraint_Clicked(self,event):
        self.dlgMake_ModifyColumnConstraint()
    def dlgMake_ModifyColumnConstraint(self,lay=None):
        if lay is None:
            self.dlg=QDialog(self)
            self.dlg.setWindowTitle('修改列约束:')
        else:
            ##self.grpModifyColumnConstraint
            self.grpModifyColumnConstraint=QGroupBox('修改列约束:')
            self.grpModifyColumnConstraint.setCheckable(True)
            self.grpModifyColumnConstraint.setChecked(False)
            lay.addWidget(self.grpModifyColumnConstraint)
        ###layModifyColumnConstraint
        layModifyColumnConstraint=QHBoxLayout()
        if lay is None:
            self.dlg.setLayout(layModifyColumnConstraint)
        else:
            self.grpModifyColumnConstraint.setLayout(layModifyColumnConstraint)
        ####lblModifyColumnConstraint_select
        lblModifyColumnConstraint_select=QLabel('选择列:')
        layModifyColumnConstraint.addWidget(lblModifyColumnConstraint_select)
        ####self.cbbModifyColumnConstraint_select
        self.cbbModifyColumnConstraint_select=QComboBox()
        self.cbbModifyColumnConstraint_select.addItems(self.columnsName)
        layModifyColumnConstraint.addWidget(self.cbbModifyColumnConstraint_select)
        ####lblModifyColumnConstraint_modifyto
        lblModifyColumnConstraint_modifyto=QLabel('约束改为:')
        layModifyColumnConstraint.addWidget(lblModifyColumnConstraint_modifyto)
        ####self.leModifyColumnConstraint_modifyto
        self.leModifyColumnConstraint_modifyto=QLineEdit()
        self.leModifyColumnConstraint_modifyto.setFixedWidth(80)
        layModifyColumnConstraint.addWidget(self.leModifyColumnConstraint_modifyto)
        ####btnModifyColumnConstraint_Store
        btnModifyColumnConstraint_Store=QPushButton('标记 >>')
        layModifyColumnConstraint.addWidget(btnModifyColumnConstraint_Store)
        ####self.cbbModifyColumnConstraint_Store
        self.cbbModifyColumnConstraint_Store=QComboBox()
        layModifyColumnConstraint.addWidget(self.cbbModifyColumnConstraint_Store,1)
        if lay is None:
            self.dlg.show()
    #----------------------------------------------------------------
    def btnOrderColumns_Clicked(self,event):
        self.dlgMake_OrderColumns()
    def dlgMake_OrderColumns(self,lay=None):
        if lay is None:
            self.dlg=QDialog(self)
            self.dlg.setWindowTitle('调整列顺序:')
        else:
            ##self.grpAdjustColumnOrder
            self.grpAdjustColumnOrder=QGroupBox('调整列顺序:')
            self.grpAdjustColumnOrder.setCheckable(True)
            self.grpAdjustColumnOrder.setChecked(False)
            lay.addWidget(self.grpAdjustColumnOrder)
        ###layAdjustColumnOrder
        layAdjustColumnOrder=QVBoxLayout()
        if lay is None:
            self.dlg.setLayout(layAdjustColumnOrder)
        else:
            self.grpAdjustColumnOrder.setLayout(layAdjustColumnOrder)
        ####lblAdjustColumnOrder
        lblAdjustColumnOrder=QLabel('请调整列顺序:')
        layAdjustColumnOrder.addWidget(lblAdjustColumnOrder)
        ####self.lstAdjustColumnOrder
        self.lstAdjustColumnOrder=QListWidget()
        self.lstAdjustColumnOrder.addItems(self.columnsName)
        self.lstAdjustColumnOrder.setFixedWidth(150)
        layAdjustColumnOrder.addWidget(self.lstAdjustColumnOrder)
        if lay is None:
            self.dlg.setFixedWidth(175)
            self.dlg.show()
    #----------------------------------------------------------------
    def btnModifyTableStruct_Clicked(self,event):
        self.dlg=QDialog(self)
        self.dlg.setWindowTitle(self.CurrentTable+'表结构修改:')
        self.dlg.setWindowFlags(Qt.Window|
                           Qt.MSWindowsFixedSizeDialogHint
                           )
        #lay
        lay=QVBoxLayout()
        self.dlgMake_AddColumn(lay)
        self.dlgMake_RenameColumn(lay)
        self.dlgMake_ModifyColumnType(lay)
        self.dlgMake_ModifyColumnConstraint(lay)
        #layLists
        layLists=QHBoxLayout()
        lay.addLayout(layLists)
        self.dlgMake_DeleteColumn(layLists)
        self.dlgMake_OrderColumns(layLists)
        ##layBtns
        layBtns=QHBoxLayout()
        lay.addLayout(layBtns)
        ##btnOk
        btnOk=QPushButton('提交修改')
        btnOk.clicked.connect(self.btnOk_Clicked)
        layBtns.addWidget(btnOk)
        ##btnCancel
        btnCancel=QPushButton('放弃修改')
        btnCancel.clicked.connect(self.btnCancel_Clicked)
        layBtns.addWidget(btnCancel)

        self.dlg.setLayout(lay)
        self.dlg.open()
    def btnOk_Clicked(self,event):
        #do something here
        self.dlg.close()
    def btnCancel_Clicked(self,event):
        self.dlg.close()
Exemplo n.º 16
0
class CWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.arr = []

        for _ in range(5):
            c = np.zeros([64, 32])
            self.arr.append(c)
        # for PyQt embedding
        self.fig = plt.Figure()
        self.ax = self.fig.add_subplot(111)

        self.im = self.ax.imshow(self.arr[0], animated=True, vmin=0, vmax=5)
        self.fig.colorbar(self.im, label='pressure')
        self.canvas = FigureCanvasQTAgg(self.fig)

        self.timeInterval = 0.1

        self.initUI()

    def initUI(self):
        self.connect_status = 0
        self.pause_status = 0
        self.record_status = 0

        self.menu = QVBoxLayout()

        self.combo_label = QLabel(self)
        self.combo_label.setText('Port')
        self.combo_label.setAlignment(Qt.AlignCenter)
        self.combo_label.setStyleSheet(
            "QLabel { background-color: #2E3D50;color:#ffffff; border: none; font-weight: regular; font-size: 15pt;font-family: Calibri;}"
        )

        self.combo = QComboBox(self)
        self.combo.addItem('select')
        #self.combo.lineEdit.setPlaceholderText("select")

        self.ports = list(serial.tools.list_ports.comports())
        for p in self.ports:
            self.combo.addItem(p[0])

        self.connect_button = QPushButton("Connect")

        #self.save_button.move(150,50)
        self.connect_button.setStyleSheet("""
            QPushButton { background-color: #2E3D50;color:#ffffff; border:  1px solid white; font-weight: regular; font-size: 15pt;font-family: Calibri;}
            QPushButton:hover{ background-color: #2E3D50; color:#ffffff;border: 3px solid white; font-weight: bold; font-size: 15pt;font-family: Calibri;}
            """)
        self.connect_button.setStyleSheet("""
            QPushButton { background-color: #2E3D50;color:#ffffff; border:  1px solid white; font-weight: regular; font-size: 15pt;font-family: Calibri;}
            QPushButton:hover{ background-color: #2E3D50; color:#ffffff;border: 3px solid white; font-weight: bold; font-size: 15pt;font-family: Calibri;}
            """)
        self.connect_button.resize(260, 464)

        self.sense_label = QLabel(self)
        self.sense_label.setText('Sensitivity')
        self.sense_label.setAlignment(Qt.AlignCenter)
        self.sense_label.setStyleSheet(
            "QLabel { background-color: #2E3D50;color:#ffffff; border: none; font-weight: regular; font-size: 15pt;font-family: Calibri;}"
        )

        self.threshold_label = QLabel(self)
        self.threshold_label.setText('Threshold')
        self.threshold_label.setAlignment(Qt.AlignCenter)
        self.threshold_label.setStyleSheet(
            "QLabel { background-color: #2E3D50;color:#ffffff; border: none; font-weight: regular; font-size: 15pt;font-family: Calibri;}"
        )

        self.save_button = QPushButton("Save")

        #self.save_button.move(150,50)
        self.save_button.setStyleSheet("""
            QPushButton { background-color: #2E3D50;color:#ffffff; border:  1px solid white; font-weight: regular; font-size: 15pt;font-family: Calibri;}
            QPushButton:hover{ background-color: #2E3D50; color:#ffffff;border: 3px solid white; font-weight: bold; font-size: 15pt;font-family: Calibri;}
            """)

        self.save_button.resize(260, 464)
        # self.logo_button.setStyleSheet("QPushButton{image:url(./image/logo.png); border:0px;}")

        self.sense_value = QLineEdit("100")
        self.sense_value.setAlignment(Qt.AlignCenter)
        self.sense_value.resize(260, 464)
        #self.option_button.move(150,50)
        #self.option_button.setStyleSheet("QPushButton { background-color: #2E3D50;color:#ffffff; border: none; font-weight: regular; font-size: 15pt;font-family: Calibri;}")

        self.sense_slider = QSlider(Qt.Horizontal)
        self.sense_slider.setRange(1, 100)

        self.threshold_value = QLineEdit("0")
        self.threshold_value.setAlignment(Qt.AlignCenter)
        self.threshold_value.resize(260, 464)

        self.threshold_slider = QSlider(Qt.Horizontal)
        self.threshold_slider.setRange(0, 300)

        self.pause_button = QPushButton("Pause")

        #self.save_button.move(150,50)
        self.pause_button.setStyleSheet("""
            QPushButton { background-color: #2E3D50;color:#ffffff; border:  1px solid white; font-weight: regular; font-size: 15pt;font-family: Calibri;}
            QPushButton:hover{ background-color: #2E3D50; color:#ffffff;border: 3px solid white; font-weight: bold; font-size: 15pt;font-family: Calibri;}
            """)
        #self.pause_button.resize(260, 464)

        self.record_button = QPushButton("Record")

        #self.save_button.move(150,50)
        self.record_button.setStyleSheet("""
            QPushButton { background-color: #2E3D50;color:#ffffff; border:  1px solid white; font-weight: regular; font-size: 15pt;font-family: Calibri;}
            QPushButton:hover{ background-color: #2E3D50; color:#ffffff;border: 3px solid white; font-weight: bold; font-size: 15pt;font-family: Calibri;}
            """)

        self.status_notice = QLineEdit()
        self.status_notice.setStyleSheet("""
            QLineEdit { background-color: #2E3D50;color:#ffffff; border:  0px solid white; font-weight: regular; font-size: 10pt;font-family: Calibri;}
            """)

        self.menu.addWidget(self.combo_label)
        self.menu.addWidget(self.combo)
        self.menu.addSpacing(5)
        self.menu.addWidget(self.connect_button)

        self.menu.addSpacing(20)
        self.menu.addWidget(self.sense_label)
        self.menu.addWidget(self.sense_value)
        self.menu.addWidget(self.sense_slider)
        self.menu.addWidget(self.threshold_label)
        self.menu.addWidget(self.threshold_value)
        self.menu.addWidget(self.threshold_slider)
        self.menu.addSpacing(50)
        self.menu.addWidget(self.save_button)
        self.menu.addSpacing(10)
        self.menu.addWidget(self.pause_button)
        self.menu.addSpacing(10)
        self.menu.addWidget(self.record_button)
        self.menu.addSpacing(10)
        self.menu.addWidget(self.status_notice)

        self.menu.setSpacing(0)
        self.menu.setContentsMargins(0, 0, 0, 0)
        #self.menu.addStretch()
        self.menu.setAlignment(Qt.AlignVCenter)

        vbox = QHBoxLayout()
        vbox.setStretchFactor(self.menu, 5)
        vbox.setStretchFactor(self.canvas, 1)
        vbox.addLayout(self.menu)
        vbox.addWidget(self.canvas)

        self.connect_button.clicked.connect(self.port_connect)
        self.save_button.clicked.connect(self.save_csv)
        self.pause_button.clicked.connect(self.pause)
        self.record_button.clicked.connect(self.record)
        self.threshold_slider.setValue(0)
        self.threshold_slider.valueChanged.connect(
            self.threshold_slider_value_changed)
        self.threshold_value.textChanged.connect(self.threshold_value_changed)

        self.sense_slider.setValue(100)
        self.sense_slider.valueChanged.connect(self.sense_slider_value_changed)
        self.sense_value.textChanged.connect(self.sense_value_changed)

        self.combo.activated[str].connect(self.onChanged)
        #self.combo.highlighted.connect(self.onClicked)

        self.setLayout(vbox)
        self.setGeometry(50, 50, 800, 800)

        # 1~1 중 1번째(1,1,1)  서브 챠트 생성
        # self.ax = self.fig.add_subplot(1,1,1)
        # # 2D line
        # self.line, = self.ax.plot(self.x, self.y)

        # 애니메이션 챠트 생성
        #self.ani = animation.FuncAnimaXtion(self.fig, self.updatefig, blit=True)
        #self.canvas.draw()
        print(self.canvas.size())
        self.ani = animation.FuncAnimation(self.fig, self.updatefig, blit=True)
        self.canvas.draw()
        self.show()

    def port_connect(self):
        try:
            self.ser = serial.Serial(self.port_num,
                                     baudrate=115200,
                                     timeout=2.5,
                                     parity=serial.PARITY_NONE,
                                     bytesize=serial.EIGHTBITS,
                                     stopbits=serial.STOPBITS_ONE)
            self.connect_status = 1

            self.status_notice.setText("{} connected".format(self.port_num))
        except:
            try:
                print(self.port_num)
                print("port error")

            except:
                print("port error")

    def record(self):
        if self.record_status == 0:
            self.record_status = 1

            self.record_button.setText("Stop")
            self.record_button.setStyleSheet("""
            QPushButton { background-color: #2E3D50; color:#ffffff;border: 3px solid white; font-weight: bold; font-size: 15pt;font-family: Calibri;}
            """)

            self.record_file_name = './data/{}.csv'.format(
                datetime.datetime.now().strftime("%m-%d-%Y-%H-%M-%S"))

            self.status_notice.setText("recording")

        elif self.record_status == 1:
            self.record_status = 0
            self.record_button.setText("Record")
            self.record_button.setStyleSheet("""
            QPushButton { background-color: #2E3D50;color:#ffffff; border:  1px solid white; font-weight: regular; font-size: 15pt;font-family: Calibri;}
            QPushButton:hover{ background-color: #2E3D50; color:#ffffff;border: 3px solid white; font-weight: bold; font-size: 15pt;font-family: Calibri;}
            """)

            self.status_notice.setText("record finished")

    def pause(self):
        if self.pause_status == 0:
            self.pause_status = 1
            self.pause_button.setText("Resume")
            self.pause_button.setStyleSheet("""
            QPushButton {  background-color: #2E3D50; color:#ffffff;border: 3px solid white; font-weight: bold; font-size: 15pt;font-family: Calibri;}
            """)
            self.status_notice.setText("paused")

        elif self.pause_status == 1:
            self.pause_status = 0
            self.pause_button.setText("Pause")
            self.pause_button.setStyleSheet("""
            QPushButton { background-color: #2E3D50;color:#ffffff; border:  1px solid white; font-weight: regular; font-size: 15pt;font-family: Calibri;}
            QPushButton:hover{ background-color: #2E3D50; color:#ffffff;border: 3px solid white; font-weight: bold; font-size: 15pt;font-family: Calibri;}
            """)
            self.status_notice.setText("resume")

    def save_csv(self, ):
        f = open('./data/{}.csv'.format(
            datetime.datetime.now().strftime("%m-%d-%Y-%H-%M-%S")),
                 'w',
                 encoding='utf-8',
                 newline='')
        wr = csv.writer(f)

        for i in range(64):
            wr.writerow(self.data[i])

        f.close()

    def onChanged(self, text):
        #print(text)
        self.port_num = text

    def onClicked(self):
        self.ports = list(serial.tools.list_ports.comports())
        self.combo.clear()
        for p in self.ports:
            self.combo.addItem(p[0])

    def paintEvent(self, event):
        height = self.size().height()
        width = self.size().width()
        painter = QPainter(self)

        painter.setPen(QPen(QColor(46, 61, 80), 5, Qt.SolidLine))
        painter.setBrush(QBrush(QColor(46, 61, 80), Qt.SolidPattern))
        #painter.drawRect(0, 0, width-self.canvas.size().width() , height)
        painter.drawRect(0, 0, width, height)

    def threshold_value_changed(self):
        try:
            if self.threshold_value.text() == '':
                self.threshold_slider.setValue(1)
            elif self.threshold_value.text() == '0':
                self.threshold_slider.setValue(1)
            else:
                self.threshold_slider.setValue(int(
                    self.threshold_value.text()))
        except:
            self.threshold_slider.setValue(1)

    def threshold_slider_value_changed(self):
        self.threshold_value.setText(str(self.threshold_slider.value()))
        #print(self.threshold_slider.value())

    def sense_value_changed(self):
        try:
            if self.sense_value.text() == '':
                self.sense_slider.setValue(1)
            else:
                self.sense_slider.setValue(int(self.sense_value.text()))
        except:
            self.sense_slider.setValue(0)

    def sense_slider_value_changed(self):
        self.sense_value.setText(str(self.sense_slider.value()))
        #print(self.sense_slider.value())

    def closeEvent(self, e):
        pass

    def receive_data(self, ):
        temp = 0
        while True:
            try:
                data = self.ser.readline().decode("utf-8")

                #print(data)
                data = str(data).replace('\r\n', ' ').split(' ')[:-3]

                data[1:] = list(map(int, data[1:]))
                data[1:] = np.divide(data[1:], 100)

                if 'a' in data:
                    data_set = np.array(data[1:])
                    temp = 1

                elif 'b' in data and temp == 1:
                    data_set = np.vstack([data_set, data[1:]])

                elif 'c' in data and temp == 1:
                    data_set = np.vstack([data_set, data[1:]])
                    #print(data_set.shape)
                    if data_set.shape == (64, 32):
                        return data_set
                    else:
                        continue
            except:
                continue
            #else :
            #    print(data)

    def save_data(self, filename):
        f = open(filename, 'a', encoding='utf-8', newline='')
        wr = csv.writer(f)

        f.write('{}\n'.format(
            datetime.datetime.now().strftime("%m-%d-%Y-%H-%M-%S")))

        for i in range(64):
            wr.writerow(self.data[i])

        if self.record_status == 1:
            pass
        elif self.record_status == 0:
            self.status_notice.setText("saved")

    def updatefig(self, *args):
        if self.pause_status == 0:

            if self.connect_status == 1:
                self.display_data = self.receive_data()

            if self.connect_status == 0:
                self.display_data = np.zeros((64, 32))

            self.display_data = self.Sensitivity(self.display_data)
            self.display_data = self.Threshold(self.display_data)
            self.data = self.display_data

            #for test start
            self.data[19] = self.data[18]

            #for test end

            self.im.set_array(self.data)
            #
            # print(self.record_status)
            if self.record_status == 1:
                self.save_data(self.record_file_name)
            return self.im,

        if self.pause_status == 1:
            self.im.set_array(self.data)
            if self.record_status == 1:
                self.save_data(self.record_file_name)
            return self.im,

    def Sensitivity(self, data):
        return np.power(self.sense_slider.value(), data)

    def Threshold(self, data):
        data[data <= self.threshold_slider.value() / 100] = 0
        return data
Exemplo n.º 17
0
class App(QWidget):
    def __init__(self):
        #here we initialize the basic parameters for the gui
        super().__init__()
        self.prev_text = ""
        self.title = 'Categorizer'
        self.col_codes = {}
        self.left = 10
        self.top = 10
        self.width = 1200
        self.height = 800
        self.cur_dir = os.getcwd()
        self.title_font = QtGui.QFont("Times", 15, QtGui.QFont.Bold)
        self.base_dir = ""

        self.initUI()

    def initUI(self):
        #We set the basic geometry of the window
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        #Here we set up the button that will allow the user to find their html file of choice
        button = QPushButton('Find File', self)
        button.setToolTip(
            'This button will allow you to select an html file to process')
        button.move(150, 700)
        button.clicked.connect(self.on_click)

        #This button will allow the user to submit their predetermine color preferences

        drag_object = CustomLabel('', self)
        drag_object.move(75, 150)

        self.button = button
        self.drag_object = drag_object

        self.cur_file = ""
        self.selected_file = QLabel(self)
        self.selected_file.setText("The selected file is: " + self.cur_file)
        self.selected_file.setFont(self.title_font)
        self.selected_file.move(500, 100)

        self.directory_label = QLabel(self)
        self.directory_label.setText("Root Directory: " + self.base_dir)
        self.directory_label.move(500, 40)

        self.change_dir = QPushButton("Change Directory", self)
        self.change_dir.setToolTip("Click to change root directory")
        self.change_dir.move(900 + len(self.directory_label.text()), 40)
        self.change_dir.clicked.connect(self.change_dir_function)

        self.combo = QComboBox(self)
        self.combo.move(500, 200)
        self.combo.setToolTip(
            "Choose which folder to add the designated file to")

        self.combo_hint = QLabel(self)
        self.combo_hint.setText("Accessible Folders")
        self.combo_hint.move(500, 170)

        self.added_folders = AddedFiles("", self)

        self.add_folder = QPushButton("Add-->", self)
        self.add_folder.setToolTip(
            "Press to add the folder to the collection of folders")
        self.add_folder.move(650, 200)
        self.add_folder.clicked.connect(self.add_folder_func)

        self.added_folders_label = QLabel(self)
        self.added_folders_label.setText("Folders to add file to")
        self.added_folders_label.move(800, 170)

        self.add_simlinks = QPushButton("Add Simlinks", self)
        self.add_simlinks.setToolTip(
            "Press to add the file to the given directories")
        self.add_simlinks.move(500, 700)
        self.add_simlinks.clicked.connect(self.add_simlinks_function)

        l = QLabel(self)
        l.setText("Files/Directories")
        l.move(100, 100)

        self.show()
        self.getBaseDir()

    def add_simlinks_function(self):
        if self.cur_file == "":
            QMessageBox.question(self, "Error", 'No file selected',
                                 QMessageBox.Ok, QMessageBox.Ok)
            return

        folders = []
        for i in range(len(self.added_folders.elem)):
            if self.added_folders.elem[i].text() != '':
                folders.append(self.added_folders.elem[i].text())

        file = self.cur_file
        file_base = file.split("/")[-1]

        os.system("mv " + file + " " + self.base_dir + "/.hidden")

        for folder in folders:
            print("ln -s " + self.base_dir + "/.hidden/" + file_base + " " +
                  self.base_dir + folder)
            os.system("ln -s " + self.base_dir + "/.hidden/" + file_base +
                      " " + self.base_dir + folder)

        QMessageBox.question(
            self, "Completed",
            'The file has been successfully linked. You can find the original file in the hidden folder '
            + self.base_dir + "/.hidden", QMessageBox.Ok, QMessageBox.Ok)

        self.drag_object.update_dir()
        self.update_combo_box()
        self.cur_file = ""

    @pyqtSlot()
    def add_folder_func(self):
        self.added_folders.add_element(self.combo.currentText())

    @pyqtSlot()
    def on_click(self):
        print('Looking for file')
        location = self.openFileNameDialog()
        #do stuff

    def openFileNameDialog(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(
            self,
            "QFileDialog.getOpenFileName()",
            "",
            "All Files (*);;Python Files (*.py)",
            options=options)
        if fileName:
            print(fileName)

            self.cur_file = fileName
            self.selected_file.setText("The selected file is: " +
                                       self.cur_file)
            self.selected_file.adjustSize()

            return fileName
        else:
            return "Error"

    def getBaseDir(self):
        if not os.path.isdir(os.getcwd() + "/.hidden"):
            self.buildDirPopup()
        else:
            self.base_dir = os.getcwd()
            self.directory_label.setText("Root Directory: " + self.base_dir)
            self.directory_label.adjustSize()
            self.drag_object.update_dir()
            self.change_dir.move(900 + len(self.directory_label.text()), 40)
        self.update_combo_box()

    def buildDirPopup(self):
        self.dirPopup = DirectoryPopup(self)

    def change_dir_function(self):
        fileName = str(
            QFileDialog.getExistingDirectory(self,
                                             "QFileDialog.getOpenFileName()"))

        if fileName:
            print(fileName)

            if os.path.isdir(fileName):
                os.chdir(fileName)
                self.getBaseDir()

    def update_combo_box(self):
        self.combo.clear()
        if self.base_dir != "":
            files = self.return_directories(self.base_dir, "")
            print(files)
            self.combo.addItems(files)
            self.adjustSize()

    def return_directories(self, dir, prefix):
        files = parse_for_hidden(os.listdir(dir))
        deleted = 0

        for i in range(len(files)):
            if os.path.isdir(dir + "/" + files[i - deleted]):
                files += self.return_directories(
                    dir + "/" + files[i - deleted], files[i - deleted])
                files[i - deleted] = prefix + "/" + files[i - deleted]
            else:
                del files[i - deleted]
                deleted += 1

        return files
Exemplo n.º 18
0
class PictureEditor(QFrame):
    picture_data: Picture
    pic_path: str='./'

    def __init__(self, parent, picture_parameter: dict):
        QFrame.__init__(self, parent, flags=Qt.FramelessWindowHint)
        self.buffer = parent.buffer
        self.picture_parameter = picture_parameter

        self.picture_label = QLabel()
        self.resize_multiple = 1

        scroll = QScrollArea(self)
        scroll.setWidget(self.picture_label)
        scroll.setObjectName('picture')

        self.name_combo = QComboBox(self)
        self.index_combo = QComboBox(self)
        self.palette_combo = QComboBox(self)
        self.resize_combo = QComboBox(self)

        self.name_combo.setFixedWidth(120)
        self.index_combo.setFixedWidth(120)
        self.palette_combo.setFixedWidth(120)
        self.resize_combo.setFixedWidth(120)

        self.name_combo.setItemDelegate(QStyledItemDelegate())
        self.index_combo.setItemDelegate(QStyledItemDelegate())
        self.palette_combo.setItemDelegate(QStyledItemDelegate())
        self.resize_combo.setItemDelegate(QStyledItemDelegate())

        self.resize_combo.addItems([f'          × {i + 1}' for i in range(4)])

        self.name_combo.currentTextChanged[str].connect(self.name_change)
        self.index_combo.currentIndexChanged.connect(self.refresh_data)
        self.palette_combo.currentIndexChanged.connect(self.refresh_data)
        self.resize_combo.currentIndexChanged.connect(self.refresh_data)

        self.name_combo.addItems(picture_parameter)

        output_button = QPushButton('導出圖片')
        input_button = QPushButton('導入圖片')
        output_button.clicked.connect(self.output_picture)
        input_button.clicked.connect(self.input_picture)

        control_layout = QVBoxLayout()
        control_layout.addWidget(QLabel('選擇圖片'), alignment=Qt.AlignLeft)
        control_layout.addWidget(self.name_combo, alignment=Qt.AlignRight)
        control_layout.addWidget(QLabel('選擇編號'), alignment=Qt.AlignLeft)
        control_layout.addWidget(self.index_combo, alignment=Qt.AlignRight)
        control_layout.addWidget(QLabel('選擇色板'), alignment=Qt.AlignLeft)
        control_layout.addWidget(self.palette_combo, alignment=Qt.AlignRight)
        control_layout.addWidget(QLabel('缩放比例'), alignment=Qt.AlignLeft)
        control_layout.addWidget(self.resize_combo, alignment=Qt.AlignRight)
        control_layout.addWidget(output_button, alignment=Qt.AlignRight)
        control_layout.addWidget(input_button, alignment=Qt.AlignRight)

        control_layout.addStretch()

        layout = QHBoxLayout()
        layout.addLayout(control_layout)
        layout.addWidget(scroll)

        self.setLayout(layout)

    def name_change(self, name: str):
        picture_setting = DATA_PARAMETER.get('圖片_' + name)
        self.index_combo.disconnect()
        self.index_combo.clear()
        self.index_combo.addItems([f'{i+1:>13d}' for i in range(picture_setting['quantity']['normal_quantity'])])
        self.index_combo.currentIndexChanged.connect(self.refresh_data)

        if self.picture_parameter.get(name):
            palette_setting = PALETTE_PARAMETER.get('色板_' + self.picture_parameter.get(name))
        else:
            palette_setting = ()
        self.palette_combo.disconnect()
        self.palette_combo.clear()
        if palette_setting:
            self.palette_combo.addItems([f'0x{address:08X}' for address in palette_setting])
            self.palette_combo.setEnabled(True)
        else:
            self.palette_combo.setEnabled(False)
        self.palette_combo.currentIndexChanged.connect(self.refresh_data)
        self.refresh_data()

    def refresh_data(self):
        picture_setting = DATA_PARAMETER.get('圖片_' + self.name_combo.currentText())
        self.picture_data = Picture(self, **picture_setting)
        if self.palette_combo.isEnabled():
            self.picture_data.palette.set_normal_offset(int(self.palette_combo.currentText(), 16))
        self.resize_multiple = self.resize_combo.currentIndex() + 1
        self.set_picture()

    def set_picture(self):
        picture = self.picture_data.get_data(self.index_combo.currentIndex())
        width = self.picture_data.width * self.resize_multiple
        height = self.picture_data.height * self.resize_multiple
        self.picture_label.setFixedSize(width, height)
        self.picture_label.setPixmap(picture.resize((width, height)).toqpixmap())

    def output_picture(self):
        filename = QFileDialog.getSaveFileName(self, '导出图片', self.pic_path, 'BMP图像(*.bmp)')[0]
        if filename:
            self.pic_path = filename[0: filename.rfind('/') + 1]
            if self.index_combo.isEnabled():
                picture = self.picture_data.get_data(self.index_combo.currentIndex())
            else:
                picture = self.picture_data.get_data(0)
            picture.save(filename)

    def input_picture(self):
        filename = QFileDialog.getOpenFileName(self, '导入图片', self.pic_path, '*.bmp;;*.png;;*.gif;;*.tif')[0]
        if filename:
            self.pic_path = filename[0: filename.rfind('/') + 1]
            width = self.picture_data.width * self.resize_multiple
            height = self.picture_data.height * self.resize_multiple
            picture = Image.open(filename).resize((width, height))
            self.picture_data.set_data(self.index_combo.currentIndex(), picture)
            self.set_picture()
Exemplo n.º 19
0
class MnemonicFrame(BaseFrame):
    def __init__(self, recovered, parent=None):
        super().__init__(parent)
        self.label.setText("Mnemonic:")
        self.mnem_select = QComboBox()
        prefs = QSettings()
        prefs.beginGroup("/General")
        dark_mode = prefs.value("/DarkMode")
        prefs.endGroup()
        if dark_mode:
            self.mnem_select.setStyleSheet("QListView {color: white;}")
        else:
            self.mnem_select.setStyleSheet("QListView {color: none;}")
        self.mnem_select.setSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Fixed)
        if recovered:
            self.mnem_select.setEnabled(False)
        self.layout.addWidget(self.label)
        self.layout.addWidget(self.mnem_select)
        self.setLayout(self.layout)

        self.mnem_list_path = Path(
            __file__).parents[1] / "res" / "mnemonics.json"  # noqa: E501
        os.makedirs(os.path.dirname(self.mnem_list_path), exist_ok=True)
        if not os.path.isfile(self.mnem_list_path):
            with open(self.mnem_list_path, 'w') as mnem_file:
                mnem_file.write(
                    '{"mnemonics": ["Modify the mnemonics.json file", "in the res directory", "to change this list"]}'
                )  # noqa: E501
            print('doesn\'t exist')

        self.cur_mnemonics = None
        self.load_mnemonics()
        # Un-comment to allow user to add mnemonics
        # self.mnem_select.activated.connect(self.mnem_selected)

    def load_mnemonics(self, active=None):
        self.mnem_select.clear()
        with open(self.mnem_list_path, 'r') as mnem_list:
            try:
                self.cur_mnemonics = json.load(mnem_list)
            except Exception:
                self.new_mnem_file(self.mnem_list_path)
                # How can we handle this kind of recursive try?
                self.cur_mnemonics = json.load(mnem_list)

        self.mnem_select.setPlaceholderText('...')
        self.mnem_select.addItems(self.cur_mnemonics['mnemonics'])
        # Un-comment to allow user to add mnemonics
        # self.mnem_select.addItem('+ Add new')

        if active:
            self.mnem_select.setCurrentIndex(self.mnem_select.findText(active))

    def add_mnemonic(self, mnemonic):
        self.cur_mnemonics['mnemonics'].append(mnemonic)
        self.cur_mnemonics['mnemonics'] = sorted(
            self.cur_mnemonics['mnemonics'], key=str.casefold)
        with open(self.mnem_list_path, 'w') as mnen_list:
            mnen_list.write(json.dumps(self.cur_mnemonics))

    @pyqtSlot(int)
    def mnem_selected(self, index):
        if index == self.mnem_select.count() - 1:
            named = False
            selected = None
            while not named:
                selected = QInputDialog.getText(self, 'Add New Mnemonic',
                                                'Mnemonic:')
                if not selected[1]:
                    return
                elif not str.strip(selected[0]):
                    QMessageBox.critical(
                        self,
                        "Error",
                        "Mnemonic cannot be blank",
                    )
                elif selected[0] in [
                        self.mnem_select.itemText(i)
                        for i in range(self.mnem_select.count())
                ]:
                    QMessageBox.critical(
                        self,
                        "Error",
                        "Mnemonic already exists",
                    )
                else:
                    named = True
            mnemonic = selected[0]
            self.add_mnemonic(mnemonic)
            self.load_mnemonics(mnemonic)

    def new_mnem_file(self, mnem_list_path):
        default = json.dumps({'mnemonics': ['XXA', 'XXB']})
        with open(mnem_list_path, 'w') as mnem_list:
            mnem_list.write(default)
Exemplo n.º 20
0
class DeviceBar(QWidget):
    """ DeviceBar

        Signals:
            onDeviceUpdated()
            onDeviceSelected(str) # str = id
            onDeviceChanged(str) # str = id

    """

    onDeviceUpdated = pyqtSignal(str, name="onDeviceUpdated")
    onDeviceSelected = pyqtSignal(str, name="onDeviceSelected")
    onDeviceChanged = pyqtSignal(str, name="onDeviceChanged")

    def __init__(self, parent=None, device_type='usb'):
        super().__init__(parent=parent)

        # dont show for local
        if device_type != 'usb':
            return

        self.parent = parent
        self.wait_for_devtype = device_type
        self.is_waiting = True
        self._adb = Adb()

        if not self._adb.min_required:
            return

        self._git = Git()
        self.setAutoFillBackground(True)
        self.setStyleSheet(
            'background-color: crimson; color: white; font-weight: bold; margin: 0; padding: 10px;'
        )
        self.setup()
        self._timer = QTimer()
        self._timer.setInterval(500)
        self._timer.timeout.connect(self._on_timer)
        self._timer.start()
        self._timer_step = 0
        frida.get_device_manager().on('added', self._on_device)
        frida.get_device_manager().on('removed', self._on_device)
        self.devices_thread = DevicesUpdateThread(self)
        self.devices_thread.onAddDevice.connect(self.on_add_deviceitem)
        self.devices_thread.onDevicesUpdated.connect(self._on_devices_finished)
        self._update_thread = FridaUpdateThread(self)
        self._update_thread._adb = self._adb
        self._update_thread.onStatusUpdate.connect(self._update_statuslbl)
        self._update_thread.onFinished.connect(self._frida_updated)
        self._update_thread.onError.connect(self._on_download_error)
        self.updated_frida_version = ''
        self.updated_frida_assets_url = {}
        self._device_id = None
        self._devices = []
        remote_frida = self._git.get_frida_version()
        if remote_frida is None:
            self.updated_frida_version = ''
            self.updated_frida_assets_url.clear()
        else:
            remote_frida = remote_frida[0]
            self.updated_frida_version = remote_frida['tag_name']
            for asset in remote_frida['assets']:
                try:
                    name = asset['name']
                    tag_start = name.index('android-')
                    if name.index('server') >= 0:
                        tag = name[tag_start + 8:-3]
                        self.updated_frida_assets_url[tag] = asset[
                            'browser_download_url']
                except ValueError:
                    pass

    def setup(self):
        """ Setup ui
        """
        h_box = QHBoxLayout()
        h_box.setContentsMargins(0, 0, 0, 0)
        self.update_label = QLabel('Waiting for Device')
        self.update_label.setFixedWidth(self.parent.width())
        self.update_label.setOpenExternalLinks(True)
        self.update_label.setTextFormat(Qt.RichText)
        self.update_label.setFixedHeight(35)
        self.update_label.setTextInteractionFlags(Qt.TextBrowserInteraction)
        self._install_btn = QPushButton('Install Frida', self.update_label)
        self._install_btn.setStyleSheet('padding: 0; border-color: white;')
        self._install_btn.setGeometry(self.update_label.width() - 110, 5, 100,
                                      25)
        self._install_btn.clicked.connect(self._on_install_btn)
        self._install_btn.setVisible(False)
        self._start_btn = QPushButton('Start Frida', self.update_label)
        self._start_btn.setStyleSheet('padding: 0; border-color: white;')
        self._start_btn.setGeometry(self.update_label.width() - 110, 5, 100,
                                    25)
        self._start_btn.clicked.connect(self._on_start_btn)
        self._start_btn.setVisible(False)
        self._update_btn = QPushButton('Update Frida', self.update_label)
        self._update_btn.setStyleSheet('padding: 0; border-color: white;')
        self._update_btn.setGeometry(self.update_label.width() - 110, 5, 100,
                                     25)
        self._update_btn.clicked.connect(self._on_install_btn)
        self._update_btn.setVisible(False)
        self._restart_btn = QPushButton('Restart Frida', self.update_label)
        self._restart_btn.setStyleSheet('padding: 0; border-color: white;')
        self._restart_btn.setGeometry(self.update_label.width() - 110, 5, 100,
                                      25)
        self._restart_btn.clicked.connect(self._on_restart_btn)
        self._restart_btn.setVisible(False)
        self._devices_combobox = QComboBox(self.update_label)
        self._devices_combobox.setStyleSheet(
            'padding: 2px 5px; border-color: white;')
        self._devices_combobox.setGeometry(self.update_label.width() - 320, 5,
                                           200, 25)
        self._devices_combobox.currentIndexChanged.connect(
            self._on_device_changed)
        self._devices_combobox.setVisible(False)
        h_box.addWidget(self.update_label)
        self.setLayout(h_box)

    def on_add_deviceitem(self, device_ident):
        """ Adds an Item to the DeviceComboBox
        """
        if device_ident['type'] == self.wait_for_devtype:
            if device_ident['name'] not in self._devices:
                self._devices.append(device_ident)
            self._timer_step = -1
            self.is_waiting = False

    def _on_device_changed(self, index):
        device = None
        device_id = self._devices_combobox.itemData(index)
        if device_id:
            try:
                device = frida.get_device(device_id)
            except:
                return

            if device:
                self._device_id = device.id
                self._check_device(device)
                self.onDeviceChanged.emit(self._device_id)

    def _check_device(self, frida_device):
        self.update_label.setStyleSheet('background-color: crimson;')
        self._install_btn.setVisible(False)
        self._update_btn.setVisible(False)
        self._start_btn.setVisible(False)
        self._restart_btn.setVisible(False)
        self._adb.device = frida_device.id
        self._device_id = frida_device.id
        if self._adb.available():
            self.update_label.setText('Device: ' + frida_device.name)
            # try getting frida version
            device_frida = self._adb.get_frida_version()
            # frida not found show install button
            if device_frida is None:
                self._install_btn.setVisible(True)
            else:
                # frida is old show update button
                if self.updated_frida_version != device_frida:
                    self._start_btn.setVisible(True)
                    self._update_btn.setVisible(False)
                    # old frida is running allow use of this version
                    if self._adb.is_frida_running():
                        self._start_btn.setVisible(False)
                        if self.updated_frida_assets_url:
                            self._update_btn.setVisible(True)
                        self.update_label.setStyleSheet(
                            'background-color: yellowgreen;')
                        self.onDeviceUpdated.emit(frida_device.id)
                # frida not running show start button
                elif device_frida and not self._adb.is_frida_running():
                    self._start_btn.setVisible(True)
                # frida is running with last version show restart button
                elif device_frida and self._adb.is_frida_running():
                    self.update_label.setStyleSheet(
                        'background-color: yellowgreen;')
                    self._restart_btn.setVisible(True)
                    self.onDeviceUpdated.emit(frida_device.id)

    def _on_devices_finished(self):
        if self._devices:
            if len(self._devices) > 1:
                self._devices_combobox.clear()
                self._devices_combobox.setVisible(True)
                self.update_label.setText('Please select the Device: ')
                for device in self._devices:
                    self._devices_combobox.addItem(device['name'],
                                                   device['id'])
            else:
                self._devices_combobox.setVisible(False)
                try:
                    device = frida.get_device(self._devices[0]['id'])
                    self._check_device(device)
                except:
                    pass

    def _on_timer(self):
        if self._timer_step == -1:
            self._timer.stop()
            return

        if self._timer_step == 0:
            self.update_label.setText(self.update_label.text() + ' .')
            self._timer_step = 1
        elif self._timer_step == 1:
            self.update_label.setText(self.update_label.text() + '.')
            self._timer_step = 2
        elif self._timer_step == 2:
            self.update_label.setText(self.update_label.text() + '.')
            self._timer_step = 3
        else:
            self.update_label.setText(
                self.update_label.text()[:-self._timer_step])
            self._timer_step = 0
            if self.is_waiting and self.devices_thread is not None:
                if not self.devices_thread.isRunning():
                    self.devices_thread.start()

    def _on_download_error(self, text):
        self._timer_step = -1
        self.update_label.setStyleSheet('background-color: crimson;')
        self.update_label.setText(text)
        self._install_btn.setVisible(True)
        self._update_btn.setVisible(False)

    def _on_device(self):
        self.update_label.setText('Waiting for Device ...')
        self._timer_step = 3
        self.is_waiting = True
        self._on_timer()

    def _on_install_btn(self):
        # urls are empty
        if not self.updated_frida_assets_url:
            return

        arch = self._adb.get_device_arch()
        request_url = ''

        if arch is not None and len(arch) > 1:
            arch = arch.join(arch.split())

            if arch == 'arm64' or arch == 'arm64-v8a':
                request_url = self.updated_frida_assets_url['arm64']
            elif arch == 'armeabi-v7a':
                request_url = self.updated_frida_assets_url['arm']
            else:
                if arch in self.updated_frida_assets_url:
                    request_url = self.updated_frida_assets_url[arch]

            try:
                if self._adb.available() and request_url.index(
                        'https://') == 0:
                    self._install_btn.setVisible(False)
                    self._update_btn.setVisible(False)

                    if self._update_thread is not None:
                        if not self._update_thread.isRunning():
                            self._update_thread.frida_update_url = request_url
                            self._update_thread.adb = self._adb
                            self._update_thread.start()

            except ValueError:
                # something wrong in .git_cache folder
                print("request_url not set")

    def _update_statuslbl(self, text):
        self._timer.stop()
        self._timer_step = 0
        self._timer.start()
        self.update_label.setText(text)

    def _frida_updated(self):
        #self._timer_step = 3
        #self.is_waiting = True
        self._on_devices_finished()

    def _on_start_btn(self):
        if self._adb.available():
            self._start_btn.setVisible(False)
            if self._adb.start_frida():
                #self.onDeviceUpdated.emit(self._device_id)
                self._on_devices_finished()
            else:
                self._start_btn.setVisible(True)

    def _on_restart_btn(self):
        if self._adb.available():
            self._restart_btn.setVisible(False)
            if self._adb.start_frida(restart=True):
                self._restart_btn.setVisible(True)
                #self.onDeviceUpdated.emit(self._device_id)
                self._on_devices_finished()
Exemplo n.º 21
0
class App(QMainWindow):
    send_to_generator = pyqtSignal(str, tuple, str, str, str)

    def __init__(self):
        super().__init__()
        self.title = "Generator Holzworth"
        self.left = 30
        self.top = 30
        self.width = 720
        self.height = 500
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        # get available ports on start
        self.available_ports = genserialport.list_ports()
        # combo for choose appropriate port
        self.port_select = QComboBox(self)
        self.port_select.addItems(self.available_ports)
        self.port_select.move(550, 400)
        self.port_select.adjustSize()
        # LCDs and labels for frequency, power and phase settings
        self.lcd_frequency_channel1 = QLCDNumber(self)
        self.lcd_frequency_channel1.move(20, 30)
        self.lcd_frequency_channel1.resize(260, 50)
        self.lcd_frequency_channel1.display(100.0)
        self.lcd_frequency_channel1.setDigitCount(11)

        self.channel1_mhz_label = QLabel("MHz", self)
        self.channel1_mhz_label.move(285, 40)
        self.channel1_mhz_label.setFont(QFont("Times", 20))

        self.lcd_power_channel1 = QLCDNumber(self)
        self.lcd_power_channel1.move(350, 30)
        self.lcd_power_channel1.resize(100, 50)
        self.lcd_power_channel1.display(0.0)

        ch1_dbm_label = QLabel("dBm", self)
        ch1_dbm_label.move(455, 40)
        ch1_dbm_label.setFont(QFont("Times", 20))

        self.lcd_phase_channel1 = QLCDNumber(self)
        self.lcd_phase_channel1.move(525, 30)
        self.lcd_phase_channel1.resize(100, 50)
        self.lcd_phase_channel1.display(0.0)

        ch1_degree_label = QLabel(u"°", self)
        ch1_degree_label.move(630, 30)
        ch1_degree_label.setFont(QFont("Times", 20))
        # checkbox to choose channel
        self.label_channel1 = QLabel(u"Kanał 1", self)
        self.label_channel1.move(20, 5)

        self.label_channel2 = QLabel(u"Kanał 2", self)
        self.label_channel2.move(20, 95)

        self.checkbox_channel1 = QCheckBox(u"Kanał 1", self)
        self.checkbox_channel1.move(20, 300)

        self.checkbox_channel2 = QCheckBox(u"Kanał 2", self)
        self.checkbox_channel2.move(20, 330)
        #LCDs and labels for second channel
        self.lcd_frequency_channel2 = QLCDNumber(self)
        self.lcd_frequency_channel2.move(20, 120)
        self.lcd_frequency_channel2.resize(260, 50)
        self.lcd_frequency_channel2.display(100.0)
        self.lcd_frequency_channel2.setDigitCount(11)

        self.f2_label = QLabel("MHz", self)
        self.f2_label.move(285, 130)
        self.f2_label.setFont(QFont("Times", 20))

        self.lcd_power_channel2 = QLCDNumber(self)
        self.lcd_power_channel2.move(350, 120)
        self.lcd_power_channel2.resize(100, 50)
        self.lcd_power_channel2.display(0.0)

        ch2_dbm_label = QLabel("dBm", self)
        ch2_dbm_label.move(455, 130)
        ch2_dbm_label.setFont(QFont("Times", 20))

        self.lcd_phase_channel2 = QLCDNumber(self)
        self.lcd_phase_channel2.move(525, 120)
        self.lcd_phase_channel2.resize(100, 50)
        self.lcd_phase_channel2.display(0.0)

        ch2_degree_label = QLabel(u"°", self)
        ch2_degree_label.move(630, 120)
        ch2_degree_label.setFont(QFont("Times", 20))
        # textbox to edit to set generator parameters
        self.textbox_frequency_set = QLineEdit(self)
        self.textbox_frequency_set.move(20, 220)
        self.textbox_frequency_set.resize(200, 40)

        self.textbox_power_set = QLineEdit(self)
        self.textbox_power_set.move(350, 220)
        self.textbox_power_set.resize(100, 40)

        label_frequency = QLabel(u"Częstotliwość", self)
        label_frequency.move(20, 195)
        label_frequency.adjustSize()

        label_power = QLabel("Moc", self)
        label_power.move(350, 195)

        label_dbm = QLabel("dBm", self)
        label_dbm.move(455, 220)

        label_phase = QLabel(u"Przesunięcie fazy", self)
        label_phase.move(525, 195)
        label_phase.adjustSize()

        self.textbox_phase_set = QLineEdit(self)
        self.textbox_phase_set.move(525, 220)
        self.textbox_phase_set.resize(100, 40)

        label_Hz = QLabel("Hz", self)
        label_Hz.move(230, 220)
        # regular expression for settings
        reg_exp_freq = QRegExp(
            "[0-9]{0,4}[.]{0,1}[0-9]{0,6}[kMG]"
        )  # 4 digits before dot, 6 after, must end with k,M or G
        gen_validator = QRegExpValidator(reg_exp_freq,
                                         self.textbox_frequency_set)
        self.textbox_frequency_set.setValidator(gen_validator)
        # regex for power settings
        reg_exp_power = QRegExp("[-]*[0-9]+[.]*[0-9]{2}")
        gen_validator = QRegExpValidator(reg_exp_power, self.textbox_power_set)
        self.textbox_power_set.setValidator(gen_validator)
        # regex for phase settings
        phase_validator = QRegExpValidator(QRegExp("[0-9]+[.]*[0-9]"),
                                           self.textbox_phase_set)
        self.textbox_phase_set.setValidator(phase_validator)
        # button for refresh available serial ports
        self.ports_button = QPushButton(u"Odśwież porty", self)
        self.ports_button.move(400, 400)
        self.ports_button.clicked.connect(self.refresh_ports)
        self.ports_button.adjustSize()
        # button to set generator
        self.activate_button = QPushButton("Ustaw", self)
        self.activate_button.move(300, 400)
        # thread creation and signals and slots connection
        self.generator_thread = QThread()
        self.generator_worker = GeneratorWorker()
        self.generator_worker.moveToThread(self.generator_thread)
        self.activate_button.clicked.connect(
            self.get_user_input_and_send_to_generator)
        self.send_to_generator.connect(
            self.generator_worker.send_settings_to_generator)
        self.generator_worker.set_display.connect(self.show_on_display)
        self.generator_worker.event_occured.connect(self.show_event)
        self.generator_thread.start()

        self.show()

    def show_on_display(self, setting: str):
        if setting == "frequency":
            user_freq_set = self.textbox_frequency_set.text()
            self.lcd_frequency_channel2.display(
                user_freq_set[0:len(user_freq_set) - 1])
            self.f2_label.setText(
                GeneratorWorker.freq_dict[user_freq_set[len(user_freq_set) -
                                                        1]])
        elif setting == "power":
            self.lcd_power_channel2.display(self.textbox_power_set.text())
        elif setting == "phase":
            self.lcd_phase_channel2.display(self.textbox_phase_set.text())

    def show_event(self, message):
        QMessageBox.about(self, "Komunikat", message)

    def get_user_input_and_send_to_generator(self):
        user_freq = self.textbox_frequency_set.text()
        user_pwr = self.textbox_power_set.text()
        user_ph = self.textbox_phase_set.text()
        current_port = str(self.port_select.currentText())
        active_channels = (self.checkbox_channel1.isChecked(),
                           self.checkbox_channel2.isChecked())
        self.send_to_generator.emit(current_port, active_channels, user_freq,
                                    user_pwr, user_ph)

    def refresh_ports(self):
        self.port_select.clear()
        self.port_select.addItems(genserialport.list_ports())
Exemplo n.º 22
0
class Window(QMainWindow):
    """Class for making a GUI for a data anlysis program for single quantum dot spectroscopy.
    
    The Class creates a gui with 3 tabs to view several 2d maps of the CCD image, the spectrum of
    quantum dots and to see histograms of the FWHM and central energy of all the quantum dots in the
    PL-image.
    """
    def __init__(self):
        """Initializes global variables and creates the frame of the application."""

        super().__init__()

        self.corr_file_loaded = False
        self.files_loaded = False
        self.data_is_available = False
        self.counter = 0

        self.all_files_data = []
        self.FWHM_hist_data = []
        self.central_energy_hist_data = []

        self.titles = [
            "Raw data", "No background noise, non-corrected data",
            "Raw corrected data", "No background noise, corrected data"
        ]

        # Setting geometry
        self.setGeometry(100, 50, 1700, 900)

        # Setting title
        self.window = QMainWindow(self)
        self.setCentralWidget(self.window)
        self.setWindowTitle("Single Quantum Dot Spectroscopy")

        # Calling method
        self.UiComponents()

        # Showing all the widgets
        self.show()

    def UiComponents(self):
        """Method for creating UI components such as tabs, color maps and sidepanel items.
        
        This method specifically includes a color map for 2d maps, 3 tabbed windows (one for 2d maps, one
        for graphs and one for histograms) and a sidepanel containing options to select files and to fill in measurement
        settings.
        """

        # Creating a widget object
        widget = QWidget()

        # Setting configuration options
        pg.setConfigOptions(antialias=True)

        # --- Color map (for 2d maps) ---
        self.colors = [(68.08602, 1.24287, 84.000825),
                       (64.75342500000001, 67.63977, 135.145665),
                       (41.724374999999995, 120.13891500000001, 142.32774),
                       (34.34646, 167.95218, 132.000495),
                       (121.76352, 209.46821999999997, 81.139725),
                       (253.27824, 231.070035, 36.703680000000006)]
        self.cmap = pg.ColorMap(pos=np.linspace(0.0, 1.0, 6),
                                color=self.colors)
        # --------------------------------

        # Creating a grid layout and adding plots to grid
        layout = QHBoxLayout()
        file_box = QGroupBox("Load Files")
        settings_box = QGroupBox("Measurement Settings")

        # --- Tabbed windows ---
        # Initialize tabs
        tabwidget = QTabWidget()
        tabwidget.setMinimumWidth(1200)
        tabwidget.setMaximumWidth(1201)
        self.tab1 = QWidget()
        self.tab2 = QWidget()
        self.tab3 = QWidget()

        # Add tabs to tab widget
        tabwidget.addTab(self.tab1, "2d maps")
        tabwidget.addTab(self.tab2, "Data fitting")
        tabwidget.addTab(self.tab3, "Histogram")

        # Create first tab
        self.tab1.layout = QGridLayout()
        self.tab2.layout = QGridLayout()
        self.tab3.layout = QVBoxLayout()
        self.tab3.top_layout = QHBoxLayout()
        self.tab3.bottom_layout = QHBoxLayout()
        self.tab3.layout.addLayout(self.tab3.top_layout)
        self.tab3.layout.addLayout(self.tab3.bottom_layout)

        # Add layouts to tabs
        self.tab1.setLayout(self.tab1.layout)
        self.tab2.setLayout(self.tab2.layout)
        self.tab3.setLayout(self.tab3.layout)
        # ----------------------

        # --- User interface Sidepanel ---
        # Create sidepanel items
        self.files_combobox = QComboBox()
        self.files_combobox.currentIndexChanged.connect(self.update_plots)

        # Buttons / status updates
        self.button_groupbox = QGroupBox()
        self.file_label = QLabel("Select file for analysis")
        self.open_files_button = QPushButton("Load Files",
                                             default=False,
                                             autoDefault=False)
        self.open_files_button.clicked.connect(self.load_files)
        self.open_corr_file_button = QPushButton("Load Correction File",
                                                 default=False,
                                                 autoDefault=False)
        self.open_corr_file_button.clicked.connect(self.load_corr_file)
        self.corr_file_status = QLineEdit()
        self.corr_file_status.setReadOnly(True)
        self.corr_file_status.setText("No correction file is loaded")
        self.files_status = QLineEdit()
        self.files_status.setReadOnly(True)
        self.files_status.setText("No files loaded")
        self.run_analysis_button = QPushButton("Run Analysis")
        self.run_analysis_button.clicked.connect(self.start_analysis)
        self.pbar = QProgressBar()

        # Measurement settings user interface
        self.lower_wavelength_label = QLabel("Lower wavelength (in nm)")
        self.lower_wavelength_dspinbox = QDoubleSpinBox()
        self.lower_wavelength_dspinbox.setMaximum(1000000)
        self.lower_wavelength_dspinbox.setDecimals(8)
        self.lower_wavelength_dspinbox.setValue(610.00929128)

        self.upper_wavelength_label = QLabel("Upper wavelength (in nm)")
        self.upper_wavelength_dspinbox = QDoubleSpinBox()
        self.upper_wavelength_dspinbox.setMaximum(1000000)
        self.upper_wavelength_dspinbox.setDecimals(8)
        self.upper_wavelength_dspinbox.setValue(886.93139111)

        self.CCD_resolution_label = QLabel(
            "CCD resolution of data files (x, y)")
        self.coordinate_label1 = QLabel("(")
        self.coordinate_label1.setMaximumWidth(5)
        self.coordinate_label2 = QLabel(",")
        self.coordinate_label2.setMaximumWidth(5)
        self.coordinate_label3 = QLabel(")")
        self.coordinate_label3.setMaximumWidth(5)
        self.CCD_resolution_x_spinbox = QSpinBox()
        self.CCD_resolution_x_spinbox.setMaximumWidth(60)
        self.CCD_resolution_x_spinbox.setMaximum(100000)
        self.CCD_resolution_x_spinbox.setValue(167)
        self.CCD_resolution_y_spinbox = QSpinBox()
        self.CCD_resolution_y_spinbox.setMaximumWidth(60)
        self.CCD_resolution_y_spinbox.setMaximum(100000)
        self.CCD_resolution_y_spinbox.setValue(200)

        self.CCD_resolution_corr_label = QLabel(
            "CCD resolution of correction files (x, y)")
        self.coordinate_label4 = QLabel("(")
        self.coordinate_label4.setMaximumWidth(5)
        self.coordinate_label5 = QLabel(",")
        self.coordinate_label5.setMaximumWidth(5)
        self.coordinate_label6 = QLabel(")")
        self.coordinate_label6.setMaximumWidth(5)
        self.CCD_resolution_corr_x_spinbox = QSpinBox()
        self.CCD_resolution_corr_x_spinbox.setMaximumWidth(60)
        self.CCD_resolution_corr_x_spinbox.setMaximum(100000)
        self.CCD_resolution_corr_x_spinbox.setValue(1340)
        self.CCD_resolution_corr_y_spinbox = QSpinBox()
        self.CCD_resolution_corr_y_spinbox.setMaximumWidth(60)
        self.CCD_resolution_corr_y_spinbox.setMaximum(100000)
        self.CCD_resolution_corr_y_spinbox.setValue(400)

        # Create sidepanel
        self.sidepanel = QWidget()
        self.sidepanel.layout = QVBoxLayout()  # general layout
        self.sidepanel.file_layout = QVBoxLayout(
        )  # file selection layout (for groupbox)
        self.sidepanel.select_file_layout = QFormLayout(
        )  # sublayout for drop down menu
        self.sidepanel.settings_layout = QVBoxLayout()  # settings layout
        self.sidepanel.settings_layout1 = QFormLayout(
        )  # sublayout for wavelength settings
        self.sidepanel.settings_layout2 = QGridLayout(
        )  # sublayout for CCD settings
        self.sidepanel.run_analysis_layout = QVBoxLayout(
        )  # sublayout for analysis button and pbar

        self.sidepanel.file_layout.addWidget(self.open_corr_file_button)
        self.sidepanel.file_layout.addWidget(self.corr_file_status)
        self.sidepanel.file_layout.addWidget(self.open_files_button)
        self.sidepanel.file_layout.addWidget(self.files_status)
        self.sidepanel.file_layout.addLayout(self.sidepanel.select_file_layout)
        file_box.setLayout(self.sidepanel.file_layout)
        self.sidepanel.layout.addWidget(file_box)
        self.sidepanel.layout.addSpacing(20)
        self.sidepanel.layout.addWidget(settings_box)
        self.sidepanel.layout.addSpacing(20)
        self.sidepanel.run_analysis_layout.addWidget(self.run_analysis_button)
        self.sidepanel.layout.addLayout(self.sidepanel.run_analysis_layout)

        self.sidepanel.select_file_layout.addRow(self.file_label,
                                                 self.files_combobox)
        self.sidepanel.settings_layout1.addRow(self.lower_wavelength_label,
                                               self.lower_wavelength_dspinbox)
        self.sidepanel.settings_layout1.addRow(self.upper_wavelength_label,
                                               self.upper_wavelength_dspinbox)
        self.sidepanel.settings_layout2.addWidget(self.CCD_resolution_label, 0,
                                                  0)
        self.sidepanel.settings_layout2.addWidget(self.coordinate_label1, 0, 1)
        self.sidepanel.settings_layout2.addWidget(
            self.CCD_resolution_x_spinbox, 0, 2)
        self.sidepanel.settings_layout2.addWidget(self.coordinate_label2, 0, 3)
        self.sidepanel.settings_layout2.addWidget(
            self.CCD_resolution_y_spinbox, 0, 4)
        self.sidepanel.settings_layout2.addWidget(self.coordinate_label3, 0, 5)

        self.sidepanel.settings_layout2.addWidget(
            self.CCD_resolution_corr_label, 1, 0)
        self.sidepanel.settings_layout2.addWidget(self.coordinate_label4, 1, 1)
        self.sidepanel.settings_layout2.addWidget(
            self.CCD_resolution_corr_x_spinbox, 1, 2)
        self.sidepanel.settings_layout2.addWidget(self.coordinate_label5, 1, 3)
        self.sidepanel.settings_layout2.addWidget(
            self.CCD_resolution_corr_y_spinbox, 1, 4)
        self.sidepanel.settings_layout2.addWidget(self.coordinate_label6, 1, 5)

        self.sidepanel.settings_layout.addLayout(
            self.sidepanel.settings_layout1)
        self.sidepanel.settings_layout.addLayout(
            self.sidepanel.settings_layout2)
        settings_box.setLayout(self.sidepanel.settings_layout)

        self.sidepanel.layout.insertSpacing(0, 5)
        self.sidepanel.layout.addStretch()
        self.sidepanel.setLayout(self.sidepanel.layout)
        # ---------------------------------

        # Add tab widget and sidepanel to central widget
        layout.addWidget(tabwidget)
        layout.addWidget(self.sidepanel)

        # Stting this layout to the widget
        widget.setLayout(layout)

        # Setting this widget as central widget of the main widow
        self.setCentralWidget(widget)

    def load_corr_file(self):
        """Method for loading in the correction file."""

        # Dialog window
        self.meas_corr_curve_file_path, _ = QFileDialog.getOpenFileName(
            filter="CSV files(*.csv)")

        if self.meas_corr_curve_file_path != '':
            # Status box update
            shortfilename = get_file_name_from_path(
                self.meas_corr_curve_file_path)
            self.corr_file_status.setText(
                f"Succesfully loaded {shortfilename}")
            self.files_status.setText("No files loaded")
            self.corr_file_loaded = True

        else:
            self.corr_file_status.setText("No correction file is loaded")
            self.corr_file_loaded = False

    def load_files(self):
        """Method for loading in data files."""

        # Dialog window
        self.filenames, _ = QFileDialog.getOpenFileNames(
            filter="CSV files(*.csv)")

        # Dropdown menu
        self.shortfilenames = []
        for filename in self.filenames:
            shortfilename = get_file_name_from_path(filename)
            self.shortfilenames.append(shortfilename)

        self.files_combobox.clear()
        self.files_combobox.addItems(self.shortfilenames)

        # Update status
        if len(self.filenames) > 0:
            self.files_status.setText(f"Succesfully loaded files")
            self.files_loaded = True

        else:
            self.files_status.setText(f"No files loaded")
            self.files_loaded = False

        self.clear_plots(self.tab1.layout)
        self.clear_plots(self.tab2.layout)

        if self.tab3.top_layout.count() > 1:
            self.clear_plots(self.tab3.sidepanel_top)
            self.tab3.top_layout.removeItem(self.tab3.sidepanel_top)
            self.clear_plots(self.tab3.top_layout)
            self.clear_plots(self.tab3.sidepanel_bottom)
            self.tab3.bottom_layout.removeItem(self.tab3.sidepanel_bottom)
            self.clear_plots(self.tab3.bottom_layout)

    def get_spinbox_values(self):
        """Method to retreive the current values of the measurement spinboxes.
        
        Returns:
            All the values in the spinboxes, contained in a tuple.
        """
        self.CCD_width = self.CCD_resolution_x_spinbox.value()
        self.CCD_height = self.CCD_resolution_y_spinbox.value()

        self.CCD_width_corr = self.CCD_resolution_corr_x_spinbox.value()
        self.CCD_height_corr = self.CCD_resolution_corr_y_spinbox.value()

        self.lower_wavelength = self.lower_wavelength_dspinbox.value()
        self.upper_wavelength = self.upper_wavelength_dspinbox.value()

        return self.CCD_width, self.CCD_height, self.CCD_width_corr, self.CCD_height_corr, self.lower_wavelength, self.upper_wavelength

    def start_analysis(self):
        """Method for running the analysis on the files.
        
        This method starts a worker thread for the data analysis on the data files, and adds
        a progress bar to the GUI when the data is being analyzed.
        """

        if self.corr_file_loaded == True and self.files_loaded == True:
            self.CCD_width, self.CCD_height, self.CCD_width_corr, self.CCD_height_corr, self.lower_wavelength, self.upper_wavelength = self.get_spinbox_values(
            )
            self.sidepanel.run_analysis_layout.addWidget(self.pbar)

            self.thread = QThread()
            self.worker = Worker()
            self.worker.moveToThread(self.thread)

            def start_long_func():
                self.all_files_data, self.FWHM_hist_data, self.central_energy_hist_data, = self.worker.run(
                    self.CCD_width, self.CCD_height, self.CCD_width_corr,
                    self.CCD_height_corr, self.lower_wavelength,
                    self.upper_wavelength, self.filenames,
                    self.meas_corr_curve_file_path)

            self.thread.started.connect(start_long_func)
            self.worker.finished.connect(self.thread.quit)
            self.worker.finished.connect(self.worker.deleteLater)
            self.thread.finished.connect(self.thread.deleteLater)
            self.worker.progress.connect(self.report_progress)

            self.thread.start()
            self.run_analysis_button.setEnabled(False)
            self.thread.finished.connect(
                lambda: self.run_analysis_button.setEnabled(True))

            def set_boolean():
                self.data_is_available = True

            def remove_pbar():
                self.pbar.setParent(None)

            self.thread.finished.connect(remove_pbar)
            self.thread.finished.connect(set_boolean)
            self.thread.finished.connect(self.update_plots)

    def update_plots(self):
        """Method for updating plot widgets.
        
        This method creates the plot items for the 2d maps and the QDot graphs.
        """

        if self.data_is_available is True:
            file_index = self.files_combobox.currentIndex()
            file_data = self.all_files_data[file_index]

            self.mapdata = [file_data[i].values for i in range(4)]
            self.Q_Dot_plot_data = file_data[4]

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

            # Create ticks for x axis
            tick_strings_lower = floor(
                file_data[0].reset_index()['index'].loc[0] * 10) / 10
            tick_strings_upper = ceil(
                file_data[0].reset_index()['index'].loc[self.CCD_width - 1] *
                10) / 10
            tick_strings = np.arange(tick_strings_lower, tick_strings_upper,
                                     -0.1)

            energies = file_data[0].reset_index()['index'].to_numpy()

            tick_values = []
            for E in tick_strings:
                tick_value = (E - energies[0]) * (self.CCD_width /
                                                  (energies[-1] - energies[0]))
                tick_values.append(tick_value)

            tick_tuples = []
            for i in range(len(tick_values)):
                tick_tuples.append(
                    (float(tick_values[i]), "{:.1f}".format(tick_strings[i])))

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

            # Create 2d maps image views
            rows = [1, 1, 4, 4]
            columns = [1, 2, 1, 2]
            plots_2dmap = {}
            axis_2dmap = {}
            imv_2dmap = {}
            for i in range(4):
                axis_2dmap[i] = pg.AxisItem('bottom')
                axis_2dmap[i].setTicks([tick_tuples])

                plots_2dmap[i] = pg.PlotItem(
                    title=self.titles[i], axisItems={"bottom": axis_2dmap[i]})
                plots_2dmap[i].setLabel(axis='left', text='Slit position')
                plots_2dmap[i].setLabel(axis='bottom', text='Energy (eV)')
                imv_2dmap[i] = pg.ImageView(view=plots_2dmap[i])
                imv_2dmap[i].setImage(self.mapdata[i])
                imv_2dmap[i].setColorMap(self.cmap)
                # imv_2dmap[i].ui.histogram.hide()
                imv_2dmap[i].ui.roiBtn.hide()
                imv_2dmap[i].ui.menuBtn.hide()

                # Add plots to layout of tab1
                self.tab1.layout.addWidget(imv_2dmap[i], rows[i], columns[i],
                                           3, 1)

            # Create plot items for each QDot
            self.Q_Dot_plot_data_arr = self.Q_Dot_plot_data.swapaxes(
                'index', 'columns').to_numpy()
            column_headers = list(self.Q_Dot_plot_data.columns)
            counter = 1
            plots_Qdot = {}
            axis_Qdot = {}
            for QdotIndex in range(0, len(self.Q_Dot_plot_data_arr), 2):
                row = floor((counter - 1) / 3)
                column = counter - ((row * 3)) - 1

                axis_Qdot[QdotIndex / 2] = pg.AxisItem('bottom')
                axis_Qdot[QdotIndex / 2].setTicks([tick_tuples])

                plots_Qdot[QdotIndex / 2] = pg.PlotWidget(
                    title=f"Slit position: {column_headers[QdotIndex]}",
                    axisItems={"bottom": axis_Qdot[QdotIndex / 2]})
                plots_Qdot[QdotIndex / 2].addLegend()
                plots_Qdot[QdotIndex / 2].plot(
                    self.Q_Dot_plot_data_arr[QdotIndex],
                    symbol="o",
                    symbolSize=6,
                    pen=None,
                    name="PL-spectrum")
                plots_Qdot[QdotIndex / 2].plot(
                    self.Q_Dot_plot_data_arr[QdotIndex + 1],
                    pen=pg.mkPen('r'),
                    name="Optimal gaussian fit")
                plots_Qdot[QdotIndex / 2].setLabel(axis='left',
                                                   text='Intensity')
                plots_Qdot[QdotIndex / 2].setLabel(axis='bottom',
                                                   text='Energy (eV)')

                # Add plots to layout of tab2
                self.tab2.layout.addWidget(plots_Qdot[QdotIndex / 2], row,
                                           column, 1, 1)
                counter += 1

            if self.tab3.top_layout.count() == 0:
                self.make_histogram()

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

    def make_histogram(self):
        """Method for creating the FWHM and Central energy histograms."""

        # Create sidepanel for top histogram
        self.tab3.sidepanel_top = QFormLayout(self)

        self.FWHM_bin_spinbox = QSpinBox()
        self.FWHM_bin_spinbox.setRange(1, 100)
        self.FWHM_bin_spinbox.setValue(30)
        self.FWHM_bin_spinbox.valueChanged.connect(self.update_histograms)

        self.FWHM_min_spinbox = QDoubleSpinBox()
        self.FWHM_min_spinbox.setDecimals(2)
        self.FWHM_min_spinbox.setRange(0.00, 999.99)
        self.FWHM_min_spinbox.setSingleStep(0.1)
        self.FWHM_min_spinbox.setValue(0)
        self.FWHM_min_spinbox.valueChanged.connect(self.update_histograms)

        self.FWHM_max_spinbox = QDoubleSpinBox()
        self.FWHM_max_spinbox.setDecimals(2)
        self.FWHM_max_spinbox.setRange(0.01, 1000.00)
        self.FWHM_max_spinbox.setSingleStep(0.1)
        self.FWHM_max_spinbox.setValue(1000.00)
        self.FWHM_max_spinbox.valueChanged.connect(self.update_histograms)

        self.tab3.sidepanel_top.addRow(QLabel("Bins:"), self.FWHM_bin_spinbox)
        self.tab3.sidepanel_top.addRow(QLabel("Minimum FWHM:"),
                                       self.FWHM_min_spinbox)
        self.tab3.sidepanel_top.addRow(QLabel("Maximum FWHM:"),
                                       self.FWHM_max_spinbox)

        # Create histogram for FWHM
        self.FWHM_hist = pg.PlotWidget(title="FWHM histogram of all QDots")
        FWHM_bins = self.FWHM_bin_spinbox.value()
        FWHM_min = self.FWHM_min_spinbox.value()
        FWHM_max = self.FWHM_max_spinbox.value()
        x, y, x_new, best_fit = QDot_spectroscopy_Model.histogram(
            self.FWHM_hist_data, FWHM_bins, FWHM_min, FWHM_max)

        FWHM_curve = pg.PlotCurveItem(x,
                                      y,
                                      stepMode=True,
                                      fillLevel=0,
                                      brush=(0, 0, 255, 80))
        FWHM_fit = pg.PlotDataItem(x_new, best_fit, pen=pg.mkPen('r'))
        self.FWHM_hist.addItem(FWHM_curve)
        self.FWHM_hist.addItem(FWHM_fit)
        self.FWHM_hist.setLabel(axis='left', text='Frequency')
        self.FWHM_hist.setLabel(axis='bottom', text='FWHM (eV)')
        self.tab3.top_layout.addWidget(self.FWHM_hist)
        self.tab3.top_layout.addLayout(self.tab3.sidepanel_top)

        # Create sidepanel for bottom histogram
        self.tab3.sidepanel_bottom = QFormLayout(self)

        self.c_energy_bin_spinbox = QSpinBox()
        self.c_energy_bin_spinbox.setRange(1, 100)
        self.c_energy_bin_spinbox.setValue(30)
        self.c_energy_bin_spinbox.valueChanged.connect(self.update_histograms)

        self.c_energy_min_spinbox = QDoubleSpinBox()
        self.c_energy_min_spinbox.setDecimals(2)
        self.c_energy_min_spinbox.setRange(-1000.00, 999.99)
        self.c_energy_min_spinbox.setSingleStep(0.1)
        self.c_energy_min_spinbox.setValue(-100)
        self.c_energy_min_spinbox.valueChanged.connect(self.update_histograms)

        self.c_energy_max_spinbox = QDoubleSpinBox()
        self.c_energy_max_spinbox.setDecimals(2)
        self.c_energy_max_spinbox.setRange(0.01, 1000.00)
        self.c_energy_max_spinbox.setSingleStep(0.1)
        self.c_energy_max_spinbox.setValue(1000.00)
        self.c_energy_max_spinbox.valueChanged.connect(self.update_histograms)

        self.tab3.sidepanel_bottom.addRow(QLabel("Bins:"),
                                          self.c_energy_bin_spinbox)
        self.tab3.sidepanel_bottom.addRow(QLabel("Minimum central energy:"),
                                          self.c_energy_min_spinbox)
        self.tab3.sidepanel_bottom.addRow(QLabel("Maximum central energy:"),
                                          self.c_energy_max_spinbox)

        # Create histogram for central energies
        self.c_energy_hist = pg.PlotWidget(
            title="Central energy histogram of all QDots")
        c_energy_bins = self.c_energy_bin_spinbox.value()
        c_energy_min = self.c_energy_min_spinbox.value()
        c_energy_max = self.c_energy_max_spinbox.value()
        x, y, x_new, best_fit = QDot_spectroscopy_Model.histogram(
            self.central_energy_hist_data, c_energy_bins, c_energy_min,
            c_energy_max)

        c_energy_curve = pg.PlotCurveItem(x,
                                          y,
                                          stepMode=True,
                                          fillLevel=0,
                                          brush=(0, 0, 255, 80))
        c_energy_fit = pg.PlotDataItem(x_new, best_fit, pen=pg.mkPen('r'))
        self.c_energy_hist.addItem(c_energy_curve)
        self.c_energy_hist.addItem(c_energy_fit)
        self.c_energy_hist.setLabel(axis='left', text='Frequency')
        self.c_energy_hist.setLabel(axis='bottom', text='Central energy (eV)')

        self.tab3.bottom_layout.addWidget(self.c_energy_hist)
        self.tab3.bottom_layout.addLayout(self.tab3.sidepanel_bottom)

    def update_histograms(self):
        """Method for updating histograms based on sidepanel settings."""

        self.FWHM_hist.clear()

        FWHM_bins = self.FWHM_bin_spinbox.value()
        FWHM_min = self.FWHM_min_spinbox.value()
        FWHM_max = self.FWHM_max_spinbox.value()

        x, y, x_new, best_fit = QDot_spectroscopy_Model.histogram(
            self.FWHM_hist_data, FWHM_bins, FWHM_min, FWHM_max)

        FWHM_curve = pg.PlotCurveItem(x,
                                      y,
                                      stepMode=True,
                                      fillLevel=0,
                                      brush=(0, 0, 255, 80))
        FWHM_fit = pg.PlotDataItem(x_new, best_fit, pen=pg.mkPen('r'))
        self.FWHM_hist.addItem(FWHM_curve)
        self.FWHM_hist.addItem(FWHM_fit)

        self.c_energy_hist.clear()

        c_energy_bins = self.c_energy_bin_spinbox.value()
        c_energy_min = self.c_energy_min_spinbox.value()
        c_energy_max = self.c_energy_max_spinbox.value()

        x, y, x_new, best_fit = QDot_spectroscopy_Model.histogram(
            self.central_energy_hist_data, c_energy_bins, c_energy_min,
            c_energy_max)

        c_energy_curve = pg.PlotCurveItem(x,
                                          y,
                                          stepMode=True,
                                          fillLevel=0,
                                          brush=(0, 0, 255, 80))
        c_energy_fit = pg.PlotDataItem(x_new, best_fit, pen=pg.mkPen('r'))
        self.c_energy_hist.addItem(c_energy_curve)
        self.c_energy_hist.addItem(c_energy_fit)

    def report_progress(self, n):
        """Method for updating the progress bar in the GUI."""
        self.pbar.setValue(n)
Exemplo n.º 23
0
class MusicPreviewWidget(QWidget):
    def __init__(self,
                 parent=None,
                 showProgress=True,
                 showWaiting=False,
                 progressHidden=False,
                 progressHiddenWhileIdle=True,
                 progressShowFinished=3000,
                 showLog=True):
        super(MusicPreviewWidget, self).__init__(parent)
        self._lastbuildtime = 10.0
        self._running = None
        self._current = None

        self._showLog = showLog
        if showLog:
            self._log = log.Log()
        self._showProgress = showProgress

        self._chooserLabel = QLabel()
        self._chooser = QComboBox(self, activated=self.selectDocument)
        self._view = popplerview.View()

        self._showWaiting = showWaiting
        if showWaiting:
            from widgets.waitingoverlay import Overlay
            self._waiting = Overlay(self._view)
            self._waiting.hide()

        self._stack = QStackedLayout()
        self._top = QWidget()

        layout = QVBoxLayout()
        self.setLayout(layout)

        layout.addWidget(self._top)
        layout.addLayout(self._stack)
        if self._showProgress:
            self._progress = widgets.progressbar.TimedProgressBar(
                parent=self,
                hidden=progressHidden,
                hideWhileIdle=progressHiddenWhileIdle,
                showFinished=progressShowFinished)
            layout.addWidget(self._progress)

        top = QHBoxLayout()
        top.setContentsMargins(0, 0, 0, 0)
        top.setSpacing(2)
        self._top.setLayout(top)
        top.addWidget(self._chooserLabel)
        top.addWidget(self._chooser)
        top.addStretch(1)

        if showLog:
            self._stack.addWidget(self._log)
        self._stack.addWidget(self._view)

        self._top.hide()
        app.aboutToQuit.connect(self.cleanup)
        app.translateUI(self)

    def translateUI(self):
        self._chooserLabel.setText(_("Document:"))

    def abort_running(self):
        """Ensures no running job is left behind.
        This *can* be called by the using dialog/widget."""
        j = self._running
        if j and j.is_running():
            if self._showLog:
                self._log.disconnectJob(j)
            j.done.disconnect(self._done)
            j.abort()

    def preview(self,
                text,
                title=None,
                base_dir=None,
                temp_dir='',
                cached=False):
        """Runs LilyPond on the given text and shows the resulting PDF."""
        self.abort_running()
        if cached:
            self._running = j = job.lilypond.CachedPreviewJob(
                text, target_dir=temp_dir, base_dir=base_dir, title=title)
            if not self._running.needs_compilation():
                self._done(None)
                return
        else:
            self._running = j = job.lilypond.VolatileTextJob(text, title=title)
        j.done.connect(self._done)
        if self._showLog:
            self._log.clear()
            self._log.connectJob(j)
            self._stack.setCurrentWidget(self._log)
        if self._showProgress:
            j.started.connect(
                lambda: self._progress.start(self._lastbuildtime))
            self._progress.start(self._lastbuildtime)
        if self._showWaiting:
            self._waiting.start()
        app.job_queue().add_job(j, 'generic')

    def _done(self, success):
        # TODO: Handle failed compilation (= no file to show)
        if self._showProgress:
            self._progress.stop()
        if self._showWaiting:
            self._waiting.stop()
        pdfs = self._running.resultfiles()
        self.setDocuments(pdfs)
        if not pdfs and self._showLog:
            self._stack.setCurrentWidget(self._log)
            return
        self._lastbuildtime = self._running.elapsed_time()
        self._stack.setCurrentWidget(self._view)
        if self._current:
            self._current.cleanup()
        self._current = self._running  # keep the tempdir
        self._running = None

    def setDocuments(self, pdfs):
        """Loads the given PDF path names in the UI."""
        self._documents = [popplertools.Document(name) for name in pdfs]
        self._chooser.clear()
        self._chooser.addItems([d.name() for d in self._documents])
        self._top.setVisible(len(self._documents) > 1)
        if pdfs:
            self._chooser.setCurrentIndex(0)
            self.selectDocument(0)
        else:
            self._view.clear()

    def selectDocument(self, index):
        doc = self._documents[index].document()
        if doc:
            self._view.load(doc)

    def cleanup(self):
        if self._running:
            self._running.abort()
            self._running.cleanup()
            self._running = None
        if self._current:
            self._current.cleanup()
            self._current = None
        if self._showLog:
            self._stack.setCurrentWidget(self._log)
        self._top.hide()
        self._view.clear()

    def print_(self):
        """Prints the currently displayed document."""
        if self._documents:
            doc = self._documents[self._chooser.currentIndex()]
            import popplerprint
            popplerprint.printDocument(doc, self)
Exemplo n.º 24
0
class MainApp(QWidget):
  def __init__(self):
    super(MainApp, self).__init__()
    self.setGeometry(100, 150, 700, 400)
    self.setWindowTitle("Bloomberg Stock Checker")
    self.initUI()
  
  def initUI(self):
    grid = QGridLayout()
    self.setLayout(grid)
    self.widgets = []
    self.threads = QThreadPool()

    names = ['Stocks', 'stock_combobox', 'x', 'x', 'x', 'refresh', 
              'Name', '', 'x', 'x', 'x', 'x', 
              'Price', '', 'x', 'Currency', '', 'x', 
              'Open', '', 'Prev Close', '', 'Volume', '',
              'Market Cap', '', 'Day Range', '', '52 Week Range', '']
    
    positions = [(y, x) for y in range(5) for x in range(6)]

    for position, name in zip(positions, names):
      if name == 'x':
        continue
      elif name == '':
        label = QLabel()
        label.setText("")
        grid.addWidget(label, *position)
        self.widgets.append(label)
      elif "_combobox" in name:
        self.combobox = QComboBox()
        grid.addWidget(self.combobox, *position)
      elif 'refresh' in name:
        refreshBtn = QPushButton("Refresh \nData")
        grid.addWidget(refreshBtn, *position)
        refreshBtn.clicked.connect(self.refreshBtn_pressed)
      else:
        label = QLabel()
        label.setText(name)
        grid.addWidget(label, *position)
        self.widgets.append(label)
        
    

  def refreshBtn_pressed(self):
    requester = DataRequester(self.combobox, self.add_comboBox_item)
    self.threads.start(requester)
    #self.add_comboBox_item(self.combobox)

    

  def add_comboBox_item(self):
    stock_names = read_json()
    self.combobox.clear()
    for i in stock_names.keys():
      self.combobox.addItem(i)
    
    self.combobox.activated[str].connect(self.check_stock)

  def check_stock(self, name):
    stock_names = read_json()
    data = stock_names[name]
    for i in range(0, len(self.widgets)):
      if i == 19:
        pass
      if self.widgets[i].text() != "":
        for k, v in data.items():
          if k == self.widgets[i].text():
            self.widgets[i+1].setText(v)
Exemplo n.º 25
0
class AvailableSizes(QDialog):
    def __init__(self):
        super(AvailableSizes, self).__init__()
        
        self.createCombos()
        self.createHeader()
        #self.createMenuBar()
        
        self.printOut = QTextEdit()
        self.printOut.setFont(QFont('Helvetica', 11, QFont.Bold))
        self.printOut.setReadOnly(True)
        
        mainLayout = QVBoxLayout()
        #mainLayout.setMenuBar(self.menuBar)
        mainLayout.addWidget(self.frmHeader)
        mainLayout.addWidget(self.grpBox)
        mainLayout.addWidget(self.printOut)
        #mainLayout.setAlignment(self.frmHeader, Qt.AlignRight)
        self.setLayout(mainLayout)
        
        #self.setWindowTitle("Available Sizes")
        self.setWindowFlags(Qt.FramelessWindowHint)
        bgColor = QPalette()
        bgColor.setColor(self.backgroundRole(), Qt.gray)
        self.setPalette(bgColor)
        self.setWindowIcon(QIcon('icon/PS_Icon.png'))
        self.cbSku.setFocus()
        
    def createHeader(self):
        blk = QPalette()
        blk.setColor(blk.Foreground, Qt.white)
        
        lblTitle = QLabel("Availability Checker")
        lblTitle.setFont(QFont("Times", 12, QFont.Bold ))
        lblTitle.setPalette(blk) 
         
        btnClose = QToolButton()
        btnClose.setIcon(QIcon("icon\size_exit.png"))
        btnClose.setAutoRaise(True)
        btnClose.setIconSize(QSize(25,25))
        btnClose.clicked.connect(lambda: self.close())
        
        hbHeader = QHBoxLayout()
        hbHeader.addWidget(lblTitle)
        hbHeader.addWidget(btnClose)
        hbHeader.setContentsMargins(0, 0, 0, 0)
        
        self.frmHeader = QFrame()
        self.frmHeader.setLayout(hbHeader)
        
    def createCombos(self):
        cbFont = QFont("Times", 8, QFont.Bold)
        designs = self.getDesigns()
        
        self.grpBox = QGroupBox()
        self.grpBox.setFont(QFont('Times', 10, QFont.Bold))
        layout = QFormLayout()
        
        self.cbSku = QComboBox()
        self.cbSku.addItem("Designs")
        self.cbSku.addItems(designs)
        self.cbSku.setFont(cbFont)
        self.cbSku.currentIndexChanged.connect(self.skuChanged)
        
        self.cbStyle = QComboBox()
        self.cbStyle.addItem("Styles")
        self.cbStyle.setFont(cbFont)
        self.cbStyle.currentIndexChanged.connect(self.styleChanged)
        
        layout.addRow(QLabel("Design:"), self.cbSku)
        layout.addRow(QLabel("Style:"), self.cbStyle)
        
        self.grpBox.setLayout(layout)
    
    def skuChanged(self):
        
        if self.cbStyle.count() > 0:
            self.cbStyle.clear()
            self.cbStyle.addItem("Style")
            self.cbStyle.setCurrentIndex(0)
            styles = self.getStyles(self.cbSku.currentText())
        else: 
            styles = self.getStyles(self.cbSku.currentText())
        self.cbStyle.addItems(styles)
        
    def styleChanged(self):
        self.printOut.clear()
        sizes = self.getSizes(self.cbSku.currentText(), self.cbStyle.currentText())
        if self.cbStyle.currentText() != "Styles":
            for i in sizes:
                self.printOut.insertPlainText(i + '\n')
                    
       
    def createMenuBar(self):
        self.menuBar = QMenuBar()

        self.fileMenu = QMenu("&File", self)
        self.exitAction = self.fileMenu.addAction("E&xit")
        self.menuBar.addMenu(self.fileMenu)

        self.exitAction.triggered.connect(self.accept)
        
    def getDesigns(self):
        sd = mysql_db.mysql_connect(self)
        sd.execute("""SELECT 
                            DISTINCT CONCAT(d.sku_code, " - ", d.name) design
                        FROM
                            designs d
                        JOIN packages p on p.design_id = d.id
                        ORDER BY RIGHT(d.sku_code, 3), LEFT(d.sku_code,1)""")
        ds = sd.fetchall()
        lsDesigns = []
        for i in ds:
            lsDesigns.append(i[0])
        return lsDesigns    
    
    def getStyles(self, sku):
        sd = mysql_db.mysql_connect(self)
        sd.execute("""SELECT
                            DISTINCT g.name
                        FROM 
                            garment_styles_ages g
                        JOIN packages p ON p.garment_styles_age_id = g.id
                        JOIN designs d ON d.id = p.design_id
                        WHERE d.sku_code = '""" + sku[:4] + """'
                        ORDER BY g.name""")
        ds = sd.fetchall()
        lsStyles = []
        for i in ds:
            lsStyles.append(i[0])
        return lsStyles
    
    def getSizes(self, sku, style):
        style = style.replace("'", "\\'")
        sd = mysql_db.mysql_connect(self)
        sd.execute("""
                        SELECT
                            DISTINCT CONCAT(s.name, ' - ', c.name) size
                        FROM 
                            sizes s
                        JOIN packages p ON p.size_id = s.id
                        JOIN designs d ON d.id = p.design_id
                        JOIN colors c ON c.id = p.color_id
                        JOIN garment_styles_ages g ON g.id = p.garment_styles_age_id
                        WHERE 
                            d.sku_code = '""" + sku[:4] + """'
                        AND
                            g.name = '""" + style + """'""")
        ds = sd.fetchall()
        lsSizes = []
        for i in ds:
            lsSizes.append(i[0])
        return lsSizes

    
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.leftClick = True
            self.offset = event.pos()

    def mouseMoveEvent(self, event):
        if self.leftClick == True:
            x=event.globalX()
            y=event.globalY()
            x_w = self.offset.x()
            y_w = self.offset.y()
            self.move(x-x_w, y-y_w)
            
    def mouseReleaseEvent(self, event):
        self.leftClick = False       
Exemplo n.º 26
0
class RangeSelector(QWidget):

    __LOG: Logger = LogHelper.logger("RangeSelector")

    def __init__(self, parent=None):
        super().__init__(parent)
        self.__init_ui__()

    def __init_ui__(self):
        layout = QHBoxLayout()

        from_layout = QVBoxLayout()
        from_layout.addWidget(QLabel("From:"))

        self.__from_select = QComboBox(self)
        # TODO get ignored for certain styles, like Mac, when not editable
        # TODO possibly allow editable but make it jump to item instead of adding to list?
        self.__from_select.setMaxVisibleItems(20)
        self.__from_select.currentIndexChanged.connect(
            self.__handle_from_changed)

        from_layout.addWidget(self.__from_select)
        layout.addLayout(from_layout)

        to_layout = QVBoxLayout()
        to_layout.addWidget(QLabel("To:"))

        self.__to_select = QComboBox(self)
        # TODO get ignored for certain styles, like Mac, when not editable
        # TODO possibly allow editable but make it jump to item instead of adding to list?
        self.__to_select.setMaxVisibleItems(20)
        self.__to_select.currentIndexChanged.connect(self.__handle_to_changed)

        to_layout.addWidget(self.__to_select)
        layout.addLayout(to_layout)

        self.setLayout(layout)

    @pyqtSlot(int)
    def __handle_from_changed(self, index: int):
        RangeSelector.__LOG.debug("from index changed to: {0}".format(index))
        if self.__to_select.currentIndex() < index:
            self.__to_select.setCurrentIndex(index)

    @pyqtSlot(int)
    def __handle_to_changed(self, index: int):
        RangeSelector.__LOG.debug("to index changed to: {0}".format(index))
        if self.__from_select.currentIndex() > index:
            self.__from_select.setCurrentIndex(index)

    def clear(self):
        self.__from_select.clear()
        self.__to_select.clear()

    def from_value(self) -> int:
        return int(self.__from_select.currentText())

    def to_value(self) -> int:
        return int(self.__to_select.currentText())

    def set_range(self, start: int, end: int):
        if end <= start:
            raise ValueError("end value must be greater than start")

        self.__from_select.currentIndexChanged.disconnect(
            self.__handle_from_changed)
        self.__to_select.currentIndexChanged.disconnect(
            self.__handle_to_changed)

        index = 0
        for item in range(start, end):
            self.__from_select.insertItem(index, str(item))
            self.__to_select.insertItem(index, str(item + 1))
            index += 1

        self.__from_select.setCurrentIndex(0)
        self.__to_select.setCurrentIndex(end - 2)

        self.__from_select.currentIndexChanged.connect(
            self.__handle_from_changed)
        self.__to_select.currentIndexChanged.connect(self.__handle_to_changed)
Exemplo n.º 27
0
class DebugViewer(QWidget):
    """
    Class implementing a widget conatining various debug related views.
    
    The individual tabs contain the interpreter shell (optional),
    the filesystem browser (optional), the two variables viewers
    (global and local), a breakpoint viewer, a watch expression viewer and
    the exception logger. Additionally a list of all threads is shown.
    
    @signal sourceFile(string, int) emitted to open a source file at a line
    """
    sourceFile = pyqtSignal(str, int)
    
    def __init__(self, debugServer, docked, vm, parent=None,
                 embeddedShell=True, embeddedBrowser=True):
        """
        Constructor
        
        @param debugServer reference to the debug server object
        @param docked flag indicating a dock window
        @param vm reference to the viewmanager object
        @param parent parent widget (QWidget)
        @param embeddedShell flag indicating whether the shell should be
            included. This flag is set to False by those layouts, that have
            the interpreter shell in a separate window.
        @param embeddedBrowser flag indicating whether the file browser should
            be included. This flag is set to False by those layouts, that
            have the file browser in a separate window or embedded
            in the project browser instead.
        """
        super(DebugViewer, self).__init__(parent)
        
        self.debugServer = debugServer
        self.debugUI = None
        
        self.setWindowIcon(UI.PixmapCache.getIcon("eric.png"))
        
        self.__mainLayout = QVBoxLayout()
        self.__mainLayout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self.__mainLayout)
        
        self.__tabWidget = E5TabWidget()
        self.__mainLayout.addWidget(self.__tabWidget)
        
        self.embeddedShell = embeddedShell
        if embeddedShell:
            from QScintilla.Shell import ShellAssembly
            # add the interpreter shell
            self.shellAssembly = ShellAssembly(debugServer, vm, False)
            self.shell = self.shellAssembly.shell()
            index = self.__tabWidget.addTab(
                self.shellAssembly,
                UI.PixmapCache.getIcon("shell.png"), '')
            self.__tabWidget.setTabToolTip(index, self.shell.windowTitle())
        
        self.embeddedBrowser = embeddedBrowser
        if embeddedBrowser:
            from UI.Browser import Browser
            # add the browser
            self.browser = Browser()
            index = self.__tabWidget.addTab(
                self.browser,
                UI.PixmapCache.getIcon("browser.png"), '')
            self.__tabWidget.setTabToolTip(index, self.browser.windowTitle())
        
        from .VariablesViewer import VariablesViewer
        # add the global variables viewer
        self.glvWidget = QWidget()
        self.glvWidgetVLayout = QVBoxLayout(self.glvWidget)
        self.glvWidgetVLayout.setContentsMargins(0, 0, 0, 0)
        self.glvWidgetVLayout.setSpacing(3)
        self.glvWidget.setLayout(self.glvWidgetVLayout)
        
        self.globalsViewer = VariablesViewer(self.glvWidget, True)
        self.glvWidgetVLayout.addWidget(self.globalsViewer)
        
        self.glvWidgetHLayout = QHBoxLayout()
        self.glvWidgetHLayout.setContentsMargins(3, 3, 3, 3)
        
        self.globalsFilterEdit = QLineEdit(self.glvWidget)
        self.globalsFilterEdit.setSizePolicy(
            QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.glvWidgetHLayout.addWidget(self.globalsFilterEdit)
        self.globalsFilterEdit.setToolTip(
            self.tr("Enter regular expression patterns separated by ';'"
                    " to define variable filters. "))
        self.globalsFilterEdit.setWhatsThis(
            self.tr("Enter regular expression patterns separated by ';'"
                    " to define variable filters. All variables and"
                    " class attributes matched by one of the expressions"
                    " are not shown in the list above."))
        
        self.setGlobalsFilterButton = QPushButton(
            self.tr('Set'), self.glvWidget)
        self.glvWidgetHLayout.addWidget(self.setGlobalsFilterButton)
        self.glvWidgetVLayout.addLayout(self.glvWidgetHLayout)
        
        index = self.__tabWidget.addTab(
            self.glvWidget,
            UI.PixmapCache.getIcon("globalVariables.png"), '')
        self.__tabWidget.setTabToolTip(index, self.globalsViewer.windowTitle())
        
        self.setGlobalsFilterButton.clicked.connect(
            self.__setGlobalsFilter)
        self.globalsFilterEdit.returnPressed.connect(self.__setGlobalsFilter)
        
        # add the local variables viewer
        self.lvWidget = QWidget()
        self.lvWidgetVLayout = QVBoxLayout(self.lvWidget)
        self.lvWidgetVLayout.setContentsMargins(0, 0, 0, 0)
        self.lvWidgetVLayout.setSpacing(3)
        self.lvWidget.setLayout(self.lvWidgetVLayout)
        
        self.lvWidgetHLayout1 = QHBoxLayout()
        self.lvWidgetHLayout1.setContentsMargins(3, 3, 3, 3)
        
        self.stackComboBox = QComboBox(self.lvWidget)
        self.stackComboBox.setSizePolicy(
            QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.lvWidgetHLayout1.addWidget(self.stackComboBox)

        self.sourceButton = QPushButton(self.tr('Source'), self.lvWidget)
        self.lvWidgetHLayout1.addWidget(self.sourceButton)
        self.sourceButton.setEnabled(False)
        self.lvWidgetVLayout.addLayout(self.lvWidgetHLayout1)

        self.localsViewer = VariablesViewer(self.lvWidget, False)
        self.lvWidgetVLayout.addWidget(self.localsViewer)
        
        self.lvWidgetHLayout2 = QHBoxLayout()
        self.lvWidgetHLayout2.setContentsMargins(3, 3, 3, 3)
        
        self.localsFilterEdit = QLineEdit(self.lvWidget)
        self.localsFilterEdit.setSizePolicy(
            QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.lvWidgetHLayout2.addWidget(self.localsFilterEdit)
        self.localsFilterEdit.setToolTip(
            self.tr(
                "Enter regular expression patterns separated by ';' to define "
                "variable filters. "))
        self.localsFilterEdit.setWhatsThis(
            self.tr(
                "Enter regular expression patterns separated by ';' to define "
                "variable filters. All variables and class attributes matched"
                " by one of the expressions are not shown in the list above."))
        
        self.setLocalsFilterButton = QPushButton(
            self.tr('Set'), self.lvWidget)
        self.lvWidgetHLayout2.addWidget(self.setLocalsFilterButton)
        self.lvWidgetVLayout.addLayout(self.lvWidgetHLayout2)
        
        index = self.__tabWidget.addTab(
            self.lvWidget,
            UI.PixmapCache.getIcon("localVariables.png"), '')
        self.__tabWidget.setTabToolTip(index, self.localsViewer.windowTitle())
        
        self.sourceButton.clicked.connect(self.__showSource)
        self.stackComboBox.currentIndexChanged[int].connect(
            self.__frameSelected)
        self.setLocalsFilterButton.clicked.connect(self.__setLocalsFilter)
        self.localsFilterEdit.returnPressed.connect(self.__setLocalsFilter)
        
        from .CallStackViewer import CallStackViewer
        # add the call stack viewer
        self.callStackViewer = CallStackViewer(self.debugServer)
        index = self.__tabWidget.addTab(
            self.callStackViewer,
            UI.PixmapCache.getIcon("step.png"), "")
        self.__tabWidget.setTabToolTip(
            index, self.callStackViewer.windowTitle())
        self.callStackViewer.sourceFile.connect(self.sourceFile)
        self.callStackViewer.frameSelected.connect(
            self.__callStackFrameSelected)
        
        from .CallTraceViewer import CallTraceViewer
        # add the call trace viewer
        self.callTraceViewer = CallTraceViewer(self.debugServer)
        index = self.__tabWidget.addTab(
            self.callTraceViewer,
            UI.PixmapCache.getIcon("callTrace.png"), "")
        self.__tabWidget.setTabToolTip(
            index, self.callTraceViewer.windowTitle())
        self.callTraceViewer.sourceFile.connect(self.sourceFile)
        
        from .BreakPointViewer import BreakPointViewer
        # add the breakpoint viewer
        self.breakpointViewer = BreakPointViewer()
        self.breakpointViewer.setModel(self.debugServer.getBreakPointModel())
        index = self.__tabWidget.addTab(
            self.breakpointViewer,
            UI.PixmapCache.getIcon("breakpoints.png"), '')
        self.__tabWidget.setTabToolTip(
            index, self.breakpointViewer.windowTitle())
        self.breakpointViewer.sourceFile.connect(self.sourceFile)
        
        from .WatchPointViewer import WatchPointViewer
        # add the watch expression viewer
        self.watchpointViewer = WatchPointViewer()
        self.watchpointViewer.setModel(self.debugServer.getWatchPointModel())
        index = self.__tabWidget.addTab(
            self.watchpointViewer,
            UI.PixmapCache.getIcon("watchpoints.png"), '')
        self.__tabWidget.setTabToolTip(
            index, self.watchpointViewer.windowTitle())
        
        from .ExceptionLogger import ExceptionLogger
        # add the exception logger
        self.exceptionLogger = ExceptionLogger()
        index = self.__tabWidget.addTab(
            self.exceptionLogger,
            UI.PixmapCache.getIcon("exceptions.png"), '')
        self.__tabWidget.setTabToolTip(
            index, self.exceptionLogger.windowTitle())
        
        if self.embeddedShell:
            self.__tabWidget.setCurrentWidget(self.shellAssembly)
        else:
            if self.embeddedBrowser:
                self.__tabWidget.setCurrentWidget(self.browser)
            else:
                self.__tabWidget.setCurrentWidget(self.glvWidget)
        
        # add the threads viewer
        self.__mainLayout.addWidget(QLabel(self.tr("Threads:")))
        self.__threadList = QTreeWidget()
        self.__threadList.setHeaderLabels(
            [self.tr("ID"), self.tr("Name"),
             self.tr("State"), ""])
        self.__threadList.setSortingEnabled(True)
        self.__mainLayout.addWidget(self.__threadList)
        
        self.__doThreadListUpdate = True
        
        self.__threadList.currentItemChanged.connect(self.__threadSelected)
        
        self.__mainLayout.setStretchFactor(self.__tabWidget, 5)
        self.__mainLayout.setStretchFactor(self.__threadList, 1)
        
        self.currPage = None
        self.currentStack = None
        self.framenr = 0
        
        self.debugServer.clientStack.connect(self.handleClientStack)
        
        self.__autoViewSource = Preferences.getDebugger("AutoViewSourceCode")
        self.sourceButton.setVisible(not self.__autoViewSource)
        
    def preferencesChanged(self):
        """
        Public slot to handle the preferencesChanged signal.
        """
        self.__autoViewSource = Preferences.getDebugger("AutoViewSourceCode")
        self.sourceButton.setVisible(not self.__autoViewSource)
        
    def setDebugger(self, debugUI):
        """
        Public method to set a reference to the Debug UI.
        
        @param debugUI reference to the DebugUI object (DebugUI)
        """
        self.debugUI = debugUI
        self.debugUI.clientStack.connect(self.handleClientStack)
        self.callStackViewer.setDebugger(debugUI)
        
    def handleResetUI(self):
        """
        Public method to reset the SBVviewer.
        """
        self.globalsViewer.handleResetUI()
        self.localsViewer.handleResetUI()
        self.__setGlobalsFilter()
        self.__setLocalsFilter()
        self.sourceButton.setEnabled(False)
        self.currentStack = None
        self.stackComboBox.clear()
        self.__threadList.clear()
        if self.embeddedShell:
            self.__tabWidget.setCurrentWidget(self.shellAssembly)
        else:
            if self.embeddedBrowser:
                self.__tabWidget.setCurrentWidget(self.browser)
            else:
                self.__tabWidget.setCurrentWidget(self.glvWidget)
        self.breakpointViewer.handleResetUI()
        
    def handleRawInput(self):
        """
        Public slot to handle the switch to the shell in raw input mode.
        """
        if self.embeddedShell:
            self.saveCurrentPage()
            self.__tabWidget.setCurrentWidget(self.shellAssembly)
        
    def initCallStackViewer(self, projectMode):
        """
        Public method to initialize the call stack viewer.
        
        @param projectMode flag indicating to enable the project mode (boolean)
        """
        self.callStackViewer.clear()
        self.callStackViewer.setProjectMode(projectMode)
        
    def isCallTraceEnabled(self):
        """
        Public method to get the state of the call trace function.
        
        @return flag indicating the state of the call trace function (boolean)
        """
        return self.callTraceViewer.isCallTraceEnabled()
        
    def clearCallTrace(self):
        """
        Public method to clear the recorded call trace.
        """
        self.callTraceViewer.clear()
        
    def setCallTraceToProjectMode(self, enabled):
        """
        Public slot to set the call trace viewer to project mode.
        
        In project mode the call trace info is shown with project relative
        path names.
        
        @param enabled flag indicating to enable the project mode (boolean)
        """
        self.callTraceViewer.setProjectMode(enabled)
        
    def showVariables(self, vlist, globals):
        """
        Public method to show the variables in the respective window.
        
        @param vlist list of variables to display
        @param globals flag indicating global/local state
        """
        if globals:
            self.globalsViewer.showVariables(vlist, self.framenr)
        else:
            self.localsViewer.showVariables(vlist, self.framenr)
            
    def showVariable(self, vlist, globals):
        """
        Public method to show the variables in the respective window.
        
        @param vlist list of variables to display
        @param globals flag indicating global/local state
        """
        if globals:
            self.globalsViewer.showVariable(vlist)
        else:
            self.localsViewer.showVariable(vlist)
            
    def showVariablesTab(self, globals):
        """
        Public method to make a variables tab visible.
        
        @param globals flag indicating global/local state
        """
        if globals:
            self.__tabWidget.setCurrentWidget(self.glvWidget)
        else:
            self.__tabWidget.setCurrentWidget(self.lvWidget)
        
    def saveCurrentPage(self):
        """
        Public slot to save the current page.
        """
        self.currPage = self.__tabWidget.currentWidget()
        
    def restoreCurrentPage(self):
        """
        Public slot to restore the previously saved page.
        """
        if self.currPage is not None:
            self.__tabWidget.setCurrentWidget(self.currPage)
            
    def handleClientStack(self, stack):
        """
        Public slot to show the call stack of the program being debugged.
        
        @param stack list of tuples with call stack data (file name,
            line number, function name, formatted argument/values list)
        """
        block = self.stackComboBox.blockSignals(True)
        self.framenr = 0
        self.stackComboBox.clear()
        self.currentStack = stack
        self.sourceButton.setEnabled(len(stack) > 0)
        for s in stack:
            # just show base filename to make it readable
            s = (os.path.basename(s[0]), s[1], s[2])
            self.stackComboBox.addItem('{0}:{1}:{2}'.format(*s))
        self.stackComboBox.blockSignals(block)
        
    def setVariablesFilter(self, globalsFilter, localsFilter):
        """
        Public slot to set the local variables filter.
        
        @param globalsFilter filter list for global variable types
            (list of int)
        @param localsFilter filter list for local variable types (list of int)
        """
        self.globalsFilter = globalsFilter
        self.localsFilter = localsFilter
        
    def __showSource(self):
        """
        Private slot to handle the source button press to show the selected
        file.
        """
        index = self.stackComboBox.currentIndex()
        if index > -1 and self.currentStack:
            s = self.currentStack[index]
            self.sourceFile.emit(s[0], int(s[1]))
        
    def __frameSelected(self, frmnr):
        """
        Private slot to handle the selection of a new stack frame number.
        
        @param frmnr frame number (0 is the current frame) (int)
        """
        self.framenr = frmnr
        self.debugServer.remoteClientVariables(0, self.localsFilter, frmnr)
        
        if self.__autoViewSource:
            self.__showSource()
        
    def __setGlobalsFilter(self):
        """
        Private slot to set the global variable filter.
        """
        filter = self.globalsFilterEdit.text()
        self.debugServer.remoteClientSetFilter(1, filter)
        self.debugServer.remoteClientVariables(2, self.globalsFilter)
        
    def __setLocalsFilter(self):
        """
        Private slot to set the local variable filter.
        """
        filter = self.localsFilterEdit.text()
        self.debugServer.remoteClientSetFilter(0, filter)
        if self.currentStack:
            self.debugServer.remoteClientVariables(
                0, self.localsFilter, self.framenr)
        
    def handleDebuggingStarted(self):
        """
        Public slot to handle the start of a debugging session.
        
        This slot sets the variables filter expressions.
        """
        self.__setGlobalsFilter()
        self.__setLocalsFilter()
        self.showVariablesTab(False)
        
    def currentWidget(self):
        """
        Public method to get a reference to the current widget.
        
        @return reference to the current widget (QWidget)
        """
        return self.__tabWidget.currentWidget()
        
    def setCurrentWidget(self, widget):
        """
        Public slot to set the current page based on the given widget.
        
        @param widget reference to the widget (QWidget)
        """
        self.__tabWidget.setCurrentWidget(widget)
        
    def showThreadList(self, currentID, threadList):
        """
        Public method to show the thread list.
        
        @param currentID id of the current thread (integer)
        @param threadList list of dictionaries containing the thread data
        """
        citm = None
        
        self.__threadList.clear()
        for thread in threadList:
            if thread['broken']:
                state = self.tr("waiting at breakpoint")
            else:
                state = self.tr("running")
            itm = QTreeWidgetItem(self.__threadList,
                                  ["{0:d}".format(thread['id']),
                                   thread['name'], state])
            if thread['id'] == currentID:
                citm = itm
        
        self.__threadList.header().resizeSections(QHeaderView.ResizeToContents)
        self.__threadList.header().setStretchLastSection(True)
        
        if citm:
            self.__doThreadListUpdate = False
            self.__threadList.setCurrentItem(citm)
            self.__doThreadListUpdate = True
        
    def __threadSelected(self, current, previous):
        """
        Private slot to handle the selection of a thread in the thread list.
        
        @param current reference to the new current item (QTreeWidgetItem)
        @param previous reference to the previous current item
            (QTreeWidgetItem)
        """
        if current is not None and self.__doThreadListUpdate:
            tid = int(current.text(0))
            self.debugServer.remoteSetThread(tid)
    
    def __callStackFrameSelected(self, frameNo):
        """
        Private slot to handle the selection of a call stack entry of the
        call stack viewer.
        
        @param frameNo frame number (index) of the selected entry (integer)
        """
        if frameNo >= 0:
            self.stackComboBox.setCurrentIndex(frameNo)
Exemplo n.º 28
0
class RadioStationWidget(QDialog):
    """

    """
    listen_radio_station_signal = pyqtSignal(str, str)
    """在线收听"""
    def __init__(self):
        super(RadioStationWidget, self).__init__()

        self.radio_station_type_label = QLabel('电台类别: ')
        self.radio_station_type_combobox = QComboBox()
        self.radio_station_type_combobox.currentIndexChanged.connect(
            self.answer_radio_station_type_combobox_current_index_changed)
        self.radio_station_type_list = ['通用', '地方']

        self.radio_station_id_label = QLabel('电台频道: ')
        self.radio_station_id_combobox = QComboBox()
        self.radio_station_id_combobox.currentIndexChanged.connect(
            self.answer_radio_station_id_combobox_current_index_changed)
        self.universal_radio_station_id_list = [
            "中国交通广播",
            "环球资讯广播 FM90.5",
            "中文环球广播",
            "经典音乐广播 101.8",
            "哈语广播",
            "藏语广播",
            "维语广播",
            "中国乡村之声",
            "经济之声",
            "中国之声",
            "音乐之声",
            "中华之声",
            "神州之声",
            "华夏之声",
            "香港之声",
            "文艺之声",
            "老年之声",
            "闽南之音",
            "南海之声",
            "客家之声",
            "海峡飞虹",
            "轻松调频 FM91.5",
            "Hit FM FM88.7",
        ]
        self.local_radio_station_id_list = [
            "北京新闻广播 FM100.6",
            "北京音乐广播 FM97.4",
            "北京交通广播 FM103.9",
            "北京文艺广播 FM87.6",
            "北京欢乐时光 FM106.5",
            "北京怀旧金曲 FM107.5",
            "北京古典音乐 FM98.6",
            "北京教学广播 FM99.4",
            "北京长书广播 FM104.3",
            "北京戏曲曲艺 FM105.1",
            "北京房山经典音乐 FM96.9",
            "北京好音乐 FM95.9",
            "重庆新闻广播 FM96.8",
            "重庆经济广播 FM101.5",
            "重庆交通广播 FM95.5",
            "重庆音乐广播 FM88.1",
            "重庆都市广播 FM93.8",
            "重庆文艺广播 FM103.5",
            "巴渝之声 FM104.5"
            "南川人民广播电台 FM107.0",
            "万盛旅游交通广播 FM92.2",
            "万州交通广播",
            "福建新闻广播 FM103.6",
            "福建经济广播 FM96.1",
            "福建音乐广播 FM91.3",
            "福建交通广播 FM100.7",
            "福建东南广播 AM585",
            "福建私家车广播 FM98.7",
            "甘肃新闻综合广播 FM96.1",
            "甘肃都市调频 FM106.6",
            "甘肃交通广播 FM93.4",
            "甘肃经济广播 FM93.4",
            "甘肃农村广播 FM92.2",
            "兰州新闻综合广播 FM97.3",
            "兰州交通音乐广播 FM99.5",
            "兰州生活文艺广播 FM100.8",
            "广东新闻频道 FM91.4",
            "广东珠江经济台 FM97.4",
            "广东音乐之声 FM99.3",
            "广东城市之声 FM103.6",
            "广东南方生活广播 FM93.6",
            "广东羊城交通广播 FM105.2",
            "广东文体广播 FM107.7",
            "广东股市广播 FM95.3",
            "广东优悦广播 FM105.7",
            "广州新闻电台 FM96.2",
            "广州汽车音乐电台 FM102.7",
            "广州交通电台 FM106.1",
            "东莞音乐广播 FM104",
            "东莞交通广播",
            "当涂人民广播电台 FM90.1",
        ]

        self.search_result_label = QLabel('获取结果: ')
        self.audio_result_line_edit = QLineEdit()
        self.audio_result_line_edit.setReadOnly(True)

        self.get_audio_btn = QPushButton('获取音频源')
        self.get_audio_btn.clicked.connect(self.answer_get_audio_btn_clicked)
        self.copy_audio_btn = QPushButton('复制音频源')
        self.copy_audio_btn.setDisabled(True)
        self.copy_audio_btn.clicked.connect(self.answer_copy_audio_btn_clicked)
        self.listen_audio_btn = QPushButton('在线收听')
        self.listen_audio_btn.setDisabled(True)
        self.listen_audio_btn.clicked.connect(
            self.answer_watch_audio_btn_clicked)
        self.clean_btn = QPushButton('信息清空')
        self.clean_btn.clicked.connect(self.answer_clean_btn_clicked)

        self.init_ui()

    def init_ui(self):
        """

        :return:
        """
        self.radio_station_type_combobox.addItems(self.radio_station_type_list)
        self.radio_station_id_combobox.addItems(
            self.universal_radio_station_id_list)

        radio_station_type_layout = QHBoxLayout()
        radio_station_type_layout.setContentsMargins(10, 10, 10, 10)
        radio_station_type_layout.setSpacing(5)
        radio_station_type_layout.addWidget(self.radio_station_type_label)
        radio_station_type_layout.addWidget(self.radio_station_type_combobox)
        radio_station_type_layout.addStretch()

        radio_station_id_layout = QHBoxLayout()
        radio_station_id_layout.setContentsMargins(10, 10, 10, 10)
        radio_station_id_layout.setSpacing(5)
        radio_station_id_layout.addWidget(self.radio_station_id_label)
        radio_station_id_layout.addWidget(self.radio_station_id_combobox)
        radio_station_id_layout.addStretch()

        search_result_layout = QHBoxLayout()
        search_result_layout.setContentsMargins(10, 10, 10, 10)
        search_result_layout.setSpacing(5)
        search_result_layout.addWidget(self.search_result_label)
        search_result_layout.addWidget(self.audio_result_line_edit)
        search_result_layout.addWidget(self.get_audio_btn)
        search_result_layout.addWidget(self.copy_audio_btn)
        search_result_layout.addWidget(self.listen_audio_btn)
        search_result_layout.addWidget(self.clean_btn)
        search_result_layout.addStretch()

        main_layout = QVBoxLayout()
        main_layout.setContentsMargins(0, 0, 0, 0)
        main_layout.setSpacing(0)
        main_layout.addLayout(radio_station_type_layout)
        main_layout.addLayout(radio_station_id_layout)
        main_layout.addLayout(search_result_layout)
        self.setLayout(main_layout)

        self.setWindowTitle("广播电台")
        self.setWindowIcon(QIcon('./resources/img/[email protected]'))
        self.setWindowFlags(Qt.WindowCloseButtonHint)

    def answer_radio_station_type_combobox_current_index_changed(self, index):
        """

        :param index:
        :return:
        """
        self.radio_station_id_combobox.clear()
        if index == 0:
            self.radio_station_id_combobox.addItems(
                self.universal_radio_station_id_list)
        else:
            self.radio_station_id_combobox.addItems(
                self.local_radio_station_id_list)
        self.copy_audio_btn.setDisabled(True)
        self.listen_audio_btn.setDisabled(True)

    def answer_radio_station_id_combobox_current_index_changed(self, index):
        """

        :param index:
        :return:
        """
        self.copy_audio_btn.setDisabled(True)
        self.listen_audio_btn.setDisabled(True)

    def answer_get_audio_btn_clicked(self):
        """

        :return:
        """
        result = get_real_url_from_radio_station_content(
            self.radio_station_type_combobox.currentText(),
            self.radio_station_id_combobox.currentText())
        print("search result: ", result)
        if result:
            self.audio_result_line_edit.setText(result)
            self.copy_audio_btn.setDisabled(False)
            self.listen_audio_btn.setDisabled(False)
        else:
            self.copy_audio_btn.setDisabled(True)
            self.listen_audio_btn.setDisabled(True)
            _box = PromptBox(2, "获取结果失败!", 1)
            width, height = get_window_center_point(_box)
            _box.move(width, height)
            _box.exec_()

    def answer_copy_audio_btn_clicked(self):
        """

        :return:
        """
        clipboard = QApplication.clipboard()
        clipboard.setText(self.audio_result_line_edit.text())
        _box = PromptBox(0, "已复制音频源到剪切板!", 1)
        width, height = get_window_center_point(_box)
        _box.move(width, height)
        _box.exec_()

    def answer_watch_audio_btn_clicked(self):
        """

        :return:
        """
        self.close()
        self.listen_radio_station_signal.emit(
            self.audio_result_line_edit.text(), PlayerEnum.MrlTypeRS.value[1])

    def answer_clean_btn_clicked(self):
        """

        :return:
        """
        self.radio_station_type_combobox.setCurrentIndex(0)
        self.radio_station_id_combobox.setCurrentIndex(0)
        self.audio_result_line_edit.clear()
        self.copy_audio_btn.setDisabled(True)
        self.listen_audio_btn.setDisabled(True)
Exemplo n.º 29
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        centralWidget = QWidget()

        fontLabel = QLabel("Font:")
        self.fontCombo = QFontComboBox()
        sizeLabel = QLabel("Size:")
        self.sizeCombo = QComboBox()
        styleLabel = QLabel("Style:")
        self.styleCombo = QComboBox()
        fontMergingLabel = QLabel("Automatic Font Merging:")
        self.fontMerging = QCheckBox()
        self.fontMerging.setChecked(True)

        self.scrollArea = QScrollArea()
        self.characterWidget = CharacterWidget()
        self.scrollArea.setWidget(self.characterWidget)

        self.findStyles(self.fontCombo.currentFont())
        self.findSizes(self.fontCombo.currentFont())

        self.lineEdit = QLineEdit()
        clipboardButton = QPushButton("&To clipboard")

        self.clipboard = QApplication.clipboard()

        self.fontCombo.currentFontChanged.connect(self.findStyles)
        self.fontCombo.activated[str].connect(self.characterWidget.updateFont)
        self.styleCombo.activated[str].connect(self.characterWidget.updateStyle)
        self.sizeCombo.currentIndexChanged[str].connect(self.characterWidget.updateSize)
        self.characterWidget.characterSelected.connect(self.insertCharacter)
        clipboardButton.clicked.connect(self.updateClipboard)

        controlsLayout = QHBoxLayout()
        controlsLayout.addWidget(fontLabel)
        controlsLayout.addWidget(self.fontCombo, 1)
        controlsLayout.addWidget(sizeLabel)
        controlsLayout.addWidget(self.sizeCombo, 1)
        controlsLayout.addWidget(styleLabel)
        controlsLayout.addWidget(self.styleCombo, 1)
        controlsLayout.addWidget(fontMergingLabel)
        controlsLayout.addWidget(self.fontMerging, 1)
        controlsLayout.addStretch(1)

        lineLayout = QHBoxLayout()
        lineLayout.addWidget(self.lineEdit, 1)
        lineLayout.addSpacing(12)
        lineLayout.addWidget(clipboardButton)

        centralLayout = QVBoxLayout()
        centralLayout.addLayout(controlsLayout)
        centralLayout.addWidget(self.scrollArea, 1)
        centralLayout.addSpacing(4)
        centralLayout.addLayout(lineLayout)
        centralWidget.setLayout(centralLayout)

        self.setCentralWidget(centralWidget)
        self.setWindowTitle("Character Map")

    def findStyles(self, font):
        fontDatabase = QFontDatabase()
        currentItem = self.styleCombo.currentText()
        self.styleCombo.clear()

        for style in fontDatabase.styles(font.family()):
            self.styleCombo.addItem(style)

        styleIndex = self.styleCombo.findText(currentItem)
        if styleIndex == -1:
            self.styleCombo.setCurrentIndex(0)
        else:
            self.styleCombo.setCurrentIndex(styleIndex)

    def findSizes(self, font):
        fontDatabase = QFontDatabase()
        currentSize = self.sizeCombo.currentText()
        self.sizeCombo.blockSignals(True)
        self.sizeCombo.clear()

        if fontDatabase.isSmoothlyScalable(font.family(), fontDatabase.styleString(font)):
            for size in QFontDatabase.standardSizes():
                self.sizeCombo.addItem(str(size))
                self.sizeCombo.setEditable(True)
        else:
            for size in fontDatabase.smoothSizes(font.family(), fontDatabase.styleString(font)):
                self.sizeCombo.addItem(str(size))
                self.sizeCombo.setEditable(False)

        self.sizeCombo.blockSignals(False)

        sizeIndex = self.sizeCombo.findText(currentSize)
        if sizeIndex == -1:
            self.sizeCombo.setCurrentIndex(max(0, self.sizeCombo.count() / 3))
        else:
            self.sizeCombo.setCurrentIndex(sizeIndex)

    def insertCharacter(self, character):
        self.lineEdit.insert(character)

    def updateClipboard(self):
        self.clipboard.setText(self.lineEdit.text(), QClipboard.Clipboard)
        self.clipboard.setText(self.lineEdit.text(), QClipboard.Selection)
Exemplo n.º 30
0
class NewDocument(preferences.Group):
    def __init__(self, page):
        super(NewDocument, self).__init__(page)

        grid = QGridLayout()
        self.setLayout(grid)

        def changed():
            self.changed.emit()
            self.combo.setEnabled(self.template.isChecked())

        self.emptyDocument = QRadioButton(toggled=changed)
        self.lilyVersion = QRadioButton(toggled=changed)
        self.template = QRadioButton(toggled=changed)
        self.combo = QComboBox(currentIndexChanged=changed)

        grid.addWidget(self.emptyDocument, 0, 0, 1, 2)
        grid.addWidget(self.lilyVersion, 1, 0, 1, 2)
        grid.addWidget(self.template, 2, 0, 1, 1)
        grid.addWidget(self.combo, 2, 1, 1, 1)
        self.loadCombo()
        app.translateUI(self)

    def translateUI(self):
        self.setTitle(_("When creating new documents"))
        self.emptyDocument.setText(_("Create an empty document"))
        self.lilyVersion.setText(_("Create a document that contains the LilyPond version statement"))
        self.template.setText(_("Create a document from a template:"))
        from snippet import snippets
        for i, name in enumerate(self._names):
            self.combo.setItemText(i, snippets.title(name))

    def loadCombo(self):
        from snippet import snippets
        self._names = [name for name in snippets.names()
                        if snippets.get(name).variables.get('template')]
        self.combo.clear()
        self.combo.addItems([''] * len(self._names))

    def loadSettings(self):
        s = QSettings()
        ndoc = s.value("new_document", "empty", str)
        template = s.value("new_document_template", "", str)
        if template in self._names:
            self.combo.setCurrentIndex(self._names.index(template))
        if ndoc == "template":
            self.template.setChecked(True)
        elif ndoc == "version":
            self.lilyVersion.setChecked(True)
        else:
            self.emptyDocument.setChecked(True)

    def saveSettings(self):
        s = QSettings()
        if self._names and self.template.isChecked():
            s.setValue("new_document", "template")
            s.setValue("new_document_template", self._names[self.combo.currentIndex()])
        elif self.lilyVersion.isChecked():
            s.setValue("new_document", "version")
        else:
            s.setValue("new_document", "empty")
class IterationTable(QWidget):
    """Widget that handles pipeline iteration.

    Methods:
        - add_tag: adds a tag to visualize in the iteration table
        - emit_iteration_table_updated: emits a signal when the iteration
           scans have been updated
        - fill_values: fill values_list depending on the visualized tags
        - refresh_layout: updates the layout of the widget
        - remove_tag: removes a tag to visualize in the iteration table
        - select_iterated_tag: opens a pop-up to let the user select on which
           tag to iterate
        - select_visualized_tag: opens a pop-up to let the user select which
           tag to visualize in the iteration table
        - update_iterated_tag: updates the widget
        - update_table: updates the iteration table

    """

    iteration_table_updated = pyqtSignal(list)

    def __init__(self, project, scan_list, main_window):
        """
        Initialization of the IterationTable widget

        :param project: current project in the software
        :param scan_list: list of the selected database files
        :param main_window: software's main_window
        """

        QWidget.__init__(self)

        #Necessary for using MIA bricks
        ProcessMIA.project = project

        self.project = project

        if not scan_list:
            self.scan_list = self.project.session.get_documents_names(
                COLLECTION_CURRENT)
        else:
            self.scan_list = scan_list

        self.main_window = main_window
        self.iterated_tag = None

        # values_list will contain the different values of each selected tag
        self.values_list = [[], []]

        # Checkbox to choose to iterate the pipeline or not
        self.check_box_iterate = QCheckBox("Iterate pipeline")
        self.check_box_iterate.stateChanged.connect(
            self.emit_iteration_table_updated)

        # Label "Iterate over:"
        self.label_iterate = QLabel("Iterate over:")

        # Label that displays the name of the selected tag
        self.iterated_tag_label = QLabel("Select a tag")

        # Push button to select the tag to iterate
        self.iterated_tag_push_button = QPushButton("Select")
        self.iterated_tag_push_button.clicked.connect(
            self.select_iteration_tag)

        # QComboBox
        self.combo_box = QComboBox()
        self.combo_box.currentIndexChanged.connect(self.update_table)

        # QTableWidget
        self.iteration_table = QTableWidget()

        # Label tag
        self.label_tags = QLabel("Tags to visualize:")

        # Each push button will allow the user to visualize a tag in
        # the iteration browser
        push_button_tag_1 = QPushButton()
        push_button_tag_1.setText("SequenceName")
        push_button_tag_1.clicked.connect(
            lambda: self.select_visualized_tag(0))

        push_button_tag_2 = QPushButton()
        push_button_tag_2.setText("AcquisitionDate")
        push_button_tag_2.clicked.connect(
            lambda: self.select_visualized_tag(1))

        # The list of all the push buttons
        # (the user can add as many as he or she wants)
        self.push_buttons = []
        self.push_buttons.insert(0, push_button_tag_1)
        self.push_buttons.insert(1, push_button_tag_2)

        # Labels to add/remove a tag (a push button)
        self.add_tag_label = ClickableLabel()
        self.add_tag_label.setObjectName('plus')
        sources_images_dir = Config().getSourceImageDir()
        add_tag_picture = QPixmap(os.path.relpath(os.path.join(
            sources_images_dir, "green_plus.png")))
        add_tag_picture = add_tag_picture.scaledToHeight(15)
        self.add_tag_label.setPixmap(add_tag_picture)
        self.add_tag_label.clicked.connect(self.add_tag)

        self.remove_tag_label = ClickableLabel()
        remove_tag_picture = QPixmap(os.path.relpath(os.path.join(
            sources_images_dir, "red_minus.png")))
        remove_tag_picture = remove_tag_picture.scaledToHeight(20)
        self.remove_tag_label.setPixmap(remove_tag_picture)
        self.remove_tag_label.clicked.connect(self.remove_tag)

        # Layout
        self.v_layout = QVBoxLayout()
        self.setLayout(self.v_layout)
        self.refresh_layout()

    def add_tag(self):
        """Add a tag to visualize in the iteration table.

        Used only for tests
        """

        idx = len(self.push_buttons)
        push_button = QPushButton()
        push_button.setText('Tag n°' + str(len(self.push_buttons) + 1))
        push_button.clicked.connect(lambda: self.select_visualized_tag(idx))
        self.push_buttons.insert(len(self.push_buttons), push_button)
        self.refresh_layout()

    def emit_iteration_table_updated(self):
        """
        Emit a signal when the iteration scans have been updated

        """

        if self.check_box_iterate.checkState():
            if hasattr(self, 'scans'):
                self.iteration_table_updated.emit(self.iteration_scans)
            else:
                self.iteration_table_updated.emit(self.scan_list)
        else:
            self.iteration_table_updated.emit(self.scan_list)

    def fill_values(self, idx):
        """
        Fill values_list depending on the visualized tags

        :param idx:
        """

        """ Method that fills the values list when a tag is added
        or removed. """
        tag_name = self.push_buttons[idx].text()
        values = []
        for scan in self.project.session.get_documents_names(
                COLLECTION_CURRENT):
            current_value = self.project.session.get_value(COLLECTION_CURRENT,
                                                           scan, tag_name)
            if current_value is not None:
                values.append(current_value)

        idx_to_fill = len(self.values_list)
        while len(self.values_list) <= idx:
            self.values_list.insert(idx_to_fill, [])
            idx_to_fill += 1

        if self.values_list[idx] is not None:
            self.values_list[idx] = []

        for value in values:
            if value not in self.values_list[idx]:
                self.values_list[idx].append(value)

    def refresh_layout(self):
        """Update the layout of the widget.

        Called in widget's initialization and when a tag push button
        is added or removed.
        """

        first_v_layout = QVBoxLayout()
        first_v_layout.addWidget(self.check_box_iterate)

        second_v_layout = QVBoxLayout()
        second_v_layout.addWidget(self.label_iterate)
        second_v_layout.addWidget(self.iterated_tag_label)

        third_v_layout = QVBoxLayout()
        third_v_layout.addWidget(self.iterated_tag_push_button)
        third_v_layout.addWidget(self.combo_box)

        top_layout = QHBoxLayout()
        top_layout.addLayout(first_v_layout)
        top_layout.addLayout(second_v_layout)
        top_layout.addLayout(third_v_layout)

        self.v_layout.addLayout(top_layout)
        self.v_layout.addWidget(self.iteration_table)

        self.h_box = QHBoxLayout()
        self.h_box.setSpacing(10)
        self.h_box.addWidget(self.label_tags)

        for tag_label in self.push_buttons:
            self.h_box.addWidget(tag_label)

        self.h_box.addWidget(self.add_tag_label)
        self.h_box.addWidget(self.remove_tag_label)
        self.h_box.addStretch(1)

        self.v_layout.addLayout(self.h_box)

    def remove_tag(self):
        """Remove a tag to visualize in the iteration table.

        Used only for tests.
        """
        push_button = self.push_buttons[-1]
        push_button.deleteLater()
        push_button = None
        del self.push_buttons[-1]
        del self.values_list[-1]
        self.refresh_layout()

    def select_iteration_tag(self):
        """
        Open a pop-up to let the user select on which tag to iterate

        """

        ui_select = PopUpSelectTagCountTable(
            self.project,
            self.project.session.get_fields_names(COLLECTION_CURRENT),
            self.iterated_tag)
        if ui_select.exec_():
            self.update_iterated_tag(ui_select.selected_tag)

    def select_visualized_tag(self, idx):
        """Open a pop-up to let the user select which tag to visualize in the
           iteration table

        :param idx: index of the clicked push button
        """

        popUp = PopUpSelectTagCountTable(
            self.project,
            self.project.session.get_fields_names(COLLECTION_CURRENT),
            self.push_buttons[idx].text())
        if popUp.exec_():
            self.push_buttons[idx].setText(popUp.selected_tag)
            self.fill_values(idx)
            self.update_table()

    def update_iterated_tag(self, tag_name):
        """
        Update the widget when the iterated tag is modified

        :param tag_name: name of the iterated tag
        """

        if not self.scan_list:
            self.scan_list = self.project.session.get_documents_names(
                COLLECTION_CURRENT)

        self.iterated_tag_push_button.setText(tag_name)
        self.iterated_tag = tag_name
        self.iterated_tag_label.setText(tag_name + ":")

        # Update combo_box
        scans_names = self.project.session.get_documents_names(
            COLLECTION_CURRENT)
        scans_names = list(set(scans_names).intersection(self.scan_list))

        # tag_values_list contains all the values that can take iterated tag
        self.tag_values_list = []
        for scan_name in scans_names:
            tag_value = self.project.session.get_value(COLLECTION_CURRENT,
                                                       scan_name, tag_name)
            if str(tag_value) not in self.tag_values_list:
                self.tag_values_list.append(str(tag_value))

        self.combo_box.clear()
        self.combo_box.addItems(self.tag_values_list)

        self.update_table()

    def update_table(self):
        """
        Update the iteration table

        """

        # Updating the scan list
        if not self.scan_list:
            self.scan_list = self.project.session.get_documents_names(
                COLLECTION_CURRENT)

        # Clearing the table and preparing its columns
        self.iteration_table.clear()
        self.iteration_table.setColumnCount(len(self.push_buttons))

        # Headers
        for idx in range(len(self.push_buttons)):
            header_name = self.push_buttons[idx].text()
            if header_name not in self.project.session.get_fields_names(
                    COLLECTION_CURRENT):
                print("{0} not in the project's tags".format(header_name))
                return

            item = QTableWidgetItem()
            item.setText(header_name)
            self.iteration_table.setHorizontalHeaderItem(idx, item)

        # Searching the database scans that correspond to iterated tag value
        filter_query = "({" + self.iterated_tag + "} " + "==" + " \"" + \
                       self.combo_box.currentText() + "\")"
        scans_list = self.project.session.filter_documents(COLLECTION_CURRENT,
                                                           filter_query)
        scans_res = [getattr(document, TAG_FILENAME)
                     for document in scans_list]

        # Taking the intersection between the found database scans and the
        # user selection in the data_browser
        self.iteration_scans = list(
            set(scans_res).intersection(self.scan_list))
        self.iteration_table.setRowCount(len(self.iteration_scans))

        # Filling the table cells
        row = -1
        for scan_name in self.iteration_scans:
            row += 1
            for idx in range(len(self.push_buttons)):
                tag_name = self.push_buttons[idx].text()

                item = QTableWidgetItem()
                item.setText(str(self.project.session.get_value(
                    COLLECTION_CURRENT, scan_name, tag_name)))
                self.iteration_table.setItem(row, idx, item)

        # This will change the scans list in the current Pipeline Manager tab
        self.iteration_table_updated.emit(self.iteration_scans)
Exemplo n.º 32
0
class Gui(QWidget):
    def prepareWidgets(self):
        self.setWindowTitle('Spycer')

        self.locale = locales.getLocale()

        main_grid = QGridLayout()
        main_grid.addWidget(self.init3dWidget(), 0, 0, 20, 5)
        main_grid.addLayout(self.initRightPanel(), 0, 5, 20, 2)

        self.bottom_panel = self.initBottomPanel()
        self.bottom_panel.setEnabled(False)
        main_grid.addWidget(self.bottom_panel, 20, 0, 2, 7)

        self.setLayout(main_grid)

        self.planeActor = gui_utils.createPlaneActorCircle()
        self.planeTransform = vtk.vtkTransform()
        self.render.AddActor(self.planeActor)

        self.stateNothing()
        self.render.ResetCamera()

        self.planes = []
        self.planesActors = []

        self.openedStl = "/home/l1va/Downloads/1_odn2.stl"  # TODO: removeme
        self.loadSTL(self.openedStl)
        # self.colorizeModel()

    def init3dWidget(self):
        widget3d = QVTKRenderWindowInteractor()
        widget3d.Initialize()
        widget3d.Start()
        self.render = vtk.vtkRenderer()
        self.render.SetBackground(params.BackgroundColor)
        widget3d.GetRenderWindow().AddRenderer(self.render)
        self.interactor = widget3d.GetRenderWindow().GetInteractor()
        self.interactor.GetInteractorStyle().SetCurrentStyleToTrackballCamera()
        self.axesWidget = gui_utils.createAxes(self.interactor)
        return widget3d

    def initRightPanel(self):
        right_panel = QGridLayout()
        right_panel.setSpacing(5)
        right_panel.setColumnStretch(0, 2)

        # Front-end development at its best
        self.cur_row = 1
        def get_next_row():
            self.cur_row += 1
            return self.cur_row
        def get_cur_row():
            return self.cur_row

        thickness_label = QLabel(self.locale.Thickness)
        self.thickness_value = QLineEdit("0.2")
        right_panel.addWidget(thickness_label, get_next_row(), 1)
        right_panel.addWidget(self.thickness_value, get_cur_row(), 2)

        printSpeed_label = QLabel(self.locale.PrintSpeed)
        self.printSpeed_value = QLineEdit("50")
        right_panel.addWidget(printSpeed_label, get_next_row(), 1)
        right_panel.addWidget(self.printSpeed_value, get_cur_row(), 2)

        printSpeedLayer1_label = QLabel(self.locale.PrintSpeedLayer1)
        self.printSpeedLayer1_value = QLineEdit("50")
        right_panel.addWidget(printSpeedLayer1_label, get_next_row(), 1)
        right_panel.addWidget(self.printSpeedLayer1_value, get_cur_row(), 2)

        printSpeedWall_label = QLabel(self.locale.PrintSpeedWall)
        self.printSpeedWall_value = QLineEdit("50")
        right_panel.addWidget(printSpeedWall_label, get_next_row(), 1)
        right_panel.addWidget(self.printSpeedWall_value, get_cur_row(), 2)

        extruderTemp_label = QLabel(self.locale.ExtruderTemp)
        self.extruderTemp_value = QLineEdit("200")
        right_panel.addWidget(extruderTemp_label, get_next_row(), 1)
        right_panel.addWidget(self.extruderTemp_value, get_cur_row(), 2)

        bedTemp_label = QLabel(self.locale.BedTemp)
        self.bedTemp_value = QLineEdit("60")
        right_panel.addWidget(bedTemp_label, get_next_row(), 1)
        right_panel.addWidget(self.bedTemp_value, get_cur_row(), 2)

        fillDensity_label = QLabel(self.locale.FillDensity)
        self.fillDensity_value = QLineEdit("20")
        right_panel.addWidget(fillDensity_label, get_next_row(), 1)
        right_panel.addWidget(self.fillDensity_value, get_cur_row(), 2)

        wallThickness_label = QLabel(self.locale.WallThickness)
        self.wallThickness_value = QLineEdit("0.8")
        right_panel.addWidget(wallThickness_label, get_next_row(), 1)
        right_panel.addWidget(self.wallThickness_value, get_cur_row(), 2)

        nozzle_label = QLabel(self.locale.Nozzle)
        self.nozzle_value = QLineEdit("0.4")
        right_panel.addWidget(nozzle_label, get_next_row(), 1)
        right_panel.addWidget(self.nozzle_value, get_cur_row(), 2)

        filling_type_label = QLabel(self.locale.FillingType)
        right_panel.addWidget(filling_type_label, get_next_row(), 1)
        # todo fix displaying shifting (feature is below)
        right_panel.addWidget(self.nozzle_value, get_cur_row(), 2)
        filling_type_valuesW = QWidget()
        self.filling_type_values = QComboBox(filling_type_valuesW)
        self.filling_type_values.addItems(self.locale.FillingTypeValues)
        right_panel.addWidget(filling_type_valuesW, get_cur_row(), 2)


        self.fanOffLayer1_box = QCheckBox(self.locale.FanOffLayer1)
        right_panel.addWidget(self.fanOffLayer1_box, get_next_row(), 1)

        self.modelSwitch_box = QCheckBox(self.locale.ShowStl)
        self.modelSwitch_box.stateChanged.connect(self.switchModels)
        right_panel.addWidget(self.modelSwitch_box, get_next_row(), 1)

        self.slider_label = QLabel(self.locale.LayersCount)
        self.layersNumber_label = QLabel()
        right_panel.addWidget(self.slider_label, get_next_row(), 1)
        right_panel.addWidget(self.layersNumber_label, get_cur_row(), 2)

        self.pictureSlider = QSlider()
        self.pictureSlider.setOrientation(QtCore.Qt.Horizontal)
        self.pictureSlider.setMinimum(1)
        self.pictureSlider.setValue(1)
        self.pictureSlider.valueChanged.connect(self.changeLayerView)
        right_panel.addWidget(self.pictureSlider, get_next_row(), 1, 1, 2)

        self.xPosition_value = QLineEdit("0")
        right_panel.addWidget(self.xPosition_value, get_next_row(), 1)
        self.yPosition_value = QLineEdit("0")
        right_panel.addWidget(self.yPosition_value, get_cur_row(), 2)
        self.zPosition_value = QLineEdit("0")
        right_panel.addWidget(self.zPosition_value, get_next_row(), 1)
        self.move_button = QPushButton(self.locale.MoveModel)
        self.move_button.clicked.connect(self.moveModel)
        right_panel.addWidget(self.move_button, get_cur_row(), 2, 1, 1)

        loadModel_button = QPushButton(self.locale.OpenModel)
        loadModel_button.clicked.connect(self.openFile)
        right_panel.addWidget(loadModel_button, get_next_row(), 1, 1, 1)

        self.editPlanes_button = QPushButton("Редактировать")  # TODO: locales
        self.editPlanes_button.clicked.connect(lambda: self.loadSTL(self.openedStl))
        right_panel.addWidget(self.editPlanes_button, get_cur_row(), 2, 1, 1)

        self.slice3a_button = QPushButton(self.locale.Slice3Axes)
        self.slice3a_button.clicked.connect(lambda: self.sliceSTL("3axes"))
        right_panel.addWidget(self.slice3a_button, get_next_row(), 1, 1, 1)

        self.sliceVip_button = QPushButton(self.locale.SliceVip)
        self.sliceVip_button.clicked.connect(lambda: self.sliceSTL("vip"))
        right_panel.addWidget(self.sliceVip_button, get_cur_row(), 2, 1, 1)

        self.saveGCode_button = QPushButton(self.locale.SaveGCode)
        self.saveGCode_button.clicked.connect(self.saveGCodeFile)
        right_panel.addWidget(self.saveGCode_button, get_next_row(), 1, 1, 1)

        self.analyzeModel_button = QPushButton("Анализировать")  # TODO: locales
        self.analyzeModel_button.clicked.connect(self.analyzeModel)
        right_panel.addWidget(self.analyzeModel_button, get_cur_row(), 2, 1, 1)

        self.colorizeAngle_value = QLineEdit("30")
        right_panel.addWidget(self.colorizeAngle_value, get_next_row(), 1)

        self.colorModel_button = QPushButton(self.locale.ColorModel)
        self.colorModel_button.clicked.connect(self.colorizeModel)
        right_panel.addWidget(self.colorModel_button, get_cur_row(), 2, 1, 1)

        return right_panel

    def initBottomPanel(self):

        bottom_layout = QGridLayout()
        bottom_layout.setSpacing(5)
        bottom_layout.setColumnStretch(7, 1)

        self.addPlane_button = QPushButton("Добавить")
        self.addPlane_button.clicked.connect(self.addPlane)
        bottom_layout.addWidget(self.addPlane_button, 1, 0)

        comboW = QWidget()
        self.combo = QComboBox(comboW)
        self.combo.currentIndexChanged.connect(self.changeComboSelect)
        bottom_layout.addWidget(comboW, 0, 0, 1, 2)

        self.removePlane_button = QPushButton("Удалить")
        self.removePlane_button.clicked.connect(self.removePlane)
        bottom_layout.addWidget(self.removePlane_button, 2, 0)

        self.tilted_checkbox = QCheckBox(self.locale.Tilted)
        self.tilted_checkbox.stateChanged.connect(self.applyPlaneChange)
        bottom_layout.addWidget(self.tilted_checkbox, 0, 3)

        x_label = QLabel("X:")  # TODO: to locales
        bottom_layout.addWidget(x_label, 0, 4)
        self.x_value = QLineEdit("3.0951")
        self.x_value.editingFinished.connect(self.applyEditsChange)
        bottom_layout.addWidget(self.x_value, 0, 5)

        y_label = QLabel("Y:")  # TODO: to locales
        bottom_layout.addWidget(y_label, 1, 4)
        self.y_value = QLineEdit("5.5910")
        self.y_value.editingFinished.connect(self.applyEditsChange)
        bottom_layout.addWidget(self.y_value, 1, 5)

        z_label = QLabel("Z:")  # TODO: to locales
        bottom_layout.addWidget(z_label, 2, 4)
        self.z_value = QLineEdit("89.5414")
        self.z_value.editingFinished.connect(self.applyEditsChange)
        bottom_layout.addWidget(self.z_value, 2, 5)

        rotated_label = QLabel("Повёрнута:")  # TODO: to locales
        bottom_layout.addWidget(rotated_label, 3, 4)
        self.rotated_value = QLineEdit("31.0245")
        self.rotated_value.editingFinished.connect(self.applyEditsChange)
        bottom_layout.addWidget(self.rotated_value, 3, 5)

        self.xSlider = QSlider()
        self.xSlider.setOrientation(QtCore.Qt.Horizontal)
        self.xSlider.setMinimum(-100)
        self.xSlider.setMaximum(100)
        self.xSlider.setValue(1)
        self.xSlider.valueChanged.connect(self.applyPlaneChange)
        bottom_layout.addWidget(self.xSlider, 0, 6, 1, 2)
        self.ySlider = QSlider()
        self.ySlider.setOrientation(QtCore.Qt.Horizontal)
        self.ySlider.setMinimum(-100)
        self.ySlider.setMaximum(100)
        self.ySlider.setValue(1)
        self.ySlider.valueChanged.connect(self.applyPlaneChange)
        bottom_layout.addWidget(self.ySlider, 1, 6, 1, 2)
        self.zSlider = QSlider()
        self.zSlider.setOrientation(QtCore.Qt.Horizontal)
        self.zSlider.setMinimum(0)
        self.zSlider.setMaximum(200)
        self.zSlider.setValue(1)
        self.zSlider.valueChanged.connect(self.applyPlaneChange)
        bottom_layout.addWidget(self.zSlider, 2, 6, 1, 2)
        self.rotSlider = QSlider()
        self.rotSlider.setOrientation(QtCore.Qt.Horizontal)
        self.rotSlider.setMinimum(-180)
        self.rotSlider.setMaximum(180)
        self.rotSlider.setValue(0)
        self.rotSlider.valueChanged.connect(self.applyPlaneChange)
        bottom_layout.addWidget(self.rotSlider, 3, 6, 1, 2)

        # self.applyPlane_button = QPushButton("Применить")  # TODO:
        # self.applyPlane_button.clicked.connect(self.applyPlaneChange)
        # bottom_layout.addWidget(self.applyPlane_button, 2, 2)

        bottom_panel = QWidget()
        bottom_panel.setLayout(bottom_layout)

        return bottom_panel

    def applyEditsChange(self):
        self.xSlider.setValue(float(self.x_value.text()))
        self.ySlider.setValue(float(self.y_value.text()))
        self.zSlider.setValue(float(self.z_value.text()))
        self.rotSlider.setValue(float(self.rotated_value.text()))

    def applyPlaneChange(self):
        self.x_value.setText(str(self.xSlider.value()))
        self.y_value.setText(str(self.ySlider.value()))
        self.z_value.setText(str(self.zSlider.value()))
        self.rotated_value.setText(str(self.rotSlider.value()))

        center = [float(self.xSlider.value()), float(self.ySlider.value()), float(self.zSlider.value())]
        ind = self.combo.currentIndex()
        if ind == -1:
            return
        self.planes[ind] = gui_utils.Plane(self.tilted_checkbox.isChecked(), float(self.rotSlider.value()), center)
        self.drawPlanes()

    def addPlane(self):
        if len(self.planes)==0:
            self.planes.append(gui_utils.Plane(True, 0, [10,10,10]))
        else:
            path = [self.planes[-1].x, self.planes[-1].y, self.planes[-1].z + 10]
            self.planes.append(gui_utils.Plane(False, 0, path))
        self.loadPlanes()

    def removePlane(self):
        ind = self.combo.currentIndex()
        if ind == -1:
            return
        del self.planes[ind]
        self.loadPlanes()

    def changeComboSelect(self):
        ind = self.combo.currentIndex()
        if ind==-1:
            return
        plane = self.planes[ind]
        self.tilted_checkbox.setChecked(plane.tilted)
        self.rotated_value.setText(str(plane.rot))
        self.x_value.setText(str(plane.x))
        self.y_value.setText(str(plane.y))
        self.z_value.setText(str(plane.z))
        self.xSlider.setValue(plane.x)
        self.ySlider.setValue(plane.y)
        self.zSlider.setValue(plane.z)
        self.rotSlider.setValue(plane.rot)
        self.planesActors[ind].GetProperty().SetColor(params.LastLayerColor)
        self.reloadScene()

    def loadPlanes(self):
        #if len(self.planes) == 0:
        #    self.bottom_panel.setEnabled(False)
        #    return

        #self.bottom_panel.setEnabled(True)

        self.combo.clear()
        for i in range(len(self.planes)):
            self.combo.addItem("Плоскость " + str(i + 1))

        self.changeComboSelect()

        self.drawPlanes()

    def drawPlanes(self):  # TODO: optimize
        for p in self.planesActors:
            self.render.RemoveActor(p)
        self.planesActors = []
        for p in self.planes:
            # rot = self.rotations[self.lays2rots[-1]]

            act = gui_utils.createPlaneActorCircleByCenterAndRot([p.x, p.y, p.z], -60 if p.tilted else 0, p.rot)
            # act = utils.createPlaneActorCircleByCenterAndRot([p.x, p.y, p.z], 0,0)
            # print("tilted" if p.tilted else "NOT")
            self.planesActors.append(act)
            self.render.AddActor(act)
        ind = self.combo.currentIndex()
        if ind != -1:
            self.planesActors[ind].GetProperty().SetColor(params.LastLayerColor)
        # print("was draw planes: ",len(self.planes))
        self.reloadScene()

    def stateNothing(self):
        self.modelSwitch_box.setEnabled(False)
        self.modelSwitch_box.setChecked(False)
        self.slider_label.setEnabled(False)
        self.layersNumber_label.setEnabled(False)
        self.layersNumber_label.setText(" ")
        self.currLayerNumber = 0
        self.pictureSlider.setEnabled(False)
        self.pictureSlider.setSliderPosition(0)
        self.move_button.setEnabled(False)
        self.slice3a_button.setEnabled(False)
        self.colorModel_button.setEnabled(False)
        self.editPlanes_button.setEnabled(False)
        # self.slice5aProfile_button.setEnabled(False)
        # self.slice5a_button.setEnabled(False)
        self.sliceVip_button.setEnabled(False)
        self.saveGCode_button.setEnabled(False)
        self.state = NothingState

    def stateGcode(self, layers_count):
        self.modelSwitch_box.setEnabled(False)
        self.modelSwitch_box.setChecked(False)
        self.slider_label.setEnabled(True)
        self.layersNumber_label.setEnabled(True)
        self.layersNumber_label.setText(str(layers_count))
        self.currLayerNumber = layers_count
        self.pictureSlider.setEnabled(True)
        self.pictureSlider.setMaximum(layers_count)
        self.pictureSlider.setSliderPosition(layers_count)
        self.move_button.setEnabled(False)
        self.slice3a_button.setEnabled(False)
        self.colorModel_button.setEnabled(False)
        self.editPlanes_button.setEnabled(True)
        # self.slice5aProfile_button.setEnabled(False)
        # self.slice5a_button.setEnabled(False)
        self.sliceVip_button.setEnabled(False)
        self.saveGCode_button.setEnabled(True)
        self.state = GCodeState

    def stateStl(self):
        self.modelSwitch_box.setEnabled(False)
        self.modelSwitch_box.setChecked(False)
        self.slider_label.setEnabled(False)
        self.layersNumber_label.setEnabled(False)
        self.layersNumber_label.setText(" ")
        self.currLayerNumber = 0
        self.pictureSlider.setEnabled(False)
        self.pictureSlider.setSliderPosition(0)
        self.move_button.setEnabled(True)
        self.slice3a_button.setEnabled(True)
        self.colorModel_button.setEnabled(True)
        self.editPlanes_button.setEnabled(False)
        # self.slice5aProfile_button.setEnabled(True)
        # self.slice5a_button.setEnabled(True)
        self.sliceVip_button.setEnabled(True)
        self.saveGCode_button.setEnabled(False)
        self.state = StlState

    def stateBoth(self, layers_count):
        self.modelSwitch_box.setEnabled(True)
        self.modelSwitch_box.setChecked(False)
        self.slider_label.setEnabled(True)
        self.layersNumber_label.setEnabled(True)
        self.layersNumber_label.setText(str(layers_count))
        self.currLayerNumber = layers_count
        self.pictureSlider.setEnabled(True)
        self.pictureSlider.setMaximum(layers_count)
        self.pictureSlider.setSliderPosition(layers_count)
        self.move_button.setEnabled(True)
        self.slice3a_button.setEnabled(True)
        self.colorModel_button.setEnabled(True)
        self.editPlanes_button.setEnabled(True)
        # self.slice5aProfile_button.setEnabled(True)
        # self.slice5a_button.setEnabled(True)
        self.sliceVip_button.setEnabled(True)
        self.saveGCode_button.setEnabled(True)
        self.state = BothState

    def moveModel(self):
        self.stlTranslation = [float(self.xPosition_value.text()), float(self.yPosition_value.text()),
                               float(self.zPosition_value.text())]
        print(self.stlTranslation)
        transform = vtk.vtkTransform()
        transform.Translate(self.stlTranslation[0], self.stlTranslation[1],
                            self.stlTranslation[2])
        self.stlActor.SetUserTransform(transform)
        self.reloadScene()

    def loadGCode(self, filename, addStl):
        gode = gcode.readGCode(filename)
        self.gode = gode
        blocks = gui_utils.makeBlocks(gode.layers)
        self.actors = gui_utils.wrapWithActors(blocks, gode.rotations, gode.lays2rots)

        self.clearScene()
        self.render.AddActor(self.planeActor)
        if addStl:
            self.render.AddActor(self.stlActor)

        self.rotatePlane(gode.rotations[-1])
        for actor in self.actors:
            self.render.AddActor(actor)

        #self.loadPlanes()
        self.bottom_panel.setEnabled(False)

        if addStl:
            self.stateBoth(len(self.actors))
        else:
            self.stateGcode(len(self.actors))

        self.openedGCode = filename
        self.render.ResetCamera()
        self.reloadScene()

    def loadSTL(self, filename, method=gui_utils.createStlActorInOrigin):
        self.stlActor, self.stlTranslation, self.stlBounds = method(filename)
        # self.xSlider.setMinimum(self.stlBounds[0])
        # self.xSlider.setMaximum(self.stlBounds[1])
        # self.ySlider.setMinimum(self.stlBounds[2])
        # self.ySlider.setMaximum(self.stlBounds[3])
        # self.zSlider.setMinimum(self.stlBounds[4])
        # self.zSlider.setMaximum(self.stlBounds[5])
        # print(self.stlTranslation)
        self.xPosition_value.setText(str(self.stlTranslation[0])[:10])
        self.yPosition_value.setText(str(self.stlTranslation[1])[:10])
        self.zPosition_value.setText(str(self.stlTranslation[2])[:10])

        self.clearScene()
        self.render.AddActor(self.planeActor)

        self.render.AddActor(self.stlActor)
        self.bottom_panel.setEnabled(True)
        self.loadPlanes()
        self.stateStl()
        self.openedStl = filename
        self.render.ResetCamera()
        self.reloadScene()

    def changeLayerView(self):
        newSliderValue = self.pictureSlider.value()

        self.actors[newSliderValue - 1].GetProperty().SetColor(params.LastLayerColor)
        self.actors[self.currLayerNumber - 1].GetProperty().SetColor(params.LayerColor)

        self.layersNumber_label.setText(str(newSliderValue))

        if newSliderValue < self.currLayerNumber:
            for layer in range(newSliderValue, self.currLayerNumber):
                self.actors[layer].VisibilityOff()
        else:
            for layer in range(self.currLayerNumber, newSliderValue):
                self.actors[layer].VisibilityOn()

        if self.gode.lays2rots[newSliderValue - 1] != self.gode.lays2rots[self.currLayerNumber - 1]:
            currRotation = self.gode.rotations[self.gode.lays2rots[newSliderValue - 1]]
            for block in range(newSliderValue):
                transform = vtk.vtkTransform()

                transform.PostMultiply()
                transform.RotateX(-self.gode.rotations[self.gode.lays2rots[block]].x_rot)
                transform.PostMultiply()
                transform.RotateZ(-self.gode.rotations[self.gode.lays2rots[block]].z_rot)

                transform.PostMultiply()
                transform.RotateZ(currRotation.z_rot)
                transform.PostMultiply()
                transform.RotateX(currRotation.x_rot)
                self.actors[block].SetUserTransform(transform)

            self.rotatePlane(currRotation)
            for i in range(len(self.planes)):
                self.rotateAnyPlane(self.planesActors[i], self.planes[i], currRotation)
        self.currLayerNumber = newSliderValue
        self.reloadScene()

    def rotatePlane(self, rotation):
        transform = vtk.vtkTransform()
        transform.PostMultiply()
        transform.RotateZ(rotation.z_rot)
        transform.PostMultiply()
        transform.RotateX(rotation.x_rot)
        self.planeActor.SetUserTransform(transform)
        self.planeTransform = transform

    def rotateAnyPlane(self, planeActor, plane, rotation):
        transform = vtk.vtkTransform()
        transform.PostMultiply()
        transform.RotateX(-60 if plane.tilted else 0)
        transform.PostMultiply()
        transform.RotateZ(plane.rot)
        transform.Translate(plane.x, plane.y, plane.z - 0.1)

        transform.PostMultiply()
        transform.RotateZ(rotation.z_rot)
        transform.PostMultiply()
        transform.RotateX(rotation.x_rot)
        planeActor.SetUserTransform(transform)

    def sliceSTL(self, slicing_type):
        values = {
            "stl": format_path(self.openedStl),
            "gcode": params.OutputGCode,
            "originx": self.stlTranslation[0],
            "originy": self.stlTranslation[1],
            "originz": self.stlTranslation[2],
            "rotcx": params.RotationCenter[0],
            "rotcy": params.RotationCenter[1],
            "rotcz": params.RotationCenter[2],

            "thickness": self.thickness_value.text(),
            "wall_thickness": self.wallThickness_value.text(),
            "fill_density": self.fillDensity_value.text(),
            "bed_temperature": self.bedTemp_value.text(),
            "extruder_temperature": self.extruderTemp_value.text(),
            "print_speed": self.printSpeed_value.text(),
            "print_speed_layer1": self.printSpeedLayer1_value.text(),
            "print_speed_wall": self.printSpeedWall_value.text(),
            "nozzle": self.nozzle_value.text(),
            "filling_type": locales.getLocaleByLang("en").FillingTypeValues[self.filling_type_values.currentIndex()],
            "slicing_type": slicing_type,
            "planes_file": params.PlanesFile,
        }
        self.savePlanesToFile()
        cmd = params.SliceCommand.format(**values)
        if self.fanOffLayer1_box.isChecked():
            cmd += " --fan_off_layer1"
        print(cmd)
        subprocess.check_output(str.split(cmd))
        self.stlActor.VisibilityOff()
        self.loadGCode(params.OutputGCode, True)

    def savePlanesToFile(self):
        with open(params.PlanesFile, 'w') as out:
            for p in self.planes:
                out.write(p.toFile() + '\n')


    def colorizeModel(self):
        values = {
            "stl": format_path(self.openedStl),
            "out": params.ColorizeResult,
            "angle": self.colorizeAngle_value.text(),
        }
        cmd = params.ColorizeStlCommand.format(**values)
        subprocess.check_output(str.split(cmd))
        self.loadSTL(self.openedStl, method=gui_utils.createStlActorInOriginWithColorize)

    def analyzeModel(self):
        values = {
            "stl": format_path(self.openedStl),
            "angle": self.colorizeAngle_value.text(),
            "out": params.AnalyzeResult,
            "originx": self.stlTranslation[0],
            "originy": self.stlTranslation[1],
            "originz": self.stlTranslation[2],
            "rotcx": params.RotationCenter[0],
            "rotcy": params.RotationCenter[1],
            "rotcz": params.RotationCenter[2],
        }
        cmd = params.AnalyzeStlCommand.format(**values)
        subprocess.check_output(str.split(cmd))
        self.planes = gui_utils.read_planes()
        self.bottom_panel.setEnabled(True)
        # self.openedStl = "cuttedSTL.stl"
        self.loadSTL(self.openedStl, method=gui_utils.createStlActorInOrigin)

    def clearScene(self):
        self.render.RemoveAllViewProps()

    def reloadScene(self):
        self.render.Modified()
        self.interactor.Render()

    def switchModels(self, state):
        if state == QtCore.Qt.Checked:
            for actor in self.actors:
                actor.VisibilityOff()
            self.stlActor.VisibilityOn()
        else:
            for layer in range(self.pictureSlider.value()):
                self.actors[layer].VisibilityOn()
            self.stlActor.VisibilityOff()
        self.reloadScene()

    def openFile(self):
        try:
            filename = str(
                QFileDialog.getOpenFileName(None, self.locale.OpenModel, "/home/l1va/Downloads/5axes_3d_printer/test",
                                            "STL (*.stl)")[0])  # TODO: fix path
            if filename != "":
                self.planes = []
                fileExt = os.path.splitext(filename)[1].upper()
                filename = str(Path(filename))
                if fileExt == ".STL":
                    self.loadSTL(filename)
                elif fileExt == ".GCODE":
                    self.loadGCode(filename, False)
                else:
                    print("This file format isn't supported:", fileExt)
        except IOError as e:
            print("Error during file opening:", e)

    def saveGCodeFile(self):
        try:
            name = str(QFileDialog.getSaveFileName(None, self.locale.SaveGCode, "", "Gcode (*.gcode)")[0])
            if name != "":
                if not name.endswith(".gcode"):
                    name += ".gcode"
                copy2(self.openedGCode, name)
        except IOError as e:
            print("Error during file saving:", e)
Exemplo n.º 33
0
class NewDocument(preferences.Group):
    def __init__(self, page):
        super(NewDocument, self).__init__(page)
        
        grid = QGridLayout()
        self.setLayout(grid)
        
        def changed():
            self.changed.emit()
            self.combo.setEnabled(self.template.isChecked())
        
        self.emptyDocument = QRadioButton(toggled=changed)
        self.lilyVersion = QRadioButton(toggled=changed)
        self.template = QRadioButton(toggled=changed)
        self.combo = QComboBox(currentIndexChanged=changed)
        
        grid.addWidget(self.emptyDocument, 0, 0, 1, 2)
        grid.addWidget(self.lilyVersion, 1, 0, 1, 2)
        grid.addWidget(self.template, 2, 0, 1, 1)
        grid.addWidget(self.combo, 2, 1, 1, 1)
        self.loadCombo()
        app.translateUI(self)
        
    def translateUI(self):
        self.setTitle(_("When creating new documents"))
        self.emptyDocument.setText(_("Create an empty document"))
        self.lilyVersion.setText(_("Create a document that contains the LilyPond version statement"))
        self.template.setText(_("Create a document from a template:"))
        from snippet import snippets
        for i, name in enumerate(self._names):
            self.combo.setItemText(i, snippets.title(name))
    
    def loadCombo(self):
        from snippet import snippets
        self._names = [name for name in snippets.names()
                        if snippets.get(name).variables.get('template')]
        self.combo.clear()
        self.combo.addItems([''] * len(self._names))
        
    def loadSettings(self):
        s = QSettings()
        ndoc = s.value("new_document", "empty", str)
        template = s.value("new_document_template", "", str)
        if template in self._names:
            self.combo.setCurrentIndex(self._names.index(template))
        if ndoc == "template":
            self.template.setChecked(True)
        elif ndoc == "version":
            self.lilyVersion.setChecked(True)
        else:
            self.emptyDocument.setChecked(True)

    def saveSettings(self):
        s = QSettings()
        if self._names and self.template.isChecked():
            s.setValue("new_document", "template")
            s.setValue("new_document_template", self._names[self.combo.currentIndex()])
        elif self.lilyVersion.isChecked():
            s.setValue("new_document", "version")
        else:
            s.setValue("new_document", "empty")
Exemplo n.º 34
0
class EditorAssembly(QWidget):
    """
    Class implementing the editor assembly widget containing the navigation
    combos and the editor widget.
    """
    def __init__(self, dbs, fn=None, vm=None, filetype="", editor=None,
                 tv=None):
        """
        Constructor
        
        @param dbs reference to the debug server object
        @param fn name of the file to be opened (string). If it is None,
            a new (empty) editor is opened
        @param vm reference to the view manager object
            (ViewManager.ViewManager)
        @param filetype type of the source file (string)
        @param editor reference to an Editor object, if this is a cloned view
        @param tv reference to the task viewer object
        """
        super(EditorAssembly, self).__init__()
        
        self.__layout = QGridLayout(self)
        self.__layout.setContentsMargins(0, 0, 0, 0)
        self.__layout.setSpacing(1)
        
        self.__globalsCombo = QComboBox()
        self.__membersCombo = QComboBox()
        from .Editor import Editor
        self.__editor = Editor(dbs, fn, vm, filetype, editor, tv)
        
        self.__layout.addWidget(self.__globalsCombo, 0, 0)
        self.__layout.addWidget(self.__membersCombo, 0, 1)
        self.__layout.addWidget(self.__editor, 1, 0, 1, -1)
        
        self.__module = None
        
        self.__globalsCombo.activated[int].connect(self.__globalsActivated)
        self.__membersCombo.activated[int].connect(self.__membersActivated)
        self.__editor.cursorLineChanged.connect(self.__editorCursorLineChanged)
        
        self.__parseTimer = QTimer(self)
        self.__parseTimer.setSingleShot(True)
        self.__parseTimer.setInterval(5 * 1000)
        self.__parseTimer.timeout.connect(self.__parseEditor)
        self.__editor.textChanged.connect(self.__resetParseTimer)
        self.__editor.refreshed.connect(self.__resetParseTimer)
        
        self.__selectedGlobal = ""
        self.__selectedMember = ""
        self.__globalsBoundaries = {}
        self.__membersBoundaries = {}
        
        QTimer.singleShot(0, self.__parseEditor)
    
    def shutdownTimer(self):
        """
        Public method to stop and disconnect the timer.
        """
        self.__parseTimer.stop()
        self.__parseTimer.timeout.disconnect(self.__parseEditor)
        self.__editor.textChanged.disconnect(self.__resetParseTimer)
        self.__editor.refreshed.disconnect(self.__resetParseTimer)
    
    def getEditor(self):
        """
        Public method to get the reference to the editor widget.
        
        @return reference to the editor widget (Editor)
        """
        return self.__editor
    
    def __globalsActivated(self, index, moveCursor=True):
        """
        Private method to jump to the line of the selected global entry and to
        populate the members combo box.
        
        @param index index of the selected entry (integer)
        @keyparam moveCursor flag indicating to move the editor cursor
            (boolean)
        """
        # step 1: go to the line of the selected entry
        lineno = self.__globalsCombo.itemData(index)
        if lineno is not None:
            if moveCursor:
                txt = self.__editor.text(lineno - 1).rstrip()
                pos = len(txt.replace(txt.strip(), ""))
                self.__editor.gotoLine(
                    lineno, pos if pos == 0 else pos + 1, True)
                self.__editor.setFocus()
            
            # step 2: populate the members combo, if the entry is a class
            self.__membersCombo.clear()
            self.__membersBoundaries = {}
            self.__membersCombo.addItem("")
            memberIndex = 0
            entryName = self.__globalsCombo.itemText(index)
            if self.__module:
                if entryName in self.__module.classes:
                    entry = self.__module.classes[entryName]
                elif entryName in self.__module.modules:
                    entry = self.__module.modules[entryName]
                    # step 2.0: add module classes
                    items = {}
                    for cl in entry.classes.values():
                        if cl.isPrivate():
                            icon = UI.PixmapCache.getIcon("class_private.png")
                        elif cl.isProtected():
                            icon = UI.PixmapCache.getIcon(
                                "class_protected.png")
                        else:
                            icon = UI.PixmapCache.getIcon("class.png")
                        items[cl.name] = (icon, cl.lineno, cl.endlineno)
                    for key in sorted(items.keys()):
                        itm = items[key]
                        self.__membersCombo.addItem(itm[0], key, itm[1])
                        memberIndex += 1
                        self.__membersBoundaries[(itm[1], itm[2])] = \
                            memberIndex
                else:
                    return
                
                # step 2.1: add class methods
                from Utilities.ModuleParser import Function
                items = {}
                for meth in entry.methods.values():
                    if meth.modifier == Function.Static:
                        icon = UI.PixmapCache.getIcon("method_static.png")
                    elif meth.modifier == Function.Class:
                        icon = UI.PixmapCache.getIcon("method_class.png")
                    elif meth.isPrivate():
                        icon = UI.PixmapCache.getIcon("method_private.png")
                    elif meth.isProtected():
                        icon = UI.PixmapCache.getIcon("method_protected.png")
                    else:
                        icon = UI.PixmapCache.getIcon("method.png")
                    items[meth.name] = (icon, meth.lineno, meth.endlineno)
                for key in sorted(items.keys()):
                    itm = items[key]
                    self.__membersCombo.addItem(itm[0], key, itm[1])
                    memberIndex += 1
                    self.__membersBoundaries[(itm[1], itm[2])] = memberIndex
                
                # step 2.2: add class instance attributes
                items = {}
                for attr in entry.attributes.values():
                    if attr.isPrivate():
                        icon = UI.PixmapCache.getIcon("attribute_private.png")
                    elif attr.isProtected():
                        icon = UI.PixmapCache.getIcon(
                            "attribute_protected.png")
                    else:
                        icon = UI.PixmapCache.getIcon("attribute.png")
                    items[attr.name] = (icon, attr.lineno)
                for key in sorted(items.keys()):
                    itm = items[key]
                    self.__membersCombo.addItem(itm[0], key, itm[1])
                
                # step 2.3: add class attributes
                items = {}
                icon = UI.PixmapCache.getIcon("attribute_class.png")
                for glob in entry.globals.values():
                    items[glob.name] = (icon, glob.lineno)
                for key in sorted(items.keys()):
                    itm = items[key]
                    self.__membersCombo.addItem(itm[0], key, itm[1])
    
    def __membersActivated(self, index, moveCursor=True):
        """
        Private method to jump to the line of the selected members entry.
        
        @param index index of the selected entry (integer)
        @keyparam moveCursor flag indicating to move the editor cursor
            (boolean)
        """
        lineno = self.__membersCombo.itemData(index)
        if lineno is not None and moveCursor:
            txt = self.__editor.text(lineno - 1).rstrip()
            pos = len(txt.replace(txt.strip(), ""))
            self.__editor.gotoLine(lineno, pos if pos == 0 else pos + 1, True)
            self.__editor.setFocus()
    
    def __resetParseTimer(self):
        """
        Private slot to reset the parse timer.
        """
        self.__parseTimer.stop()
        self.__parseTimer.start()
    
    def __parseEditor(self):
        """
        Private method to parse the editor source and repopulate the globals
        combo.
        """
        from Utilities.ModuleParser import Module, getTypeFromTypeName
        
        self.__module = None
        sourceType = getTypeFromTypeName(self.__editor.determineFileType())
        if sourceType != -1:
            src = self.__editor.text()
            if src:
                fn = self.__editor.getFileName()
                if fn is None:
                    fn = ""
                self.__module = Module("", fn, sourceType)
                self.__module.scan(src)
                
                # remember the current selections
                self.__selectedGlobal = self.__globalsCombo.currentText()
                self.__selectedMember = self.__membersCombo.currentText()
                
                self.__globalsCombo.clear()
                self.__membersCombo.clear()
                self.__globalsBoundaries = {}
                self.__membersBoundaries = {}
                
                self.__globalsCombo.addItem("")
                index = 0
                
                # step 1: add modules
                items = {}
                for module in self.__module.modules.values():
                    items[module.name] = (UI.PixmapCache.getIcon("module.png"),
                                          module.lineno, module.endlineno)
                for key in sorted(items.keys()):
                    itm = items[key]
                    self.__globalsCombo.addItem(itm[0], key, itm[1])
                    index += 1
                    self.__globalsBoundaries[(itm[1], itm[2])] = index
                
                # step 2: add classes
                items = {}
                for cl in self.__module.classes.values():
                    if cl.isPrivate():
                        icon = UI.PixmapCache.getIcon("class_private.png")
                    elif cl.isProtected():
                        icon = UI.PixmapCache.getIcon("class_protected.png")
                    else:
                        icon = UI.PixmapCache.getIcon("class.png")
                    items[cl.name] = (icon, cl.lineno, cl.endlineno)
                for key in sorted(items.keys()):
                    itm = items[key]
                    self.__globalsCombo.addItem(itm[0], key, itm[1])
                    index += 1
                    self.__globalsBoundaries[(itm[1], itm[2])] = index
                
                # step 3: add functions
                items = {}
                for func in self.__module.functions.values():
                    if func.isPrivate():
                        icon = UI.PixmapCache.getIcon("method_private.png")
                    elif func.isProtected():
                        icon = UI.PixmapCache.getIcon("method_protected.png")
                    else:
                        icon = UI.PixmapCache.getIcon("method.png")
                    items[func.name] = (icon, func.lineno, func.endlineno)
                for key in sorted(items.keys()):
                    itm = items[key]
                    self.__globalsCombo.addItem(itm[0], key, itm[1])
                    index += 1
                    self.__globalsBoundaries[(itm[1], itm[2])] = index
                
                # step 4: add attributes
                items = {}
                for glob in self.__module.globals.values():
                    if glob.isPrivate():
                        icon = UI.PixmapCache.getIcon("attribute_private.png")
                    elif glob.isProtected():
                        icon = UI.PixmapCache.getIcon(
                            "attribute_protected.png")
                    else:
                        icon = UI.PixmapCache.getIcon("attribute.png")
                    items[glob.name] = (icon, glob.lineno)
                for key in sorted(items.keys()):
                    itm = items[key]
                    self.__globalsCombo.addItem(itm[0], key, itm[1])
                
                # reset the currently selected entries without moving the
                # text cursor
                index = self.__globalsCombo.findText(self.__selectedGlobal)
                if index != -1:
                    self.__globalsCombo.setCurrentIndex(index)
                    self.__globalsActivated(index, moveCursor=False)
                index = self.__membersCombo.findText(self.__selectedMember)
                if index != -1:
                    self.__membersCombo.setCurrentIndex(index)
                    self.__membersActivated(index, moveCursor=False)
    
    def __editorCursorLineChanged(self, lineno):
        """
        Private slot handling a line change of the cursor of the editor.
        
        @param lineno line number of the cursor (integer)
        """
        lineno += 1     # cursor position is zero based, code info one based
        
        # step 1: search in the globals
        for (lower, upper), index in self.__globalsBoundaries.items():
            if upper == -1:
                upper = 1000000     # it is the last line
            if lower <= lineno <= upper:
                break
        else:
            index = 0
        self.__globalsCombo.setCurrentIndex(index)
        self.__globalsActivated(index, moveCursor=False)
        
        # step 2: search in members
        for (lower, upper), index in self.__membersBoundaries.items():
            if upper == -1:
                upper = 1000000     # it is the last line
            if lower <= lineno <= upper:
                break
        else:
            index = 0
        self.__membersCombo.setCurrentIndex(index)
        self.__membersActivated(index, moveCursor=False)
Exemplo n.º 35
0
class Browser(QWidget):
    """LilyPond documentation browser widget."""
    def __init__(self, dockwidget):
        super(Browser, self).__init__(dockwidget)
        
        layout = QVBoxLayout(spacing=0)
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)
        
        self.toolbar = tb = QToolBar()
        self.webview = QWebView(contextMenuPolicy=Qt.CustomContextMenu)
        self.chooser = QComboBox(sizeAdjustPolicy=QComboBox.AdjustToContents)
        self.search = SearchEntry(maximumWidth=200)
        
        layout.addWidget(self.toolbar)
        layout.addWidget(self.webview)
        
        ac = dockwidget.actionCollection
        ac.help_back.triggered.connect(self.webview.back)
        ac.help_forward.triggered.connect(self.webview.forward)
        ac.help_home.triggered.connect(self.showHomePage)
        ac.help_print.triggered.connect(self.slotPrint)
        
        self.webview.page().setNetworkAccessManager(lilydoc.network.accessmanager())
        self.webview.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks)
        self.webview.page().linkClicked.connect(self.openUrl)
        self.webview.page().setForwardUnsupportedContent(True)
        self.webview.page().unsupportedContent.connect(self.slotUnsupported)
        self.webview.urlChanged.connect(self.slotUrlChanged)
        self.webview.customContextMenuRequested.connect(self.slotShowContextMenu)
        
        tb.addAction(ac.help_back)
        tb.addAction(ac.help_forward)
        tb.addSeparator()
        tb.addAction(ac.help_home)
        tb.addAction(ac.help_print)
        tb.addSeparator()
        tb.addWidget(self.chooser)
        tb.addWidget(self.search)
        
        self.chooser.activated[int].connect(self.showHomePage)
        self.search.textEdited.connect(self.slotSearchChanged)
        self.search.returnPressed.connect(self.slotSearchReturnPressed)
        dockwidget.mainwindow().iconSizeChanged.connect(self.updateToolBarSettings)
        dockwidget.mainwindow().toolButtonStyleChanged.connect(self.updateToolBarSettings)
        
        app.settingsChanged.connect(self.readSettings)
        self.readSettings()
        self.loadDocumentation()
        self.showInitialPage()
        app.settingsChanged.connect(self.loadDocumentation)
        app.translateUI(self)
    
    def readSettings(self):
        s = QSettings()
        s.beginGroup("documentation")
        ws = self.webview.page().settings()
        family = s.value("fontfamily", self.font().family(), str)
        size = s.value("fontsize", 16, int)
        ws.setFontFamily(QWebSettings.StandardFont, family)
        ws.setFontSize(QWebSettings.DefaultFontSize, size)
        fixed = textformats.formatData('editor').font
        ws.setFontFamily(QWebSettings.FixedFont, fixed.family())
        ws.setFontSize(QWebSettings.DefaultFixedFontSize, fixed.pointSizeF() * 96 / 72)
        
    def keyPressEvent(self, ev):
        if ev.text() == "/":
            self.search.setFocus()
        else:
            super(Browser, self).keyPressEvent(ev)
        
    def translateUI(self):
        try:
            self.search.setPlaceholderText(_("Search..."))
        except AttributeError:
            pass # not in Qt 4.6
    
    def showInitialPage(self):
        """Shows the preferred start page.
        
        If a local documentation instance already has a suitable version,
        just loads it. Otherwise connects to the allLoaded signal, that is
        emitted when all the documentation instances have loaded their version
        information and then shows the start page (if another page wasn't yet
        loaded).
        
        """
        if self.webview.url().isEmpty():
            docs = lilydoc.manager.docs()
            version = lilypondinfo.preferred().version()
            index = -1
            if version:
                for num, doc in enumerate(docs):
                    if doc.version() is not None and doc.version() >= version:
                        index = num # a suitable documentation is found
                        break
            if index == -1:
                # nothing found (or LilyPond version not available),
                # wait for loading or show the most recent version
                if not lilydoc.manager.loaded():
                    lilydoc.manager.allLoaded.connect(self.showInitialPage)
                    return
                index = len(docs) - 1
            self.chooser.setCurrentIndex(index)
            self.showHomePage()
    
    def loadDocumentation(self):
        """Puts the available documentation instances in the combobox."""
        i = self.chooser.currentIndex()
        self.chooser.clear()
        for doc in lilydoc.manager.docs():
            v = doc.versionString()
            if doc.isLocal():
                t = _("(local)")
            else:
                t = _("({hostname})").format(hostname=doc.url().host())
            self.chooser.addItem("{0} {1}".format(v or _("<unknown>"), t))
        self.chooser.setCurrentIndex(i)
        if not lilydoc.manager.loaded():
            lilydoc.manager.allLoaded.connect(self.loadDocumentation, -1)
            return
        
    def updateToolBarSettings(self):
        mainwin = self.parentWidget().mainwindow()
        self.toolbar.setIconSize(mainwin.iconSize())
        self.toolbar.setToolButtonStyle(mainwin.toolButtonStyle())
        
    def showManual(self):
        """Invoked when the user presses F1."""
        self.slotHomeFrescobaldi() # TEMP
        
    def slotUrlChanged(self):
        ac = self.parentWidget().actionCollection
        ac.help_back.setEnabled(self.webview.history().canGoBack())
        ac.help_forward.setEnabled(self.webview.history().canGoForward())
    
    def openUrl(self, url):
        if url.path().endswith(('.ily', '.lyi', '.ly')):
            self.sourceViewer().showReply(lilydoc.network.get(url))
        else:
            self.webview.load(url)
    
    def slotUnsupported(self, reply):
        helpers.openUrl(reply.url())
    
    def slotSearchChanged(self):
        text = self.search.text()
        if not text.startswith(':'):
            self.webview.page().findText(text, QWebPage.FindWrapsAroundDocument)
    
    def slotSearchReturnPressed(self):
        text = self.search.text()
        if not text.startswith(':'):
            self.slotSearchChanged()
        else:
            pass # TODO: implement full doc search
    
    def sourceViewer(self):
        try:
            return self._sourceviewer
        except AttributeError:
            from . import sourceviewer
            self._sourceviewer = sourceviewer.SourceViewer(self)
            return self._sourceviewer
    
    def showHomePage(self):
        """Shows the homepage of the LilyPond documentation."""
        i = self.chooser.currentIndex()
        if i < 0:
            i = 0
        doc = lilydoc.manager.docs()[i]
        
        url = doc.home()
        if doc.isLocal():
            path = url.toLocalFile()
            langs = lilydoc.network.langs()
            if langs:
                for lang in langs:
                    if os.path.exists(path + '.' + lang + '.html'):
                        path += '.' + lang
                        break
            url = QUrl.fromLocalFile(path + '.html')
        self.webview.load(url)
    
    def slotPrint(self):
        printer = QPrinter()
        dlg = QPrintDialog(printer, self)
        dlg.setWindowTitle(app.caption(_("Print")))
        if dlg.exec_():
            self.webview.print_(printer)
    
    def slotShowContextMenu(self, pos):
        hit = self.webview.page().currentFrame().hitTestContent(pos)
        menu = QMenu()
        if hit.linkUrl().isValid():
            a = self.webview.pageAction(QWebPage.CopyLinkToClipboard)
            a.setIcon(icons.get("edit-copy"))
            a.setText(_("Copy &Link"))
            menu.addAction(a)
            menu.addSeparator()
            a = menu.addAction(icons.get("window-new"), _("Open Link in &New Window"))
            a.triggered.connect((lambda url: lambda: self.slotNewWindow(url))(hit.linkUrl()))
        else:
            if hit.isContentSelected():
                a = self.webview.pageAction(QWebPage.Copy)
                a.setIcon(icons.get("edit-copy"))
                a.setText(_("&Copy"))
                menu.addAction(a)
                menu.addSeparator()
            a = menu.addAction(icons.get("window-new"), _("Open Document in &New Window"))
            a.triggered.connect((lambda url: lambda: self.slotNewWindow(url))(self.webview.url()))
        if menu.actions():
            menu.exec_(self.webview.mapToGlobal(pos))
    
    def slotNewWindow(self, url):
        helpers.openUrl(url)
Exemplo n.º 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()
Exemplo n.º 37
0
class H5PlotGUI(QDialog):
    """The main GUI for H5Plot.

    From here the SolSets, SolTabs and antennas to plot are selected.
    """
    def __init__(self, h5file, logging_instance, parent=None):
        super(H5PlotGUI, self).__init__(parent)
        self.logger = logging_instance
        self.figures = []

        self.h5parm = lh5.h5parm(h5file)
        self.solset_labels = self.h5parm.getSolsetNames()
        self.solset = self.h5parm.getSolset('sol000')

        self.soltab_labels = self.solset.getSoltabNames()
        self.soltab = self.solset.getSoltab(self.soltab_labels[0])

        self.stations = self.soltab.getValues()[1]['ant']
        self.refant = 'CS001HBA0'
        self.wrapphase = True

        self.stcache = SoltabCache(self.soltab.getValues(), self.soltab.getAxesNames())
        rvals, raxes = reorder_soltab(self.soltab)
        self.stcache.update(rvals, raxes)

        self.move(300, 300)
        self.setWindowTitle('H5Plot')

        self.solset_label = QLabel('SolSet: ')
        self.solset_picker = QComboBox()
        for l in self.solset_labels:
            self.solset_picker.addItem(l)
        self.solset_picker.activated.connect(self._solset_picker_event)

        self.soltab_label_y = QLabel('Plot ')
        self.soltab_label_x = QLabel(' vs ')
        self.soltab_picker = QComboBox()
        for l in self.soltab_labels:
            self.soltab_picker.addItem(l)
        self.soltab_picker.activated.connect(self._soltab_picker_event)
        self.axis_picker = QComboBox()
        self.axis_picker.addItems(['time', 'freq'])
        self.axis_picker.activated.connect(self._axis_picker_event)
        self.axis = 'time'

        self.refant_label = QLabel('Ref. Ant. ')
        self.refant_picker = QComboBox()
        self.refant_picker.addItems(self.stations)
        self.refant_picker.activated.connect(self._refant_picker_event)

        self.phasewrap_box = QCheckBox('Wrap Phases')
        self.phasewrap_box.setChecked(True)
        self.phasewrap_box.setEnabled(False)
        self.phasewrap_box.stateChanged.connect(self._phasewrap_event)

        self.plot_button = QPushButton('Plot')
        self.plot_button.clicked.connect(self._plot_button_event)

        self.station_picker = QListWidget()
        self.station_picker.addItems(self.stations)
        self.station_picker.setCurrentRow(0)


        plot_layout = QGridLayout()
        plot_layout.addWidget(self.soltab_label_y, 0, 0)
        plot_layout.addWidget(self.soltab_picker, 0, 1)
        plot_layout.addWidget(self.soltab_label_x, 0, 2)
        plot_layout.addWidget(self.axis_picker, 0, 3)
        plot_layout.addWidget(self.refant_label, 1, 0)
        plot_layout.addWidget(self.refant_picker, 1, 1)
        plot_layout.addWidget(self.phasewrap_box, 1, 3)

        layout = QFormLayout(self)
        layout.addRow(self.solset_label, self.solset_picker)
        layout.addRow(plot_layout)
        layout.addRow(self.plot_button)
        layout.addRow(self.station_picker)

    def _axis_picker_event(self):
        """Callback function for when the x-axis is changed.

        Sets the `axis` attribute to the selected axis
        """
        self.logger.debug('Axis changed to: ' + self.axis_picker.currentText())
        self.axis = self.axis_picker.currentText()

    def closeEvent(self, event):
        self.logger.info('Closing all open figures before exiting.')
        plt.close('all' )
        event.accept()

    def _refant_picker_event(self):
        self.logger.debug('Reference antenna changed to: ' + self.refant_picker.currentText())
        self.refant = self.refant_picker.currentText()

    def _solset_picker_event(self):
        """Callback function for when the SolSet is changed.

        Sets the `solset` attribute.
        """
        self.logger.debug('Solset changed to: ' + self.solset_picker.currentText())
        self.solset = self.h5parm.getSolset(self.solset_picker.currentText())
        self.soltab_labels = self.solset.getSoltabNames()
        self.soltab_picker.clear()
        for l in self.soltab_labels:
            self.soltab_picker.addItem(l)
        self._soltab_picker_event()

    def _soltab_picker_event(self):
        """Callback function for when the SolTab is changed.

        Sets the `soltab` attribute.
        """
        self.logger.debug('Soltab changed to: ' + self.soltab_picker.currentText())
        self.soltab = self.solset.getSoltab(self.soltab_picker.currentText())
        rvals, raxes = reorder_soltab(self.soltab)
        self.stcache.update(rvals, raxes)

    def _phasewrap_event(self):
        self.logger.debug('Phase wrapping changed to ' + str(self.phasewrap_box.isChecked()))
        self.wrapphase = self.phasewrap_box.isChecked()

    def _plot_button_event(self):
        """Callback function for when the plot button is pressed.

        Calls the `plot` function subsecquently.
        """
        self.logger.debug('Plotting button pressed.')
        self.plot(labels=(self.axis, self.soltab.name))

    def plot(self, labels=('x-axis', 'y-axis'), limits=([None, None], [None, None])):
        self.logger.info('Plotting ' + self.soltab.name + ' vs ' + self.axis + \
                         ' for ' + self.solset.name)

        antenna = self.station_picker.currentRow()
        refantenna = self.refant_picker.currentIndex()
        # Values have shape (timestamps, frequencies, antennas, polarizations, directions).
        values = self.stcache.values[0]
        if (('rotationmeasure' in self.soltab.name) or ('RMextract' in self.soltab.name) or ('clock' in self.soltab.name)) and (self.axis == 'freq'):
            self.logger.warning('Rotation Measure does not support frequency axis! Switch to time instead.')
            return
        else:
            x_axis = self.stcache.values[1][self.axis]
        st_type = self.soltab.getType()
        print(st_type)

        fig = plt.figure()
        ax = fig.add_subplot(111)
        ax.set_title(self.stations[antenna])

        if self.axis == 'time':
            if 'rotationmeasure' in self.soltab.name:
                y_axis = values[:, antenna]
                ax.plot(x_axis, y_axis)
            elif ('pol' in self.stcache.axes) and ('dir' in self.stcache.axes):
                if st_type == 'phase':
                    ax.set_ylim(-np.pi, np.pi)
                    # Plot phase-like quantities w.r.t. to a reference antenna.
                    y_axis = values[:, 0, antenna, :, 0] - values[:, 0, refantenna, :, 0]
                    if self.wrapphase:
                        y_axis = wrap_phase(y_axis)
                elif (st_type == 'clock') or (st_type == 'rotationmeasure'):
                    y_axis = values[:, antenna]
                else:
                    y_axis = values[:, 0, antenna, :, 0]
                for i,y in enumerate(y_axis):
                    ax.plot(x_axis, y[:,i], 'h', label=self.stcache.values[1]['pol'][i])
            elif 'pol' in self.stcache.axes:
                if st_type == 'phase':
                    ax.set_ylim(-np.pi, np.pi)
                    # Plot phase-like quantities w.r.t. to a reference antenna.
                    y_axis = values[:, 0, antenna, :] - values[:, 0, refantenna, :]
                    if self.wrapphase:
                        y_axis = wrap_phase(y_axis)
                elif (st_type == 'clock') or (st_type == 'rotationmeasure'):
                    y_axis = values[:, antenna]
                else:
                    y_axis = values[:, 0, antenna, :]
                for i in range(y_axis.shape[1]):
                    ax.plot(x_axis, y_axis[:, i], 'h', label=self.stcache.values[1]['pol'][i])
            elif 'dir' in self.stcache.axes:
                if st_type == 'phase':
                    ax.set_ylim(-np.pi, np.pi)
                    # Plot phase-like quantities w.r.t. to a reference antenna.
                    y_axis = values[:, 0, antenna, 0] - values[:, 0, refantenna, 0]
                    if self.wrapphase:
                        y_axis = wrap_phase(y_axis)
                elif (st_type == 'clock') or (st_type == 'rotationmeasure'):
                    y_axis = values[:, antenna]
                else:
                    y_axis = values[:, 0, antenna, 0]
                ax.plot(x_axis, y_axis[:, i], 'h')
            elif ('pol' not in self.stcache.axes) and ('dir' not in self.stcache.axes):
                if (st_type == 'clock') or (st_type == 'rotationmeasure'):
                    y_axis = values[:, antenna]
                else:
                    y_axis = values[:, 0, antenna]
                ax.plot(x_axis, y_axis)
        elif self.axis == 'freq':
            if ('rotationmeasure' in self.soltab.name) or ('clock' in self.soltab.name):
                self.logger.warning('Rotation Measure does not support frequency axis! Switch to time instead.')
            if ('pol' in self.stcache.axes) and ('dir' in self.stcache.axes):
                if st_type == 'phase':
                    ax.set_ylim(-np.pi, np.pi)
                    # Plot phase-like quantities w.r.t. to a reference antenna.
                    y_axis = values[0, :, antenna, :, 0] - values[0, :, refantenna, :, 0]
                    if self.wrapphase:
                        y_axis = wrap_phase(y_axis)
                else:
                    y_axis = values[0, :, antenna, :, 0]
                for i,y in enumerate(y_axis):
                    ax.plot(x_axis, y[:,i])
            elif 'pol' in self.stcache.axes:
                if st_type == 'phase':
                    ax.set_ylim(-np.pi, np.pi)
                    # Plot phase-like quantities w.r.t. to a reference antenna.
                    y_axis = values[0, :, antenna, :] - values[0, :, refantenna, :]
                    if self.wrapphase:
                        y_axis = wrap_phase(y_axis)
                else:
                    y_axis = values[0, :, antenna, :]
                for i in range(y_axis.shape[1]):
                    ax.plot(x_axis, y_axis[:, i], 'h', label=self.stcache.values[1]['pol'][i])
            elif 'dir' in self.stcache.axes:
                if st_type == 'phase':
                    ax.set_ylim(-np.pi, np.pi)
                    # Plot phase-like quantities w.r.t. to a reference antenna.
                    y_axis = values[0, :, antenna, 0] - values[0, :, refantenna, 0]
                    if self.wrapphase:
                        y_axis = wrap_phase(y_axis)
                else:
                    y_axis = values[0, :, antenna, 0]
            elif ('pol' not in self.stcache.axes) and ('dir' not in self.stcache.axes):
                y_axis = values[0, :, antenna]
                ax.plot(x_axis, y_axis)

        ax.set(xlabel=self.axis, ylabel=labels[1], xlim=limits[0], ylim=limits[1])
        if ax.get_legend_handles_labels()[1]:
            ax.legend()
        self.figures.append(fig)
        fig.show()
Exemplo n.º 38
0
class SvgView(QWidget):
    def __init__(self, dockwidget):
        super(SvgView, self).__init__(dockwidget)

        self._document = None
        self._setting_zoom = False

        self.view = view.View(self)

        self.pageLabel = QLabel()
        self.pageCombo = QComboBox(sizeAdjustPolicy=QComboBox.AdjustToContents)

        layout = QVBoxLayout(spacing=0)
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)
        hbox = QHBoxLayout(spacing=0)
        hbox.addWidget(self.pageLabel)
        hbox.addWidget(self.pageCombo)

        self.zoomInButton = QToolButton(autoRaise=True)
        self.zoomOutButton = QToolButton(autoRaise=True)
        self.zoomOriginalButton = QToolButton(autoRaise=True)
        self.zoomNumber = QSpinBox(minimum=10, maximum=1000, suffix="%")
        ac = dockwidget.actionCollection
        self.zoomInButton.setDefaultAction(ac.svg_zoom_in)
        self.zoomOutButton.setDefaultAction(ac.svg_zoom_out)
        self.zoomOriginalButton.setDefaultAction(ac.svg_zoom_original)
        hbox.addWidget(self.zoomInButton)
        hbox.addWidget(self.zoomNumber)
        hbox.addWidget(self.zoomOutButton)
        hbox.addWidget(self.zoomOriginalButton)

        self.resetButton = QPushButton("reload", self)
        self.resetButton.clicked.connect(self.reLoadDoc)
        hbox.addWidget(self.resetButton)

        self.saveButton = QPushButton("save edits", self)
        self.saveButton.clicked.connect(self.callSave)
        hbox.addWidget(self.saveButton)

        hbox.addStretch(1)
        layout.addLayout(hbox)
        layout.addWidget(self.view)

        app.jobFinished.connect(self.initSvg)
        app.documentClosed.connect(self.slotDocumentClosed)
        app.documentLoaded.connect(self.initSvg)
        self.pageCombo.currentIndexChanged.connect(self.changePage)
        self.zoomNumber.valueChanged.connect(self.slotZoomNumberChanged)
        self.view.zoomFactorChanged.connect(self.slotViewZoomChanged)
        dockwidget.mainwindow().currentDocumentChanged.connect(self.initSvg)
        self.zoomNumber.setValue(100)
        doc = dockwidget.mainwindow().currentDocument()
        if doc:
            self.initSvg(doc)
        app.translateUI(self)

    def translateUI(self):
        self.pageLabel.setText(_("Page:"))

    def mainwindow(self):
        return self.parent().mainwindow()

    def initSvg(self, doc):
        """Opens first page of score after compilation"""
        if doc == self.mainwindow().currentDocument():
            files = svgfiles.SvgFiles.instance(doc)
            model = files.model()  # forces update
            if files:
                self._document = doc
                with qutil.signalsBlocked(self.pageCombo):
                    self.pageCombo.setModel(model)
                    self.pageCombo.setCurrentIndex(files.current)
                self.view.load(files.url(files.current))

    def reLoadDoc(self):
        """Reloads current document."""
        if self._document:
            self.initSvg(self._document)

    def callSave(self):
        """Call save function"""
        self.view.evalSave()

    def getCurrent(self):
        files = svgfiles.SvgFiles.instance(self._document)
        return files.filename(files.current)

    def slotZoomNumberChanged(self, value):
        self._setting_zoom = True
        self.view.setZoomFactor(value / 100.0)
        self._setting_zoom = False

    def slotViewZoomChanged(self):
        if not self._setting_zoom:
            self.zoomNumber.setValue(int(self.view.zoomFactor() * 100))

    def changePage(self, page_index):
        """change page of score"""
        doc = self._document
        if doc:
            files = svgfiles.SvgFiles.instance(doc)
            if files:
                files.current = page_index
                svg = files.url(page_index)
                self.view.load(svg)

    def slotDocumentClosed(self, doc):
        if doc == self._document:
            self._document = None
            if self.pageCombo.model():
                self.pageCombo.model().deleteLater()
            self.pageCombo.clear()
            self.pageCombo.update()  # otherwise it doesn't redraw
            self.view.clear()
Exemplo n.º 39
0
class InputTab(SerafinInputTab):
    def __init__(self, parent):
        super().__init__(parent)
        self.old_options = ('1', '')

        self.data = None
        self.mesh = None
        self.polylines = []
        self.var_IDs = []

        self._initWidgets()  # some instance attributes will be set there
        self._setLayout()
        self._bindEvents()

        self.setMinimumWidth(800)

    def _initWidgets(self):
        # create the button open Polygon
        self.btnOpenPolyline = QPushButton('Load\nSections', self,
                                           icon=self.style().standardIcon(QStyle.SP_DialogOpenButton))
        self.btnOpenPolyline.setToolTip('<b>Open</b> a .i2s or .shp file')
        self.btnOpenPolyline.setFixedSize(105, 50)
        self.btnOpenPolyline.setEnabled(False)

        # create some text fields displaying the IO files info
        self.polygonNameBox = QPlainTextEdit()
        self.polygonNameBox.setReadOnly(True)
        self.polygonNameBox.setFixedHeight(50)
        self.csvNameBox = QLineEdit()
        self.csvNameBox.setReadOnly(True)
        self.csvNameBox.setFixedHeight(30)

        # create some widgets for flux options
        self.fluxBox = QComboBox()
        self.fluxBox.setFixedSize(400, 30)
        self.timeSampling = QLineEdit('1')
        self.timeSampling.setFixedWidth(50)

        # create the submit button
        self.btnSubmit = QPushButton('Submit\n(to .csv)', self,
                                     icon=self.style().standardIcon(QStyle.SP_DialogSaveButton))
        self.btnSubmit.setFixedSize(105, 50)
        self.btnSubmit.setEnabled(False)

    def _bindEvents(self):
        self.btnOpen.clicked.connect(self.btnOpenSerafinEvent)
        self.btnOpenPolyline.clicked.connect(self.btnOpenPolylineEvent)
        self.btnSubmit.clicked.connect(self.btnSubmitEvent)
        self.timeSampling.editingFinished.connect(self._checkSamplingFrequency)

    def _setLayout(self):
        mainLayout = QVBoxLayout()
        mainLayout.addItem(QSpacerItem(10, 10))
        mainLayout.setSpacing(15)
        mainLayout.addLayout(self.input_layout)
        mainLayout.addItem(QSpacerItem(10, 20))

        hlayout = QHBoxLayout()
        hlayout.addItem(QSpacerItem(30, 1))
        hlayout.addWidget(self.btnOpenPolyline)
        hlayout.addWidget(self.polygonNameBox)
        mainLayout.addLayout(hlayout)
        mainLayout.addItem(QSpacerItem(10, 10))
        mainLayout.addStretch()

        glayout = QGridLayout()
        glayout.addWidget(QLabel('     Select the flux to compute'), 1, 1)
        glayout.addWidget(self.fluxBox, 1, 2)
        hlayout = QHBoxLayout()
        hlayout.addWidget(QLabel('Time sampling frequency'))
        hlayout.addWidget(self.timeSampling)
        hlayout.setAlignment(self.timeSampling, Qt.AlignLeft)
        hlayout.addStretch()
        glayout.addLayout(hlayout, 2, 2)

        glayout.setAlignment(Qt.AlignLeft)
        glayout.setSpacing(10)
        mainLayout.addLayout(glayout)

        hlayout = QHBoxLayout()
        hlayout.addItem(QSpacerItem(30, 1))
        hlayout.addWidget(self.btnSubmit)
        hlayout.addWidget(self.csvNameBox)
        mainLayout.addLayout(hlayout)
        mainLayout.addStretch()
        mainLayout.addItem(QSpacerItem(10, 15))
        mainLayout.addWidget(QLabel('   Message logs'))
        mainLayout.addWidget(self.logTextBox.widget)
        self.setLayout(mainLayout)

    def _reinitInput(self):
        self.reset()
        self.data = None
        self.csvNameBox.clear()
        self.mesh = None
        self.csvNameBox.clear()
        self.old_options = (self.timeSampling.text(),
                            self.fluxBox.currentText())
        self.btnOpenPolyline.setEnabled(False)
        self.timeSampling.setText('1')
        self.fluxBox.clear()
        self.btnSubmit.setEnabled(False)

    def _resetDefaultOptions(self):
        sampling_frequency, flux_type = self.old_options
        if int(sampling_frequency) <= len(self.data.time):
            self.timeSampling.setText(sampling_frequency)
        for i in range(self.fluxBox.count()):
            text = self.fluxBox.itemText(i)
            if text == flux_type:
                self.fluxBox.setCurrentIndex(i)
                self.btnSubmit.setEnabled(True)
                break

    def _addFluxOptions(self, header):
        for possible_flux in PossibleFluxComputation(header.var_IDs, header.var_names):
            self.fluxBox.addItem(possible_flux)
        return self.fluxBox.count() > 0

    def _checkSamplingFrequency(self):
        try:
            sampling_frequency = int(self.timeSampling.text())
        except ValueError:
            QMessageBox.critical(self, 'Error', 'The sampling frequency must be a number!',
                                 QMessageBox.Ok)
            self.timeSampling.setText('1')
            return
        if sampling_frequency < 1 or sampling_frequency > len(self.data.time):
            QMessageBox.critical(self, 'Error', 'The sampling frequency must be in the range [1; nbFrames]!',
                                 QMessageBox.Ok)
            self.timeSampling.setText('1')
            return

    def _getFluxSection(self):
        selection = self.fluxBox.currentText()
        var_IDs = PossibleFluxComputation.get_variables(selection)
        flux_type = PossibleFluxComputation.get_flux_type(var_IDs)
        return flux_type, var_IDs, selection

    def btnOpenSerafinEvent(self):
        canceled, filename = super().open_event()
        if canceled:
            return

        self._reinitInput()
        success, data = self.read_2d(filename)
        if not success:
            return

        flux_added = self._addFluxOptions(data.header)
        if not flux_added:
            QMessageBox.critical(self, 'Error', 'No flux is computable from this file.', QMessageBox.Ok)
            self.summaryTextBox.clear()
            return

        # record the mesh for future visualization and calculations
        self.parent.inDialog()
        meshLoader = LoadMeshDialog('flux', data.header)
        self.mesh = meshLoader.run()
        self.parent.outDialog()
        if meshLoader.thread.canceled:
            self.fluxBox.clear()
            self.polygonNameBox.clear()
            self.summaryTextBox.clear()
            return

        self.data = data
        self._resetDefaultOptions()
        self.btnOpenPolyline.setEnabled(True)
        self.parent.imageTab.reset()
        self.parent.tab.setTabEnabled(1, False)

    def btnOpenPolylineEvent(self):
        success, filename, polylines = open_polylines()
        if not success:
            return
        self.polylines = polylines
        logging.info('Finished reading the polyline file %s' % filename)
        self.polygonNameBox.clear()
        self.polygonNameBox.appendPlainText(filename + '\n' + 'The file contains {} open polyline{}.'.format(
            len(self.polylines), 's' if len(self.polylines) > 1 else ''))
        self.csvNameBox.clear()
        self.btnSubmit.setEnabled(True)
        self.parent.imageTab.reset()
        self.parent.tab.setTabEnabled(1, False)

    def btnSubmitEvent(self):
        canceled, filename = save_dialog('CSV')
        if canceled:
            return
        self.csvNameBox.setText(filename)

        sampling_frequency = int(self.timeSampling.text())
        flux_type, self.var_IDs, flux_title = self._getFluxSection()
        self.parent.tab.setTabEnabled(1, False)

        logging.info('Writing the output to %s' % filename)
        self.parent.inDialog()

        # initialize the progress bar
        progressBar = OutputProgressDialog()

        # do the calculations
        names = [poly.id for poly in self.polylines]

        try:
            with Serafin.Read(self.data.filename, self.data.language) as input_stream:
                input_stream.header = self.data.header
                input_stream.time = self.data.time
                calculator = FluxCalculatorThread(flux_type, self.var_IDs,
                                                  input_stream, names, self.polylines, sampling_frequency,
                                                  self.mesh, self.parent.csv_separator, self.parent.fmt_float)
                progressBar.setValue(5)
                QApplication.processEvents()

                with open(filename, 'w') as f2:
                    progressBar.connectToThread(calculator)
                    calculator.write_csv(f2)
        except (Serafin.SerafinRequestError, Serafin.SerafinValidationError) as e:
            QMessageBox.critical(None, 'Serafin Error', e.message, QMessageBox.Ok, QMessageBox.Ok)
            return

        if not calculator.canceled:
            progressBar.outputFinished()
        progressBar.exec_()
        self.parent.outDialog()

        if calculator.canceled:
            self.csvNameBox.clear()
            return

        # unlock the image viewer
        self.parent.imageTab.getData(flux_title)
        self.parent.tab.setTabEnabled(1, True)
Exemplo n.º 40
0
class ToneGenerator(QWidget):

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        super().__init__(parent)

        # start new thread that constantly polls MIDI input
        self.create_MIDI()

        # create GUI (windows, slider, etc...)
        self.create_UI(parent)

        format = QAudioFormat()
        self.create_AUDIO(format)
        self.generator = Flute(format, self)
        self.generator.start()
        self.output.start(self.generator)


    def create_AUDIO(self, format):
        format.setChannelCount(AUDIO_CHANS)
        format.setSampleRate(SAMPLE_RATE)
        format.setSampleSize(SAMPLE_SIZE)
        format.setCodec("audio/pcm")
        format.setByteOrder(
            QAudioFormat.LittleEndian
        )
        format.setSampleType(
            QAudioFormat.SignedInt
        )

        self.output = QAudioOutput(format, self)
        output_buffer_size = \
            int(2*SAMPLE_RATE \
                 *CTRL_INTERVAL/1000)
        self.output.setBufferSize(
            output_buffer_size
        )

    def create_MIDI(self):
        # Create the port reader object
        self.midiListener = MidiPortReader()

        # Create a thread which will read it
        self.listenerThread = QThread()

        # Take the object and move it
        # to the new thread (it isn't running yet)
        self.midiListener.moveToThread(self.listenerThread)

        # Tell Qt the function to call
        # when it starts the thread
        self.listenerThread.started.connect(self.midiListener.listener)

        # connect pyqtSignals to slots in ToneGenerator
        self.midiListener.newNoteFrequency.connect(self.on_newNoteFrequency)
        self.midiListener.newNoteVelocity.connect(self.on_newNoteVelocity)
        self.midiListener.portClosed.connect(self.on_portClosed)


        # Fingers in ears, eyes tight shut...
        self.listenerThread.start()

        # Good grief, IT WORKS!




    def create_UI(self, parent):
        # Create a slider to fine tune freq and two buttons
        #self.octaveBox = QSlider(Qt.Horizontal)
        #self.octaveBox.setMinimum(-100)
        #self.octaveBox.setMaximum(100)
        self.octaveBox = QSpinBox()
        self.octaveBox.setRange(-5,5)

        self.octaveLabel = QLabel("Octave: ")
        self.quitButton = QPushButton(self.tr('&Quit'))

        # create dropdown menu so user can choose midi device in use (populate list from data from midi listener object)
        self.MIDIMenu = QComboBox()
        self.MIDIMenu.addItems(self.midiListener.getMIDIDevices())

        # create ADSR sliders
        self.aSlider = QSlider(Qt.Vertical)
        self.aSlider.setMinimum(1)
        self.aSlider.setMaximum(50)
        self.aSlider.setSliderPosition(1)

        self.dSlider = QSlider(Qt.Vertical)
        self.dSlider.setMinimum(1)
        self.dSlider.setMaximum(50)
        self.dSlider.setSliderPosition(8)

        self.sSlider = QSlider(Qt.Vertical)
        self.sSlider.setMinimum(1)
        self.sSlider.setMaximum(100)
        self.sSlider.setSliderPosition(80)

        self.rSlider = QSlider(Qt.Vertical)
        self.rSlider.setMinimum(1)
        self.rSlider.setMaximum(100)
        self.rSlider.setSliderPosition(50)


        # No parent: we're going to add this
        # to vLayout.
        hLayout1 = QHBoxLayout()
        hLayout1.addWidget(self.octaveLabel)
        hLayout1.addWidget(self.octaveBox)

        hLayout2 = QHBoxLayout()
        hLayout2.addWidget(self.aSlider)
        hLayout2.addWidget(self.dSlider)
        hLayout2.addWidget(self.sSlider)
        hLayout2.addWidget(self.rSlider)

        hLayout3 = QHBoxLayout()
        hLayout3.addWidget(self.MIDIMenu)
        hLayout3.addWidget(self.quitButton)


        # parent = self: this is the
        # "top level" layout
        vLayout = QVBoxLayout(self)
        vLayout.addLayout(hLayout1)
        vLayout.addLayout(hLayout2)
        vLayout.addLayout(hLayout3)

        # connect qt object signals to slots

        self.quitButton.clicked.connect(self.quitClicked)
        self.octaveBox.valueChanged.connect(self.changeOctave)
        self.aSlider.valueChanged.connect(self.changeADSRParam)
        self.dSlider.valueChanged.connect(self.changeADSRParam)
        self.sSlider.valueChanged.connect(self.changeADSRParam)
        self.rSlider.valueChanged.connect(self.changeADSRParam)
        self.MIDIMenu.currentIndexChanged[str].connect(self.changeMIDIDevice)

    # this isn't a @pyqtSlot(), the text is passed directly to the function
    def changeMIDIDevice(self, dev):
        self.midiListener.setMIDIDevice(dev)


    @pyqtSlot()
    def quitClicked(self):
        self.close()

    @pyqtSlot()
    def changeOctave(self):
        #scale slider value to freq and pass to subclass to update filter
        self.generator.setOctave(self.octaveBox.value())

    @pyqtSlot(float)
    def on_newNoteFrequency(self, freq):
        # change value of filter cutoff so it sounds like we're playing a different note
        self.generator.updateFilter(freq)

    @pyqtSlot(int)
    def on_newNoteVelocity(self, value):
        # note_off message doesn't work with shit USB keyboards, so we simulate a note_off message with the velocity
        if value != 0:
            self.generator.playNote()
        else:
            self.generator.stopNote()

    @pyqtSlot()
    def on_portClosed(self):
        # when port has closed, clear drop down menu and rescan for MIDI devices
        self.MIDIMenu.clear()
        self.MIDIMenu.addItems(self.midiListener.getMIDIDevices())


    @pyqtSlot()
    def changeADSRParam(self):
        self.generator.updateADSR(self.aSlider.value()/10, self.dSlider.value()/10, self.sSlider.value()/100, self.rSlider.value()/10)
class MainView(base, form):
    def __init__(self, pipeline, parent=None):

        super(base, self).__init__(parent)
        self.setupUi(self)
        self.pipeline = pipeline
        self.pip_widgets = []
        self.default_pips = []

        self.draw_ui()
        self.connect_ui()

    def register_observers(self):
        pass

    def connect_ui(self):
        """
        This function connects the ui using signals from the
        ui elements and its method counterparts.
        """
        self.input_btn.clicked.connect(self.set_input_url)
        self.output_btn.clicked.connect(self.set_output_url)
        self.save_btn.clicked.connect(self.save_pipeline)
        self.load_favorite_pipelines()
        self.fav_pips_combo_box.activated.connect(self.select_default_pip)
        self.run_btn.clicked.connect(self.run)
        self.delete_btn.clicked.connect(self.trash_pipeline)
        self.add_btn.clicked.connect(lambda: self.add_pipe_entry_new())

    def draw_ui(self):
        """
        This function draws all additional UI elements. If you want the
        application to display any additional things like a button you can
        either add it in the QtDesigner or declare it here.
        """

        # *TODO* Create these ones with Qt Designer and put them into select_cat_alg_vbox_layout. I failed
        self.ComboxCategories = QComboBox()
        self.stackedWidgetComboxesAlgorithms = QStackedWidget()
        self.select_cat_alg_vbox_layout.addWidget(self.ComboxCategories)
        self.select_cat_alg_vbox_layout.addWidget(self.stackedWidgetComboxesAlgorithms)
        self.ComboxCategories.hide()


        """
        This function is concerned with drawing all non static elements  into the
        GUI.
        """
        """self.set_pip_title("A. Junius2")

        self.set_preset(["A.Junius", "test", "test", "test"])


        self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed")
        self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed")
        self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed")
        self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed")
        self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed")
        self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed")
        self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed")
        self.add_cat_image("../assets/images/seg_fav.jpeg", "Preprocessing")
        self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing")
        self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing")
        self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing")
        self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing")
        self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing")
        self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing")

        self.main_image_label.setPixmap(QtGui.QPixmap("wing.jpeg"))

        category_combo_box = ComboBoxWidget("type")
        category_combo_box.add_item("Preprocessing", "../assets/images/P.png")
        category_combo_box.add_item("Segmentation", "../assets/images/S.png")
        category_combo_box.add_item("Graph Detection", "../assets/images/D.png")
        category_combo_box.add_item("Graph Filtering", "../assets/images/F.png")

        alg_combo_box = ComboBoxWidget("algorithm")
        alg_combo_box.add_item("Otsus")
        alg_combo_box.add_item("Guo Hall")
        alg_combo_box.add_item("Adaptive Treshold")

        slider_1 = SliderWidget("slider1das", 0, 10, 1, 4, True)
        slider_2 = SliderWidget("slider1", 0, 10, 2, 4, False)
        slider_3 = SliderWidget("sliderböadsad", 0, 10, 1, 4, True)
        slider_4 = SliderWidget("sliderböadsad", 0, 10, 1, 4, True)
        slider_5 = SliderWidget("sliderböadsad", 0, 10, 1, 4, True)
        checkbox_1 = CheckBoxWidget("checkbox1", True)

        self.setting_widget_vbox_layout.addWidget(category_combo_box)
        self.setting_widget_vbox_layout.addWidget(alg_combo_box)
        self.setting_widget_vbox_layout.addWidget(slider_1)
        self.setting_widget_vbox_layout.addWidget(slider_2)
        self.setting_widget_vbox_layout.addWidget(slider_3)
        self.setting_widget_vbox_layout.addWidget(slider_4)
        self.setting_widget_vbox_layout.addWidget(slider_5)
        self.setting_widget_vbox_layout.addWidget(checkbox_1)
        self.setting_widget_vbox_layout.setAlignment(Qt.AlignTop)"""

    def set_pip_title(self, title):
        """
        Sets the title of the current selected pipeline in the ui.

        Args:
            | *title*: the title of the pipeline
            | *label_ref*: the reference to the label.
        """
        self.current_pip_label.setText(title)

    def load_dark_theme(self, application):
        """
        This function is called to load the white theme with
        all its icons for the buttons and the css file.
        Args:
            application: the cureent app instance
        """
        # load buttons
        pixmap_icon = QtGui.QPixmap("./assets/images/add_white.png")
        q_icon = QtGui.QIcon(pixmap_icon)
        self.add_btn.setIcon(q_icon)

        pixmap_icon = QtGui.QPixmap("./assets/images/trash_white.png")
        q_icon = QtGui.QIcon(pixmap_icon)
        self.delete_btn.setIcon(q_icon)

        pixmap_icon = QtGui.QPixmap("./assets/images/diskette_white.png")
        q_icon = QtGui.QIcon(pixmap_icon)
        self.save_btn.setIcon(q_icon)

        pixmap_icon = QtGui.QPixmap("./assets/images/up-arrow_white.png")
        q_icon = QtGui.QIcon(pixmap_icon)
        self.input_btn.setIcon(q_icon)

        pixmap_icon = QtGui.QPixmap("./assets/images/folder_white.png")
        q_icon = QtGui.QIcon(pixmap_icon)
        self.output_btn.setIcon(q_icon)

    @pyqtSlot(int)
    def select_default_pip(self, index):
        """
        This is the slot for the Pipeline combobox in the ui
        Args:
            index: index of the option currently selected
        """

        # delete current pipeline

        self.trash_pipeline()

        # get url and name
        name, url = self.default_pips[index - 1]

        # parse the json in the model
        self.pipeline.load_pipeline_json(url)

        print("PARSER" + str(self.pipeline.executed_cats[0].active_algorithm))
        print("PARSER" + str(self.pipeline.executed_cats[1].active_algorithm))

        # set the title
        self.set_pip_title(name)

        # Create an entry in the pipeline widget for every step in the pipeline
        for i in range(0, len(self.pipeline.executed_cats)):
            self.add_pipe_entry_new(i)
            self.scroll_down_pip()

            """for widget in alg_widgets:
                self.setting_widget_vbox_layout.addWidget(widget)"""

    def trash_pipeline(self):
        """
        This method clears the complete pipeline while users clicked the trash
        button.
        """
        # remove all entries in the pipeline list

        while self.pip_widget_vbox_layout.count():
            child = self.pip_widget_vbox_layout.takeAt(0)
            child.widget().deleteLater()

        while self.stackedWidget_Settings.currentWidget() is not None:
            self.stackedWidget_Settings.removeWidget(self.stackedWidget_Settings.currentWidget())
            self.settings_collapsable.setTitle("")

        # remove the pipeline name
        self.set_pip_title("")

        # remove all entries int the executed_cats of the model pipeline
        del self.pipeline.executed_cats[:]

        # remove all widgets
        del self.pip_widgets[:]

        # remove category algorith dropdown
        self.remove_cat_alg_dropdown()

        # remove all entries from the pipeline model

        del self.pipeline.executed_cats[:]

    @pyqtSlot()
    def run(self):
        """
        This method runs the the pipeline by calling the process methode
        in pipeline
        """

        self.pipeline.process()

    @pyqtSlot()
    def set_input_url(self):
        """
        This method sets the url for the input image in the pipeline.
        """
        url = QtWidgets.QFileDialog.getOpenFileNames()
        if url[0]:
            print(url[0])
            print(url[0][0])
            self.lineEdit.setText(url[0][0])
            self.pipeline.set_input(url[0][0])


    @pyqtSlot()
    def set_output_url(self):
        """
        This method sets the url for the output folder in the pipeline.
        Args:
            url: the url to the output folder a user selected in the ui
        """
        url = QtWidgets.QFileDialog.getExistingDirectory()
        if url:
            print(url)
            print(url)
            self.custom_line_edit.setText(url)
            self.pipeline.set_output_dir(url)

    def load_favorite_pipelines(self):
        """
        Scans the directory for default pipelines to display all available items
        """
        self.fav_pips_combo_box.addItem("Please Select")

        # scan the directory for default pipelines
        for file in os.listdir("./_default_pipelines"):
            if file.endswith(".json"):
                name = file.split(".")[0]
                url = os.path.abspath("./_default_pipelines" + "/" + file)
                self.default_pips.append([name, url])
                self.fav_pips_combo_box.addItem(name)

    @pyqtSlot()
    def save_pipeline(self):
        """
        Saves the pipeline as a json at the users file system.
        """
        url = str(QtWidgets.QFileDialog.getSaveFileName()[0])

        split_list = url.split("/")
        name = split_list[len(split_list) - 1].split(".")[0]
        del split_list[len(split_list) - 1]
        url = url.replace(name, "")
        self.pipeline.save_pipeline_json(name, url)

    @pyqtSlot(int)
    def remove_pip_entry(self, pipe_entry_widget, settings_widget, cat=None):
        """
        Removes the pip entry at the given position in the ui
        Args:
            pipeline_index (object):
            settings_widget:
            position: position at which the pip entry gets removed
        """

        # remove pipeline entry widget from ui
        self.pip_widget_vbox_layout.removeWidget(pipe_entry_widget)
        pipe_entry_widget.deleteLater()

        # remove it settings widgets from ui
        if settings_widget is not None:
            if self.stackedWidget_Settings.currentWidget() == settings_widget:
                self.stackedWidget_Settings.hide()
                self.remove_cat_alg_dropdown()
                self.settings_collapsable.setTitle("Settings")

            self.stackedWidget_Settings.removeWidget(settings_widget)

        # remove in model
        if cat is not None:
            print("Remove entry at pos " + str(self.pipeline.get_index(cat)) + " " + str(cat))
            self.pipeline.delete_category(self.pipeline.get_index(cat))

    def change_pip_entry_alg(self, position, new_category, new_algorithm, pipe_entry_widget, settings_widget):
        """
        Changes the selected algorithm of the pipeline entry at the position.
        Afterwards create all widgets for this algorithm instance
        Args:
            position: the position of the pipeline entry
            algorithm: the selected algorithm for this category
        """
        print("Position to be changed:" + str(position))
        print("Pipeline length: " + str(len(self.pipeline.executed_cats)))

        old_cat = self.pipeline.executed_cats[position]
        old_alg = old_cat.active_algorithm
        print("Old Cat found in pipeline: " + str(old_cat))
        print("Old Alg: found in pipeline:" + str(old_alg))

        print("New Category given:" + str(new_category))
        print("New Algorithm given:" + str(new_algorithm))

        # set in model
        self.pipeline.change_category(new_category, position)
        self.pipeline.change_algorithm(new_algorithm, position)

        new_cat = self.pipeline.executed_cats[position]
        new_alg = new_cat.active_algorithm

        # change settings widgets
        self.remove_pip_entry(pipe_entry_widget, settings_widget)
        (new_pipe_entry_widget, new_settings_widget) = self.add_pipe_entry_new(position)

        self.stackedWidget_Settings.show()
        self.stackedWidget_Settings.setCurrentIndex(position)
        self.settings_collapsable.setTitle(new_alg.get_name() + " Settings")

        self.remove_cat_alg_dropdown()
        self.create_cat_alg_dropdown(position, new_pipe_entry_widget, new_settings_widget)
        self.set_cat_alg_dropdown(new_cat, new_alg)


        print("New Cat found in pipeline: " + str(new_cat))
        print("New Alg found in pipeline: " + str(new_alg))


    def load_settings_widgets_from_pipeline_groupbox(self, position):
        """
        Extracts all widgets from a single algorithm and returns a QBoxLayout
        Args:
            alg: the alg instance we extract from

        Returns: a QBoxLayout containing all widgets for this particular alg.

        """

        alg = self.pipeline.executed_cats[position].active_algorithm

        print("alg " + str(alg))
        print("cat " + str(self.pipeline.executed_cats[position]))

        empty_flag = True

        groupOfSliders = QGroupBox()
        sp = QSizePolicy()
        sp.setVerticalPolicy(QSizePolicy.Preferred)
        # groupOfSliders.setSizePolicy(sp)
        groupOfSliderssLayout = QBoxLayout(QBoxLayout.TopToBottom)
        groupOfSliderssLayout.setContentsMargins(0, -0, -0, 0)
        groupOfSliderssLayout.setAlignment(Qt.AlignTop)
        groupOfSliderssLayout.setSpacing(0)

        print("Build Slider @ "+ str(position))

        # create integer sliders
        for slider in alg.integer_sliders:
            empty_flag = False
            print("slider.value " + str(slider.value))
            print("slider " + str(slider))
            #print(alg.get_name() + ": add slider (int).")
            groupOfSliderssLayout.addWidget(
                SliderWidget(slider.name, slider.lower, slider.upper, slider.step_size, slider.value,
                             slider.set_value, False))

        # create float sliders
        for slider in alg.float_sliders:
            empty_flag = False
            #print(alg.get_name() + ": add slider (float).")
            groupOfSliderssLayout.addWidget(
                SliderWidget(slider.name, slider.lower, slider.upper, slider.step_size, slider.value,
                             slider.set_value, True), 0, Qt.AlignTop)

        # create checkboxes
        for checkbox in alg.checkboxes:
            empty_flag = False
            #print(alg.get_name() + ": add checkbox.")
            groupOfSliderssLayout.addWidget(CheckBoxWidget(checkbox.name, checkbox.value, checkbox.set_value), 0,
                                            Qt.AlignTop)

        # create dropdowns
        for combobox in alg.drop_downs:
            empty_flag = False
            #print(alg.get_name() + ": add combobox.")
            groupOfSliderssLayout.addWidget(
                ComboBoxWidget(combobox.name, combobox.options, combobox.set_value, combobox.value), 0, Qt.AlignTop)

        if empty_flag:
            label = QLabel()
            label.setText("This algorithm has no Settings.")
            groupOfSliderssLayout.addWidget(label, 0, Qt.AlignHCenter)

        groupOfSliders.setLayout(groupOfSliderssLayout)

        return groupOfSliders

    def create_cat_alg_dropdown(self, cat_position, pipe_entry_widget, settings_widget):

        """
        Args:
            last_cat (object):
        """
        layout = self.select_cat_alg_vbox_layout
        cat = self.pipeline.executed_cats[cat_position]

        last_cat = None

        # Show only allowed categories in dropdown
        if len(self.pipeline.executed_cats) > 1:
            last_cat = self.pipeline.executed_cats[cat_position - 1]

        # Combobox for selecting Category
        self.ComboxCategories.show()
        self.ComboxCategories.setFixedHeight(30)
        self.ComboxCategories.addItem("<Please Select Category>")

        self.stackedWidgetComboxesAlgorithms = QStackedWidget()
        self.stackedWidgetComboxesAlgorithms.setFixedHeight(30)
        self.stackedWidgetComboxesAlgorithms.hide()

        def setCurrentIndexCat(index):
            #print("Set Cat")
            if self.ComboxCategories.currentIndex() == 0:
                self.stackedWidgetComboxesAlgorithms.hide()
            else:
                self.stackedWidgetComboxesAlgorithms.show()
                self.stackedWidgetComboxesAlgorithms.setCurrentIndex(index - 1)

        for category_name in self.pipeline.report_available_cats(last_cat):

            # Add Category to combobox
            self.ComboxCategories.addItem(category_name)
            tmp1 = QComboBox()
            tmp1.addItem("<Please Select Algorithm>")
            tmp1.setFixedHeight(30)
            category = self.pipeline.get_category(category_name)
            #self.current_index = -1

            def setCurrentIndexAlg(index):
                if self.ComboxCategories.currentIndex() == 0 or self.stackedWidgetComboxesAlgorithms.currentWidget().currentIndex() == 0:
                    pass
                else: #self.current_index != index:
                    self.change_pip_entry_alg(self.pipeline.get_index(cat), self.ComboxCategories.currentText(),
                                              self.stackedWidgetComboxesAlgorithms.currentWidget().currentText(),
                                              pipe_entry_widget, settings_widget)
                    #self.current_index = index

            tmp1.activated.connect(setCurrentIndexAlg)

            for algorithm_name in self.pipeline.get_all_algorithm_list(category):
                tmp1.addItem(algorithm_name)

            self.stackedWidgetComboxesAlgorithms.addWidget(tmp1)

        layout.addWidget(self.ComboxCategories)
        layout.addWidget(self.stackedWidgetComboxesAlgorithms)

        self.ComboxCategories.activated.connect(setCurrentIndexCat)

    def set_cat_alg_dropdown(self, category, algorithm):

        indexC = self.ComboxCategories.findText(category.get_name())
        #print("IndexC " + str(indexC))
        self.ComboxCategories.setCurrentIndex(indexC)
        self.stackedWidgetComboxesAlgorithms.show()
        self.stackedWidgetComboxesAlgorithms.setCurrentIndex(indexC - 1)
        indexA = self.stackedWidgetComboxesAlgorithms.currentWidget().findText(algorithm.get_name())
        #print("IndexA " + str(indexA))
        self.stackedWidgetComboxesAlgorithms.currentWidget().setCurrentIndex(indexA)

    def remove_cat_alg_dropdown(self):

        """

        Returns:
            object:
        """
        self.ComboxCategories.clear()

        while self.stackedWidgetComboxesAlgorithms.currentWidget() is not None:
            self.stackedWidgetComboxesAlgorithms.removeWidget(self.stackedWidgetComboxesAlgorithms.currentWidget())

        while self.select_cat_alg_vbox_layout.count():
            child = self.select_cat_alg_vbox_layout.takeAt(0)
            child.widget().hide()

    def scroll_down_pip(self):
        self.pip_scroll.verticalScrollBar().setSliderPosition(self.pip_scroll.verticalScrollBar().maximum())

    def add_pipe_entry_new(self, position=None):
        """
            Creates a entry in the ui pipeline with a given position in pipeline.
            It also creates the corresponding settings widget.
            """
        # create an widget that displays the pip entry in the ui and connect the remove button

        pip_main_widget = QWidget()
        pip_main_widget.setFixedHeight(70)
        pip_main_widget.setFixedWidth(300)
        pip_main_layout = QHBoxLayout()
        pip_main_widget.setLayout(pip_main_layout)

        new_marker = False

        if position is None:
            position = len(self.pipeline.executed_cats)
            cat = self.pipeline.new_category(position)
            label = "<Click to specify new step>"
            icon = None
            new_marker = True
        else:
            cat = self.pipeline.executed_cats[position]
            alg = cat.active_algorithm
            label = alg.get_name()
            icon = cat.get_icon()
            new_marker = False

        pixmap = QPixmap(icon)
        pixmap_scaled_keeping_aspec = pixmap.scaled(30, 30, QtCore.Qt.KeepAspectRatio)
        pixmap_label = QtWidgets.QLabel()
        pixmap_label.setPixmap(pixmap_scaled_keeping_aspec)

        pip_up_down = QWidget()
        pip_up_down.setFixedHeight(70)
        pip_up_down_layout = QVBoxLayout()
        pip_up_down.setLayout(pip_up_down_layout)

        up_btn = QToolButton()
        dw_btn = QToolButton()

        up_btn.setArrowType(Qt.UpArrow)
        up_btn.setFixedHeight(25)
        dw_btn.setArrowType(Qt.DownArrow)
        dw_btn.setFixedHeight(25)

        pip_up_down_layout.addWidget(up_btn)
        pip_up_down_layout.addWidget(dw_btn)

        string_label = QLabel()
        string_label.setText(label)
        string_label.setFixedWidth(210)

        btn = QtWidgets.QPushButton()
        btn.setFixedSize(20, 20)

        pixmap_icon = QtGui.QPixmap("./assets/images/delete_x_white.png")
        q_icon = QtGui.QIcon(pixmap_icon)
        btn.setIcon(q_icon)

        pip_main_layout.addWidget(pip_up_down, Qt.AlignVCenter)
        pip_main_layout.addWidget(pixmap_label, Qt.AlignVCenter)
        pip_main_layout.addWidget(string_label, Qt.AlignLeft)
        pip_main_layout.addWidget(btn, Qt.AlignVCenter)

        self.pip_widget_vbox_layout.insertWidget(position, pip_main_widget)

        # Create the corresponding settings widget and connect it
        self.settings_collapsable.setTitle("Settings")
        self.stackedWidget_Settings.hide()
        settings_main_widget = None
        if not new_marker:
            settings_main_widget = self.load_settings_widgets_from_pipeline_groupbox(position)
            self.stackedWidget_Settings.insertWidget(position, settings_main_widget)

        def show_settings():
            # Set background color while widget is selected. Doesn't work because of theme? *TODO*
            p = pip_main_widget.palette()
            p.setColor(pip_main_widget.backgroundRole(), Qt.red)
            pip_main_widget.setPalette(p)

            if not new_marker:
                self.stackedWidget_Settings.show()
                self.stackedWidget_Settings.setCurrentIndex(self.pipeline.get_index(cat))
                self.settings_collapsable.setTitle(alg.get_name() + " Settings")
            else:
                self.stackedWidget_Settings.hide()

            # Create drop down for cats and algs
            self.remove_cat_alg_dropdown()
            self.create_cat_alg_dropdown(self.pipeline.get_index(cat), pip_main_widget, settings_main_widget)

            if not new_marker:
                self.set_cat_alg_dropdown(cat, alg)

        # Connect Button to remove step from pipeline
        def delete_button_clicked():
            self.remove_cat_alg_dropdown()
            self.remove_pip_entry(pip_main_widget, settings_main_widget, cat)

        self.clickable(pixmap_label).connect(show_settings)
        self.clickable(string_label).connect(show_settings)
        btn.clicked.connect(delete_button_clicked)


        return (pip_main_widget, settings_main_widget)



    def add_pip_entry_empty(self):
        """
        Creates an blank entry in the ui pipeline since the user still needs to specify
        a type and an algorithm of the category.
        It also creates the corresponding settings widget.
        """
        # create an widget that displays the pip entry in the ui and connect the remove button
        pip_main_widget = QWidget()
        pip_main_widget.setFixedHeight(70)
        pip_main_widget.setFixedWidth(300)
        pip_main_layout = QHBoxLayout()
        pip_main_widget.setLayout(pip_main_layout)

        label = "<Click to specify new step>"
        icon = None

        pixmap = QPixmap(icon)
        pixmap_scaled_keeping_aspec = pixmap.scaled(30, 30, QtCore.Qt.KeepAspectRatio)
        pixmap_label = QtWidgets.QLabel()
        pixmap_label.setPixmap(pixmap_scaled_keeping_aspec)

        pip_up_down = QWidget()
        pip_up_down.setFixedHeight(70)
        pip_up_down_layout = QVBoxLayout()
        pip_up_down.setLayout(pip_up_down_layout)

        up_btn = QToolButton()
        dw_btn = QToolButton()

        up_btn.setArrowType(Qt.UpArrow)
        up_btn.setFixedHeight(25)
        dw_btn.setArrowType(Qt.DownArrow)
        dw_btn.setFixedHeight(25)

        pip_up_down_layout.addWidget(up_btn)
        pip_up_down_layout.addWidget(dw_btn)

        string_label = QLabel()
        string_label.setText(label)
        string_label.setFixedWidth(210)

        btn = QtWidgets.QPushButton()
        btn.setFixedSize(20, 20)

        pixmap_icon = QtGui.QPixmap("./assets/images/delete_x_white.png")
        q_icon = QtGui.QIcon(pixmap_icon)
        btn.setIcon(q_icon)

        pip_main_layout.addWidget(pip_up_down, Qt.AlignVCenter)
        pip_main_layout.addWidget(pixmap_label, Qt.AlignVCenter)
        pip_main_layout.addWidget(string_label, Qt.AlignLeft)
        pip_main_layout.addWidget(btn, Qt.AlignVCenter)

        cat_position = len(self.pipeline.executed_cats)

        self.pip_widget_vbox_layout.insertWidget(cat_position, pip_main_widget)
        index = self.pip_widget_vbox_layout.indexOf(pip_main_widget)
        #print(index)

        # Create the corresponding empty settings widget and connect it
        # settings = self.load_widgets_from_cat_groupbox(cat_position) *TODO* EMPTY

        self.settings_collapsable.setTitle("Settings")
        self.stackedWidget_Settings.hide()

        # Add new step to pipeline
        new_category = self.pipeline.new_category(cat_position)

        print("Create new entry " + str(new_category))
        print("Pipeline length: " + str(len(self.pipeline.executed_cats)) + ".")

        settings_main_widget = None

        # Connect pipeline entry with corresponding settings widget
        def show_settings():
            #print("click")
            self.stackedWidget_Settings.show()

            self.remove_cat_alg_dropdown()

            # Create drop down for cats and algs
            self.create_cat_alg_dropdown(self.pipeline.get_index(new_category), pip_main_widget, settings_main_widget)
            self.stackedWidget_Settings.hide()

        # Connect Button to remove step from pipeline
        def delete_button_clicked():
            self.remove_cat_alg_dropdown()
            self.remove_pip_entry(pip_main_widget, settings_main_widget, new_category)

        self.clickable(pixmap_label).connect(show_settings)
        self.clickable(string_label).connect(show_settings)
        btn.clicked.connect(delete_button_clicked)

        self.scroll_down_pip()

    def add_pip_entry(self, cat_position):
        """
        Creates a entry in the ui pipeline with a given position in pipeline.
        It also creates the corresponding settings widget.
        """
        # create an widget that displays the pip entry in the ui and connect the remove button

        pip_main_widget = QWidget()
        pip_main_widget.setFixedHeight(70)
        pip_main_widget.setFixedWidth(300)
        pip_main_layout = QHBoxLayout()
        pip_main_widget.setLayout(pip_main_layout)

        cat = self.pipeline.executed_cats[cat_position]
        alg = cat.active_algorithm
        label = alg.get_name()
        icon = cat.get_icon()

        pixmap = QPixmap(icon)
        pixmap_scaled_keeping_aspec = pixmap.scaled(30, 30, QtCore.Qt.KeepAspectRatio)
        pixmap_label = QtWidgets.QLabel()
        pixmap_label.setPixmap(pixmap_scaled_keeping_aspec)

        pip_up_down = QWidget()
        pip_up_down.setFixedHeight(70)
        pip_up_down_layout = QVBoxLayout()
        pip_up_down.setLayout(pip_up_down_layout)

        up_btn = QToolButton()
        dw_btn = QToolButton()

        up_btn.setArrowType(Qt.UpArrow)
        up_btn.setFixedHeight(25)
        dw_btn.setArrowType(Qt.DownArrow)
        dw_btn.setFixedHeight(25)

        pip_up_down_layout.addWidget(up_btn)
        pip_up_down_layout.addWidget(dw_btn)

        string_label = QLabel()
        string_label.setText(label)
        string_label.setFixedWidth(210)

        btn = QtWidgets.QPushButton()
        btn.setFixedSize(20, 20)

        pixmap_icon = QtGui.QPixmap("./assets/images/delete_x_white.png")
        q_icon = QtGui.QIcon(pixmap_icon)
        btn.setIcon(q_icon)

        pip_main_layout.addWidget(pip_up_down, Qt.AlignVCenter)
        pip_main_layout.addWidget(pixmap_label, Qt.AlignVCenter)
        pip_main_layout.addWidget(string_label, Qt.AlignLeft)
        pip_main_layout.addWidget(btn, Qt.AlignVCenter)

        self.pip_widget_vbox_layout.insertWidget(cat_position, pip_main_widget)
        index = self.pip_widget_vbox_layout.indexOf(pip_main_widget)
        #print(index)

        # Create the corresponding settings widget and connect it
        settings_main_widget = self.load_settings_widgets_from_pipeline_groupbox(cat_position)

        self.settings_collapsable.setTitle("Settings")
        self.stackedWidget_Settings.hide()
        self.stackedWidget_Settings.insertWidget(cat_position, settings_main_widget)

        #print("Read from pipeline entry " + str(cat))
        #print("Pipeline length: " + str(len(self.pipeline.executed_cats)) + ".")

        def show_settings():
            # Set background color while widget is selected. Doesn't work because of theme? *TODO*
            p = pip_main_widget.palette()
            p.setColor(pip_main_widget.backgroundRole(), Qt.red)
            pip_main_widget.setPalette(p)

            self.stackedWidget_Settings.show()
            self.stackedWidget_Settings.setCurrentIndex(self.pipeline.get_index(cat))
            self.settings_collapsable.setTitle(alg.get_name() + " Settings")

            self.remove_cat_alg_dropdown()

            # Create drop down for cats and algs
            self.create_cat_alg_dropdown(self.pipeline.get_index(cat), pip_main_widget, settings_main_widget)
            #print(cat)
            #print(alg)
            self.set_cat_alg_dropdown(cat, alg)

        # Connect Button to remove step from pipeline
        def delete_button_clicked():
            self.remove_pip_entry(pip_main_widget, settings_main_widget, cat)

        self.clickable(pixmap_label).connect(show_settings)
        self.clickable(string_label).connect(show_settings)
        btn.clicked.connect(delete_button_clicked)

        return (pip_main_widget, settings_main_widget)

    # https://wiki.python.org/moin/PyQt/Making%20non-clickable%20widgets%20clickable
    def clickable(self, widget):
        """
        Convert any widget to a clickable widget.
        """

        class Filter(QObject):

            clicked = pyqtSignal()

            def eventFilter(self, obj, event):

                if obj == widget:
                    if event.type() == QEvent.MouseButtonPress:
                        if obj.rect().contains(event.pos()):
                            self.clicked.emit()
                            # The developer can opt for .emit(obj) to get the object within the slot.
                            return True

                return False

        filter = Filter(widget)
        widget.installEventFilter(filter)
        return filter.clicked
Exemplo n.º 42
0
class HeapPluginForm(PluginForm):
    def __init__(self):
        super(HeapPluginForm, self).__init__()
        self.parent = None
        self.config_path = None
        self.config = None
        self.tracer = None
        self.heap = None
        self.cur_arena = None  # default: main_arena
        self.ptr_size = get_arch_ptrsize()

    def OnCreate(self, form):
        self.parent = self.FormToPyQtWidget(form)
        self.setup_gui()
        self.init_heap()
        self.populate_gui()

    def setup_gui(self):
        self.chunk_widget = ChunkWidget(self)
        self.tracer_tab = TracerWidget(self)
        self.arena_widget = ArenaWidget(self)
        self.bins_widget = BinsWidget(self)
        self.tcache_widget = TcacheWidget(self)
        self.magic_widget = MagicWidget(self)
        self.config_widget = ConfigWidget(self)

        self.tabs = QTabWidget()
        self.tabs.addTab(self.tracer_tab, "Tracer")
        self.tabs.addTab(self.arena_widget, "Arena")
        self.tabs.addTab(self.bins_widget, "Bins")
        self.tabs.addTab(self.tcache_widget, "Tcache")
        self.tabs.addTab(self.magic_widget, "Magic")
        self.tabs.addTab(self.config_widget, "Config")

        self.btn_reload = QPushButton("Reload info")
        icon = QtGui.QIcon(os.path.normpath(ICONS_DIR + '/refresh.png'))
        self.btn_reload.setIcon(icon)
        self.btn_reload.setFixedWidth(120)
        self.btn_reload.setEnabled(False)
        self.btn_reload.clicked.connect(self.reload_gui_info)

        self.cb_arenas = QComboBox()
        self.cb_arenas.setFixedWidth(150)
        self.cb_arenas.currentIndexChanged[int].connect(self.cb_arenas_changed)

        hbox_arenas = QHBoxLayout()
        hbox_arenas.addWidget(QLabel('Switch arena: '))
        hbox_arenas.addWidget(self.cb_arenas)
        hbox_arenas.setContentsMargins(0, 0, 0, 0)

        self.arenas_widget = QWidget()
        self.arenas_widget.setLayout(hbox_arenas)
        self.arenas_widget.setVisible(False)

        self.txt_warning = QLabel()
        self.txt_warning.setStyleSheet("font-weight: bold; color: red")
        self.txt_warning.setVisible(False)

        hbox_top = QHBoxLayout()
        hbox_top.addWidget(self.btn_reload)
        hbox_top.addWidget(self.arenas_widget)
        hbox_top.addWidget(self.txt_warning)
        hbox_top.setContentsMargins(0, 0, 0, 0)
        hbox_top.addStretch(1)

        vbox_left_panel = QVBoxLayout()
        vbox_left_panel.addLayout(hbox_top)
        vbox_left_panel.addWidget(self.tabs)
        vbox_left_panel.setContentsMargins(0, 0, 0, 0)

        left_panel = QWidget()
        left_panel.setLayout(vbox_left_panel)

        self.splitter = QSplitter(QtCore.Qt.Horizontal)
        self.splitter.addWidget(left_panel)
        self.splitter.addWidget(self.chunk_widget)
        self.splitter.setStretchFactor(0, 1)

        main_layout = QVBoxLayout()
        main_layout.addWidget(self.splitter)
        self.parent.setLayout(main_layout)

    def populate_gui(self):
        self.magic_widget.populate_libc_offsets()
        self.reload_gui_info()

    def reload_gui_info(self, from_arena_cb=False):
        if not self.heap:
            return

        if not self.heap.get_heap_base():
            self.show_warning('Heap not initialized')
            return

        self.hide_warning()
        self.arenas_widget.setVisible(True)

        if not from_arena_cb:
            self.populate_arenas()

        self.arena_widget.populate_table()
        self.tcache_widget.populate_table()
        self.bins_widget.populate_tables()

    def init_heap(self):
        try:
            self.config_path = CONFIG_PATH
            self.config = HeapConfig(self.config_path)
            self.config_widget.load_config()

        except Exception as e:
            self.config = None
            self.show_warning('Please, update the config file')
            warning(str(e))
            return

        if not self.config.offsets:
            arch_bits = self.ptr_size * 8
            self.show_warning('Config: Libc offsets for %d bits not found.' %
                              arch_bits)
            return

        try:
            current_libc_version = get_libc_version()
            if self.config.libc_version == current_libc_version or current_libc_version == None:
                self.heap = Heap(self.config)
                self.btn_reload.setEnabled(True)
                self.tabs.setTabEnabled(3, self.heap.tcache_enabled)
            else:
                self.show_warning('Config: glibc version mismatched: %s != %s' % \
                    (str(self.config.libc_version), str(current_libc_version)))

        except AttributeError:
            self.show_warning('Invalid config file content')

    def populate_arenas(self):
        old_arena = self.cur_arena
        self.cb_arenas.clear()

        for addr, arena in self.heap.arenas():
            if addr == self.heap.main_arena_addr:
                self.cb_arenas.addItem("main_arena", None)
            else:
                self.cb_arenas.addItem("0x%x" % addr, addr)

        idx = self.cb_arenas.findData(old_arena)
        if idx != -1:
            self.cb_arenas.setCurrentIndex(idx)

    def show_warning(self, txt):
        self.txt_warning.setText(txt)
        self.txt_warning.setVisible(True)

    def hide_warning(self):
        self.txt_warning.setVisible(False)

    def cb_arenas_changed(self, idx):
        self.cur_arena = self.cb_arenas.itemData(idx)
        self.reload_gui_info(True)

    def show_chunk_info(self, address):
        self.chunk_widget.show_chunk(address)

    def Show(self):
        return PluginForm.Show(self,
                               PLUGNAME,
                               options=(PluginForm.FORM_TAB
                                        | PluginForm.FORM_CLOSE_LATER))

    def OnClose(self, form):
        if self.tracer:
            self.tracer.unhook()
            log("Tracer disabled")
        log("Form closed")
Exemplo n.º 43
0
class MainWindow(QMainWindow, Ui_MainWindow):
    """
    classdocs
    """

    def __init__(self, app):
        """
        Init
        :param sakia.core.app.Application app: application
        :type: sakia.core.app.Application
        """
        # Set up the user interface from Designer.
        super().__init__()
        self.app = app
        self.initialized = False
        self.password_asker = None
        self.import_dialog = None

        super().setupUi(self)

        QApplication.setWindowIcon(QIcon(":/icons/sakia_logo"))

        self.app.version_requested.connect(self.latest_version_requested)

        self.status_label = QLabel("", self)
        self.status_label.setTextFormat(Qt.RichText)
        self.statusbar.addPermanentWidget(self.status_label, 1)

        self.label_time = QLabel("", self)
        self.statusbar.addPermanentWidget(self.label_time)

        self.combo_referential = QComboBox(self)
        self.combo_referential.setEnabled(False)
        self.combo_referential.currentIndexChanged.connect(self.referential_changed)
        self.statusbar.addPermanentWidget(self.combo_referential)

        self.homescreen = HomeScreenWidget(self.app, self.status_label)
        self.homescreen.frame_communities.community_tile_clicked.connect(self.change_community)
        self.homescreen.toolbutton_new_account.clicked.connect(self.open_add_account_dialog)
        self.homescreen.toolbutton_new_account.addAction(self.action_add_account)
        self.homescreen.toolbutton_new_account.addAction(self.action_import)
        self.homescreen.button_add_community.clicked.connect(self.action_open_add_community)
        self.homescreen.button_disconnect.clicked.connect(lambda :self.action_change_account(""))
        self.centralWidget().layout().addWidget(self.homescreen)
        self.homescreen.toolbutton_connect.setMenu(self.menu_change_account)

        self.community_view = CommunityWidget(self.app, self.status_label)
        self.community_view.button_home.clicked.connect(lambda: self.change_community(None))
        self.community_view.button_certification.clicked.connect(self.open_certification_dialog)
        self.community_view.button_send_money.clicked.connect(self.open_transfer_money_dialog)
        self.centralWidget().layout().addWidget(self.community_view)

    def startup(self):
        self.update_time()
        # FIXME : Need python 3.5 self.app.get_last_version()
        if self.app.preferences['maximized']:
            self.showMaximized()
        else:
            self.show()
        if self.app.current_account:
            self.password_asker = PasswordAskerDialog(self.app.current_account)
            self.community_view.change_account(self.app.current_account, self.password_asker)
        self.refresh()

    @asyncify
    @asyncio.coroutine
    def open_add_account_dialog(self, checked=False):
        dialog = ProcessConfigureAccount(self.app, None)
        result = yield from dialog.async_exec()
        if result == QDialog.Accepted:
            self.action_change_account(self.app.current_account.name)

    @asyncify
    @asyncio.coroutine
    def open_configure_account_dialog(self, checked=False):
        dialog = ProcessConfigureAccount(self.app, self.app.current_account)
        result = yield from dialog.async_exec()
        if result == QDialog.Accepted:
            if self.app.current_account:
                self.action_change_account(self.app.current_account.name)
            else:
                self.refresh()

    @pyqtSlot(str)
    def display_error(self, error):
        QMessageBox.critical(self, ":(",
                             error,
                             QMessageBox.Ok)

    @pyqtSlot(str)
    def referential_changed(self, index):
        if self.app.current_account:
            self.app.current_account.set_display_referential(index)
            if self.community_view:
                self.community_view.referential_changed()
                self.homescreen.referential_changed()

    @pyqtSlot()
    def update_time(self):
        dateTime = QDateTime.currentDateTime()
        self.label_time.setText("{0}".format(QLocale.toString(
                        QLocale(),
                        QDateTime.currentDateTime(),
                        QLocale.dateTimeFormat(QLocale(), QLocale.NarrowFormat)
                    )))
        timer = QTimer()
        timer.timeout.connect(self.update_time)
        timer.start(1000)

    @pyqtSlot()
    def delete_contact(self):
        contact = self.sender().data()
        self.app.current_account.contacts.remove(contact)
        self.refresh_contacts()

    @pyqtSlot()
    def edit_contact(self):
        index = self.sender().data()
        dialog = ConfigureContactDialog(self.app.current_account, self, None, index)
        result = dialog.exec_()
        if result == QDialog.Accepted:
            self.window().refresh_contacts()

    def action_change_account(self, account_name):
        self.app.change_current_account(self.app.get_account(account_name))
        self.password_asker = PasswordAskerDialog(self.app.current_account)
        self.community_view.change_account(self.app.current_account, self.password_asker)
        self.refresh()

    @pyqtSlot()
    def action_open_add_community(self):
        dialog = ProcessConfigureCommunity(self.app,
                                           self.app.current_account, None,
                                           self.password_asker)
        if dialog.exec_() == QDialog.Accepted:
            self.app.save(self.app.current_account)
            dialog.community.start_coroutines()
            self.homescreen.refresh()

    def open_transfer_money_dialog(self):
        dialog = TransferMoneyDialog(self.app,
                                     self.app.current_account,
                                     self.password_asker,
                                     self.community_view.community,
                                     None)
        if dialog.exec_() == QDialog.Accepted:
            self.community_view.tab_history.table_history.model().sourceModel().refresh_transfers()

    def open_certification_dialog(self):
        dialog = CertificationDialog(self.app,
                                     self.app.current_account,
                                     self.password_asker)
        dialog.exec_()

    def open_add_contact_dialog(self):
        dialog = ConfigureContactDialog(self.app.current_account, self)
        result = dialog.exec_()
        if result == QDialog.Accepted:
            self.window().refresh_contacts()

    def open_preferences_dialog(self):
        dialog = PreferencesDialog(self.app)
        result = dialog.exec_()

    def open_about_popup(self):
        """
        Open about popup window
        """
        aboutDialog = QDialog(self)
        aboutUi = Ui_AboutPopup()
        aboutUi.setupUi(aboutDialog)

        latest = self.app.available_version
        version_info = ""
        version_url = ""
        if not latest[0]:
            version_info = self.tr("Latest release : {version}") \
                .format(version=latest[1])
            version_url = latest[2]

            new_version_text = """
                <p><b>{version_info}</b></p>
                <p><a href="{version_url}">{link_text}</a></p>
                """.format(version_info=version_info,
                            version_url=version_url,
                            link_text=self.tr("Download link"))
        else:
            new_version_text = ""

        text = self.tr("""
        <h1>sakia</h1>

        <p>Python/Qt uCoin client</p>

        <p>Version : {:}</p>
        {new_version_text}

        <p>License : GPLv3</p>

        <p><b>Authors</b></p>

        <p>inso</p>
        <p>vit</p>
        <p>Moul</p>
        <p>canercandan</p>
        """).format(__version__, new_version_text=new_version_text)

        aboutUi.label.setText(text)
        aboutDialog.show()

    @pyqtSlot()
    def latest_version_requested(self):
        latest = self.app.available_version
        logging.debug("Latest version requested")
        if not latest[0]:
            version_info = self.tr("Please get the latest release {version}") \
                .format(version=latest[1])
            version_url = latest[2]

            if self.app.preferences['notifications']:
                toast.display("sakia", """{version_info}""".format(
                version_info=version_info,
                version_url=version_url))

    @pyqtSlot(Community)
    def change_community(self, community):
        if community:
            self.homescreen.hide()
            self.community_view.show()
        else:
            self.community_view.hide()
            self.homescreen.show()

        self.community_view.change_community(community)

    def refresh_accounts(self):
        self.menu_change_account.clear()
        for account_name in sorted(self.app.accounts.keys()):
            action = QAction(account_name, self)
            action.triggered.connect(lambda checked, account_name=account_name: self.action_change_account(account_name))
            self.menu_change_account.addAction(action)

    def refresh_contacts(self):
        self.menu_contacts_list.clear()
        if self.app.current_account:
            for index, contact in enumerate(self.app.current_account.contacts):
                contact_menu = self.menu_contacts_list.addMenu(contact['name'])
                edit_action = contact_menu.addAction(self.tr("Edit"))
                edit_action.triggered.connect(self.edit_contact)
                edit_action.setData(index)
                delete_action = contact_menu.addAction(self.tr("Delete"))
                delete_action.setData(contact)
                delete_action.triggered.connect(self.delete_contact)

    def refresh(self):
        """
        Refresh main window
        When the selected account changes, all the widgets
        in the window have to be refreshed
        """
        logging.debug("Refresh started")
        self.refresh_accounts()
        self.community_view.hide()
        self.homescreen.show()
        self.homescreen.refresh()

        if self.app.current_account is None:
            self.setWindowTitle(self.tr("sakia {0}").format(__version__))
            self.action_add_a_contact.setEnabled(False)
            self.actionCertification.setEnabled(False)
            self.actionTransfer_money.setEnabled(False)
            self.action_configure_parameters.setEnabled(False)
            self.action_set_as_default.setEnabled(False)
            self.menu_contacts_list.setEnabled(False)
            self.combo_referential.setEnabled(False)
            self.status_label.setText(self.tr(""))
            self.password_asker = None
        else:
            self.password_asker = PasswordAskerDialog(self.app.current_account)

            self.combo_referential.blockSignals(True)
            self.combo_referential.clear()
            for ref in money.Referentials:
                self.combo_referential.addItem(ref.translated_name())

            self.combo_referential.setEnabled(True)
            self.combo_referential.blockSignals(False)
            logging.debug(self.app.preferences)
            self.combo_referential.setCurrentIndex(self.app.preferences['ref'])
            self.action_add_a_contact.setEnabled(True)
            self.actionCertification.setEnabled(True)
            self.actionTransfer_money.setEnabled(True)
            self.menu_contacts_list.setEnabled(True)
            self.action_configure_parameters.setEnabled(True)
            self.setWindowTitle(self.tr("sakia {0} - Account : {1}").format(__version__,
                                                                               self.app.current_account.name))

        self.refresh_contacts()

    def import_account(self):
        self.import_dialog = ImportAccountDialog(self.app, self)
        self.import_dialog.accepted.connect(self.import_account_accepted)
        self.import_dialog.exec_()

    def import_account_accepted(self):
        # open account after import
        self.action_change_account(self.import_dialog.edit_name.text())

    def export_account(self):
        # Testable way of using a QFileDialog
        export_dialog = QFileDialog(self)
        export_dialog.setObjectName('ExportFileDialog')
        export_dialog.setWindowTitle(self.tr("Export an account"))
        export_dialog.setNameFilter(self.tr("All account files (*.acc)"))
        export_dialog.setLabelText(QFileDialog.Accept, self.tr('Export'))
        export_dialog.setOption(QFileDialog.DontUseNativeDialog, True)
        export_dialog.accepted.connect(self.export_account_accepted)
        export_dialog.show()

    def export_account_accepted(self):
        export_dialog = self.sender()
        selected_file = export_dialog.selectedFiles()
        if selected_file:
            if selected_file[0][-4:] == ".acc":
                path = selected_file[0]
            else:
                path = selected_file[0] + ".acc"
            self.app.export_account(path, self.app.current_account)

    def closeEvent(self, event):
        self.app.stop()
        super().closeEvent(event)

    def changeEvent(self, event):
        """
        Intercepte LanguageChange event to translate UI
        :param QEvent QEvent: Event
        :return:
        """
        if event.type() == QEvent.LanguageChange:
            self.retranslateUi(self)
            self.refresh()
        return super(MainWindow, self).changeEvent(event)
Exemplo n.º 44
0
class MainWindow(QMainWindow):
    """Show the main window of SCCT."""

    EXIT_CODE_REBOOT = -123

    def __init__(self, controller, app, showChangelog):
        """Init the main window."""
        try:
            super().__init__()

            self._save = True
            self.tlock = TriggerLock()
            self.controller = controller
            self.game_list = {}

            with self.tlock:
                self.createFormMatchDataBox()
            self.createTabs()
            self.createHorizontalGroupBox()
            self.createBackgroundTasksBox()

            self.createMenuBar()

            mainLayout = QVBoxLayout()
            mainLayout.addWidget(self.tabs, 0)
            mainLayout.addWidget(self.fromMatchDataBox, 1)
            mainLayout.addWidget(self.backgroundTasksBox, 0)
            mainLayout.addWidget(self.horizontalGroupBox, 0)

            self.setWindowTitle(
                "WarCraft III – Meta Plays Casting Tool v{}".format(
                    hwctool.__version__))

            self.window = QWidget()
            self.window.setLayout(mainLayout)
            self.setCentralWidget(self.window)

            # self.size
            self.statusBar()

            self.leds = dict()
            for scope in self.controller.websocketThread.get_primary_scopes():
                self.leds[scope] = LedIndicator(self)

            for key, led in self.leds.items():
                self.controller.toogleLEDs(0, key, self)
                self.statusBar().addPermanentWidget(led)

            self.app = app
            self.controller.setView(self)
            self.controller.refreshButtonStatus()

            self.processEvents()
            self.settings = QSettings(ClientConfig.APP_NAME,
                                      ClientConfig.COMPANY_NAME)
            self.restoreGeometry(
                self.settings.value("geometry", self.saveGeometry()))
            self.restoreState(
                self.settings.value("windowState", self.saveState()))

            self.mysubwindows = dict()

            self.show()
            self.raise_()

            if showChangelog:
                self.openChangelog()

        except Exception as e:
            module_logger.exception("message")

    # def showAbout(self):
    #     """Show subwindow with about info."""
    #     html = markdown2.markdown_path(
    #         hwctool.settings.getResFile("about.md"))

    #     html = html.replace("%VERSION%", hwctool.__version__)
    #     if(not hwctool.__new_version__):
    #         new_version = _("Halo Wars Casting Tool is up to date.")
    #     else:
    #         new_version = _("The new version {} is available!").format(
    #             hwctool.__latest_version__)
    #     html = html.replace('%NEW_VERSION%', new_version)

    #     # use self as parent here
    #     QMessageBox.about(
    #         self, _("Halo Wars Casting Tool - About"), html)

    def closeEvent(self, event):
        """Close and clean up window."""
        try:
            try:
                for name, window in self.mysubwindows.items():
                    if (window and window.isVisible()):
                        window.close()
            finally:
                self.settings.setValue("geometry", self.saveGeometry())
                self.settings.setValue("windowState", self.saveState())
                self.controller.cleanUp(self._save)
                QMainWindow.closeEvent(self, event)
                # event.accept()
        except Exception as e:
            module_logger.exception("message")

    def updateGame(self, title):
        """updates game played"""
        self.setWindowTitle("{} – Meta Plays Casting Tool v{}".format(
            title, hwctool.__version__))  #change title
        hwctool.settings.races = hwctool.settings.game_races[
            title]  #update races
        hwctool.settings.current_game = title  #update current game

        #uncheck, check
        for item in self.game_list.keys():
            self.game_list[item].setChecked(False)

        self.game_list[title].setChecked(True)

        #updates dropdown menu for players
        max_no_sets = hwctool.settings.max_no_sets
        for player_idx in range(max_no_sets):
            for team_idx in range(2):
                self.cb_race[team_idx][player_idx].clear()
                for race in hwctool.settings.races:
                    self.cb_race[team_idx][player_idx].addItem(race)

        #update styles
        self.openStyleDialog()

    def createMenuBar(self):
        """Create the menu bar."""
        try:
            menubar = self.menuBar()

            # BROWSER SOURCES
            self.createBrowserSrcMenu()

            #SETTINGS
            settingsMenu = menubar.addMenu(_('Settings'))
            # apiAct = QAction(QIcon(hwctool.settings.getResFile(
            #     'browser.png')), _('Browser Sources'), self)
            # apiAct.setToolTip(
            #     _('Edit Settings for all Browser Sources'))
            # apiAct.triggered.connect(self.openBrowserSourcesDialog)
            # settingsMenu.addAction(apiAct)

            apiAct = QAction(QIcon(hwctool.settings.getResFile('twitch.png')),
                             _('Twitch'), self)
            apiAct.setToolTip(
                _('Edit Intro-Settings and API-Settings'
                  ' for Twitch'))
            apiAct.triggered.connect(self.openApiDialog)
            settingsMenu.addAction(apiAct)

            # styleAct = QAction(QIcon(hwctool.settings.getResFile(
            #     'pantone.png')), _('Styles'), self)
            # styleAct.setToolTip('')
            # styleAct.triggered.connect(self.openStyleDialog)
            # settingsMenu.addAction(styleAct)

            apiAct = QAction(QIcon(hwctool.settings.getResFile('browser.png')),
                             _('Intro settings'), self)
            apiAct.setToolTip(_('Edit Settings for all Browser Sources'))
            apiAct.triggered.connect(self.openBrowserSourcesDialog)
            settingsMenu.addAction(apiAct)

            styleAct = QAction(
                QIcon(hwctool.settings.getResFile('pantone.png')),
                _('Source styles'), self)
            styleAct.setToolTip('')
            styleAct.triggered.connect(self.openStyleDialog)
            settingsMenu.addAction(styleAct)

            ProfileMenu(self, self.controller)

            infoMenu = menubar.addMenu(_('Info && Links'))

            myAct = QAction(QIcon(hwctool.settings.getResFile('folder.png')),
                            _('Open log folder'), self)
            myAct.triggered.connect(lambda: os.startfile(
                hwctool.settings.getAbsPath(hwctool.settings.getLogDir())))
            infoMenu.addAction(myAct)

            infoMenu.addSeparator()

            websiteAct = QAction(
                QIcon(hwctool.settings.getResFile('github.ico')),
                'Github - Meta Plays Casting Tool', self)
            websiteAct.triggered.connect(lambda: self.controller.openURL(
                "https://github.com/FluffyMaguro/MetaPlaysCastingTool/"))
            infoMenu.addAction(websiteAct)

            ixAct = QAction(QIcon(hwctool.settings.getResFile('icon.png')),
                            'Meta Plays (website)', self)
            ixAct.triggered.connect(
                lambda: self.controller.openURL("https://meta-plays.com/"))
            infoMenu.addAction(ixAct)

            websiteAct = QAction(
                QIcon(hwctool.settings.getResFile('favicon.jpg')),
                'Maguro.one (website)', self)
            websiteAct.triggered.connect(
                lambda: self.controller.openURL("https://www.maguro.one/"))
            infoMenu.addAction(websiteAct)

            infoMenu.addSeparator()

            websiteAct = QAction(
                QIcon(hwctool.settings.getResFile('hwct.ico')),
                'StarCraft Casting Tool - Docs', self)
            websiteAct.triggered.connect(lambda: self.controller.openURL(
                "https://teampheenix.github.io/StarCraft-Casting-Tool/"))
            infoMenu.addAction(websiteAct)

            myAct = QAction(QIcon(hwctool.settings.getResFile('patreon.png')),
                            _('StarCraft Casting Tool - Patreon'), self)
            myAct.triggered.connect(lambda: self.controller.openURL(
                "https://www.patreon.com/StarCraftCastingTool"))
            infoMenu.addAction(myAct)

            myAct = QAction(QIcon(hwctool.settings.getResFile('donate.ico')),
                            _('StarCraft Casting Tool - PayPal'), self)
            myAct.triggered.connect(lambda: self.controller.openURL(
                "https://paypal.me/StarCraftCastingTool"))
            infoMenu.addAction(myAct)

            #Choose the game
            gameMenu = menubar.addMenu(_('Game'))

            icon_dict = {
                'StarCraft II': 'SC2.png',
                'WarCraft III': 'WC3.png',
                'Age of Empires IV': 'AOEIV.png',
                'Age of Empires Online': 'AOEO.png',
                'Age of Mythology': 'AOM.png',
                'Halo Wars 2': 'HW.png',
                'SpellForce 3': 'SF3.png'
            }
            for game in hwctool.settings.game_races:
                if game in icon_dict:
                    myAct = QAction(QIcon(
                        hwctool.settings.getResFile(icon_dict[game])),
                                    _(game),
                                    self,
                                    checkable=True)
                else:
                    myAct = QAction(QIcon(
                        hwctool.settings.getResFile('loading.png')),
                                    _(game),
                                    self,
                                    checkable=True)

                myAct.triggered.connect(partial(self.updateGame, game))
                gameMenu.addAction(myAct)
                self.game_list[game] = myAct

        except Exception as e:
            module_logger.exception("message")

    def createBrowserSrcMenu(self):
        menubar = self.menuBar()
        main_menu = menubar.addMenu(_('Browser Sources'))

        srcs = []
        srcs.append({
            'name': _('Intro'),
            'file': 'intro.html',
            'settings': lambda: self.openBrowserSourcesDialog('intro')
        })
        srcs.append({'name': _('Score'), 'file': 'score.html'})

        act = QAction(QIcon(hwctool.settings.getResFile('folder.png')),
                      _('Open Folder'), self)
        act.triggered.connect(lambda: os.startfile(
            hwctool.settings.getAbsPath(hwctool.settings.casting_html_dir)))
        main_menu.addAction(act)
        main_menu.addSeparator()

        for src in srcs:
            myMenu = QMenu(src['name'], self)
            sub = src.get('sub', False)
            if sub:
                for icon in sub:
                    mySubMenu = QMenu(icon['name'], self)
                    icon['file'] = os.path.join(
                        hwctool.settings.casting_html_dir, icon['file'])
                    act = QAction(
                        QIcon(hwctool.settings.getResFile('html.png')),
                        _('Open in Browser'), self)
                    act.triggered.connect(
                        lambda x, file=icon['file']: self.controller.openURL(
                            hwctool.settings.getAbsPath(file)))
                    mySubMenu.addAction(act)
                    act = QAction(
                        QIcon(hwctool.settings.getResFile('copy.png')),
                        _('Copy URL to Clipboard'), self)
                    act.triggered.connect(
                        lambda x, file=icon['file']: QApplication.clipboard(
                        ).setText(hwctool.settings.getAbsPath(file)))
                    mySubMenu.addAction(act)
                    if icon.get('settings', None) is not None:
                        act = QAction(
                            QIcon(hwctool.settings.getResFile('browser.png')),
                            _('Settings'), self)
                        act.triggered.connect(icon['settings'])
                        mySubMenu.addAction(act)
                    myMenu.addMenu(mySubMenu)
            else:
                src['file'] = os.path.join(hwctool.settings.casting_html_dir,
                                           src['file'])
                act = QAction(QIcon(hwctool.settings.getResFile('html.png')),
                              _('Open in Browser'), self)
                act.triggered.connect(
                    lambda x, file=src['file']: self.controller.openURL(
                        hwctool.settings.getAbsPath(file)))
                myMenu.addAction(act)
                act = QAction(QIcon(hwctool.settings.getResFile('copy.png')),
                              _('Copy URL to Clipboard'), self)
                act.triggered.connect(
                    lambda x, file=src['file']: QApplication.clipboard(
                    ).setText(hwctool.settings.getAbsPath(file)))
                myMenu.addAction(act)

            if src.get('settings', None) is not None:
                act = QAction(
                    QIcon(hwctool.settings.getResFile('browser.png')),
                    _('Settings'), self)
                act.triggered.connect(src['settings'])
                myMenu.addAction(act)
            main_menu.addMenu(myMenu)

        main_menu.addSeparator()

        # apiAct = QAction(QIcon(hwctool.settings.getResFile(
        #     'browser.png')), _('Settings'), self)
        # apiAct.setToolTip(
        #     _('Edit Settings for all Browser Sources'))
        # apiAct.triggered.connect(self.openBrowserSourcesDialog)
        # main_menu.addAction(apiAct)

        # styleAct = QAction(QIcon(hwctool.settings.getResFile(
        #     'pantone.png')), _('Styles'), self)
        # styleAct.setToolTip('')
        # styleAct.triggered.connect(self.openStyleDialog)
        # main_menu.addAction(styleAct)

    def openApiDialog(self):
        """Open subwindow with connection settings."""
        self.mysubwindows['connections'] = SubwindowConnections()
        self.mysubwindows['connections'].createWindow(self)
        self.mysubwindows['connections'].show()

    def openStyleDialog(self):
        """Open subwindow with style settings."""
        self.mysubwindows['styles'] = SubwindowStyles()
        self.mysubwindows['styles'].createWindow(self)
        self.mysubwindows['styles'].show()

    def openBrowserSourcesDialog(self, tab=''):
        """Open subwindow with browser sources settings."""
        self.mysubwindows['browser'] = SubwindowBrowserSources()
        self.mysubwindows['browser'].createWindow(self, tab)
        self.mysubwindows['browser'].show()

    def openReadme(self):
        """Open subwindow with readme viewer."""
        self.mysubwindows['readme'] = SubwindowMarkdown()
        self.mysubwindows['readme'].createWindow(
            self, _("Readme"), hwctool.settings.getResFile('readme.ico'),
            hwctool.settings.getResFile("../README.md"))
        self.mysubwindows['readme'].show()

    def openChangelog(self):
        """Open subwindow with readme viewer."""
        self.mysubwindows['changelog'] = SubwindowMarkdown()
        self.mysubwindows['changelog'].createWindow(
            self, "Halo Wars Casting Tool " + _("Changelog"),
            hwctool.settings.getResFile("changelog.png"),
            hwctool.settings.getResFile("../CHANGELOG.md"))
        self.mysubwindows['changelog'].show()

    def changeLanguage(self, language):
        """Change the language."""
        hwctool.settings.config.parser.set("SCT", "language", language)
        self.restart()

    def createTabs(self):
        """Create tabs in main window."""
        try:
            # Initialize tab screen
            self.tabs = QTabWidget()
            self.tab2 = QWidget()
            # self.tabs.resize(300,200)

            # Add tabs
            self.tabs.addTab(self.tab2, _("Custom Match"))

            # Create second tab

            self.tab2.layout = QVBoxLayout()

            container = QHBoxLayout()

            label = QLabel()
            label.setMinimumWidth(self.labelWidth)
            container.addWidget(label, 0)

            label = QLabel(_("Match Format:"))
            label.setMinimumWidth(80)
            container.addWidget(label, 0)

            container.addWidget(QLabel(_("Best of")), 0)

            self.cb_bestof = QComboBox()
            for idx in range(0, hwctool.settings.max_no_sets):
                self.cb_bestof.addItem(str(idx + 1))
            self.cb_bestof.setCurrentIndex(3)
            string = _('"Best of 6/4": First, a Bo5/3 is played and the'
                       ' ace map gets extended to a Bo3 if needed;'
                       ' Best of 2: Bo3 with only two maps played.')
            self.cb_bestof.setToolTip(string)
            self.cb_bestof.setMaximumWidth(40)
            self.cb_bestof.currentIndexChanged.connect(self.changeBestOf)
            container.addWidget(self.cb_bestof, 0)

            container.addWidget(QLabel(_(" but at least")), 0)

            self.cb_minSets = QComboBox()

            self.cb_minSets.setToolTip(
                _('Minimum number of maps played (even if the match'
                  ' is decided already)'))
            self.cb_minSets.setMaximumWidth(40)
            container.addWidget(self.cb_minSets, 0)
            container.addWidget(QLabel(" " + _("maps") + "  "), 0)
            self.cb_minSets.currentIndexChanged.connect(
                lambda idx: self.highlightApplyCustom())

            ###### APPLY BUTTON
            label = QLabel("")
            container.addWidget(label, 1)
            self.applycustom_is_highlighted = False
            self.pb_applycustom = QToolButton()
            action = QAction(_("Apply Format"))
            action.triggered.connect(self.applycustom_click)
            self.pb_applycustom.setDefaultAction(action)
            self.pb_applycustom.setFixedWidth(100)
            container.addWidget(self.pb_applycustom, 0)
            self.defaultButtonPalette = self.pb_applycustom.palette()
            self.tab2.layout.addLayout(container)

            ###### RESET BUTTON
            label = QLabel("")
            container.addWidget(label, 1)
            self.pb_resetdata = QPushButton(_("Reset Match Data"))
            self.pb_resetdata.setFixedWidth(100)
            self.pb_resetdata.clicked.connect(self.resetdata_click)
            container.addWidget(self.pb_resetdata, 0)
            self.tab2.layout.addLayout(container)
            self.tab2.setLayout(self.tab2.layout)

            ###### SPACING
            container.insertSpacing(-1, 100)

            ########## REMOVED CUSTOM URL

            # container = QHBoxLayout()
            # label = QLabel()
            # label.setMinimumWidth(self.labelWidth)
            # container.addWidget(label, 0)
            # label = QLabel(_("Match-URL:"))
            # label.setMinimumWidth(80)
            # container.addWidget(label, 0)

            self.le_url_custom = MonitoredLineEdit()
            # self.le_url_custom.setAlignment(Qt.AlignCenter)
            # self.le_url_custom.setToolTip(
            #     _('Optionally specify the Match-URL,'
            #       ' e.g., for Nightbot commands'))
            # self.le_url_custom.setPlaceholderText(
            #     _("Specify the Match-URL of your Custom Match"))

            # completer = QCompleter(
            #     ["http://"], self.le_url_custom)
            # completer.setCaseSensitivity(Qt.CaseInsensitive)
            # completer.setCompletionMode(
            #     QCompleter.UnfilteredPopupCompletion)
            # completer.setWrapAround(True)
            # self.le_url_custom.setCompleter(completer)
            # self.le_url_custom.setMinimumWidth(360)
            # self.le_url_custom.textModified.connect(self.highlightApplyCustom)
            # container.addWidget(self.le_url_custom, 11)

        except Exception as e:
            module_logger.exception("message")

    def changeBestOf(self, bestof):
        """Change the minimum sets combo box on change of BoX."""
        bestof = bestof + 1
        self.cb_minSets.clear()
        self.highlightApplyCustom()
        for idx in range(0, bestof):
            self.cb_minSets.addItem(str(idx + 1))
            if bestof == 2:
                self.cb_minSets.setCurrentIndex(1)
            else:
                self.cb_minSets.setCurrentIndex(int((bestof - 1) / 2))

    def updatePlayerCompleters(self):
        """Refresh the completer for the player line edits."""
        list = ["TBD"] + self.controller.historyManager.getPlayerList()
        for player_idx in range(self.max_no_sets):
            for team_idx in range(2):
                completer = QCompleter(list,
                                       self.le_player[team_idx][player_idx])
                completer.setCaseSensitivity(Qt.CaseInsensitive)
                completer.setCompletionMode(QCompleter.InlineCompletion)
                completer.setWrapAround(True)
                self.le_player[team_idx][player_idx].setCompleter(completer)

    def createFormMatchDataBox(self):
        """Create the froms for the match data."""
        try:

            self.max_no_sets = hwctool.settings.max_no_sets
            self.scoreWidth = 35
            self.raceWidth = 100
            self.labelWidth = 25
            self.mimumLineEditWidth = 130

            self.fromMatchDataBox = QGroupBox(_("Match Data"))
            layout2 = QVBoxLayout()

            self.le_league = MonitoredLineEdit()
            self.le_league.setText("League TBD")
            self.le_league.setAlignment(Qt.AlignCenter)
            self.le_league.setPlaceholderText("League TBD")
            self.le_league.textModified.connect(self.league_changed)
            policy = QSizePolicy()
            policy.setHorizontalStretch(3)
            policy.setHorizontalPolicy(QSizePolicy.Expanding)
            policy.setVerticalStretch(1)
            policy.setVerticalPolicy(QSizePolicy.Fixed)
            self.le_league.setSizePolicy(policy)
            self.le_player = [[
                MonitoredLineEdit() for x in range(self.max_no_sets)
            ] for y in range(2)]
            self.cb_race = [[QComboBox() for x in range(self.max_no_sets)]
                            for y in range(2)]
            self.sl_score = [
                QSlider(Qt.Horizontal) for y in range(self.max_no_sets)
            ]
            self.label_set = [
                QLabel('#{}'.format(y + 1), self)
                for y in range(self.max_no_sets)
            ]
            self.setContainer = [
                QHBoxLayout() for y in range(self.max_no_sets)
            ]

            container = QGridLayout()

            button = QPushButton()
            pixmap = QIcon(hwctool.settings.getResFile('update.png'))
            button.setIcon(pixmap)
            button.clicked.connect(lambda: self.controller.swapTeams())
            button.setFixedWidth(self.labelWidth)
            button.setToolTip(_("Swap players."))
            container.addWidget(button, 0, 0, 1, 1)

            label = QLabel(_("League:"))
            label.setAlignment(Qt.AlignCenter)
            label.setFixedWidth(self.raceWidth)
            container.addWidget(label, 0, 1, 1, 1)

            container.addWidget(self.le_league, 0, 2, 1, 3)

            label = QLabel("")
            label.setFixedWidth(self.raceWidth)
            container.addWidget(label, 0, 5, 1, 1)

            layout2.addLayout(container)

            for player_idx in range(self.max_no_sets):
                for team_idx in range(2):
                    self.cb_race[team_idx][player_idx].\
                        currentIndexChanged.connect(
                        lambda idx,
                        t=team_idx,
                        p=player_idx: self.race_changed(t, p))
                    self.le_player[team_idx][player_idx].textModified.connect(
                        lambda t=team_idx, p=player_idx: self.player_changed(
                            t, p))
                    self.le_player[team_idx][player_idx].setText("TBD")
                    self.le_player[team_idx][player_idx].setAlignment(
                        Qt.AlignCenter)
                    self.le_player[team_idx][player_idx].setPlaceholderText(
                        _("Player {} of team {}").format(
                            player_idx + 1, team_idx + 1))
                    self.le_player[team_idx][player_idx].setMinimumWidth(
                        self.mimumLineEditWidth)

                    for race in hwctool.settings.races:
                        self.cb_race[team_idx][player_idx].addItem(race)

                    self.cb_race[team_idx][player_idx].setFixedWidth(
                        self.raceWidth)

                self.sl_score[player_idx].setMinimum(-1)
                self.sl_score[player_idx].setMaximum(1)
                self.sl_score[player_idx].setValue(0)
                self.sl_score[player_idx].setTickPosition(
                    QSlider.TicksBothSides)
                self.sl_score[player_idx].setTickInterval(1)
                self.sl_score[player_idx].setTracking(False)
                self.sl_score[player_idx].valueChanged.connect(
                    lambda x, player_idx=player_idx: self.sl_changed(
                        player_idx, x))
                self.sl_score[player_idx].setToolTip(_('Set the score'))
                self.sl_score[player_idx].setFixedWidth(self.scoreWidth)

                self.setContainer[player_idx] = QHBoxLayout()
                # self.label_set[player_idx].setText("#" + str(player_idx + 1))
                self.label_set[player_idx].setAlignment(Qt.AlignCenter)
                self.label_set[player_idx].setFixedWidth(self.labelWidth)
                self.setContainer[player_idx].addWidget(
                    self.label_set[player_idx], 0)
                self.setContainer[player_idx].addWidget(
                    self.cb_race[0][player_idx], 0)
                self.setContainer[player_idx].addWidget(
                    self.le_player[0][player_idx], 4)
                self.setContainer[player_idx].addWidget(
                    self.sl_score[player_idx], 0)
                self.setContainer[player_idx].addWidget(
                    self.le_player[1][player_idx], 4)
                self.setContainer[player_idx].addWidget(
                    self.cb_race[1][player_idx], 0)
                layout2.addLayout(self.setContainer[player_idx])

            layout2.addItem(
                QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding))
            self.fromMatchDataBox.setLayout(layout2)

            self.updatePlayerCompleters()

        except Exception as e:
            module_logger.exception("message")

    def createHorizontalGroupBox(self):
        """Create horizontal group box for tasks."""
        try:
            self.horizontalGroupBox = QGroupBox(_("Tasks"))
            layout = QHBoxLayout()

            self.pb_twitchupdate = QPushButton(_("Update Twitch Title"))
            self.pb_twitchupdate.clicked.connect(self.updatetwitch_click)

            # self.pb_nightbotupdate = QPushButton(
            #     _("Update Nightbot"))
            # self.pb_nightbotupdate.clicked.connect(self.updatenightbot_click)

            self.pb_resetscore = QPushButton(_("Reset Score"))
            self.pb_resetscore.clicked.connect(self.resetscore_click)

            layout.addWidget(self.pb_twitchupdate)
            # layout.addWidget(self.pb_nightbotupdate)
            layout.addWidget(self.pb_resetscore)

            self.horizontalGroupBox.setLayout(layout)

        except Exception as e:
            module_logger.exception("message")

    def createBackgroundTasksBox(self):
        """Create group box for background tasks."""
        try:
            self.backgroundTasksBox = QGroupBox(_("Background Tasks"))

            self.cb_autoTwitch = QCheckBox(_("Auto Twitch Update"))
            self.cb_autoTwitch.setChecked(False)
            self.cb_autoTwitch.stateChanged.connect(self.autoTwitch_change)

            # self.cb_autoNightbot = QCheckBox(
            #     _("Auto Nightbot Update"))
            # self.cb_autoNightbot.setChecked(False)
            # self.cb_autoNightbot.stateChanged.connect(
            #     self.autoNightbot_change)

            layout = QGridLayout()

            layout.addWidget(self.cb_autoTwitch, 0, 0)
            # layout.addWidget(self.cb_autoNightbot, 0, 1)

            self.backgroundTasksBox.setLayout(layout)

        except Exception as e:
            module_logger.exception("message")

    def autoTwitch_change(self):
        """Handle change of auto twitch check box."""
        try:
            if (self.cb_autoTwitch.isChecked()):
                self.controller.autoRequestsThread.activateTask('twitch')
            else:
                self.controller.autoRequestsThread.deactivateTask('twitch')
        except Exception as e:
            module_logger.exception("message")

    # def autoNightbot_change(self):
    #     """Handle change of auto twitch check box."""
    #     try:
    #         if(self.cb_autoNightbot.isChecked()):
    #             self.controller.autoRequestsThread.activateTask('nightbot')
    #         else:
    #             self.controller.autoRequestsThread.deactivateTask('nightbot')
    #     except Exception as e:
    #         module_logger.exception("message")

    def autoUpdate_change(self):
        """Handle change of auto score update check box."""
        try:
            if (self.cb_autoUpdate.isChecked()):
                self.controller.runSC2ApiThread("updateScore")
            else:
                self.controller.stopSC2ApiThread("updateScore")
        except Exception as e:
            module_logger.exception("message")

    def autoToggleScore_change(self):
        """Handle change of toggle score check box."""
        try:
            if (self.cb_autoToggleScore.isChecked()):
                self.controller.runSC2ApiThread("toggleScore")
            else:
                self.controller.stopSC2ApiThread("toggleScore")
        except Exception as e:
            module_logger.exception("message")

    def autoToggleProduction_change(self):
        """Handle change of toggle production tab check box."""
        try:
            if (self.cb_autoToggleProduction.isChecked()):
                self.controller.runSC2ApiThread("toggleProduction")
            else:
                self.controller.stopSC2ApiThread("toggleProduction")
        except Exception as e:
            module_logger.exception("message")

    def applyCustomFormat(self, format):
        """Handle click to apply custom format."""
        QApplication.setOverrideCursor(Qt.WaitCursor)
        try:
            with self.tlock:
                self.controller.matchData.applyCustomFormat(format)
                self.controller.updateForms()
                self.resizeWindow()
            self.highlightApplyCustom(False)
        except Exception as e:
            module_logger.exception("message")
        finally:
            QApplication.restoreOverrideCursor()

    def applycustom_click(self):
        """Handle click to apply custom match."""
        QApplication.setOverrideCursor(Qt.WaitCursor)
        try:
            with self.tlock:
                self.statusBar().showMessage(_('Applying Custom Match...'))
                msg = self.controller.applyCustom(
                    int(self.cb_bestof.currentText()), False, True,
                    int(self.cb_minSets.currentText()),
                    self.le_url_custom.text().strip())
                self.statusBar().showMessage(msg)
            self.highlightApplyCustom(False)
        except Exception as e:
            module_logger.exception("message")
        finally:
            QApplication.restoreOverrideCursor()

    def resetdata_click(self):
        """Handle click to reset the data."""
        QApplication.setOverrideCursor(Qt.WaitCursor)
        try:
            with self.tlock:
                msg = self.controller.resetData()
                self.statusBar().showMessage(msg)
        except Exception as e:
            module_logger.exception("message")
        finally:
            QApplication.restoreOverrideCursor()

    def openBrowser_click(self):
        """Handle request to open URL in browser."""
        try:
            url = self.le_url.text()
            self.controller.openURL(url)
        except Exception as e:
            module_logger.exception("message")

    # def updatenightbot_click(self):
    #     """Handle click to change nightbot command."""
    #     try:
    #         self.statusBar().showMessage(_('Updating Nightbot Command...'))
    #         msg = self.controller.updateNightbotCommand()
    #         self.statusBar().showMessage(msg)
    #     except Exception as e:
    #         module_logger.exception("message")

    def updatetwitch_click(self):
        """Handle click to change twitch title."""
        try:
            self.statusBar().showMessage(_('Updating Twitch Title...'))
            msg = self.controller.updateTwitchTitle()
            self.statusBar().showMessage(msg)
        except Exception as e:
            module_logger.exception("message")

    def resetscore_click(self, myteam=False):
        """Handle click to reset the score."""
        try:
            self.statusBar().showMessage(_('Resetting Score...'))
            with self.tlock:
                for set_idx in range(self.max_no_sets):
                    self.sl_score[set_idx].setValue(0)
                    self.controller.matchData.setMapScore(set_idx,
                                                          0,
                                                          overwrite=True)
                if myteam:
                    self.sl_team.setValue(0)
                    self.controller.matchData.setMyTeam(0)
                if not self.controller.resetWarning():
                    self.statusBar().showMessage('')

        except Exception as e:
            module_logger.exception("message")

    def setScore(self, idx, score, allkill=True):
        """Handle change of the score."""
        try:
            if (self.sl_score[idx].value() == 0):
                self.statusBar().showMessage(_('Updating Score...'))
                with self.tlock:
                    self.sl_score[idx].setValue(score)
                    self.controller.matchData.setMapScore(idx, score, True)
                    if not self.controller.resetWarning():
                        self.statusBar().showMessage('')
                return True
            else:
                return False
        except Exception as e:
            module_logger.exception("message")

    def league_changed(self):
        if not self.tlock.trigger():
            return
        self.controller.matchData.setLeague(self.le_league.text())

    def sl_changed(self, set_idx, value):
        """Handle a new score value."""
        try:
            if self.tlock.trigger():
                if set_idx == -1:
                    self.controller.matchData.setMyTeam(value)
                else:
                    self.controller.matchData.setMapScore(set_idx, value, True)
        except Exception as e:
            module_logger.exception("message")

    def player_changed(self, team_idx, player_idx):
        """Handle a change of player names."""
        if not self.tlock.trigger():
            return
        try:
            player = self.le_player[team_idx][player_idx].text().strip()
            race = self.cb_race[team_idx][player_idx].currentText()
            if (player_idx == 0 and self.controller.matchData.getSolo()):
                for p_idx in range(1, self.max_no_sets):
                    self.le_player[team_idx][p_idx].setText(player)
                    self.player_changed(team_idx, p_idx)
            self.controller.historyManager.insertPlayer(player, race)
            self.controller.matchData.setPlayer(
                team_idx, player_idx,
                self.le_player[team_idx][player_idx].text())

            if race == "Random":
                new_race = self.controller.historyManager.getRace(player)
                if new_race != "Random":
                    index = self.cb_race[team_idx][player_idx].findText(
                        new_race, Qt.MatchFixedString)
                    if index >= 0:
                        self.cb_race[team_idx][player_idx].setCurrentIndex(
                            index)
            elif player.lower() == "tbd":
                self.cb_race[team_idx][player_idx].setCurrentIndex(0)
            self.updatePlayerCompleters()
        except Exception as e:
            module_logger.exception("message")

    def race_changed(self, team_idx, player_idx):
        """Handle a change of player names."""
        if not self.tlock.trigger():
            return
        player = self.le_player[team_idx][player_idx].text().strip()
        race = self.cb_race[team_idx][player_idx].currentText()
        self.controller.historyManager.insertPlayer(player, race)
        self.controller.matchData.setRace(
            team_idx, player_idx,
            self.cb_race[team_idx][player_idx].currentText())
        try:
            if (player_idx == 0 and self.controller.matchData.getSolo()):
                race = self.cb_race[team_idx][0].currentText()
                for player_idx in range(1, self.max_no_sets):
                    index = self.cb_race[team_idx][player_idx].findText(
                        race, Qt.MatchFixedString)
                    if index >= 0:
                        self.cb_race[team_idx][player_idx].setCurrentIndex(
                            index)

        except Exception as e:
            module_logger.exception("message")

    def highlightApplyCustom(self, highlight=True, force=False):
        if not force and not self.tlock.trigger():
            return
        try:
            if self.applycustom_is_highlighted == highlight:
                return highlight
        except AttributeError:
            return False

        if highlight:
            myPalette = self.pb_applycustom.palette()
            myPalette.setColor(QPalette.Background, Qt.darkRed)
            myPalette.setColor(QPalette.ButtonText, Qt.darkRed)
            self.pb_applycustom.setPalette(myPalette)
        else:
            self.pb_applycustom.setPalette(self.defaultButtonPalette)

        self.applycustom_is_highlighted = highlight
        return highlight

    def resizeWindow(self):
        """Resize the window height to size hint."""
        if (not self.isMaximized()):
            self.processEvents()
            self.resize(self.width(), self.sizeHint().height())

    def processEvents(self):
        """Process ten PyQt5 events."""
        for i in range(0, 10):
            self.app.processEvents()

    def restart(self, save=True):
        """Restart the main window."""
        self._save = save
        self.close()
        self.app.exit(self.EXIT_CODE_REBOOT)
Exemplo n.º 45
0
class NewFolderWindow(QDialog):
    def __init__(self, parent):
        super(NewFolderWindow, self).__init__()
        self.parent = parent
        self.setWindowTitle("Gridsync - Add New Sync Folder")
        self.resize(500, 225)
        self.layout = QVBoxLayout(self)
        self.folder = None

        layout = QVBoxLayout()

        grid_group_box = QGroupBox(self)
        grid_group_box.setTitle("Select remote storage grid to use:")
        grid_layout = QHBoxLayout(grid_group_box)
        self.grid_combo_box = QComboBox(grid_group_box)
        self.populate_combo_box()
        grid_layout.addWidget(self.grid_combo_box)
        layout.addWidget(grid_group_box)

        folder_group_box = QGroupBox(self)
        folder_group_box.setTitle("Select local folder to sync:")
        folder_layout = QHBoxLayout(folder_group_box)
        self.folder_text = QLineEdit(folder_group_box)
        folder_layout.addWidget(self.folder_text)
        folder_button = QPushButton(folder_group_box)
        folder_button.setText("Browse...")
        folder_button.clicked.connect(self.get_folder)
        folder_layout.addWidget(folder_button)
        layout.addWidget(folder_group_box)

        self.layout.addLayout(layout)

        button_box = QDialogButtonBox(self)
        button_box.setStandardButtons(
            QDialogButtonBox.Cancel | QDialogButtonBox.Ok)
        button_box.rejected.connect(self.close)
        button_box.accepted.connect(self.create_new_folder)
        self.layout.addWidget(button_box)

    def populate_combo_box(self):
        logging.debug("(Re-)populating combo box...")
        self.grid_combo_box.clear()
        for gateway in self.parent.gateways:
            self.grid_combo_box.addItem(gateway.location, gateway)
        self.grid_combo_box.insertSeparator(len(self.parent.gateways))
        self.grid_combo_box.addItem("Add New Grid...")
        #self.grid_combo_box.setEnabled(False)

    def get_folder(self):
        self.folder = QFileDialog.getExistingDirectory(
            self, "Select local folder to sync")
        if self.folder:
            self.folder_text.setText(self.folder)

    def create_new_folder(self):
        if self.folder_text.text() and self.grid_combo_box.currentText():
            self.close()
            selected_folder = str(self.folder_text.text())
            selected_grid = str(self.grid_combo_box.currentText())
            for gateway in self.parent.gateways:
                if gateway.name == selected_grid:
                    tahoe = gateway
            tahoe.add_sync_folder(selected_folder)
Exemplo n.º 46
0
class Spectrum(QWidget):
    """Plot the power spectrum for a specified channel.

    Attributes
    ----------
    parent : instance of QMainWindow
        the main window.
    x_limit : tuple or list
        2 values specifying the limit on x-axis
    y_limit : tuple or list
        2 values specifying the limit on y-axis
    log : bool
        log-transform the data or not
    idx_chan : instance of QComboBox
        the element with the list of channel names.
    idx_x_min : instance of QLineEdit
        value with min x value
    idx_x_max : instance of QLineEdit
        value with max x value
    idx_y_min : instance of QLineEdit
        value with min y value
    idx_y_max : instance of QLineEdit
        value with max y value
    idx_log : instance of QCheckBox
        widget that defines if log should be used or not
    idx_fig : instance of QGraphicsView
        the view with the power spectrum
    scene : instance of QGraphicsScene
        the scene with GraphicsItems

    Notes
    -----
    If data contains NaN, it doesn't create any spectrum (feature or bug?).
    """
    def __init__(self, parent):
        super().__init__()
        self.parent = parent

        self.config = ConfigSpectrum(self.display_window)

        self.selected_chan = None
        self.idx_chan = None
        self.idx_fig = None
        self.scene = None

        self.create()

    def create(self):
        """Create empty scene for power spectrum."""
        self.idx_chan = QComboBox()
        self.idx_chan.activated.connect(self.display_window)

        self.idx_fig = QGraphicsView(self)
        self.idx_fig.scale(1, -1)

        layout = QVBoxLayout()
        layout.addWidget(self.idx_chan)
        layout.addWidget(self.idx_fig)
        self.setLayout(layout)

        self.resizeEvent(None)

    def show_channame(self, chan_name):
        self.selected_chan = self.idx_chan.currentIndex()

        self.idx_chan.clear()
        self.idx_chan.addItem(chan_name)
        self.idx_chan.setCurrentIndex(0)

    def update(self):
        """Add channel names to the combobox."""
        self.idx_chan.clear()
        for chan_name in self.parent.traces.chan:
            self.idx_chan.addItem(chan_name)

        if self.selected_chan is not None:
            self.idx_chan.setCurrentIndex(self.selected_chan)
            self.selected_chan = None

    def display_window(self):
        """Read the channel name from QComboBox and plot its spectrum.

        This function is necessary it reads the data and it sends it to
        self.display. When the user selects a smaller chunk of data from the
        visible traces, then we don't need to call this function.
        """
        if self.idx_chan.count() == 0:
            self.update()

        chan_name = self.idx_chan.currentText()
        lg.debug('Power spectrum for channel ' + chan_name)

        if chan_name:
            trial = 0
            data = self.parent.traces.data(trial=trial, chan=chan_name)
            self.display(data)
        else:
            self.scene.clear()

    def display(self, data):
        """Make graphicsitem for spectrum figure.

        Parameters
        ----------
        data : ndarray
            1D vector containing the data only

        This function can be called by self.display_window (which reads the
        data for the selected channel) or by the mouse-events functions in
        traces (which read chunks of data from the user-made selection).
        """
        value = self.config.value
        self.scene = QGraphicsScene(value['x_min'], value['y_min'],
                                    value['x_max'] - value['x_min'],
                                    value['y_max'] - value['y_min'])
        self.idx_fig.setScene(self.scene)

        self.add_grid()
        self.resizeEvent(None)

        s_freq = self.parent.traces.data.s_freq
        f, Pxx = welch(data, fs=s_freq, nperseg=int(min(
            (s_freq, len(data)))))  # force int

        freq_limit = (value['x_min'] <= f) & (f <= value['x_max'])

        if self.config.value['log']:
            Pxx_to_plot = log(Pxx[freq_limit])
        else:
            Pxx_to_plot = Pxx[freq_limit]

        self.scene.addPath(Path(f[freq_limit], Pxx_to_plot),
                           QPen(QColor(LINE_COLOR), LINE_WIDTH))

    def add_grid(self):
        """Add axis and ticks to figure.

        Notes
        -----
        I know that visvis and pyqtgraphs can do this in much simpler way, but
        those packages create too large a padding around the figure and this is
        pretty fast.

        """
        value = self.config.value

        # X-AXIS
        # x-bottom
        self.scene.addLine(value['x_min'], value['y_min'],
                           value['x_min'], value['y_max'],
                           QPen(QColor(LINE_COLOR), LINE_WIDTH))
        # at y = 0, dashed
        self.scene.addLine(value['x_min'], 0, value['x_max'], 0,
                           QPen(QColor(LINE_COLOR), LINE_WIDTH, Qt.DashLine))
        # ticks on y-axis
        y_high = int(floor(value['y_max']))
        y_low = int(ceil(value['y_min']))
        x_length = (value['x_max'] - value['x_min']) / value['x_tick']
        for y in range(y_low, y_high):
            self.scene.addLine(value['x_min'], y, value['x_min'] + x_length, y,
                               QPen(QColor(LINE_COLOR), LINE_WIDTH))
        # Y-AXIS
        # left axis
        self.scene.addLine(value['x_min'], value['y_min'],
                           value['x_max'], value['y_min'],
                           QPen(QColor(LINE_COLOR), LINE_WIDTH))
        # larger ticks on x-axis every 10 Hz
        x_high = int(floor(value['x_max']))
        x_low = int(ceil(value['x_min']))
        y_length = (value['y_max'] - value['y_min']) / value['y_tick']
        for x in range(x_low, x_high, 10):
            self.scene.addLine(x, value['y_min'], x, value['y_min'] + y_length,
                               QPen(QColor(LINE_COLOR), LINE_WIDTH))
        # smaller ticks on x-axis every 10 Hz
        y_length = (value['y_max'] - value['y_min']) / value['y_tick'] / 2
        for x in range(x_low, x_high, 5):
            self.scene.addLine(x, value['y_min'], x, value['y_min'] + y_length,
                               QPen(QColor(LINE_COLOR), LINE_WIDTH))

    def resizeEvent(self, event):
        """Fit the whole scene in view.

        Parameters
        ----------
        event : instance of Qt.Event
            not important

        """
        value = self.config.value
        self.idx_fig.fitInView(value['x_min'], value['y_min'],
                               value['x_max'] - value['x_min'],
                               value['y_max'] - value['y_min'])

    def reset(self):
        """Reset widget as new"""
        self.idx_chan.clear()
        if self.scene is not None:
            self.scene.clear()
        self.scene = None
Exemplo n.º 47
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.parts = []
        self.blocks = []
        self.centralBlock = [0, 0, 0, 1]
        self.resolution = 16
        self.createGUI()
        self.createMenu()
        self.connectSlots()
        self.project_file = ""
        self.current_block = 0
        self.block_count = 0

    def createGUI(self):
        self.widget = QWidget(self)
        self.gvMain = MainView(self, 0, self.blocks)
        self.views = {key: XYZview(self, self.blocks, key)
                for key in ('xy', 'yz', 'zx')}
        self.cbSelectBox = QComboBox(self)
        self.pbAddBox = QPushButton("Add Box", self)
        self.pbDeleteBox = QPushButton("Delete selected box", self)
        self.slScale = QSlider(self)
        self.slScale.setOrientation(Qt.Horizontal)
        self.slScale.setRange(2, 15)
        self.slScale.setValue(5)
        self.slResolution = QSlider(self)
        self.slResolution.setOrientation(Qt.Horizontal)
        self.slResolution.setRange(1, 6) # resolution is 2**this_value
        self.slResolution.setValue(4) # 2**4 is 16 -- initial resolution
        self.turn_buttons = {'x': QPushButton("Turn around X axis", self),
                             'y': QPushButton("Turn around Y axis", self),
                             'z': QPushButton("Turn around Z axis", self)}
        self.swap_buttons = {'xy': QPushButton("Swap X and Y", self),
                             'yz': QPushButton("Swap Y and Z", self),
                             'zx': QPushButton("Swap Z and X", self)}
        self.grLayout = QGridLayout()
        self.grLayout.addWidget(QLabel("Main view"), 0, 0)
        self.grLayout.addWidget(self.gvMain, 1, 0)
        self.grLayout.addWidget(QLabel("Y view"), 0, 1)
        self.grLayout.addWidget(self.views['zx'], 1, 1)

        self.vbRightLayout = QVBoxLayout()
        self.vbRightLayout.addWidget(QLabel("Select box"))
        self.vbRightLayout.addWidget(self.cbSelectBox)
        self.vbRightLayout.addWidget(self.pbAddBox)
        self.vbRightLayout.addWidget(self.pbDeleteBox)
        self.vbRightLayout.addWidget(QLabel("Scale"))
        self.vbRightLayout.addWidget(self.slScale)
        self.vbRightLayout.addWidget(QLabel("Resolution"))
        self.vbRightLayout.addWidget(self.slResolution)
        self.vbRightLayout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding))
        for button in self.swap_buttons.values():
            self.vbRightLayout.addWidget(button)
        for button in self.turn_buttons.values():
            self.vbRightLayout.addWidget(button)

        self.hbMainLayout = QHBoxLayout()
        self.hbMainLayout.addLayout(self.grLayout, 10)
        self.hbMainLayout.addLayout(self.vbRightLayout, 1)

        self.grLayout.addWidget(QLabel("X view"), 2, 0)
        self.grLayout.addWidget(self.views['yz'], 3, 0)
        self.grLayout.addWidget(QLabel("Z view"), 2, 1)
        self.grLayout.addWidget(self.views['xy'], 3, 1)
        self.widget.setLayout(self.hbMainLayout)
        self.setCentralWidget(self.widget)
        self.setWindowTitle("Nodebox editor")
        self.resize(1000, 600)

    def createMenu(self):
        self.menuBar = QMenuBar()
        self.fileMenu = self.menuBar.addMenu("&File")
        self.helpMenu = self.menuBar.addMenu("&Help")
        self.aNewProject = self.fileMenu.addAction("Start new project")
        self.aOpen = self.fileMenu.addAction("Open")
        self.aSave = self.fileMenu.addAction("Save as...")
        self.aExport = self.fileMenu.addAction("Export as...")
        self.fileMenu.addSeparator()
        self.aExitApp = self.fileMenu.addAction("Exit")
        self.setMenuBar(self.menuBar)

    def addBox(self):
        self.blocks.append(Block([-8, -8, -8, 1],
                                 [8, 8, 8, 1]))
        self.block_count += 1 # BTW, we will not decrease this value
        self.cbSelectBox.addItems(["Block" + str(self.block_count)])
        self.cbSelectBox.setCurrentIndex(self.cbSelectBox.count()-1)
        self.update()
        self.current_block = self.blocks[self.cbSelectBox.currentIndex()]
        self.sendCurrentBlock(self.current_block)

    def deleteBox(self):
        if self.cbSelectBox.count() != 0:
            idx = self.cbSelectBox.currentIndex()
            del self.blocks[idx]
            self.cbSelectBox.removeItem(idx)
            if self.cbSelectBox.count() != 0:
                self.cbSelectBox.setCurrentIndex(0)
                self.current_block = self.blocks[0]
                self.sendCurrentBlock(self.current_block)
            else:
                self.current_block = 0;
                self.sendCurrentBlock(0)
        self.update()

    def connectSlots(self):
        self.aExitApp.triggered.connect(lambda: sys.exit(0))
        self.aExport.triggered.connect(self.actionExport)
        self.aSave.triggered.connect(self.actionSave)
        self.aNewProject.triggered.connect(self.actionNewProject)
        self.pbAddBox.clicked.connect(self.addBox)
        self.pbDeleteBox.clicked.connect(self.deleteBox)
        self.cbSelectBox.activated.connect(self.cbSwitch)
        self.slScale.valueChanged.connect(self.slScaleChange)
        self.slResolution.valueChanged.connect(self.slResolutionChange)
        self.aOpen.triggered.connect(self.actionOpen)
        for (key, button) in self.turn_buttons.items():
            button.clicked.connect(partial(self.turn, key))
        for (key, button) in self.swap_buttons.items():
            button.clicked.connect(partial(self.swap, key))

    def actionNewProject(self):
        self.blocks.clear()
        self.current_block = 0
        self.cbSelectBox.clear()
        self.sendCurrentBlock(0)
        self.block_count = 0
        self.update()

    def actionExport(self):
        if using_qt5:
            export_as = QFileDialog.getSaveFileName(self, "Export as...")[0]
        else:
            export_as = QFileDialog.getSaveFileName(self, "Export as...")
        create_code = codegen.codegen(self, "mynode", self.blocks, self.resolution)
        if export_as != "":
            create_code.writeToFile(export_as)

    def actionSave(self):
        if using_qt5:
            save_as = QFileDialog.getSaveFileName(self, "Save as...")[0]
        else:
            save_as = QFileDialog.getSaveFileName(self, "Save as...")
        if save_as != "":
            output_file = open(save_as, "w+")
            for b in self.blocks:
                output_file.write(" ".join([
                    str(b.p1()[0]), str(b.p1()[2]), str(b.p1()[1]),
                    str(b.p2()[0]), str(b.p2()[2]), str(b.p2()[1])]) + "\n")
            output_file.close()

    def sendCurrentBlock(self, block):
        for view in self.views.values():
            view.set_current_block(block)

    def sendScale(self, scale):
        for view in self.views.values():
            view.set_scale(scale)
        self.gvMain.scale = scale

    def sendResolution(self, resolution):
        for view in self.views.values():
            view.set_resolution(resolution)
        self.gvMain.resolution = resolution
        self.resolution        = resolution

    def actionOpen(self):
        if using_qt5:
            open_from = QFileDialog.getOpenFileName(self, "Open file")[0]
        else:
            open_from = QFileDialog.getOpenFileName(self, "Open file")
        input_file = open(open_from, "r")
        self.blocks.clear()
        self.sendCurrentBlock(0)
        self.cbSelectBox.clear()
        for line in input_file:
            t = [int(token) for token in line.split(" ")]
            self.blocks.append(Block([t[0], t[2], t[1], 1],
                [t[3], t[5], t[4], 1]))
            self.cbSelectBox.addItems(["Block" + str(len(self.blocks))])
        input_file.close()
        self.update()

    def cbSwitch(self):
        self.current_block = self.blocks[self.cbSelectBox.currentIndex()]
        self.sendCurrentBlock(self.current_block)
        self.update()

    def slScaleChange(self):
        self.sendScale(self.slScale.value())
        self.update()

    def slResolutionChange(self):
        self.sendResolution(2**self.slResolution.value())
        self.update()

    def swap(self, coords):
        for b in self.blocks:
            b.swap(coords)
        self.update()

    def turn(self, coord):
        for b in self.blocks:
            b.turn(coord)
        self.update()
Exemplo n.º 48
0
class App(QWidget):
    def __init__(self):
        super().__init__()
        self.title = "Science Fact Generator"
        # location of window
        self.left = 100
        self.top = 100
        # dimenssions of window
        self.width = 800
        self.height = 800
        # function that initalizes the window
        self.initUI()
        self.data = webscraper.webscraper()
        # print(self.data.genFactList(1,1))

    # function to initalize the content of our window
    def initUI(self):
        # window frame attributes
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        #  Generate button
        button = QPushButton('Generate', self)
        button.setToolTip('generate fun fact')
        button.setFixedSize(100, 100)
        button.move(100, 300)
        # calls onClick function when the button has been pressed
        # The button click (signal) is connected to the action (slot).
        # the method onClick will be called if the signal emits.
        button.clicked.connect(self.onClick)

        # Month Combo Box
        comboBox = QComboBox(self)
        comboBox.move(100, 100)
        comboBox.addItem("January")
        comboBox.addItem("Febuary")
        comboBox.addItem("March")
        comboBox.addItem("April")
        comboBox.addItem("May")
        comboBox.addItem("June")
        comboBox.addItem("July")
        comboBox.addItem("August")
        comboBox.addItem("September")
        comboBox.addItem("October")
        comboBox.addItem("November")
        comboBox.addItem("December")
        comboBox.activated[str].connect(self.monthSelected)

        self.dayComboBox = QComboBox(self)
        self.dayComboBox.move(250, 100)
        maxday = monthrange(2012, 1)[1]
        days = [str(x) for x in range(1, maxday)]
        self.dayComboBox.addItems(days)

        self.show()

    # slot for button click
    @pyqtSlot()
    def onClick(self):
        date = self.calendar.selectedDate()
        print(date.month(), date.day(), date.year())
        print(self.data.factList)

    def monthSelected(self, month):
        self.dayComboBox.clear()
        maxday = monthrange(2012, self.monthToInt(month))[1]
        days = [str(x) for x in range(1, maxday)]
        self.dayComboBox.clear()
        self.dayComboBox.addItems(days)
        print(month)

    # returns integer version of coresponding month
    def monthToInt(self, month):
        if month == "January":
            return 1
        elif month == "Febuary":
            return 2
        elif month == "March":
            return 3
        elif month == "April":
            return 4
        elif month == "May":
            return 5
        elif month == "June":
            return 6
        elif month == "July":
            return 7
        elif month == "August":
            return 8
        elif month == "September":
            return 9
        elif month == "October":
            return 10
        elif month == "November":
            return 11
        else:
            return 12
Exemplo n.º 49
0
class Example(QWidget):
	def __init__(self):
		super().__init__() 
		self.ventana()
	def ventana(self):
		#Planteamiento de etiquetas
		self.inp= QLineEdit("Numero de datos", self)
		self.inp.move(5,5)
		self.x= QLineEdit(self)
		self.x.move(5,50)
		self.y= QLineEdit(self)
		self.y.move(160,50)
		lbl= QLabel("x", self)
		lbl.move(5, 30)
		lbl2= QLabel("y", self)
		lbl2.move(160, 30)
		self.lbl3= QLabel(self)
		self.lbl3.move(5,75)
		self.inp2=QLineEdit("Conocer X en",self)
		self.inp2.move(5,100)
		self.lbl4= QLabel("y=...", self)
		self.lbl4.move(160,100)
		self.com= QComboBox(self)
		self.com.move(160,5)
		but= QPushButton("Calcular", self)
		but.move(5,130)
		
		
		#Eventos
		self.com.activated[str].connect(self.onAc)
		self.inp.textChanged[str].connect(self.combo)
		self.x.textChanged[str].connect(self.lx)
		self.y.textChanged[str].connect(self.ly)
		self.inp.selectionChanged.connect(self.bor)
		self.x.selectionChanged.connect(self.bor2)
		self.y.selectionChanged.connect(self.bor3)
		self.inp2.selectionChanged.connect(self.bor4)
		but.clicked.connect(self.boton)

		#Ventana
		self.setGeometry(300, 300, 350, 160)
		self.setWindowTitle('Regresion Lineal')
		self.show()
#Metodos de los eventos
	def boton(self):
		sp=0
		ss=0
		ym= 0
		xm= 0
		b1=0
		b0=0
		te= int(self.inp.text())
		for c in range(te):
			ym+= yl[c]
			xm+= xl[c]
		c=0
		ym/=te
		xm/=te
		for c in range(te):
			sp+= (xl[c]-xm)*(yl[c]-ym)
			ss+= (xl[c]-xm)**2
		b1= sp/ss
		b0= ym-(b1*xm)
		if self.inp2.text() == '':
			self.inp2.setText("0")
		cp= float(self.inp2.text()) 		
		r= b0+(b1*cp)
		self.lbl4.setText("y="+str(r))
		self.lbl4.adjustSize()
		self.lbl3.setText("y="+str(b0)+"+("+str(b1)+"x)")
		self.lbl3.adjustSize()
	def bor(self):
		self.inp.clear()
	def bor2(self):
		self.x.clear()
	def bor3(self):
		self.y.clear()
	def bor4(self):
		self.inp2.clear()
	def combo(self, text):
		self.com.clear()
		if text =='':
			text='0'
		for c in range(int(text)):
			self.com.addItem(str(c+1))
			if len(xl)<= c:
				xl.append(0)
				yl.append(0)

	def lx(self, text):
		if text == "":
			text= "0"
		xl[(self.com.currentIndex())]= float(text)
	def ly(self, text):
		if text == "":
			text= "0"
		yl[(self.com.currentIndex())]= float(text)
	def onAc(self, text):
		
		if self.x.text()== " ":
			xl[int(text)-1]= 0
		if self.y.text()== " ":
			yl[int(text)-1]= 0
		self.x.setText(str(xl[int(text)-1]))
		self.y.setText(str(yl[int(text)-1]))
Exemplo n.º 50
0
class ScopeGroupBox(QGroupBox):
    """Define QGroupBox for icon scope."""

    dataModified = pyqtSignal()

    def __init__(self, name='', options=list(), scope='all', parent=None):
        """Init lineedit."""
        super().__init__(name, parent)
        layout = QFormLayout()
        self.bt_dynamic = QRadioButton(_("Dynamic:"))
        self.bt_dynamic.toggled.connect(lambda: self.btnstate('dynamic'))
        self.bt_dynamic.setMinimumWidth(120)
        self.scope_box = QComboBox()
        found = False
        idx = 0
        for key, item in options.items():
            self.scope_box.addItem(item, key)
            if key == scope:
                self.scope_box.setCurrentIndex(idx)
                self.bt_dynamic.setChecked(True)
                found = True
            idx = idx + 1
        layout.addRow(self.bt_dynamic, self.scope_box)

        self.bt_static = QRadioButton(_("Static:"))
        self.bt_static.toggled.connect(lambda: self.btnstate('static'))
        self.bt_static.setMinimumWidth(120)

        container = QHBoxLayout()
        self.label1 = QLabel(_('From'))
        container.addWidget(self.label1)
        self.cb_lower = QComboBox()
        for set_idx in range(0, scctool.settings.max_no_sets):
            self.cb_lower.addItem(_('Map {}').format(set_idx + 1), set_idx)
        self.cb_lower.currentIndexChanged.connect(self.adjustRangeUpper)
        container.addWidget(self.cb_lower, 0)
        self.label2 = QLabel(_('to'))
        self.label2.setAlignment(Qt.AlignCenter)
        container.addWidget(self.label2, 0)
        self.cb_upper = QComboBox()
        for set_idx in range(0, scctool.settings.max_no_sets):
            self.cb_upper.addItem(_('Map {}').format(set_idx + 1), set_idx)
        container.addWidget(self.cb_upper, 0)
        layout.addRow(self.bt_static, container)

        if not found:
            m = re.match(r'^(\d+)-(\d+)$', scope)
            if m and int(m.group(1)) <= int(m.group(2)):
                self.bt_static.setChecked(True)
                self.cb_upper.setCurrentIndex(int(m.group(2)) - 1)
                self.cb_lower.setCurrentIndex(int(m.group(1)) - 1)

        self.setLayout(layout)

        self.btnstate('dynamic')
        self.btnstate('static')

        self.bt_dynamic.toggled.connect(self.triggerSignal)
        self.bt_static.toggled.connect(self.triggerSignal)
        self.cb_upper.currentIndexChanged.connect(self.triggerSignal)
        self.cb_lower.currentIndexChanged.connect(self.triggerSignal)
        self.scope_box.currentIndexChanged.connect(self.triggerSignal)

    def btnstate(self, b):
        if b == 'dynamic':
            self.scope_box.setEnabled(self.bt_dynamic.isChecked())
        elif b == 'static':
            self.cb_lower.setEnabled(self.bt_static.isChecked())
            self.cb_upper.setEnabled(self.bt_static.isChecked())
            self.label1.setEnabled(self.bt_static.isChecked())
            self.label2.setEnabled(self.bt_static.isChecked())

    def adjustRangeUpper(self, lower):
        current_idx = self.cb_upper.itemData(self.cb_upper.currentIndex())
        self.cb_upper.clear()
        rg = range(lower, scctool.settings.max_no_sets)
        if current_idx not in rg:
            current_idx = lower
        idx = 0
        for set_idx in rg:
            self.cb_upper.addItem(_('Map {}').format(set_idx + 1), set_idx)
            if set_idx == current_idx:
                self.cb_upper.setCurrentIndex(idx)
            idx = idx + 1

    def getScope(self):
        if self.bt_dynamic.isChecked():
            return self.scope_box.itemData(self.scope_box.currentIndex())
        else:
            lower = int(self.cb_lower.itemData(
                self.cb_lower.currentIndex())) + 1
            upper = int(self.cb_upper.itemData(
                self.cb_upper.currentIndex())) + 1
            return '{}-{}'.format(lower, upper)

    def triggerSignal(self):
        self.dataModified.emit()
Exemplo n.º 51
0
class ErgebnissListe(QWidget):
    template = "<tr><td>Eintrag von </td><td>{: >20}</td><td>in der Disziplin {:<15} </td><td>{}erfolgreich {}</td></tr>"
    def __init__(self,parent=None):
        super(ErgebnissListe, self).__init__(parent)

        self.auswahlAlter = QComboBox()
        self.auswahlAlter.addItem("Bitte auswählen")
        for i in range(3,18):
            self.auswahlAlter.addItem("{} Jahre / Jahrgang {}".format(i, date.today().year-i))
        self.auswahlAlter.activated.connect(self.auswahlKlasse)
        self.auswahlAlter.activated.connect(self.waehleDisziplinen)

        self.auswahlGeschlecht = QComboBox()
        self.auswahlGeschlecht.addItem("Bitte auswählen")
        self.auswahlGeschlecht.addItem("Männlich")
        self.auswahlGeschlecht.addItem("Weiblich")
        self.auswahlGeschlecht.activated.connect(self.auswahlKlasse)
        self.auswahlGeschlecht.activated.connect(self.waehleDisziplinen)

        self.auswahlDisziplin = QComboBox()
        self.auswahlDisziplin.addItem("Bitte auswählen")
        for i in getDisziplin(10):
            self.auswahlDisziplin.addItem(i)
        self.auswahlDisziplin.activated.connect(self.auswahlKlasse)

        self.mainLayout = QGridLayout()
        self.mainLayout.addWidget(QLabel("Alter:"), 0, 0)
        self.mainLayout.addWidget(self.auswahlAlter, 0, 1, 1, 3)
        self.mainLayout.addWidget(QLabel("Geschlecht:"), 1, 0)
        self.mainLayout.addWidget(self.auswahlGeschlecht, 1, 1, 1, 3)
        self.mainLayout.addWidget(QLabel("Disziplin:"), 2, 0)
        self.mainLayout.addWidget(self.auswahlDisziplin, 2, 1, 1, 3)

        self._speichern = QPushButton("Speichern")
        self._speichern.clicked.connect(self.speichern)

        self.setLayout(self.mainLayout)

        self._sportler = []

        self.update()

    def waehleDisziplinen(self):
        self.auswahlDisziplin.clear()
        self.auswahlDisziplin.addItem("Bitte auswählen")
        for i in getDisziplin(self.auswahlAlter.currentIndex()+2):
            self.auswahlDisziplin.addItem(i)


    def auswahlKlasse(self):
        if self.auswahlAlter.currentIndex() == 0:
            return False
        elif self.auswahlGeschlecht.currentIndex() == 0:
            return False
        elif self.auswahlDisziplin.currentIndex() == 0:
            return False

        self.clearAuswahl()

        disziplin = self.auswahlDisziplin.currentIndex()-1
        if self.auswahlDisziplin.currentText() is "-":
            return

        for sportler in QueryTool().queryAndFetch("SELECT ID, Name, Vorname FROM LG_NGD WHERE WieAlt = ? AND Geschlecht = ?",
                                                 self.auswahlAlter.currentIndex()+2,
                                                 bool(self.auswahlGeschlecht.currentIndex()-1)):
            self._sportler += [sportler[0]]
            name = "{} {}".format(sportler[2],sportler[1])
            #UID, Name

            for werte in reversed(QueryTool().queryAndFetch("SELECT Wert1, Wert2, Wert3 FROM LG_NGD_Ergebnisse WHERE UID = ? "
                                                   "AND Typ = ? UNION SELECT 0, 0, 0",
                                                   sportler[0],
                                                   disziplin)):

                row = self.mainLayout.rowCount()

                self.mainLayout.addWidget(QLabel(name), row, 0)
                for i in range(0,felderzahl[disziplin]):
                    el = QDoubleSpinBox()
                    el.setMaximum(99999)
                    el.setValue(werte[i])
                    el.setSuffix(" "+einheiten[disziplin])
                    el.setSingleStep(0.01)
                    self.mainLayout.addWidget(el, row, i+1, 1, 3/felderzahl[disziplin])
                break
        self._speichern = QPushButton("Speichern")
        self._speichern.clicked.connect(self.speichern)
        self.mainLayout.addWidget(self._speichern, self.mainLayout.rowCount(), 0, 1, 4)

    def speichern(self):
        row = self.mainLayout.rowCount()-len(self._sportler)-1
        disziplin = self.auswahlDisziplin.currentIndex()-1

        ausgabe = "<table>"

        for UID in self._sportler:
            werte = ["0","0","0"]
            for col in range(1, 1+felderzahl[disziplin]):
                item = self.mainLayout.itemAtPosition(row, col)
                text = "0"
                try:
                    if type(item.widget()) is not type(QDoubleSpinBox()):
                        raise TypeError("No LineEdit")
                    text = item.widget().value()
                except TypeError:
                    text = "0"
                except AttributeError:
                    text = "0"
                werte[col-1]=text

            data = QueryTool().queryAndFetch("SELECT * FROM LG_NGD_Ergebnisse WHERE UID = ? AND Typ = ?",UID,disziplin)
            ergebnisse = None
            typ = None
            if len(data) is not 0:
                ergebniss = QueryTool().update("LG_NGD_Ergebnisse", data[0][0], Wert1=werte[0], Wert2=werte[1], Wert3=werte[2])
                typ = "aktualisiert"
            else:
                ergebniss = QueryTool().insert("LG_NGD_Ergebnisse", UID=UID, Typ=disziplin, Wert1=werte[0], Wert2=werte[1], Wert3=werte[2])
                typ = "eingetragen"

            username = self.mainLayout.itemAtPosition(row, 0)

            if type(username.widget()) is not type(QLabel()):
                username = ""
            else:
                username = username.widget().text()
            ausgabe += self.template.format(username, list(getDisziplin(self.auswahlAlter.currentIndex()+2))[disziplin],
                                            "nicht " if ergebniss is None else "", typ)

            row += 1
        ausgabe += "</table>"
        QMessageBox.information(self, "Eintragungsstatus", ausgabe)

    def clearAuswahl(self):
        for w in self.iterWidgets(True):
            w[0].setParent(None)
        self._sportler=[]

    def iterWidgets(self,allWidgets = False)->QWidget:
        for row in range(3, self.mainLayout.rowCount()-(1 if not allWidgets else 0)):
            for col in range(self.mainLayout.columnCount()):
                item = self.mainLayout.itemAtPosition(row, col)
                if item is not None and item.widget() is not None:
                    yield (item.widget(), row, col)
                else:
                    break

    def update(self):
        if not self.auswahlKlasse():
            return
Exemplo n.º 52
0
class ImageTab(QWidget):
    def __init__(self, parent):
        super(ImageTab, self).__init__(parent)
        self.parent = parent
        self.name = 'Images'

        self.formats = config.image_formats
        self.extra_img = config.image_extra_formats

        validator = QRegExpValidator(QRegExp(r'^[1-9]\d*'), self)

        converttoQL = QLabel(self.tr('Convert to:'))
        self.extQCB = QComboBox()
        commandQL = QLabel(self.tr('Extra options:'))
        self.commandQLE = QLineEdit()

        hlayout2 = utils.add_to_layout(
                'h', converttoQL, self.extQCB, commandQL, self.commandQLE)

        sizeQL = QLabel(
                '<html><p align="center">' + self.tr('Image Size:') +
                '</p></html>')
        self.widthQLE = utils.create_LineEdit((50, 16777215), validator, 4)
        self.heightQLE = utils.create_LineEdit((50, 16777215), validator, 4)
        label = QLabel('<html><p align="center">x</p></html>')
        label.setMaximumWidth(25)

        hlayout1 = utils.add_to_layout('h', self.widthQLE, label,self.heightQLE)
        sizelayout = utils.add_to_layout('v', sizeQL, hlayout1)

        self.imgaspectQChB = QCheckBox(self.tr("Maintain aspect ratio"))
        self.autocropQChB = QCheckBox(self.tr("Auto-crop"))

        vlayout = utils.add_to_layout('v', self.imgaspectQChB,self.autocropQChB)

        rotateQL = QLabel(
                "<html><div align='center'>" + self.tr("Rotate") +
                ":</div><br>(" + self.tr("degrees - clockwise") + ")</html>")
        self.rotateQLE = utils.create_LineEdit((100, 16777215), validator, 3)
        self.vflipQChB = QCheckBox(self.tr('Vertical flip'))
        self.hflipQChB = QCheckBox(self.tr('Horizontal flip'))

        vlayout2 = utils.add_to_layout('v', self.vflipQChB, self.hflipQChB)
        hlayout3 = utils.add_to_layout(
                'h', sizelayout, vlayout, rotateQL, self.rotateQLE,
                vlayout2, None)

        final_layout = utils.add_to_layout('v', hlayout2, hlayout3)
        self.setLayout(final_layout)

    def clear(self):
        """Clear self.widthQLE and self.heightQLE."""
        self.widthQLE.clear()
        self.heightQLE.clear()
        self.commandQLE.clear()
        self.rotateQLE.clear()
        self.imgaspectQChB.setChecked(False)
        self.autocropQChB.setChecked(False)
        self.vflipQChB.setChecked(False)
        self.hflipQChB.setChecked(False)

    def fill_extension_combobox(self, extraformats):
        self.extQCB.clear()
        self.extQCB.addItems(sorted(self.formats + extraformats))

    def ok_to_continue(self):
        """
        Check if everything is ok with imagetab to continue conversion.

        Check if:
        - ImageMagick is missing.
        - Either none or both size lineEdits are active at a time.

        Return True if all tests pass, else False.
        """
        width = self.widthQLE.text()
        height = self.heightQLE.text()

        if not self.parent.imagemagick:
            QMessageBox.warning(self, 'FF Multi Converter - ' + self.tr(
                'Error!'), self.tr('ImageMagick is not installed!'))
            return False
        if (width and not height) or (not width and height):
            QMessageBox.warning(self, 'FF Multi Converter - ' + self.tr(
                     'Error!'), self.tr('The size LineEdit may not be empty.'))
            if width and not height:
                self.heightQLE.setFocus()
            else:
                self.widthQLE.setFocus()
            return False
        return True

    def set_default_command(self):
        """Set the default value to self.commandQLE."""
        self.clear()
        self.commandQLE.setText(self.parent.default_command_image)
Exemplo n.º 53
0
class comics_project_details_editor(QDialog):
    configGroup = "ComicsProjectManagementTools"
    """
    Initialise the editor.
    @param projectUrl - The directory to which all paths are relative.
    """
    def __init__(self, projectUrl=str()):
        super().__init__()
        self.projectUrl = projectUrl
        layout = QFormLayout()
        self.setLayout(layout)
        self.setWindowTitle(i18n("Comic Project Settings"))
        buttons = QDialogButtonBox(QDialogButtonBox.Ok
                                   | QDialogButtonBox.Cancel)

        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)
        self.lnProjectName = QLineEdit()
        self.lnProjectConcept = QLineEdit()
        self.cmb_defaultTemplate = QComboBox()

        self.pagesLocation = path_select(
            question=i18n("Where should the pages go?"),
            projectUrl=self.projectUrl)
        self.exportLocation = path_select(
            question=i18n("Where should the export go?"),
            projectUrl=self.projectUrl)
        self.templateLocation = path_select(
            question=i18n("Where are the templates?"),
            projectUrl=self.projectUrl)
        self.keyLocation = path_select(
            question=i18n("Where are the extra auto-completion keys located?"))
        self.keyLocation.setToolTip(
            i18n(
                "The location for extra autocompletion keys in the meta-data editor. Point this at a folder containing key_characters/key_format/key_genre/key_rating/key_author_roles/key_other with inside txt files(csv for tating) containing the extra auto-completion keys, each on a new line. This path is stored in the krita configuration, and not the project configuration."
            ))
        self.templateLocation.locationChanged.connect(self.refill_templates)

        layout.addRow(i18n("Project Name:"), self.lnProjectName)
        layout.addRow(i18n("Project Concept:"), self.lnProjectConcept)
        layout.addRow(i18n("Pages Folder:"), self.pagesLocation)
        layout.addRow(i18n("Export Folder:"), self.exportLocation)
        layout.addRow(i18n("Template Folder:"), self.templateLocation)
        layout.addRow(i18n("Default Template:"), self.cmb_defaultTemplate)
        layout.addRow(i18n("Extra Keys Folder:"), self.keyLocation)

        self.layout().addWidget(buttons)

    """
    Fill the templates doc with the kra files found in the templates directory.
    Might want to extend this to other files as well, as they basically get resaved anyway...
    """

    def refill_templates(self):
        self.cmb_defaultTemplate.clear()
        templateLocation = os.path.join(self.projectUrl,
                                        self.templateLocation.getLocation())
        for entry in os.scandir(templateLocation):
            if entry.name.endswith('.kra') and entry.is_file():
                name = os.path.relpath(entry.path, templateLocation)
                self.cmb_defaultTemplate.addItem(name)

    """
    Load the UI values from the config dictionary given.
    """

    def setConfig(self, config, projectUrl):

        self.projectUrl = projectUrl
        if "projectName" in config.keys():
            self.lnProjectName.setText(config["projectName"])
        if "concept" in config.keys():
            self.lnProjectConcept.setText(config["concept"])
        if "pagesLocation" in config.keys():
            self.pagesLocation.setLocation(config["pagesLocation"])
        if "exportLocation" in config.keys():
            self.exportLocation.setLocation(config["exportLocation"])
        if "templateLocation" in config.keys():
            self.templateLocation.setLocation(config["templateLocation"])
            self.refill_templates()
        self.keyLocation.setLocation(
            Application.readSetting(self.configGroup, "extraKeysLocation",
                                    str()))

    """
    Store the GUI values into the config dictionary given.
    
    @return the config diactionary filled with new values.
    """

    def getConfig(self, config):
        config["projectName"] = self.lnProjectName.text()
        config["concept"] = self.lnProjectConcept.text()
        config["pagesLocation"] = self.pagesLocation.getLocation()
        config["exportLocation"] = self.exportLocation.getLocation()
        config["templateLocation"] = self.templateLocation.getLocation()
        config["singlePageTemplate"] = os.path.join(
            self.templateLocation.getLocation(),
            self.cmb_defaultTemplate.currentText())
        Application.writeSetting(self.configGroup, "extraKeysLocation",
                                 self.keyLocation.getLocation())
        return config
class myClass(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("下拉列表控件QComboBox")
        self.setGeometry(700, 300, 600, 500)

        myframe1 = QFrame(self)
        myframe1.move(50, 50)
        lbl_1 = QLabel("省", myframe1)
        lbl_1.move(0, 3)
        comBox1 = QComboBox(myframe1)
        comBox1.move(30, 0)

        # 传递字符串类型
        comBox1.activated[str].connect(self.myActived)  # 选择以后可以进行信号处理
        # 省份
        comBox1.addItem("选择省份")
        comBox1.addItem("广西")
        comBox1.addItem("广东")
        comBox1.addItem("福建")
        comBox1.addItem("北京")

        # 市级
        lbl_2 = QLabel("市", myframe1)
        lbl_2.move(170, 3)
        self.comBox2 = QComboBox(myframe1)
        self.comBox2.move(200, 0)
        self.comBox2.activated[str].connect(self.myActived2)

        self.show()

    def myActived(self, strName):
        # 每次选择之前先清空
        self.comBox2.clear()
        print(strName)
        if strName == "广西":
            self.comBox2.addItem("南宁")
            self.comBox2.addItem("贵港")
            self.comBox2.addItem("柳州")
            self.comBox2.addItem("桂林")
            self.comBox2.addItem("玉林")
            self.comBox2.addItem("防城港")
            self.comBox2.addItem("平果")
        elif strName == "广东":
            self.comBox2.addItem("广州")
            self.comBox2.addItem("深圳")
            self.comBox2.addItem("东莞")
            self.comBox2.addItem("珠海")
            self.comBox2.addItem("中山")
            self.comBox2.addItem("佛山")
            self.comBox2.addItem("惠州")
        elif strName == "福建":
            self.comBox2.addItem("厦门")
            self.comBox2.addItem("泉州")
        elif strName == "北京":
            self.comBox2.addItem("朝阳")
            self.comBox2.addItem("一环")
            self.comBox2.addItem("二环")
        elif strName == "选择省份":
            self.comBox2.clear()

    def myActived2(self, strName):
        print(strName)
Exemplo n.º 55
0
class LedgerAuthDialog(QDialog):
    def __init__(self, handler, data):
        '''Ask user for 2nd factor authentication. Support text and security card methods.
        Use last method from settings, but support 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.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):
            self.cfg[
                'mode'] = 0 if self.devmode == 0x11 else idx if idx > 0 else 1
            if self.cfg['mode'] > 0:
                self.handler.win.wallet.get_keystore().cfg = self.cfg
                self.handler.win.wallet.save_keystore()
            self.update_dlg()

        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)
        modelayout.addStretch(1)
        self.modebox.setMaximumHeight(50)
        vbox.addWidget(self.modebox)

        self.populate_modes()
        self.modes.currentIndexChanged.connect(on_change_mode)

        self.helpmsg = QTextEdit()
        self.helpmsg.setStyleSheet(
            "QTextEdit { color:black; 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: "Courier New", 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.QtumMainnet)
                    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.update_dlg()

    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"))
        self.modes.blockSignals(False)

    def update_dlg(self):
        self.modes.setCurrentIndex(self.cfg['mode'])
        self.modebox.setVisible(True)
        self.helpmsg.setText(helpTxt[self.cfg['mode']])
        self.helpmsg.setMinimumHeight(180 if self.txdata['confirmationType'] ==
                                      1 else 100)
        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 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:
            _logger.debug('Device getMode Failed')
        return 0x11
Exemplo n.º 56
0
class SimTab(QWidget):
    def __init__(self, main_app):
        super().__init__()
        self.main_app = main_app
        self.oengus = main_app.oengus
        self.main_params = self.oengus.MainParamDict
        self.sim_selected = self.oengus.sims[0]
        self.build_ui()

    def build_ui(self):
        min_width = 150
        max_width = 200

        layout = QGridLayout()
        self.setLayout(layout)

        ####
        #
        # Build up the sim settings tab
        #
        #  Choose Sim: | ComboBox |
        #  Choose shock finder: | ComboBox |
        #
        ####

        layout.addWidget(QLabel('Choose sim'), 0, 0)
        self.sim_combo = QComboBox(self)
        self.update_sim_list()
        self.sim_combo.currentIndexChanged.connect(self.sim_selection_changed)
        layout.addWidget(self.sim_combo, 0, 1)

        layout.addWidget(QLabel('Choose Shock Finder'), 1, 0)
        self.shock_combo = QComboBox(self)
        self.update_shock_opts()
        self.shock_combo.currentIndexChanged.connect(self.shock_finder_changed)
        layout.addWidget(self.shock_combo, 1, 1)

        ####
        #
        #  prtl stride:
        #  | QLineEdit | | x | average 1D |
        #
        ####

        sim_ind = self.sim_selected.sim_num
        sim_params = self.main_params['sim_params'][sim_ind]

        layout.addWidget(QLabel('Prtl Stride'), 2, 0)

        self.prtl_stride_edit = QLineEdit(self)
        self.prtl_stride_edit.setText(str(sim_params['PrtlStride']))
        self.prtl_stride_edit.setMaximumWidth(max_width)
        self.prtl_stride_edit.setMinimumWidth(min_width)
        self.prtl_stride_edit.returnPressed.connect(self.stride_changed)
        layout.addWidget(self.prtl_stride_edit, 2, 1)
        self.average1D_cb = QCheckBox("Average1D")
        self.average1D_cb.setChecked(sim_params['Average1D'])
        self.average1D_cb.stateChanged.connect(self.avg_changed)

        layout.addWidget(self.average1D_cb, 3, 0)

        # radio buttons to choose plane.
        row = QHBoxLayout()
        row.addWidget(QLabel('Choose 2D-plane:'))

        self.slice_radio_btns = []
        radiobutton = QRadioButton("x-y")
        radiobutton.plane = 0
        radiobutton.toggled.connect(self.radio_clicked)
        self.slice_radio_btns.append(radiobutton)
        row.addWidget(radiobutton)

        radiobutton = QRadioButton("x-z")
        radiobutton.plane = 1
        radiobutton.toggled.connect(self.radio_clicked)
        self.slice_radio_btns.append(radiobutton)

        row.addWidget(radiobutton)

        radiobutton = QRadioButton("y-z")
        radiobutton.plane = 2
        radiobutton.toggled.connect(self.radio_clicked)
        self.slice_radio_btns.append(radiobutton)

        row.addWidget(radiobutton)
        layout.addLayout(row, 4, 0, 1, 2)

        # Now do the sliders

        self.sliders_dict = {}
        for i, ax in enumerate(['x', 'y', 'z']):
            row = QHBoxLayout()
            sld_obj = {}
            sld_obj['label'] = QLabel(self)
            sld_obj['sld'] = QSlider(Qt.Horizontal, self)
            sld_obj['sld'].ax = ax
            # update the text box whenever sld is change
            sld_obj['sld'].valueChanged.connect(self.scale_handler)
            # only update the plot when the user releases the mouse
            sld_obj['sld'].mouseReleaseEvent = partial(self.update_slice_val,
                                                       ax)

            # self.sld.setRange(self.param.minimum, self.param.maximum)
            sld_obj['sld'].setFocusPolicy(Qt.NoFocus)
            sld_obj['sld'].setPageStep(1)

            row.addWidget(QLabel(f'{ax}-slice'))
            row.addWidget(sld_obj['sld'])
            row.addWidget(sld_obj['label'])
            self.sliders_dict[ax] = sld_obj

            layout.addLayout(row, 5 + i, 0, 1, 2)

        self.update_slice_widgets()

    def scale_handler(self, e):
        # if changing the scale will change the value of the parameter, do so
        sld = self.sender()
        ax = self.sim_selected.get_data(data_class='axes',
                                        attribute=sld.ax)['data']

        self.sliders_dict[sld.ax]['label'].setText(
            f'{round(ax[int(sld.value())], 2)}')

    def update_slice_val(self, ax_name, e):
        sim_ind = self.sim_selected.sim_num
        sim_params = self.main_params['sim_params'][sim_ind]

        sld = self.sliders_dict[ax_name]['sld']
        ax = self.sim_selected.get_data(data_class='axes',
                                        attribute=ax_name)['data']
        next_sld_val = float(sld.value()) / (len(ax) - 1.0)
        if next_sld_val != sim_params[f'{ax_name}Slice']:
            sim_params[f'{ax_name}Slice'] = next_sld_val
            if not sim_params['Average1D']:
                for i in range(self.oengus.MainParamDict['NumOfRows']):
                    for j in range(self.oengus.MainParamDict['NumOfCols']):
                        self.oengus.SubPlotList[i][j].save_axes_pos()
                        self.oengus.SubPlotList[i][j].refresh()
                        self.oengus.SubPlotList[i][j].load_axes_pos()
                self.oengus.canvas.draw()

    def update_slice_widgets(self):
        sim_ind = self.sim_selected.sim_num
        sim_params = self.main_params['sim_params'][sim_ind]

        for btn in self.slice_radio_btns:
            btn.setChecked(btn.plane == sim_params['2DSlicePlane'])

        x_ax = self.sim_selected.get_data(data_class='axes',
                                          attribute='x')['data']
        y_ax = self.sim_selected.get_data(data_class='axes',
                                          attribute='y')['data']
        z_ax = self.sim_selected.get_data(data_class='axes',
                                          attribute='z')['data']

        self.slice_radio_btns[1].setEnabled(len(z_ax) > 1)
        self.slice_radio_btns[2].setEnabled(  # Fals
            (len(y_ax) > 1) and (len(z_ax) > 1))

        # enable or disable sliders
        # for key in ['edit', 'sld']:
        self.sliders_dict['x']['sld'].setEnabled(
            sim_params['2DSlicePlane'] == 2 and (len(x_ax) > 1))

        self.sliders_dict['y']['sld'].setEnabled(
            (sim_params['2DSlicePlane'] != 2) and (len(y_ax) > 1))

        self.sliders_dict['z']['sld'].setEnabled((len(z_ax) > 1))
        self.update_slider_vals()

    def update_slider_vals(self):
        for key in ['x', 'y', 'z']:
            ax = self.sim_selected.get_data(data_class='axes',
                                            attribute=key)['data']

            if len(ax) > 1:
                self.sliders_dict[key]['sld'].setRange(0, len(ax) - 1)

                self.sliders_dict[key]['sld'].setValue(
                    self.oengus.calc_slices(key, self.sim_selected))

    def radio_clicked(self):
        # If the shared axes are changed, we have to call the link
        # handler on every subplot
        radioButton = self.sender()
        sim_ind = self.sim_selected.sim_num
        sim_params = self.main_params['sim_params'][sim_ind]
        if radioButton.isChecked():
            if sim_params['2DSlicePlane'] != radioButton.plane:
                sim_params['2DSlicePlane'] = radioButton.plane
                self.update_slice_widgets()
                self.oengus.figure.clf()
                self.oengus.create_graphs()
                self.oengus.canvas.draw()

    def avg_changed(self):
        ind = self.sim_selected.sim_num
        sim_params = self.main_params['sim_params'][ind]

        if sim_params['Average1D'] != self.average1D_cb.isChecked():
            sim_params['Average1D'] = self.average1D_cb.isChecked()
            for i in range(self.oengus.MainParamDict['NumOfRows']):
                for j in range(self.oengus.MainParamDict['NumOfCols']):
                    self.oengus.SubPlotList[i][j].save_axes_pos()
                    self.oengus.SubPlotList[i][j].refresh()
                    self.oengus.SubPlotList[i][j].load_axes_pos()
            self.oengus.canvas.draw()

    def stride_changed(self):
        # Note here that Tkinter passes an event object to SkipSizeChange()
        if not self.ignoreChange:
            ind = self.sim_selected.sim_num
            sim_params = self.main_params['sim_params'][ind]
            try:
                sim_params['PrtlStride'] = int(self.prtl_stride_edit.text())
                self.sim_selected.xtra_stride = sim_params['PrtlStride']
                for i in range(self.oengus.MainParamDict['NumOfRows']):
                    for j in range(self.oengus.MainParamDict['NumOfCols']):
                        self.oengus.SubPlotList[i][j].save_axes_pos()
                        self.oengus.SubPlotList[i][j].refresh()
                        self.oengus.SubPlotList[i][j].load_axes_pos()
                self.oengus.canvas.draw()
            except ValueError:
                self.prtl_stride_edit.setText(str(sim_params['PrtlStride']))

    def update_sim_list(self):
        self.ignoreChange = True
        self.sim_combo.clear()
        for name in self.oengus.sim_names:
            self.sim_combo.addItem(name)
        index = self.sim_combo.findText(self.sim_selected.name)
        if index >= 0:
            self.sim_combo.setCurrentIndex(index)
        self.ignoreChange = False

    def sim_selection_changed(self):
        if not self.ignoreChange:
            if self.sim_combo.currentText() != self.sim_selected.name:
                try:
                    ind = self.oengus.sim_names.index(
                        self.sim_combo.currentText())
                except ValueError:
                    ind = 0

                self.sim_selected = self.oengus.sims[ind]
                sim_params = self.oengus.MainParamDict['sim_params'][ind]
                self.prtl_stride_edit.setText(str(sim_params['PrtlStride']))
                self.average1D_cb.setChecked(sim_params['Average1D'])
                self.update_shock_opts()
                self.update_slice_widgets()

    def update_shock_opts(self):
        self.ignoreChange = True
        self.shock_combo.clear()

        avail_opts = self.sim_selected.get_available_quantities()
        for method_name in avail_opts['shock_finders']:
            self.shock_combo.addItem(method_name)
        sim_params = self.oengus.MainParamDict['sim_params'][
            self.sim_selected.sim_num]
        index = self.shock_combo.findText(sim_params['shock_method'])
        self.ignoreChange = False
        if index >= 0:
            self.shock_combo.setCurrentIndex(index)
        else:
            self.shock_combo.setCurrentIndex(0)

    def shock_finder_changed(self, *args):
        if not self.ignoreChange:
            combo_name = self.shock_combo.currentText()
            sim_params = self.oengus.MainParamDict['sim_params'][
                self.sim_selected.sim_num]
            if sim_params['shock_method'] != combo_name:
                sim_params['shock_method'] = combo_name
                # self.shock_finder_var.set(self.sim_selected.shock_finder_name)
                # update shock lines
                for i in range(self.oengus.MainParamDict['NumOfRows']):
                    for j in range(self.oengus.MainParamDict['NumOfCols']):
                        self.oengus.SubPlotList[i][j].save_axes_pos()
                        self.oengus.SubPlotList[i][j].refresh()
                        self.oengus.SubPlotList[i][j].load_axes_pos()
                self.oengus.canvas.draw()
Exemplo n.º 57
0
class DirectoriesDialog(QMainWindow):
    def __init__(self, app, **kwargs):
        super().__init__(None, **kwargs)
        self.app = app
        self.lastAddedFolder = platform.INITIAL_FOLDER_IN_DIALOGS
        self.recentFolders = Recent(self.app, 'recentFolders')
        self._setupUi()
        self._updateScanTypeList()
        self.directoriesModel = DirectoriesModel(self.app.model.directory_tree, view=self.treeView)
        self.directoriesDelegate = DirectoriesDelegate()
        self.treeView.setItemDelegate(self.directoriesDelegate)
        self._setupColumns()
        self.app.recentResults.addMenu(self.menuLoadRecent)
        self.app.recentResults.addMenu(self.menuRecentResults)
        self.recentFolders.addMenu(self.menuRecentFolders)
        self._updateAddButton()
        self._updateRemoveButton()
        self._updateLoadResultsButton()
        self._updateActionsState()
        self._setupBindings()

    def _setupBindings(self):
        self.appModeRadioBox.itemSelected.connect(self.appModeButtonSelected)
        self.showPreferencesButton.clicked.connect(self.app.actionPreferences.trigger)
        self.scanButton.clicked.connect(self.scanButtonClicked)
        self.loadResultsButton.clicked.connect(self.actionLoadResults.trigger)
        self.addFolderButton.clicked.connect(self.actionAddFolder.trigger)
        self.removeFolderButton.clicked.connect(self.removeFolderButtonClicked)
        self.treeView.selectionModel().selectionChanged.connect(self.selectionChanged)
        self.app.recentResults.itemsChanged.connect(self._updateLoadResultsButton)
        self.recentFolders.itemsChanged.connect(self._updateAddButton)
        self.recentFolders.mustOpenItem.connect(self.app.model.add_directory)
        self.directoriesModel.foldersAdded.connect(self.directoriesModelAddedFolders)
        self.app.willSavePrefs.connect(self.appWillSavePrefs)

    def _setupActions(self):
        # (name, shortcut, icon, desc, func)
        ACTIONS = [
            ('actionLoadResults', 'Ctrl+L', '', tr("Load Results..."), self.loadResultsTriggered),
            ('actionShowResultsWindow', '', '', tr("Results Window"), self.app.showResultsWindow),
            ('actionAddFolder', '', '', tr("Add Folder..."), self.addFolderTriggered),
        ]
        createActions(ACTIONS, self)

    def _setupMenu(self):
        self.menubar = QMenuBar(self)
        self.menubar.setGeometry(QRect(0, 0, 42, 22))
        self.menuFile = QMenu(self.menubar)
        self.menuFile.setTitle(tr("File"))
        self.menuView = QMenu(self.menubar)
        self.menuView.setTitle(tr("View"))
        self.menuHelp = QMenu(self.menubar)
        self.menuHelp.setTitle(tr("Help"))
        self.menuLoadRecent = QMenu(self.menuFile)
        self.menuLoadRecent.setTitle(tr("Load Recent Results"))
        self.setMenuBar(self.menubar)

        self.menuFile.addAction(self.actionLoadResults)
        self.menuFile.addAction(self.menuLoadRecent.menuAction())
        self.menuFile.addSeparator()
        self.menuFile.addAction(self.app.actionClearPictureCache)
        self.menuFile.addSeparator()
        self.menuFile.addAction(self.app.actionQuit)
        self.menuView.addAction(self.app.actionPreferences)
        self.menuView.addAction(self.actionShowResultsWindow)
        self.menuView.addAction(self.app.actionIgnoreList)
        self.menuHelp.addAction(self.app.actionShowHelp)
        self.menuHelp.addAction(self.app.actionOpenDebugLog)
        self.menuHelp.addAction(self.app.actionAbout)

        self.menubar.addAction(self.menuFile.menuAction())
        self.menubar.addAction(self.menuView.menuAction())
        self.menubar.addAction(self.menuHelp.menuAction())

        # Recent folders menu
        self.menuRecentFolders = QMenu()
        self.menuRecentFolders.addAction(self.actionAddFolder)
        self.menuRecentFolders.addSeparator()

        # Recent results menu
        self.menuRecentResults = QMenu()
        self.menuRecentResults.addAction(self.actionLoadResults)
        self.menuRecentResults.addSeparator()

    def _setupUi(self):
        self.setWindowTitle(self.app.NAME)
        self.resize(420, 338)
        self.centralwidget = QWidget(self)
        self.verticalLayout = QVBoxLayout(self.centralwidget)
        hl = QHBoxLayout()
        label = QLabel(tr("Application Mode:"), self)
        label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        hl.addWidget(label)
        self.appModeRadioBox = RadioBox(
            self,
            items=[tr("Standard"), tr("Music"), tr("Picture")],
            spread=False
        )
        hl.addWidget(self.appModeRadioBox)
        self.verticalLayout.addLayout(hl)
        hl = QHBoxLayout()
        hl.setAlignment(Qt.AlignLeft)
        label = QLabel(tr("Scan Type:"), self)
        label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        hl.addWidget(label)
        self.scanTypeComboBox = QComboBox(self)
        self.scanTypeComboBox.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed))
        self.scanTypeComboBox.setMaximumWidth(400)
        hl.addWidget(self.scanTypeComboBox)
        self.showPreferencesButton = QPushButton(tr("More Options"), self.centralwidget)
        self.showPreferencesButton.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        hl.addWidget(self.showPreferencesButton)
        self.verticalLayout.addLayout(hl)
        self.promptLabel = QLabel(tr("Select folders to scan and press \"Scan\"."), self.centralwidget)
        self.verticalLayout.addWidget(self.promptLabel)
        self.treeView = QTreeView(self.centralwidget)
        self.treeView.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.treeView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.treeView.setAcceptDrops(True)
        triggers = QAbstractItemView.DoubleClicked | QAbstractItemView.EditKeyPressed\
            | QAbstractItemView.SelectedClicked
        self.treeView.setEditTriggers(triggers)
        self.treeView.setDragDropOverwriteMode(True)
        self.treeView.setDragDropMode(QAbstractItemView.DropOnly)
        self.treeView.setUniformRowHeights(True)
        self.verticalLayout.addWidget(self.treeView)
        self.horizontalLayout = QHBoxLayout()
        self.removeFolderButton = QPushButton(self.centralwidget)
        self.removeFolderButton.setIcon(QIcon(QPixmap(":/minus")))
        self.removeFolderButton.setShortcut("Del")
        self.horizontalLayout.addWidget(self.removeFolderButton)
        self.addFolderButton = QPushButton(self.centralwidget)
        self.addFolderButton.setIcon(QIcon(QPixmap(":/plus")))
        self.horizontalLayout.addWidget(self.addFolderButton)
        spacerItem1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem1)
        self.loadResultsButton = QPushButton(self.centralwidget)
        self.loadResultsButton.setText(tr("Load Results"))
        self.horizontalLayout.addWidget(self.loadResultsButton)
        self.scanButton = QPushButton(self.centralwidget)
        self.scanButton.setText(tr("Scan"))
        self.scanButton.setDefault(True)
        self.horizontalLayout.addWidget(self.scanButton)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.setCentralWidget(self.centralwidget)

        self._setupActions()
        self._setupMenu()

        if self.app.prefs.directoriesWindowRect is not None:
            self.setGeometry(self.app.prefs.directoriesWindowRect)
        else:
            moveToScreenCenter(self)

    def _setupColumns(self):
        header = self.treeView.header()
        header.setStretchLastSection(False)
        header.setSectionResizeMode(0, QHeaderView.Stretch)
        header.setSectionResizeMode(1, QHeaderView.Fixed)
        header.resizeSection(1, 100)

    def _updateActionsState(self):
        self.actionShowResultsWindow.setEnabled(self.app.resultWindow is not None)

    def _updateAddButton(self):
        if self.recentFolders.isEmpty():
            self.addFolderButton.setMenu(None)
        else:
            self.addFolderButton.setMenu(self.menuRecentFolders)

    def _updateRemoveButton(self):
        indexes = self.treeView.selectedIndexes()
        if not indexes:
            self.removeFolderButton.setEnabled(False)
            return
        self.removeFolderButton.setEnabled(True)

    def _updateLoadResultsButton(self):
        if self.app.recentResults.isEmpty():
            self.loadResultsButton.setMenu(None)
        else:
            self.loadResultsButton.setMenu(self.menuRecentResults)

    def _updateScanTypeList(self):
        try:
            self.scanTypeComboBox.currentIndexChanged[int].disconnect(self.scanTypeChanged)
        except TypeError:
            # Not connected, ignore
            pass
        self.scanTypeComboBox.clear()
        scan_options = self.app.model.SCANNER_CLASS.get_scan_options()
        for scan_option in scan_options:
            self.scanTypeComboBox.addItem(scan_option.label)
        SCAN_TYPE_ORDER = [so.scan_type for so in scan_options]
        selected_scan_type = self.app.prefs.get_scan_type(self.app.model.app_mode)
        scan_type_index = SCAN_TYPE_ORDER.index(selected_scan_type)
        self.scanTypeComboBox.setCurrentIndex(scan_type_index)
        self.scanTypeComboBox.currentIndexChanged[int].connect(self.scanTypeChanged)
        self.app._update_options()

    #--- QWidget overrides
    def closeEvent(self, event):
        event.accept()
        if self.app.model.results.is_modified:
            title = tr("Unsaved results")
            msg = tr("You have unsaved results, do you really want to quit?")
            if not self.app.confirm(title, msg):
                event.ignore()
        if event.isAccepted():
            QApplication.quit()

    #--- Events
    def addFolderTriggered(self):
        title = tr("Select a folder to add to the scanning list")
        flags = QFileDialog.ShowDirsOnly
        dirpath = str(QFileDialog.getExistingDirectory(self, title, self.lastAddedFolder, flags))
        if not dirpath:
            return
        self.lastAddedFolder = dirpath
        self.app.model.add_directory(dirpath)
        self.recentFolders.insertItem(dirpath)

    def appModeButtonSelected(self, index):
        if index == 2:
            mode = AppMode.Picture
        elif index == 1:
            mode = AppMode.Music
        else:
            mode = AppMode.Standard
        self.app.model.app_mode = mode
        self._updateScanTypeList()

    def appWillSavePrefs(self):
        self.app.prefs.directoriesWindowRect = self.geometry()

    def directoriesModelAddedFolders(self, folders):
        for folder in folders:
            self.recentFolders.insertItem(folder)

    def loadResultsTriggered(self):
        title = tr("Select a results file to load")
        files = ';;'.join([tr("dupeGuru Results (*.dupeguru)"), tr("All Files (*.*)")])
        destination = QFileDialog.getOpenFileName(self, title, '', files)
        if destination:
            self.app.model.load_from(destination)
            self.app.recentResults.insertItem(destination)

    def removeFolderButtonClicked(self):
        self.directoriesModel.model.remove_selected()

    def scanButtonClicked(self):
        if self.app.model.results.is_modified:
            title = tr("Start a new scan")
            msg = tr("You have unsaved results, do you really want to continue?")
            if not self.app.confirm(title, msg):
                return
        self.app.model.start_scanning()

    def scanTypeChanged(self, index):
        scan_options = self.app.model.SCANNER_CLASS.get_scan_options()
        self.app.prefs.set_scan_type(self.app.model.app_mode, scan_options[index].scan_type)
        self.app._update_options()

    def selectionChanged(self, selected, deselected):
        self._updateRemoveButton()
Exemplo n.º 58
0
class tb_optical_model(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.dump_dir = os.path.join(get_sim_path(), "light_dump")

        self.layout = QVBoxLayout()
        label = QLabel(_("Optical model") + ":")
        self.layout.addWidget(label)

        self.cb = QComboBox()
        self.cb.activated.connect(self.on_cb_model_changed)
        self.layout.addWidget(self.cb)
        self.update()
        self.setLayout(self.layout)
        self.show()

    def get_text(self):
        out = self.cb.currentText()
        out = out.split(" ")[0]
        return out

    def file_name_set_start(self, start):
        self.start = start

    def file_name_set_end(self, end):
        self.end = end

    def find_models(self):
        ret = []
        path = get_plugins_path()

        for file in glob.glob(os.path.join(path, "*")):
            file_name = os.path.basename(file)
            if file_name.startswith("light_"):
                if file_name.endswith(".dll") or file_name.endswith(".so"):
                    ret.append(os.path.basename(file_name[6:]).split(".")[0])

        return ret

    def on_cb_model_changed(self):
        cb_text = self.cb.currentText()
        inp_update_token_value("light.inp", "#light_model", cb_text)

    def update(self):
        self.cb.blockSignals(True)

        self.cb.clear()
        models = self.find_models()
        if len(models) == 0:
            error_dlg(
                self,
                _("I can't find any optical plugins, I think the model is not installed properly."
                  ))
            return

        for i in range(0, len(models)):
            self.cb.addItem(models[i])

        used_model = inp_get_token_value(
            os.path.join(get_sim_path(), "light.inp"), "#light_model")
        print(models, used_model)
        if models.count(used_model) == 0:
            used_model = "exp"
            inp_update_token_value(os.path.join(get_sim_path(), "light.inp"),
                                   "#light_model", "exp")
            self.cb.setCurrentIndex(self.cb.findText(used_model))
        else:
            self.cb.setCurrentIndex(self.cb.findText(used_model))

        self.cb.blockSignals(False)
Exemplo n.º 59
0
class SearchWindow(QWidget):
    
    # Find all objects which property fits a given value
    # -------------
    # ComboBox: list of all subtypes of objects
    # ComboBox: list of all properties of the subtype
    # CheckBox: whether the search is regex-based or not
    # LineEdit: value 
    # PushButton: confirmation
    # -------------
    
    def __init__(self, controller):
        super().__init__()
        self.controller = controller
        self.setWindowTitle('Search window')
        self.setMinimumSize(300, 200)
        
        self.subtypes_list = QComboBox()
        self.subtypes_list.addItems(name_to_obj)
        self.subtypes_list.activated.connect(self.update_properties)
        
        self.property_list = QComboBox()
        self.checkbox_regex = QCheckBox('Regex search')
        self.entry_search = QLineEdit()
        
        button_OK = QPushButton()
        button_OK.setText('OK')
        button_OK.clicked.connect(self.search)
        
        # position in the grid
        layout = QGridLayout()
        layout.addWidget(self.subtypes_list, 0, 0, 1, 2)
        layout.addWidget(self.property_list, 1, 0, 1, 2)
        layout.addWidget(self.checkbox_regex, 2, 0, 1, 1)
        layout.addWidget(self.entry_search, 3, 0, 1, 1)
        layout.addWidget(button_OK, 4, 0, 1, 1)
        self.setLayout(layout)
        
        # update property with first value of the list
        self.update_properties()
        
    def update_properties(self):
        subtype = self.subtypes_list.currentText()
        properties = object_properties[name_to_obj[subtype]]
        properties = tuple(p.pretty_name for p in properties)
        self.property_list.clear()
        self.property_list.addItems(properties)
        
    @update_paths
    def search(self, _):
        self.view.scene.clearSelection()
        subtype = name_to_obj[self.subtypes_list.currentText()]
        property = pretty_name_to_class[self.property_list.currentText()]
        type = subtype_to_type[subtype]
        input = self.entry_search.text()
        for obj in self.network.ftr(type, subtype):
            value = getattr(obj, property.name)
            if not self.checkbox_regex.isChecked():
                converted_input = self.network.objectizer(property.name, input)
                if value == converted_input:
                    obj.gobject[self.view].setSelected(True)
            else:
                if re.search(str(input), str(value)):
                    obj.gobject[self.view].setSelected(True)
Exemplo n.º 60
0
class QVisaUnitSelector(QWidget):

	def __init__(self, config):

		# Inherits QWidget
		QWidget.__init__(self)
		self._base = collections.OrderedDict({"G" : 1e9, "M" : 1e6, "k" : 1e3, "": 1, "m" : 1e-3, "u" : 1e-6, "n" : 1e-9 })
			 
		# QVisaUnitSelector configuration dictionary example
		# {
		# 	"unit" 		: "V", 
		# 	"min"		: "u",
		# 	"max"		: "",
		# 	"label"		: "Voltage (V)",
		# 	"limit"		: 1.0, 
		# 	"signed"	: True,
		# 	"default"	: [100, "m"]
		# }
		self.config = config
	
		# If not generating a unitless value _gen_unit_range
		if self.config['unit'] not in ['__INT__', '__DOUBLE__']:
			self._gen_unit_range()
		
		# Generate the widget
		self.setLayout(self._gen_unit_selector())

	# Generate unit range based on user input
	def _gen_unit_range(self): 
	
		# Initialise 
		self._units, _append = {}, False

		# Loop through orderedDict (decending magnitude)
		for _k,_v in list(self._base.items()):
	
			if _k == self.config["max"]: 
				_append = True

			if _k == self.config["min"]:
				self._units[ str(_k) + str( self.config["unit"]) ] = _v
				break	

			if _append:
				self._units[ str(_k) + str( self.config["unit"]) ] = _v

	# Function to update spinbox range on unit maximum
	def _update_unit_selector(self):

		# If we are working with physical units
		if self.unit_select is not None:
	
			# This if is needed so clear() in update does not trigger this method
			if self.unit_select.currentText() != "":

				# Calculate unit limit in updated units
				_limit = ( self.config["limit"][0] * self._base[self.config["limit"][1]] ) / float( self._units[self.unit_select.currentText()] )
				
				# Calculate ratio between previous and current units
				_ratio = float( self._units[ self._selected ] ) / float( self._units[ self.unit_select.currentText() ] )

				# Calculate value in updated units
				_value = self.unit_value.value() * _ratio

				# Taking into account signed/unsigned input set maximum and minimum 
				if self.config["signed"] == True:
					self.unit_value.setMaximum(  1.0 * _limit ) 
					self.unit_value.setMinimum( -1.0 * _limit ) 
					self.unit_value.setValue( _value ) 

				# Set minimum takeing into account signed/unsigned input
				else: 
					self.unit_value.setMaximum(  1.0 * _limit ) 
					self.unit_value.setMinimum(  0.0 )
					self.unit_value.setValue( _value ) 
				
				# Cache new value for next ratio calculation
				self._selected = self.unit_select.currentText()

		# Otherwise ints or doubles		
		else:

			if self.config['unit'] == "__DOUBLE__":

				self.unit_value.setMaximum(self.config["limit"][0] )
				
				if self.config["signed"] == True:
					self.unit_value.setMinimum(self.config["limit"][0] ) 
				else: 
					self.unit_value.setMinimum( 0.0 )

			if self.config['unit'] == "__INT__":

				self.unit_value.setMaximum( int( self.config["limit"][0] ) )
				
				if self.config["signed"] == True:
					self.unit_value.setMinimum( int( self.config["limit"][0] ) )
				else: 
					self.unit_value.setMinimum( 0 )

					
	# Generate unit selector
	def _gen_unit_selector(self):

		# Unit selection box
		self.unit_layout = QHBoxLayout()
		self.unit_layout.setContentsMargins(0,0,0,0)

		# Generate unit box (double value)
		if self.config['unit'] == "__DOUBLE__":

			# Unit select first (see below)
			self.unit_select = None
			self._selected = None

			# Unit value Spinbox
			self.unit_value = QDoubleSpinBox()
			self.unit_value.setDecimals(3)		
			self.unit_value.setSingleStep(0.1)	
			self._update_unit_selector()
			self.unit_value.setValue(self.config["default"][0])
			self.unit_value.setFixedWidth(200)


		# Generate unit box (int value)		
		elif self.config['unit'] == "__INT__":

			# Unit select first (see below)
			self.unit_select = None
			self._selected = None

			# Unit value Spinbox
			self.unit_value = QSpinBox()
			self.unit_value.setFixedWidth(200)
			self.unit_value.setValue(int(self.config["default"][0]))
			self._update_unit_selector() 		# for limits on init

		# General case (physical units)
		else: 

			# Unit selection combobox: needs to be first so self.unit_select 
			# exists on _update_unit_limits call
			self.unit_select = QComboBox()
			self.unit_select.setFixedWidth(80)
			self.unit_select.addItems( list(self._units.keys()) )
			self.unit_select.setCurrentText(self.config["default"][1] + self.config["unit"])
			self.unit_select.currentTextChanged.connect(self._update_unit_selector)

			# Cache current value of base
			self._selected = self.unit_select.currentText()

			# Unit value Spinbox
			self.unit_value = QDoubleSpinBox()
			self.unit_value.setDecimals(3)		
			self.unit_value.setSingleStep(0.1)	
			self._update_unit_selector() 		# for limits on init
			self.unit_value.setValue(self.config["default"][0])
			self.unit_value.setFixedWidth(200)			
	
		# Add widgets to hbox
		self.unit_label=QLabel(self.config["label"]) # Pack this last

		# Pack units			
		self.unit_layout.addWidget(self.unit_value)
		if self.unit_select is not None:
			self.unit_layout.addWidget(self.unit_select)
		self.unit_layout.addWidget(self.unit_label)
		self.unit_layout.setContentsMargins(0,0,0,0)

		# Return layout
		return self.unit_layout

	# Method to re-render widget with new configuration
	def update_config(self, _config):
		
		# Update configuration and generate units
		self.config = _config
		self._gen_unit_range()

		# Clear combobox and add new unit values
		if self.unit_select is not None:
			self.unit_select.clear()
			self.unit_select.addItems( list(self._units.keys()) )

		# Call _update_unit_limits for new limits 
		# (it should be called on add_items)
		self._update_unit_limits()

		# Update default value
		self.unit_value.setValue(self.config["default"][0])
		if self.config["default"] == 2:
			self.unit_select.setCurrentText(self.config["default"][1] + self.config["unit"])

		
		# Set label text
		self.unit_label.setText(self.config["label"])

	# Wrapper for value method
	def value(self):
		
		if self.unit_select is not None: 
			return float( self._units[ self.unit_select.currentText() ] * self.unit_value.value() )
		
		else:
			return self.unit_value.value()

	# Wrapper method for setEnabled 	
	def setEnabled(self, _bool):
		self.unit_value.setEnabled(_bool)
		self.unit_select.setEnabled(_bool)