コード例 #1
0
    def dialogExtract2csv(self):
        d = QDialog(self)
        d.setFixedWidth(450)
        d.setWindowTitle("Extract data to Csv")
        d.setVisible(True)
        vbox = QVBoxLayout()
        tabWidget = QTabWidget()
        for name, mod in list(self.moduleDict.items()):
            wid = QWidget()
            grid = QGridLayout()
            grid.setSpacing(20)
            wid.dateStart = QLineEdit('%s00:00' % dt.datetime.now().strftime("%Y-%m-%dT"))
            wid.dateEnd = QLineEdit("Now")
            grid.addWidget(QLabel("From"), 0, 0)
            grid.addWidget(wid.dateStart, 0, 1)
            grid.addWidget(QLabel("To"), 0, 2)
            grid.addWidget(wid.dateEnd, 0, 3)
            for i, device in enumerate(mod.devices):
                checkbox = QCheckBox(device.deviceLabel)
                checkbox.stateChanged.connect(partial(self.csvUpdateTab, name, checkbox, device))
                checkbox.setCheckState(2)
                grid.addWidget(checkbox, 1 + i, 0, 1, 3)

            wid.setLayout(grid)
            tabWidget.addTab(wid, name)

        buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        buttonBox.button(QDialogButtonBox.Ok).clicked.connect(partial(self.extract2csv, tabWidget, d))
        buttonBox.button(QDialogButtonBox.Cancel).clicked.connect(d.close)

        vbox.addWidget(tabWidget)
        vbox.addWidget(buttonBox)
        d.setLayout(vbox)
コード例 #2
0
class PluginErrorDialog(QDialog):
    """
    Dialog with tabs each tab is a python traceback
    """
    def __init__(self):
        super(PluginErrorDialog, self).__init__()
        self.setWindowTitle(translations.TR_PLUGIN_ERROR_REPORT)
        self.resize(600, 400)
        vbox = QVBoxLayout(self)
        label = QLabel(translations.TR_SOME_PLUGINS_REMOVED)
        vbox.addWidget(label)
        self._tabs = QTabWidget()
        vbox.addWidget(self._tabs)
        hbox = QHBoxLayout()
        btnAccept = QPushButton(translations.TR_ACCEPT)
        btnAccept.setMaximumWidth(100)
        hbox.addWidget(btnAccept)
        vbox.addLayout(hbox)
        #signals
        btnAccept.clicked['bool'].connect(self.close)

    def add_traceback(self, plugin_name, traceback_msg):
        """Add a Traceback to the widget on a new tab"""
        traceback_widget = TracebackWidget(traceback_msg)
        self._tabs.addTab(traceback_widget, plugin_name)
コード例 #3
0
class ViewSourceDialogTabber(QMainWindow):
    def __init__(self, parent=None, title="Source"):
        super(ViewSourceDialogTabber, self).__init__(parent)
        self.setWindowTitle(title)
        self.tabs = QTabWidget(self)
        self.tabs.setElideMode(Qt.ElideRight)
        self.tabs.setTabsClosable(True)
        self.tabs.tabCloseRequested.connect(self.removeTab)
        self.setCentralWidget(self.tabs)
        self.tabs.currentChanged.connect(self.updateWindowTitle)
    def sizeHint(self):
        return QSize(640, 480)
    def removeTab(self):
        self.tabs.removeTab(self.tabs.currentIndex())
    def addTab(self, title="New Tab", data=""):
        vsd = ViewSourceDialog(self, str(title))
        vsd.setPlainText(data)
        self.tabs.addTab(vsd, tr("Source of %s") % (title,))
        self.tabs.setCurrentIndex(self.tabs.count()-1)
        self.raise_()
        self.activateWindow()
    def updateWindowTitle(self):
        try: self.setWindowTitle(tr("Source of %s") % (self.tabs.currentWidget().windowTitle(),))
        except: pass
        if self.tabs.count() == 0:
            self.hide()
コード例 #4
0
class MyTabWidget(QWidget):

    def __init__(self):
        super().__init__()

        # Initialize tab screen
        self.tabs = QTabWidget()
        self.tabs.resize(300, 200)

        tab1 = QWidget()
        tab2 = QWidget()

        # Add tabs
        self.tabs.addTab(tab1, "Tab 1")
        self.tabs.addTab(tab2, "Tab 2")

        # Populate the first tab
        button1 = QPushButton("PyQt5 button")
        tab1_layout = QVBoxLayout()
        tab1_layout.addWidget(button1)
        tab1.setLayout(tab1_layout)

        # Set the layout
        layout = QVBoxLayout()
        layout.addWidget(self.tabs)
        self.setLayout(layout)
コード例 #5
0
ファイル: db-view.py プロジェクト: ASMfreaK/sensorika-robot
class TabDialog(QDialog):
    def __init__(self, parent=None):
        super(TabDialog, self).__init__(parent)

        self.ctx = zmq.Context()
        self.socket = self.ctx.socket(zmq.REQ)

        self.showFullScreen()
        self.tabW = QTabWidget()

        self.Locator = SelectLocator(self)
        self.Session = SelectSession(self)
        self.View = ViewData(self)
        self.tabW.addTab(self.Locator, "Select Locator")
        self.tabW.addTab(self.Session, "Select Session")
        self.tabW.addTab(self.View, "View Data")

        self.tabW.setTabEnabled(1, False)
        self.tabW.setTabEnabled(2, False)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.tabW)
        self.setLayout(mainLayout)

        self.setWindowTitle("Tab Dialog")
コード例 #6
0
ファイル: gw2DailyQt.py プロジェクト: stigmat2033/Python
class dailyTab(QWidget):
    def __init__(self):
        super().__init__()
        # Виджет для дейлков
        # Содержит содержит главный таб виджет для дейликов
        self.tab = QTabWidget()

        self.vbox = QVBoxLayout()
        self.vbox.addWidget(self.tab)
        self.setLayout(self.vbox)

        self.threads = []
        # При ините создаём тред для получения дейликов
        self.loadDataThread = loadDataThread(r'https://api.guildwars2.com/v2/achievements/daily')
        self.loadDataThread.signal.connect(self.getEvent, Qt.QueuedConnection)
        self.loadDataThread.start()

    def getEvent(self, signal):
        signal = json.loads(signal)
        for metaEvent in signal.keys():
            setattr(self,metaEvent,frame())
            self.tab.addTab(getattr(self,metaEvent),metaEvent)
            for event in signal[metaEvent]:
                if (event['level']['max'] == 80 and metaEvent == 'pve') or metaEvent != 'pve':
                    getattr(self,metaEvent).getEvent(event)

    def addTab(self, event, metaEvent):
        getattr(self,'{}Tab'.format(metaEvent)).addEvent(event)

        self.resize(self.grid.sizeHint())
コード例 #7
0
ファイル: configurator.py プロジェクト: np/MadCatz
class T_window(QWidget):
    def __init__(self):
        super().__init__()
        self.tabs = QTabWidget()
        self.com = T_communication()
        self.pbar = QProgressBar()
        self.pbar.setFormat("Battery : %p%")
        self.grid = QGridLayout()

        self.setLayout(self.grid)
        self.grid.addWidget(self.pbar)
        self.grid.addWidget(self.tabs)

        self.dpi = T_dpi()
        self.com.getDpi(self.dpi)
        self.dpi.dataHasBeenSent()
        self.t = []
        for i in range(0, 4):
            self.t.append(T_tab(i, self.dpi, self.com))
            self.tabs.addTab(self.t[i], "Mode " + str(i + 1))

        self.data = T_data(self.pbar, self.tabs, self.dpi, self.com)
        for i in range(0, 4):
            self.t[i].sendButton.clicked.connect(self.data.sendDpi)
            self.t[i].resetButton.clicked.connect(self.com.resetDpi)
        self.timer = QBasicTimer()
        self.timer.start(100, self.data)
        self.tabs.currentChanged.connect(self.com.sendMode)
コード例 #8
0
ファイル: test.py プロジェクト: tanhuacheng/Documents
class MyTableWidget(QWidget):

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

        # Initialize tab screen
        self.tabs = QTabWidget()
        #  self.tabs.tabBar().hide()
        self.tabs.setTabPosition(QTabWidget.West)
        self.tab1 = QWidget()
        self.tab2 = QWidget()
        self.tabs.resize(300,200)

        # Add tabs
        self.tabs.addTab(self.tab1, QIcon('./liveSEC/icones/app.jpg'), "Tab 1")
        self.tabs.addTab(self.tab2,"Tab 2")

        # Create first tab
        self.tab1.layout = QVBoxLayout(self)
        self.pushButton1 = QPushButton("PyQt5 button")
        self.tab1.layout.addWidget(self.pushButton1)
        self.tab1.setLayout(self.tab1.layout)

        # Add tabs to widget
        self.layout.addWidget(self.tabs)
        self.setLayout(self.layout)

    @pyqtSlot()
    def on_click(self):
        print("\n")
        for currentQTableWidgetItem in self.tableWidget.selectedItems():
            print(currentQTableWidgetItem.row(), currentQTableWidgetItem.column(), currentQTableWidgetItem.text())
コード例 #9
0
class TabWidgets(QTabWidget):
    def __init__(self, parent):
        super(TabWidgets, self).__init__(parent)
        self.wdg1 = QWidget(self)
        self.lay_wdg1 = QVBoxLayout(self.wdg1)
        self.wdg2 = QWidget(self)
        self.lay_wdg2 = QVBoxLayout(self.wdg2)
        #self.wdg1.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)
        #self.wdg2.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        self.wdg1.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        self.wdg2.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        
        self._construct_UI()
#------------------------------------------------------------------------------
    def _construct_UI(self):
        """ Initialize UI with tabbed subplots """
        self.tabWidget = QTabWidget(self)
        self.tabWidget.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)
        self.tabWidget.addTab(self.wdg1, 'Wdg 1')
        self.tabWidget.addTab(self.wdg2, 'Wdg 2')

        layVMain = QVBoxLayout()
        layVMain.addWidget(self.tabWidget)
        self.setLayout(layVMain)
        # When user has switched the tab, call self.current_tab_redraw
        print('size wdg1: {0}'.format(self.wdg1.size()))
        print('size wdg2: {0}'.format(self.wdg2.size()))
        self.tabWidget.currentChanged.connect(self.current_tab_redraw)
#------------------------------------------------------------------------------
        
    def current_tab_redraw(self):
        pass
コード例 #10
0
ファイル: gui.py プロジェクト: vikkamath/balls-in-the-air
    def initialize(self):
        tab_widget = QTabWidget()
        tab1 = QWidget()
        tab2 = QWidget()

        juggle_button = QPushButton("Juggle")
        juggle_button.clicked.connect(self.start_simulation)

        hbox = QHBoxLayout()
        hbox.addStretch(1)
        hbox.addWidget(juggle_button)

        vbox = QVBoxLayout(tab1)
        vbox.addStretch(1)
        vbox.addLayout(hbox)

        hbox2 = QHBoxLayout(tab2)

        tab_widget.addTab(tab1, "Main")
        tab_widget.addTab(tab2, "Other")

        self.setCentralWidget(tab_widget)

        menubar = self.menuBar()
        file_menu = menubar.addMenu('&File')
        help_menu = menubar.addMenu('&Help')
        about = help_menu.addMenu('&About')
        exit_action = QAction(QIcon('exit.png'), '&Exit', self)
        exit_action.triggered.connect(qApp.quit)
        file_menu.addAction(exit_action)

        self.setGeometry(300, 300, 350, 300)
        self.setWindowTitle('Juggling Simulator')
        self.show()
コード例 #11
0
ファイル: rosconfigdialog.py プロジェクト: Diegojnb/JdeRobot
class RosConfigDialog(QDialog):
    configChanged = pyqtSignal()

    # use this for editable filtering of message types http://www.qtcentre.org/threads/23143-Combobox-entries-filter-as-I-type

    def __init__(self, name):
        super(QDialog, self).__init__()
        self.setWindowTitle(name)
        self.tabWidget = None

        self.config = None
        self.packageTab = None
        self.topicsTab = None

        self.tabWidget = QTabWidget()
        mainLayout = QFormLayout()
        mainLayout.addWidget(self.tabWidget)
        self.packageTab = PackageTab()
        self.packageTab.configChanged.connect(self.configChangedHandler)
        self.tabWidget.addTab(self.packageTab, 'Package')
        self.topicsTab = TopicsTab()
        self.topicsTab.configChanged.connect(self.configChangedHandler)
        self.tabWidget.addTab(self.topicsTab, 'Topics')
        self.resize(700, 100)
        self.setLayout(mainLayout)

    def setConfig(self, config):
        self.config = config
        self.packageTab.setConfig(self.config)
        self.topicsTab.setConfig(self.config)

    def configChangedHandler(self):
        self.configChanged.emit()
コード例 #12
0
ファイル: about_dlg.py プロジェクト: massdest/onkyoqtpy
 def __init__(self, title, text, image, contributors, parent=None):
     super(AboutDialog, self).__init__(parent)
     layout = QVBoxLayout()
     titleLayout = QHBoxLayout()
     name_versionLabel = QLabel(title)
     contentsLayout = QHBoxLayout()
     aboutBrowser = QTextBrowser()
     aboutBrowser.append(text)
     aboutBrowser.setOpenExternalLinks(True)
     creditsBrowser = QTextBrowser()
     creditsBrowser.append(contributors)
     creditsBrowser.setOpenExternalLinks(True)
     TabWidget = QTabWidget()
     TabWidget.addTab(aboutBrowser, self.tr('About'))
     TabWidget.addTab(creditsBrowser, self.tr('Contributors'))
     aboutBrowser.moveCursor(QTextCursor.Start)
     creditsBrowser.moveCursor(QTextCursor.Start)
     imageLabel = QLabel()
     imageLabel.setPixmap(QPixmap(image))
     titleLayout.addWidget(imageLabel)
     titleLayout.addWidget(name_versionLabel)
     titleLayout.addStretch()
     contentsLayout.addWidget(TabWidget)
     buttonLayout = QHBoxLayout()
     buttonBox = QDialogButtonBox(QDialogButtonBox.Ok)
     buttonLayout.addWidget(buttonBox)
     layout.addLayout(titleLayout)
     layout.addLayout(contentsLayout)
     layout.addLayout(buttonLayout)
     self.setLayout(layout)
     buttonBox.clicked.connect(self.accept)
     self.setMinimumSize(QSize(380, 400))
     self.setWindowTitle(self.tr('About Onkyo QT'))
コード例 #13
0
ファイル: gui.py プロジェクト: nomns/Parse99
class GUI(QDialog):

    def __init__(self, settings):
        super(QDialog, self).__init__()
        self.setWindowTitle("Settings")
        self.setWindowIcon(QIcon('ui/icon.png'))
        self.setModal(True)
        self.setWindowFlags(Qt.WindowStaysOnTopHint)

        self._button_box = QDialogButtonBox(
            QDialogButtonBox.Ok
        )
        self._button_box.button(QDialogButtonBox.Ok).clicked.connect(self.accept)

        self._tabs = QTabWidget()

        self._layout = QBoxLayout(QBoxLayout.TopToBottom)
        self._layout.addWidget(self._tabs)
        self._layout.addWidget(self._button_box)

        self.setLayout(self._layout)

        # setup tabs
        self.tab_list = {}
        self.widgets = {}

        # general tab
        general_tab = GeneralTab(settings)
        self._tabs.addTab(general_tab, general_tab.get_title())
        characters_tab = CharactersTab(settings)
        self._tabs.addTab(characters_tab, characters_tab.get_title())

    def set_show_tab(self, tab):
        if tab == "characters":
            self._tabs.setCurrentIndex(1)
コード例 #14
0
class class_config_window(QWidget):


	def init(self):
		self.setFixedSize(900, 600)
		self.setWindowIcon(QIcon(os.path.join(get_image_file_path(),"cog.png")))

		self.setWindowTitle(_("Configure (www.gpvdm.com)")) 
		

		self.main_vbox = QVBoxLayout()

		toolbar=QToolBar()
		toolbar.setIconSize(QSize(48, 48))

		spacer = QWidget()
		spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
		toolbar.addWidget(spacer)


		self.undo = QAction(QIcon(os.path.join(get_image_file_path(),"help.png")), 'Hide', self)
		self.undo.setStatusTip(_("Close"))
		self.undo.triggered.connect(self.callback_help)
		toolbar.addAction(self.undo)

		self.main_vbox.addWidget(toolbar)

		

		self.notebook = QTabWidget()

		self.notebook.setMovable(True)

		self.main_vbox.addWidget(self.notebook)

		files=["math.inp","dump.inp","thermal.inp","led.inp","config.inp"]
		description=["Math","Dump","Thermal","LED","GUI  config"]

		for i in range(0,len(files)):
			tab=tab_class()
			tab.init(files[i],description[i])
			self.notebook.addTab(tab,description[i])


		self.setLayout(self.main_vbox)
		self.win_list=windows()
		self.win_list.load()
		self.win_list.set_window(self,"config_window")

		#self.connect("delete-event", self.callback_close_window) 

		#self.hide()

	def callback_help(self,widget):
		webbrowser.open('http://www.gpvdm.com/man/index.html')

	def closeEvent(self, event):
		self.win_list.update(self,"config_window")
コード例 #15
0
ファイル: pulppy.py プロジェクト: bruino/pulppy
class AboutDialog(QDialog):
    def __init__(self, parent=None):
        super(AboutDialog, self).__init__(parent)
        self.create()
        
        title = QLabel()
        title.setText('Pulppy Software\nLinear Programming Software')
        title.setAlignment(Qt.AlignLeft)
        title.setStyleSheet("font-weight: bold")
        
        icon = QLabel()
        imagen = QPixmap('pulppy.ico')
        icon.setPixmap(imagen)
        
        topLayout = QHBoxLayout()
        topLayout.addWidget(icon)
        topLayout.addWidget(title)
        mainLayout = QVBoxLayout()
        mainLayout.addLayout(topLayout)
        mainLayout.addWidget(self.tabWidget)

        self.setLayout(mainLayout)
        self.setGeometry(500, 200, 350, 250)
        self.setWindowTitle('About')
        self.setWindowIcon(QIcon('pulppy.ico'))

    def create(self):
        self.tabWidget = QTabWidget()

        tab1 = QWidget()
        labelDescription = QLabel()
        labelDescription.setText("Linear Programming Software for optimizing\n"
                              "various practical problems of Operations Research.\n"
                              "\n"
                              "Repository:\n"
                              "https://github.com/bruino/pulppy\n")
        tab1hbox = QHBoxLayout()
        tab1hbox.addWidget(labelDescription)
        tab1.setLayout(tab1hbox)

        tab2 = QWidget()        
        labelAutors = QLabel()
        labelAutors.setText("+ Danert, Maldonado Jessica\n"
                              "+ Gutierrez, Mariano\n"
                              "+ Moreno, Victor Ricardo\n"
                              "+ Sarverry, Bruno Alejandro\n")
        tab2hbox = QHBoxLayout()
        tab2hbox.setContentsMargins(5, 5, 5, 5)
        tab2hbox.addWidget(labelAutors)
        tab2.setLayout(tab2hbox)

        self.tabWidget.addTab(tab1, "&About")
        self.tabWidget.addTab(tab2, "&Autors")
コード例 #16
0
ファイル: controller.py プロジェクト: duniter/sakia
    async def search_and_show_pubkey(cls, parent, app, pubkey):
        dialog = QDialog(parent)
        dialog.setWindowTitle("Informations")
        layout = QVBoxLayout(dialog)
        tabwidget = QTabWidget(dialog)
        layout.addWidget(tabwidget)

        identities = await app.identities_service.lookup(pubkey)
        for i in identities:
            user_info = cls.create(parent, app, i)
            user_info.refresh()
            tabwidget.addTab(user_info.view, i.uid)
        return await dialog_async_exec(dialog)
コード例 #17
0
ファイル: graphics.py プロジェクト: JulienRouse/ClassManager
    def __init__(self, parent=None):
        super(FenetreCentrale,
              self).__init__(parent)

        tabWidget = QTabWidget()
        tabWidget.addTab(ModaliteEvaluation(),"Modalite d'evaluation")
        tabWidget.addTab(GestionEleve(),"Gestion des eleves")
        #tabWidget.addTab(Essai(),"Lolilol")

        layout = QVBoxLayout()
        layout.addWidget(tabWidget)
        
        self.setLayout(layout)
コード例 #18
0
class CueSettings(QDialog):

    on_apply = QtCore.pyqtSignal(dict)

    def __init__(self, widgets=[], cue=None, check=False, **kwargs):
        super().__init__(**kwargs)

        conf = {}

        if(cue is not None):
            conf = deepcopy(cue.properties())
            self.setWindowTitle(conf['name'])

        self.setWindowModality(QtCore.Qt.ApplicationModal)
        self.setMaximumSize(635, 530)
        self.setMinimumSize(635, 530)
        self.resize(635, 530)

        self.sections = QTabWidget(self)
        self.sections.setGeometry(QtCore.QRect(5, 10, 625, 470))

        wsize = QtCore.QSize(625, 470 - self.sections.tabBar().height())

        for widget in widgets:
            widget = widget(wsize, cue)
            widget.set_configuration(conf)
            widget.enable_check(check)
            self.sections.addTab(widget, widget.Name)

        self.dialogButtons = QDialogButtonBox(self)
        self.dialogButtons.setGeometry(10, 490, 615, 30)
        self.dialogButtons.setStandardButtons(QDialogButtonBox.Cancel |
                                              QDialogButtonBox.Ok |
                                              QDialogButtonBox.Apply)

        self.dialogButtons.rejected.connect(self.reject)
        self.dialogButtons.accepted.connect(self.accept)
        apply = self.dialogButtons.button(QDialogButtonBox.Apply)
        apply.clicked.connect(self.apply)

    def accept(self):
        self.apply()
        super().accept()

    def apply(self):
        new_conf = {}

        for n in range(self.sections.count()):
            deep_update(new_conf, self.sections.widget(n).get_configuration())

        self.on_apply.emit(new_conf)
コード例 #19
0
ファイル: gw2DailyQt.py プロジェクト: stigmat2033/Python
class mainWindow(QWidget):
    def __init__(self):
        super().__init__()
        # Виджет для главного таб виджета
        # Содержит вкладки для дейликов и т.д.
        self.vbox = QVBoxLayout()

        self.dailyTab = dailyTab()

        self.tab = QTabWidget()
        self.tab.addTab(self.dailyTab,'Daily events')

        self.vbox.addWidget(self.tab)
        self.setLayout(self.vbox)
コード例 #20
0
ファイル: app.py プロジェクト: mistotebe/visualise_ledger
    def __init__(self):
        super(Window, self).__init__()
        self.setWindowTitle("Ledger visualizer")

        # Create a layout Object, attached to the window.
        layout = QVBoxLayout(self)

        self.options = Options(self)
        layout.addWidget(self.options)

        tabs = QTabWidget()
        layout.addWidget(tabs)

        graph = GraphTab(self.options)
        tabs.addTab(graph, "Time series")

        graph = AccountTab(self.options)
        tabs.addTab(graph, "Account breakdown")

        graph = BarTab(self.options)
        tabs.addTab(graph, "Timed breakdown")

        text = PieTab(self.options)
        tabs.addTab(text, "Pie charts")

        button = QPushButton("Quit", self)
        layout.addWidget(button)

        button.clicked.connect(app.quit)
コード例 #21
0
ファイル: view.py プロジェクト: duniter/sakia
 def show_about_referentials(self, referentials):
     dialog = QDialog(self)
     layout = QVBoxLayout(dialog)
     tabwidget = QTabWidget(dialog)
     layout.addWidget(tabwidget)
     for ref in referentials:
         widget = QWidget()
         layout = QVBoxLayout(widget)
         label = QLabel()
         label.setText(self.text_referential(ref))
         layout.addWidget(label)
         tabwidget.addTab(widget, ref.translated_name())
     dialog.setWindowTitle(self.tr("Referentials"))
     dialog.exec()
コード例 #22
0
class WritePanel(SubWindow, WindowSystemController):

    '''
    'Write' main panel. Detachable
    '''

    def __init__(self, parent=None, parent_window_system_controller=None):
        '''

        '''
        super(WritePanel, self).__init__(
            parent=parent, parent_window_system_controller=parent_window_system_controller)

        self.setWindowTitle(_("Write"))
        self.setObjectName("write_sub_window")
        self.dock_system = DockSystem(
            self, self,  DockSystem.DockTypes.WritePanelDock)

        # connect core signal to open sheets :
        cfg.core.tree_sheet_manager.sheet_is_opening.connect(
            self.open_write_tab)

        # Project tree view dock :
        self.dock_system.add_dock("write-tree-dock",  Qt.LeftDockWidgetArea)

        # set TabWidget:
        self.tab_widget = QTabWidget(self)
        self.setCentralWidget(self.tab_widget)

        # subscribe
        cfg.core.subscriber.subscribe_update_func_to_domain(
            self._clear_project,  "core.project.close")

    def open_write_tab(self, tree_sheet):

        new_write_tab = WriteTab(self, self)
        new_write_tab.tree_sheet = tree_sheet
        self.tab_widget.addTab(new_write_tab, new_write_tab.tab_title)
        # temp for test:
        new_write_tab.dock_system.add_dock("properties-dock")

    def _clear_project(self):
        # TODO: make that cleaner
        for i in range(0, self.tab_widget.count()):
            widget = self.tab_widget.widget(i)
            widget.close()
            widget.deleteLater()
        self.tab_widget.clear()
コード例 #23
0
ファイル: pl_main.py プロジェクト: roderickmackenzie/gpvdm
class pl_main(QWidget,tab_base):

	lines=[]
	edit_list=[]
	file_name=""
	line_number=[]
	save_file_name=""
	name="Luminescence"


	def __init__(self):
		QWidget.__init__(self)
		self.main_vbox = QVBoxLayout()
		self.notebook = QTabWidget()

		self.main_vbox.addWidget(self.notebook)
		self.setLayout(self.main_vbox)

		self.notebook.setTabsClosable(True)
		self.notebook.setMovable(True)
		bar=QHTabBar()
		bar.setStyleSheet("QTabBar::tab { height: 35px; width: 200px; }")
		self.notebook.setTabBar(bar)
		self.notebook.setTabPosition(QTabWidget.West)



	def update(self):
		self.notebook.clear()

		files=epitaxy_get_dos_files()
		for i in range(0,epitaxy_get_layers()):
			pl_file=epitaxy_get_pl_file(i)
			if pl_file.startswith("pl")==True:
				widget	= QWidget()
 
				name="Luminescence of "+epitaxy_get_name(i)
				print(pl_file,files)

				widget=tab_class()
				widget.init(pl_file+".inp",name)

				self.notebook.addTab(widget,name)


	def help(self):
		help_window().help_set_help(["tab.png","<big><b>Luminescence</b></big>\nIf you set 'Turn on luminescence' to true, the simulation will assume recombination is a raditave process and intergrate it to produce Voltage-Light intensity curves (lv.dat).  Each number in the tab tells the model how efficient each recombination mechanism is at producing photons."])
コード例 #24
0
ファイル: 10_tab_test.py プロジェクト: nnaabbcc/exercise
    def __init__(self, parent):
        super(QWidget, self).__init__(parent)

        tabs = QTabWidget()
        tab1 = QWidget()
        tab2 = QWidget()

        tabs.addTab(tab1, 'Tab 1')
        tabs.addTab(tab2, 'Tab 2')

        tab1_layout = QVBoxLayout()
        button = QPushButton('Button')
        tab1_layout.addWidget(button)
        tab1.setLayout(tab1_layout)

        main_layout = QVBoxLayout()
        main_layout.addWidget(tabs)
        self.setLayout(main_layout)
コード例 #25
0
ファイル: about.py プロジェクト: 19joho66/frescobaldi
    def __init__(self, mainwindow):
        """Creates the about dialog. You can simply exec_() it."""
        super(AboutDialog, self).__init__(mainwindow)

        self.setWindowTitle(_("About {appname}").format(appname = appinfo.appname))
        layout = QVBoxLayout()
        self.setLayout(layout)

        tabw = QTabWidget()
        layout.addWidget(tabw)

        tabw.addTab(About(self), _("About"))
        tabw.addTab(Credits(self), _("Credits"))
        tabw.addTab(Version(self), _("Version"))

        button = QDialogButtonBox(QDialogButtonBox.Ok)
        button.setCenterButtons(True)
        button.accepted.connect(self.accept)
        layout.addWidget(button)
        layout.setSizeConstraint(QLayout.SetFixedSize)
コード例 #26
0
ファイル: information.py プロジェクト: mandeepbhutani/Mosaic
    def __init__(self, file=None, parent=None):
        """Initialize QTabWidget with tabs for each metadata page."""
        super(InformationDialog, self).__init__(parent)
        self.setWindowTitle('Media Information')

        info_icon = utilities.resource_filename('mosaic.images', 'md_info.png')
        self.setWindowIcon(QIcon(info_icon))
        self.setFixedSize(600, 600)

        media_information = GeneralInformation(file)
        metadata_information = FullInformation(file)

        page = QTabWidget()
        page.addTab(media_information, 'General')
        page.addTab(metadata_information, 'Metadata')

        dialog_layout = QHBoxLayout()
        dialog_layout.addWidget(page)

        self.setLayout(dialog_layout)
コード例 #27
0
ファイル: application.py プロジェクト: papajoker/pacmanInfo
    def __init__(self, repo, parent=None):
        super().__init__(parent)

        fileInfo = QFileInfo(repo.fileName)

        tabWidget = QTabWidget()
        
        tabWidget.addTab(repoTab(repo),         _("Repo"))
        tabWidget.addTab(ApplicationsTab(repo), _("Files"))
        tabWidget.addTab(GeneralTab(fileInfo),  _("File"))
        
        buttonBox = QDialogButtonBox(QDialogButtonBox.Ok)

        buttonBox.accepted.connect(self.accept)
        buttonBox.rejected.connect(self.reject)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(tabWidget)
        
        '''
        key=RepoAttributes.URL.value
        if (key in repo.items):
            self.url=repo.items[key]
            self.urlbtn = QCommandLinkButton( self.url)
            self.urlbtn.clicked.connect(self.OnUrlMessage)
            #mainLayout.addWidget(self.urlbtn)
        '''
        
        mainLayout.addWidget(buttonBox)
        self.setLayout(mainLayout)

        self.setWindowTitle(repo.name)
コード例 #28
0
ファイル: HTML.py プロジェクト: olivierkes/manuskript
    def previewWidget(self):
        t = QTabWidget()
        t.setDocumentMode(True)
        t.setStyleSheet("""
            QTabBar::tab{
                background-color: #BBB;
                padding: 3px 25px;
                border: none;
            }

            QTabBar::tab:selected, QTabBar::tab:hover{
                background-color:skyblue;
            }
        """)
        w0 = QPlainTextEdit()
        w0.setFrameShape(QFrame.NoFrame)
        w0.setReadOnly(True)
        w1 = QPlainTextEdit()
        w1.setFrameShape(QFrame.NoFrame)
        w1.setReadOnly(True)
        t.addTab(w0, qApp.translate("Export", "Markdown source"))
        t.addTab(w1, qApp.translate("Export", "HTML Source"))
        
        if webView:
            w2 = webView()
            t.addTab(w2, qApp.translate("Export", "HTML Output"))

        t.setCurrentIndex(2)
        return t
コード例 #29
0
ファイル: misc_db.py プロジェクト: darmstard/happypanda
	def __init__(self, parent, window=False):
		if window:
			super().__init__(None, Qt.Window)
		else:
			super().__init__(parent)
		self.setAttribute(Qt.WA_DeleteOnClose)
		self.parent_widget = parent
		main_layout = QVBoxLayout(self)
		tabbar = QTabWidget(self)
		main_layout.addWidget(tabbar)

		# Tags tree
		self.tags_tree = TagsTreeView(parent=self, app_window=self.parent_widget)
		self.tags_tree.setHeaderHidden(True)
		tabbar.addTab(self.tags_tree, 'Namespace && Tags')
		self.tags_layout = QVBoxLayout(self.tags_tree)
		if parent.manga_list_view.gallery_model.db_emitter._finished:
			self.setup_tags()
		else:
			parent.manga_list_view.gallery_model.db_emitter.DONE.connect(self.setup_tags)
		
		# Tags stats
		self.tags_stats = QListWidget(self)
		tabbar.addTab(self.tags_stats, 'Statistics')
		tabbar.setTabEnabled(1, False)

		# About AD
		self.about_db = QWidget(self)
		tabbar.addTab(self.about_db, 'DB Info')
		tabbar.setTabEnabled(2, False)

		self.resize(300, 600)
		self.setWindowTitle('DB Overview')
		self.setWindowIcon(QIcon(app_constants.APP_ICO_PATH))
コード例 #30
0
ファイル: window_ui.py プロジェクト: xsyann/mediocre
    def setupUI(self):
        """Create User Interface.
        """
        mainWidget = QWidget()
        mainLayout = QHBoxLayout()

        tabs = QTabWidget()
        self.classes_tree_view = ClassesTreeView(self)
        tabs.addTab(self.widgetDataset(), self.tr("Dataset"))
        tabs.addTab(self.widgetTraining(), self.tr("Training"))
        tabs.addTab(self.widgetRecognition(), self.tr("Recognition"))

        leftLayout, rightLayout = QHBoxLayout(), QHBoxLayout()
        leftLayout.addWidget(self.classes_tree_view)
        rightLayout.addWidget(tabs)
        left, right = QWidget(), QWidget()
        left.setLayout(leftLayout)
        right.setLayout(rightLayout)
        self.hsplitter = QSplitter(QtCore.Qt.Horizontal)
        self.hsplitter.addWidget(left)
        self.hsplitter.addWidget(right)
        self.hsplitter.setStretchFactor(1, 3)

        mainLayout.addWidget(self.hsplitter)
        mainWidget.setLayout(mainLayout)
        self.setCentralWidget(mainWidget)
コード例 #31
0
ファイル: app.py プロジェクト: kerketta/Dwarf
class AppWindow(QMainWindow):
    onRestart = pyqtSignal(name='onRestart')

    def __init__(self, dwarf_args, flags=None):
        super(AppWindow, self).__init__(flags)

        self.dwarf_args = dwarf_args

        self.session_manager = SessionManager(self)
        self.session_manager.sessionCreated.connect(self.session_created)
        self.session_manager.sessionStopped.connect(self.session_stopped)
        self.session_manager.sessionClosed.connect(self.session_closed)

        self._tab_order = [
            'memory', 'modules', 'ranges', 'jvm-inspector', 'jvm-debugger'
        ]

        self.menu = self.menuBar()
        self._is_newer_dwarf = False
        self.view_menu = None

        #dockwidgets
        self.watchers_dwidget = None
        self.hooks_dwiget = None
        self.bookmarks_dwiget = None
        self.registers_dock = None
        self.console_dock = None
        self.backtrace_dock = None
        self.threads_dock = None
        #panels
        self.asm_panel = None
        self.console_panel = None
        self.context_panel = None
        self.backtrace_panel = None
        self.contexts_list_panel = None
        self.data_panel = None
        self.emulator_panel = None
        self.ftrace_panel = None
        self.hooks_panel = None
        self.bookmarks_panel = None
        self.smali_panel = None
        self.java_inspector_panel = None
        self.java_explorer_panel = None
        self.java_trace_panel = None
        self.memory_panel = None
        self.modules_panel = None
        self.ranges_panel = None
        self.search_panel = None
        self.trace_panel = None
        self.watchers_panel = None
        self.welcome_window = None

        self._ui_elems = []

        self.setWindowTitle(
            'Dwarf - A debugger for reverse engineers, crackers and security analyst'
        )

        # load external assets
        _app = QApplication.instance()

        self.remove_tmp_dir()

        # themes
        self.prefs = Prefs()
        self.set_theme(self.prefs.get('dwarf_ui_theme', 'black'))

        # load font
        if os.path.exists(utils.resource_path('assets/Anton.ttf')):
            QFontDatabase.addApplicationFont(
                utils.resource_path('assets/Anton.ttf'))
        if os.path.exists(utils.resource_path('assets/OpenSans-Regular.ttf')):
            QFontDatabase.addApplicationFont(
                utils.resource_path('assets/OpenSans-Regular.ttf'))
            _app.setFont(QFont("OpenSans", 9, QFont.Normal))
            if os.path.exists(utils.resource_path('assets/OpenSans-Bold.ttf')):
                QFontDatabase.addApplicationFont(
                    utils.resource_path('assets/OpenSans-Bold.ttf'))

        # mainwindow statusbar
        self.progressbar = QProgressBar()
        self.progressbar.setRange(0, 0)
        self.progressbar.setVisible(False)
        self.progressbar.setFixedHeight(15)
        self.progressbar.setFixedWidth(100)
        self.progressbar.setTextVisible(False)
        self.progressbar.setValue(30)
        self.statusbar = QStatusBar(self)
        self.statusbar.setAutoFillBackground(False)
        self.statusbar.addPermanentWidget(self.progressbar)
        self.statusbar.setObjectName("statusbar")
        self.setStatusBar(self.statusbar)

        self.main_tabs = QTabWidget(self)
        self.main_tabs.setMovable(False)
        self.main_tabs.setTabsClosable(True)
        self.main_tabs.setAutoFillBackground(True)
        self.main_tabs.tabCloseRequested.connect(self._on_close_tab)
        self.setCentralWidget(self.main_tabs)

        if self.dwarf_args.package is None:
            self.welcome_window = WelcomeDialog(self)
            self.welcome_window.setModal(True)
            self.welcome_window.onIsNewerVersion.connect(
                self._enable_update_menu)
            self.welcome_window.onUpdateComplete.connect(
                self._on_dwarf_updated)
            self.welcome_window.setWindowTitle(
                'Welcome to Dwarf - A debugger for reverse engineers, crackers and security analyst'
            )
            self.welcome_window.onSessionSelected.connect(self._start_session)
            self.welcome_window.onSessionRestore.connect(self._restore_session)
            # wait for welcome screen
            self.hide()
            self.welcome_window.show()
        else:
            if dwarf_args.package is not None:
                if dwarf_args.type is None:
                    # no device given check if package is local path
                    if os.path.exists(dwarf_args.package):
                        print('* Starting new LocalSession')
                        self._start_session('local')
                    else:
                        print('use -t to set sessiontype')
                        exit(0)
                else:
                    print('* Starting new Session')
                    self._start_session(dwarf_args.type)

    def _setup_main_menu(self):
        self.menu = self.menuBar()
        dwarf_menu = QMenu('Dwarf', self)
        theme = QMenu('Theme', dwarf_menu)
        theme.addAction('Black')
        theme.addAction('Dark')
        theme.addAction('Light')
        theme.triggered.connect(self._set_theme)
        dwarf_menu.addMenu(theme)
        dwarf_menu.addSeparator()
        if self._is_newer_dwarf:
            dwarf_menu.addAction('Update', self._update_dwarf)
        dwarf_menu.addAction('Close', self.session_manager.session.stop)
        self.menu.addMenu(dwarf_menu)

        session = self.session_manager.session
        if session is not None:
            session_menu = session.main_menu
            if isinstance(session_menu, list):
                for menu in session_menu:
                    self.menu.addMenu(menu)
            else:
                self.menu.addMenu(session_menu)

        self.view_menu = QMenu('View', self)
        subview_menu = QMenu('Subview', self.view_menu)
        subview_menu.addAction('Search',
                               lambda: self.show_main_tab('search'),
                               shortcut=QKeySequence(Qt.CTRL + Qt.Key_F3))
        subview_menu.addAction('Emulator',
                               lambda: self.show_main_tab('emulator'),
                               shortcut=QKeySequence(Qt.CTRL + Qt.Key_F2))
        subview_menu.addAction('Disassembly',
                               lambda: self.show_main_tab('disassembly'),
                               shortcut=QKeySequence(Qt.CTRL + Qt.Key_F5))
        self.view_menu.addMenu(subview_menu)
        self.view_menu.addSeparator()
        self.menu.addMenu(self.view_menu)

        if self.dwarf_args.debug_script:
            debug_menu = QMenu('Debug', self)
            debug_menu.addAction('Reload core', self._menu_reload_core)
            debug_menu.addAction('Debug dwarf js core',
                                 self._menu_debug_dwarf_js)
            self.menu.addMenu(debug_menu)

        about_menu = QMenu('About', self)
        about_menu.addAction('Dwarf on GitHub', self._menu_github)
        about_menu.addAction('Documention', self._menu_documentation)
        about_menu.addAction('Api', self._menu_api)
        about_menu.addAction('Slack', self._menu_slack)
        about_menu.addSeparator()
        about_menu.addAction('Info', self._show_about_dlg)
        self.menu.addMenu(about_menu)

    def _enable_update_menu(self):
        self._is_newer_dwarf = True

    def _update_dwarf(self):
        if self.welcome_window:
            self.welcome_window._update_dwarf()

    def _on_close_tab(self, index):
        tab_text = self.main_tabs.tabText(index)
        if tab_text:
            if tab_text.lower() in self.session_manager.session.non_closable:
                return
            try:
                self._ui_elems.remove(tab_text.lower())
            except ValueError:  # recheck ValueError: list.remove(x): x not in list
                pass
            self.main_tabs.removeTab(index)

    def _handle_tab_change(self):
        for index in range(self.main_tabs.count()):
            tab_name = self.main_tabs.tabText(index).lower().replace(' ', '-')
            if tab_name in self.session_manager.session.non_closable:
                self.main_tabs.tabBar().setTabButton(index, QTabBar.RightSide,
                                                     None)

                if tab_name in self._tab_order:
                    should_index = self._tab_order.index(tab_name)
                    if index != should_index:
                        self.main_tabs.tabBar().moveTab(index, should_index)

    def _on_dwarf_updated(self):
        self.onRestart.emit()

    def remove_tmp_dir(self):
        if os.path.exists('.tmp'):
            shutil.rmtree('.tmp', ignore_errors=True)

    def _set_theme(self, qaction):
        if qaction:
            self.set_theme(qaction.text())

    def _menu_reload_core(self):
        self.dwarf.load_script()

    def _menu_debug_dwarf_js(self):
        you_know_what_to_do = json.loads(
            self.dwarf._script.exports.debugdwarfjs())
        return you_know_what_to_do

    def show_main_tab(self, name):
        # elem doesnt exists? create it
        if name not in self._ui_elems:
            self._create_ui_elem(name)

        index = 0
        name = name.join(name.split()).lower()
        if name == 'memory':
            index = self.main_tabs.indexOf(self.memory_panel)
        elif name == 'ranges':
            index = self.main_tabs.indexOf(self.ranges_panel)
        elif name == 'search':
            index = self.main_tabs.indexOf(self.search_panel)
        elif name == 'modules':
            index = self.main_tabs.indexOf(self.modules_panel)
        elif name == 'disassembly':
            index = self.main_tabs.indexOf(self.asm_panel)
        elif name == 'trace':
            index = self.main_tabs.indexOf(self.trace_panel)
        elif name == 'data':
            index = self.main_tabs.indexOf(self.data_panel)
        elif name == 'emulator':
            index = self.main_tabs.indexOf(self.emulator_panel)
        elif name == 'java-trace':
            index = self.main_tabs.indexOf(self.java_trace_panel)
        elif name == 'jvm-inspector':
            index = self.main_tabs.indexOf(self.java_inspector_panel)
        elif name == 'jvm-debugger':
            index = self.main_tabs.indexOf(self.java_explorer_panel)
        elif name == 'smali':
            index = self.main_tabs.indexOf(self.smali_panel)

        self.main_tabs.setCurrentIndex(index)

    def jump_to_address(self, ptr, show_panel=True):
        if self.memory_panel is not None:
            if show_panel:
                self.show_main_tab('memory')
            self.memory_panel.read_memory(ptr)

    @pyqtSlot(name='mainMenuGitHub')
    def _menu_github(self):
        QDesktopServices.openUrl(QUrl('https://github.com/iGio90/Dwarf'))

    @pyqtSlot(name='mainMenuDocumentation')
    def _menu_api(self):
        QDesktopServices.openUrl(QUrl('https://igio90.github.io/Dwarf/'))

    @pyqtSlot(name='mainMenuApi')
    def _menu_documentation(self):
        QDesktopServices.openUrl(QUrl('https://igio90.github.io/Dwarf/api'))

    @pyqtSlot(name='mainMenuSlack')
    def _menu_slack(self):
        QDesktopServices.openUrl(
            QUrl('https://join.slack.com/t/resecret/shared_invite'
                 '/enQtMzc1NTg4MzE3NjA1LTlkNzYxNTIwYTc2ZTYyOWY1MT'
                 'Q1NzBiN2ZhYjQwYmY0ZmRhODQ0NDE3NmRmZjFiMmE1MDYwN'
                 'WJlNDVjZDcwNGE'))

    def _show_about_dlg(self):
        about_dlg = AboutDialog(self)
        about_dlg.show()

    def _create_ui_elem(self, elem):
        if not isinstance(elem, str):
            return

        if elem not in self._ui_elems:
            self._ui_elems.append(elem)

        if elem == 'watchers':
            from ui.panel_watchers import WatchersPanel
            self.watchers_dwidget = QDockWidget('Watchers', self)
            self.watchers_panel = WatchersPanel(self)
            # dont respond to dblclick mem cant be shown
            # self.watchers_panel.onItemDoubleClicked.connect(
            #    self._on_watcher_clicked)
            self.watchers_panel.onItemRemoved.connect(
                self._on_watcher_removeditem)
            self.watchers_panel.onItemAdded.connect(self._on_watcher_added)
            self.watchers_dwidget.setWidget(self.watchers_panel)
            self.watchers_dwidget.setObjectName('WatchersPanel')
            self.addDockWidget(Qt.LeftDockWidgetArea, self.watchers_dwidget)
            self.view_menu.addAction(self.watchers_dwidget.toggleViewAction())
        elif elem == 'hooks':
            from ui.panel_hooks import HooksPanel
            self.hooks_dwiget = QDockWidget('Breakpoints', self)
            self.hooks_panel = HooksPanel(self)
            self.hooks_panel.onShowMemoryRequest.connect(
                self._on_watcher_clicked)
            self.hooks_panel.onHookRemoved.connect(self._on_hook_removed)
            self.hooks_dwiget.setWidget(self.hooks_panel)
            self.hooks_dwiget.setObjectName('HooksPanel')
            self.addDockWidget(Qt.LeftDockWidgetArea, self.hooks_dwiget)
            self.view_menu.addAction(self.hooks_dwiget.toggleViewAction())
        elif elem == 'bookmarks':
            from ui.panel_bookmarks import BookmarksPanel
            self.bookmarks_dwiget = QDockWidget('Boomarks', self)
            self.bookmarks_panel = BookmarksPanel(self)
            self.bookmarks_panel.onShowMemoryRequest.connect(
                self._on_watcher_clicked)
            self.bookmarks_dwiget.setWidget(self.bookmarks_panel)
            self.bookmarks_dwiget.setObjectName('BookmarksPanel')
            self.addDockWidget(Qt.LeftDockWidgetArea, self.bookmarks_dwiget)
            self.view_menu.addAction(self.bookmarks_dwiget.toggleViewAction())
        elif elem == 'registers':
            from ui.panel_context import ContextPanel
            self.registers_dock = QDockWidget('Context', self)
            self.context_panel = ContextPanel(self)
            self.registers_dock.setWidget(self.context_panel)
            self.registers_dock.setObjectName('ContextsPanel')
            self.addDockWidget(Qt.RightDockWidgetArea, self.registers_dock)
            self.view_menu.addAction(self.registers_dock.toggleViewAction())
        elif elem == 'memory':
            from ui.panel_memory import MemoryPanel
            self.memory_panel = MemoryPanel(self)
            self.memory_panel.onShowDisassembly.connect(
                self._disassemble_range)
            self.memory_panel.dataChanged.connect(self._on_memory_modified)
            self.memory_panel.statusChanged.connect(self.set_status_text)
            self.main_tabs.addTab(self.memory_panel, 'Memory')
        elif elem == 'jvm-debugger':
            from ui.panel_java_explorer import JavaExplorerPanel
            self.java_explorer_panel = JavaExplorerPanel(self)
            self.main_tabs.addTab(self.java_explorer_panel, 'JVM debugger')
            self.main_tabs.tabBar().moveTab(
                self.main_tabs.indexOf(self.java_explorer_panel), 1)
        elif elem == 'jvm-inspector':
            from ui.panel_java_inspector import JavaInspector
            self.java_inspector_panel = JavaInspector(self)
            self.main_tabs.addTab(self.java_inspector_panel, 'JVM inspector')
        elif elem == 'console':
            from ui.panel_console import ConsolePanel
            self.console_dock = QDockWidget('Console', self)
            self.console_panel = ConsolePanel(self)
            self.dwarf.onLogToConsole.connect(self._log_js_output)
            self.console_dock.setWidget(self.console_panel)
            self.console_dock.setObjectName('ConsolePanel')
            self.addDockWidget(Qt.BottomDockWidgetArea, self.console_dock)
            self.view_menu.addAction(self.console_dock.toggleViewAction())
        elif elem == 'backtrace':
            from ui.panel_backtrace import BacktracePanel
            self.backtrace_dock = QDockWidget('Backtrace', self)
            self.backtrace_panel = BacktracePanel(self)
            self.backtrace_dock.setWidget(self.backtrace_panel)
            self.backtrace_dock.setObjectName('BacktracePanel')
            self.backtrace_panel.onShowMemoryRequest.connect(
                self._on_watcher_clicked)
            self.addDockWidget(Qt.RightDockWidgetArea, self.backtrace_dock)
            self.view_menu.addAction(self.backtrace_dock.toggleViewAction())
        elif elem == 'threads':
            from ui.panel_contexts_list import ContextsListPanel
            self.threads_dock = QDockWidget('Threads', self)
            self.contexts_list_panel = ContextsListPanel(self)
            self.dwarf.onThreadResumed.connect(
                self.contexts_list_panel.resume_tid)
            self.contexts_list_panel.onItemDoubleClicked.connect(
                self._manually_apply_context)
            self.threads_dock.setWidget(self.contexts_list_panel)
            self.threads_dock.setObjectName('ThreadPanel')
            self.addDockWidget(Qt.RightDockWidgetArea, self.threads_dock)
            self.view_menu.addAction(self.threads_dock.toggleViewAction())
        elif elem == 'modules':
            from ui.panel_modules import ModulesPanel
            self.modules_panel = ModulesPanel(self)
            self.modules_panel.onModuleSelected.connect(
                self._on_module_dblclicked)
            self.modules_panel.onModuleFuncSelected.connect(
                self._on_modulefunc_dblclicked)
            self.modules_panel.onAddHook.connect(self._on_addmodule_hook)
            self.modules_panel.onDumpBinary.connect(self._on_dumpmodule)
            self.main_tabs.addTab(self.modules_panel, 'Modules')
        elif elem == 'ranges':
            from ui.panel_ranges import RangesPanel
            self.ranges_panel = RangesPanel(self)
            self.ranges_panel.onItemDoubleClicked.connect(
                self._range_dblclicked)
            self.ranges_panel.onDumpBinary.connect(self._on_dumpmodule)
            # connect to watcherpanel func
            self.ranges_panel.onAddWatcher.connect(
                self.watchers_panel.do_addwatcher_dlg)
            self.main_tabs.addTab(self.ranges_panel, 'Ranges')
        elif elem == 'search':
            from ui.panel_search import SearchPanel
            self.search_panel = SearchPanel(self)
            self.search_panel.onShowMemoryRequest.connect(
                self._on_watcher_clicked)
            self.main_tabs.addTab(self.search_panel, 'Search')
        elif elem == 'data':
            from ui.panel_data import DataPanel
            self.data_panel = DataPanel(self)
            self.main_tabs.addTab(self.data_panel, 'Data')
        elif elem == 'trace':
            from ui.panel_trace import TracePanel
            self.trace_panel = TracePanel(self)
            self.main_tabs.addTab(self.trace_panel, 'Trace')
        elif elem == 'disassembly':
            from ui.widgets.disasm_view import DisassemblyView
            self.asm_panel = DisassemblyView(self)
            self.asm_panel.onShowMemoryRequest.connect(self._on_disasm_showmem)
            self.main_tabs.addTab(self.asm_panel, 'Disassembly')
        elif elem == 'emulator':
            from ui.panel_emulator import EmulatorPanel
            self.emulator_panel = EmulatorPanel(self)
            self.main_tabs.addTab(self.emulator_panel, 'Emulator')
        elif elem == 'java-trace':
            from ui.panel_java_trace import JavaTracePanel
            self.java_trace_panel = JavaTracePanel(self)
            self.main_tabs.addTab(self.java_trace_panel, 'JVM tracer')
        elif elem == 'smali':
            from ui.panel_smali import SmaliPanel
            self.smali_panel = SmaliPanel()
            self.main_tabs.addTab(self.smali_panel, 'Smali')
        else:
            print('no handler for elem: ' + elem)

        # make tabs unclosable and sort
        self._handle_tab_change()

        # TODO: remove add @2x
        for item in self.findChildren(QDockWidget):
            if item:
                if 'darwin' in sys.platform:
                    item.setStyleSheet(
                        'QDockWidget::title { padding-left:-30px; } QDockWidget::close-button, QDockWidget::float-button  { width: 10px; height:10px }'
                    )

    def set_theme(self, theme):
        if theme:
            theme = theme.replace(os.pardir, '').replace('.', '')
            theme = theme.join(theme.split()).lower()
            theme_style = 'assets/' + theme + '_style.qss'
            if not os.path.exists(utils.resource_path(theme_style)):
                return

            self.prefs.put('dwarf_ui_theme', theme)

            try:
                _app = QApplication.instance()
                with open(theme_style) as stylesheet:
                    _app.setStyleSheet(_app.styleSheet() + '\n' +
                                       stylesheet.read())
            except Exception as e:
                pass
                # err = self.dwarf.spawn(dwarf_args.package, dwarf_args.script)

    def set_status_text(self, txt):
        self.statusbar.showMessage(txt)

    # ************************************************************************
    # **************************** Properties ********************************
    # ************************************************************************
    @property
    def disassembly(self):
        return self.asm_panel

    @property
    def backtrace(self):
        return self.backtrace_panel

    @property
    def console(self):
        return self.console_panel

    @property
    def context(self):
        return self.context_panel

    @property
    def threads(self):
        return self.contexts_list_panel

    @property
    def emulator(self):
        return self.emulator_panel

    @property
    def ftrace(self):
        return self.ftrace_panel

    @property
    def hooks(self):
        return self.hooks_panel

    @property
    def java_inspector(self):
        return self.java_inspector_panel

    @property
    def java_explorer(self):
        return self.java_explorer_panel

    @property
    def memory(self):
        return self.memory_panel

    @property
    def modules(self):
        return self.memory_panel

    @property
    def ranges(self):
        return self.ranges_panel

    @property
    def trace(self):
        return self.trace_panel

    @property
    def watchers(self):
        return self.watchers_panel

    @property
    def dwarf(self):
        if self.session_manager.session is not None:
            return self.session_manager.session.dwarf
        else:
            return None

    # ************************************************************************
    # **************************** Handlers **********************************
    # ************************************************************************
    # session handlers
    def _start_session(self, session_type, session_data=None):
        if self.welcome_window is not None:
            self.welcome_window.close()
        self.session_manager.create_session(session_type,
                                            session_data=session_data)

    def _restore_session(self, session_data):
        if 'session' in session_data:
            session_type = session_data['session']
            self._start_session(session_type, session_data=session_data)

    def session_created(self):
        # session init done create ui for it
        session = self.session_manager.session
        self._setup_main_menu()
        for ui_elem in session.session_ui_sections:
            ui_elem = ui_elem.join(ui_elem.split()).lower()
            self._create_ui_elem(ui_elem)

        self.dwarf.onAttached.connect(self._on_attached)
        self.dwarf.onScriptLoaded.connect(self._on_script_loaded)

        # hookup
        self.dwarf.onSetRanges.connect(self._on_setranges)
        self.dwarf.onSetModules.connect(self._on_setmodules)

        self.dwarf.onAddNativeHook.connect(self._on_add_hook)
        self.dwarf.onApplyContext.connect(self._apply_context)
        self.dwarf.onThreadResumed.connect(self.on_tid_resumed)

        self.dwarf.onTraceData.connect(self._on_tracer_data)
        self.dwarf.onSetData.connect(self._on_set_data)

        self.session_manager.start_session(self.dwarf_args)
        q_settings = QSettings("dwarf_window_pos.ini", QSettings.IniFormat)
        ui_state = q_settings.value('dwarf_ui_state')
        if ui_state:
            self.restoreGeometry(ui_state)
        window_state = q_settings.value('dwarf_ui_window', self.saveState())
        if window_state:
            self.restoreState(window_state)

        self.showMaximized()

    def session_stopped(self):
        self.remove_tmp_dir()
        self.menu.clear()

        self.main_tabs.clear()

        # actually we need to kill this. needs a refactor
        if self.java_trace_panel is not None:
            self.java_trace_panel = None

        for elem in self._ui_elems:
            if elem == 'watchers':
                self.watchers_panel.clear_list()
                self.watchers_panel.close()
                self.watchers_panel = None
                self.removeDockWidget(self.watchers_dwidget)
                self.watchers_dwidget = None
            elif elem == 'hooks':
                self.hooks_panel.close()
                self.hooks_panel = None
                self.removeDockWidget(self.hooks_dwiget)
                self.hooks_dwiget = None
            elif elem == 'registers':
                self.context_panel.close()
                self.context_panel = None
                self.removeDockWidget(self.registers_dock)
                self.registers_dock = None
            elif elem == 'memory':
                self.memory_panel.close()
                self.memory_panel = None
                self.main_tabs.removeTab(0)
                # self.main_tabs
            elif elem == 'jvm-debugger':
                self.java_explorer_panel.close()
                self.java_explorer_panel = None
                self.removeDockWidget(self.watchers_dwidget)
            elif elem == 'console':
                self.console_panel.close()
                self.console_panel = None
                self.removeDockWidget(self.console_dock)
                self.console_dock = None
            elif elem == 'backtrace':
                self.backtrace_panel.close()
                self.backtrace_panel = None
                self.removeDockWidget(self.backtrace_dock)
            elif elem == 'threads':
                self.contexts_list_panel.close()
                self.contexts_list_panel = None
                self.removeDockWidget(self.threads_dock)
                self.threads_dock = None
            elif elem == 'bookmarks':
                self.bookmarks_panel.close()
                self.bookmarks_panel = None
                self.removeDockWidget(self.bookmarks_dwiget)
                self.bookmarks_dwiget = None

    def session_closed(self):
        self._ui_elems = []
        self.hide()
        if self.welcome_window is not None:
            self.welcome_window.exec()

        # close if it was a commandline session
        if self.welcome_window is None:
            if self.dwarf_args.package:
                self.close()

    # ui handler
    def closeEvent(self, event):
        """ Window closed
            save stuff or whatever at exit

            detaches dwarf
        """
        # save windowstuff
        q_settings = QSettings("dwarf_window_pos.ini", QSettings.IniFormat)
        q_settings.setValue('dwarf_ui_state', self.saveGeometry())
        q_settings.setValue('dwarf_ui_window', self.saveState())

        if self.dwarf:
            self.dwarf.detach()
        super().closeEvent(event)

    def _on_watcher_clicked(self, ptr):
        """ Address in Watcher/Hookpanel was clicked
            show Memory
        """
        if '.' in ptr:  # java_hook
            file_path = ptr.replace('.', os.path.sep)
            if os.path.exists('.tmp/smali/' + file_path + '.smali'):
                if self.smali_panel is None:
                    self._create_ui_elem('smali')
                self.smali_panel.set_file('.tmp/smali/' + file_path + '.smali')
                self.show_main_tab('smali')
        else:
            self.memory_panel.read_memory(ptr=ptr)
            self.show_main_tab('memory')

    def _on_disasm_showmem(self, ptr, length):
        """ Address in Disasm was clicked
            adds temphighlight for bytes from current instruction
        """
        self.memory_panel.read_memory(ptr)
        self.memory_panel.add_highlight(
            HighLight('attention', utils.parse_ptr(ptr), length))
        self.show_main_tab('memory')

    def _on_watcher_added(self, ptr):
        """ Watcher Entry was added
        """
        try:
            # set highlight
            self.memory_panel.add_highlight(
                HighLight('watcher', ptr, self.dwarf.pointer_size))
        except HighlightExistsError:
            pass

    def _on_watcher_removeditem(self, ptr):
        """ Watcher Entry was removed
            remove highlight too
        """
        self.memory_panel.remove_highlight(ptr)

    def _on_module_dblclicked(self, data):
        """ Module in ModulePanel was doubleclicked
        """
        addr, size = data
        addr = utils.parse_ptr(addr)
        size = int(size, 10)
        self.memory_panel.read_memory(ptr=addr, length=size)
        self.show_main_tab('Memory')

    def _on_modulefunc_dblclicked(self, ptr):
        """ Function in ModulePanel was doubleclicked
        """
        ptr = utils.parse_ptr(ptr)
        self.memory_panel.read_memory(ptr=ptr)
        self.show_main_tab('Memory')

    def _on_dumpmodule(self, data):
        """ DumpBinary MenuItem in ModulePanel was selected
        """
        ptr, size = data
        ptr = utils.parse_ptr(ptr)
        size = int(size, 10)
        self.dwarf.dump_memory(ptr=ptr, length=size)

    def _disassemble_range(self, mem_range):
        """ Disassemble MenuItem in Hexview was selected
        """
        if mem_range:
            if self.asm_panel is None:
                self._create_ui_elem('disassembly')

            if mem_range:
                self.asm_panel.disassemble(mem_range)
                self.show_main_tab('disassembly')

    def _range_dblclicked(self, ptr):
        """ Range in RangesPanel was doubleclicked
        """
        ptr = utils.parse_ptr(ptr)
        self.memory_panel.read_memory(ptr=ptr)
        self.show_main_tab('Memory')

    # dwarf handlers
    def _log_js_output(self, output):
        if self.console_panel is not None:
            self.console_panel.get_js_console().log(output)

    def _on_setranges(self, ranges):
        """ Dwarf wants to set Ranges
            only hooked up to switch tab or create ui
            its connected in panel after creation
        """
        if self.ranges_panel is None:
            self.show_main_tab('ranges')
            # forward only now to panel it connects after creation
            self.ranges_panel.set_ranges(ranges)

    def _on_setmodules(self, modules):
        """ Dwarf wants to set Modules
            only hooked up to switch tab or create ui
            its connected in panel after creation
        """
        if self.modules_panel is None:
            self._create_ui_elem('modules')
            self.modules_panel.set_modules(modules)

        if self.modules_panel is not None:
            self.show_main_tab('modules')

    def _manually_apply_context(self, context):
        """
        perform additional operation if the context has been manually applied from the context list
        """
        self._apply_context(context, manual=True)

    def _apply_context(self, context, manual=False):
        # update current context tid
        # this should be on top as any further api from js needs to be executed on that thread
        is_initial_hook = context['reason'] >= 0
        if manual or (self.dwarf.context_tid and not is_initial_hook):
            self.dwarf.context_tid = context['tid']

        if 'context' in context:
            if not manual:
                self.threads.add_context(context)

            is_java = context['is_java']
            if is_java:
                if self.java_explorer_panel is None:
                    self._create_ui_elem('jvm-debugger')
                self.context_panel.set_context(context['ptr'], 1,
                                               context['context'])
                self.java_explorer_panel._set_handle_arg(-1)
                self.show_main_tab('jvm-debugger')
            else:
                self.context_panel.set_context(context['ptr'], 0,
                                               context['context'])

                if 'pc' in context['context']:
                    if not 'disassembly' in self._ui_elems:
                        from lib.range import Range
                        _range = Range(Range.SOURCE_TARGET, self.dwarf)
                        _range.init_with_address(
                            int(context['context']['pc']['value'], 16))

                        self._disassemble_range(_range)

        if 'backtrace' in context:
            self.backtrace_panel.set_backtrace(context['backtrace'])

    def _on_add_hook(self, hook):
        try:
            # set highlight
            ptr = hook.get_ptr()
            ptr = utils.parse_ptr(ptr)
            self.memory_panel.add_highlight(
                HighLight('hook', ptr, self.dwarf.pointer_size))
        except HighlightExistsError:
            pass

    def _on_hook_removed(self, ptr):
        ptr = utils.parse_ptr(ptr)
        self.memory_panel.remove_highlight(ptr)

    def _on_addmodule_hook(self, data):
        ptr, name = data
        self.dwarf.hook_native(ptr, own_input=name)

    def on_tid_resumed(self, tid):
        if self.dwarf:
            if self.dwarf.context_tid == tid:
                # clear backtrace
                if 'backtrace' in self._ui_elems:
                    if self.backtrace_panel is not None:
                        self.backtrace_panel.clear()

                # remove thread
                if 'threads' in self._ui_elems:
                    if self.contexts_list_panel is not None:
                        self.contexts_list_panel.resume_tid(tid)

                # clear registers
                if 'registers' in self._ui_elems:
                    if self.context_panel is not None:
                        self.context_panel.clear()

                # clear jvm explorer
                if 'jvm-debugger' in self._ui_elems:
                    if self.java_explorer_panel is not None:
                        self.java_explorer_panel.clear_panel()

                # invalidate dwarf context tid
                self.dwarf.context_tid = 0

    def _on_tracer_data(self, data):
        if not data:
            return

        if self.trace_panel is None:
            self._create_ui_elem('trace')

        if self.trace_panel is not None:
            self.show_main_tab('Trace')
            self.trace_panel.start()

            trace_events_parts = data[1].split(',')
            while trace_events_parts:
                trace_event = TraceEvent(trace_events_parts.pop(0),
                                         trace_events_parts.pop(0),
                                         trace_events_parts.pop(0),
                                         trace_events_parts.pop(0))
                self.trace_panel.event_queue.append(trace_event)

    def _on_set_data(self, data):
        if not isinstance(data, list):
            return

        if self.data_panel is None:
            self._create_ui_elem('data')

        if self.data_panel is not None:
            self.show_main_tab('Data')
            self.data_panel.append_data(data[0], data[1], data[2])

    def show_progress(self, text):
        self.progressbar.setVisible(True)
        self.set_status_text(text)

    def hide_progress(self):
        self.progressbar.setVisible(False)
        self.set_status_text('')

    def _on_attached(self, data):
        self.setWindowTitle('Dwarf - Attached to %s (%s)' % (data[1], data[0]))

    def _on_script_loaded(self):
        # restore the loaded session if any
        self.session_manager.restore_session()

    def _on_memory_modified(self, pos, length):
        data_pos = self.memory_panel.base + pos
        data = self.memory_panel.data[pos:pos + length]
        data = [data[0]]  # todo: strange js part

        if self.dwarf.dwarf_api('writeBytes', [data_pos, data]):
            pass
        else:
            utils.show_message_box('Failed to write Memory')

    def on_add_bookmark(self, ptr):
        """
        provide ptr as int
        """
        if self.bookmarks_panel is not None:
            self.bookmarks_panel._create_bookmark(ptr=hex(ptr))
コード例 #32
0
class mainWindow(QMainWindow):
    """
    Main window of openlavaMonitor.
    """
    def __init__(self):
        super().__init__()

        self.myDrawCurve = bmonitor.drawCurve()
        self.freshMark = False

        self.initUI()

    def initUI(self):
        """
        Main process, draw the main graphic frame.
        """
        self.queueList = openlava_common.getQueueList()
        self.hostList = openlava_common.getHostList()

        # Add menubar.
        if not self.freshMark:
            self.genMenubar()

        # Define main Tab widget
        self.mainTab = QTabWidget(self)
        self.setCentralWidget(self.mainTab)

        # Define four sub-tabs (JOB/JOBS/HOSTS/QUEUES)
        self.jobTab    = QWidget()
        self.jobsTab   = QWidget()
        self.hostsTab  = QWidget()
        self.queuesTab = QWidget()

        # Add the sub-tabs into main Tab widget
        self.mainTab.addTab(self.jobTab, 'JOB')
        self.mainTab.addTab(self.jobsTab, 'JOBS')
        self.mainTab.addTab(self.hostsTab, 'HOSTS')
        self.mainTab.addTab(self.queuesTab, 'QUEUES')

        # Generate the sub-tabs
        self.genJobTab()
        self.genJobsTab()
        self.genHostsTab()
        self.genQueuesTab()

        # Show main window
        self.resize(1111, 620)
        pyqt5_common.centerWindow(self)
        self.setWindowTitle('openlavaMonitor')

    def genMenubar(self):
        """
        Generate menubar.
        """
        menubar = self.menuBar()

        # File
        exitAction = QAction('Quit', self)
        exitAction.triggered.connect(qApp.quit)

        fileMenu = menubar.addMenu('File')
        fileMenu.addAction(exitAction)

        # Setup
        freshAction = QAction('Fresh', self)
        freshAction.triggered.connect(self.fresh)

        setupMenu = menubar.addMenu('Setup')
        setupMenu.addAction(freshAction)

    def fresh(self):
        print('* Re-Loading openlava status, please wait a moment ...')
        self.freshMark = True
        self.initUI()

## Common sub-functions (begin) ##
    def guiWarning(self, warningMessage):
        """
        Show the specified warning message on both of command line and GUI window.
        """
        common.printWarning(warningMessage)
        QMessageBox.warning(self, 'openlavaMonitor Warning', warningMessage)
## Common sub-functions (end) ##


## For job TAB (begin) ## 
    def genJobTab(self):
        """
        Generate the job tab on openlavaMonitor GUI, show job informations.
        """
        # Init var
        self.currentJob = ''
        self.jobInfoDic = {}

        # self.jobTab
        self.jobTabFrame0 = QFrame(self.jobTab)
        self.jobTabFrame1 = QFrame(self.jobTab)
        self.jobTabFrame2 = QFrame(self.jobTab)
        self.jobTabFrame3 = QFrame(self.jobTab)

        self.jobTabFrame0.setFrameShadow(QFrame.Raised)
        self.jobTabFrame0.setFrameShape(QFrame.Box)
        self.jobTabFrame1.setFrameShadow(QFrame.Raised)
        self.jobTabFrame1.setFrameShape(QFrame.Box)
        self.jobTabFrame2.setFrameShadow(QFrame.Raised)
        self.jobTabFrame2.setFrameShape(QFrame.Box)
        self.jobTabFrame3.setFrameShadow(QFrame.Raised)
        self.jobTabFrame3.setFrameShape(QFrame.Box)

        # self.jobTab - Grid
        jobTabGrid = QGridLayout()

        jobTabGrid.addWidget(self.jobTabFrame0, 0, 0)
        jobTabGrid.addWidget(self.jobTabFrame1, 1, 0)
        jobTabGrid.addWidget(self.jobTabFrame2, 2, 0, 1, 2)
        jobTabGrid.addWidget(self.jobTabFrame3, 0, 1, 2, 1)

        jobTabGrid.setRowStretch(0, 1)
        jobTabGrid.setRowStretch(1, 1)
        jobTabGrid.setRowStretch(2, 10)
        jobTabGrid.setColumnStretch(0, 1)
        jobTabGrid.setColumnStretch(1, 10)

        jobTabGrid.setColumnMinimumWidth(0, 250)
        jobTabGrid.setColumnMinimumWidth(1, 500)

        self.jobTab.setLayout(jobTabGrid)

        # Generate sub-frames
        self.genJobTabFrame0()
        self.genJobTabFrame1()
        self.genJobTabFrame2()
        self.genJobTabFrame3()

    def genJobTabFrame0(self):
        # self.jobTabFrame0
        jobTabJobLabel = QLabel(self.jobTabFrame0)
        jobTabJobLabel.setText('Job')

        self.jobTabJobLine = QLineEdit()

        jobTabCheckButton = QPushButton('Check', self.jobTabFrame0)
        jobTabCheckButton.clicked.connect(self.checkJob)

        # self.jobTabFrame0 - Grid
        jobTabFrame0Grid = QGridLayout()

        jobTabFrame0Grid.addWidget(jobTabJobLabel, 0, 0)
        jobTabFrame0Grid.addWidget(self.jobTabJobLine, 0, 1)
        jobTabFrame0Grid.addWidget(jobTabCheckButton, 0, 2)

        self.jobTabFrame0.setLayout(jobTabFrame0Grid)

    def genJobTabFrame1(self):
        # self.jobTabFrame1
        jobTabUserLabel = QLabel('User', self.jobTabFrame1)
        self.jobTabUserLine = QLineEdit()

        jobTabStatusLabel = QLabel('Status', self.jobTabFrame1)
        self.jobTabStatusLine = QLineEdit()

        jobTabQueueLabel = QLabel('Queue', self.jobTabFrame1)
        self.jobTabQueueLine = QLineEdit()

        jobTabStartedOnLabel = QLabel('Host', self.jobTabFrame1)
        self.jobTabStartedOnLine = QLineEdit()

        jobTabProjectLabel = QLabel('Project', self.jobTabFrame1)
        self.jobTabProjectLine = QLineEdit()

        jobTabProcessorsRequestedLabel = QLabel('Processors', self.jobTabFrame1)
        self.jobTabProcessorsRequestedLine = QLineEdit()

        jobTabCpuTimeLabel = QLabel('Cpu Time', self.jobTabFrame1)
        self.jobTabCpuTimeLine = QLineEdit()

        jobTabRusageMemLabel = QLabel('Rusage', self.jobTabFrame1)
        self.jobTabRusageMemLine = QLineEdit()

        jobTabMemLabel = QLabel('Mem', self.jobTabFrame1)
        self.jobTabMemLine = QLineEdit()

        # self.jobTabFrame1 - Grid
        jobTabFrame1Grid = QGridLayout()

        jobTabFrame1Grid.addWidget(jobTabUserLabel, 0, 0)
        jobTabFrame1Grid.addWidget(self.jobTabUserLine, 0, 1)
        jobTabFrame1Grid.addWidget(jobTabStatusLabel, 1, 0)
        jobTabFrame1Grid.addWidget(self.jobTabStatusLine, 1, 1)
        jobTabFrame1Grid.addWidget(jobTabQueueLabel, 2, 0)
        jobTabFrame1Grid.addWidget(self.jobTabQueueLine, 2, 1)
        jobTabFrame1Grid.addWidget(jobTabStartedOnLabel, 3, 0)
        jobTabFrame1Grid.addWidget(self.jobTabStartedOnLine, 3, 1)
        jobTabFrame1Grid.addWidget(jobTabProjectLabel, 4, 0)
        jobTabFrame1Grid.addWidget(self.jobTabProjectLine, 4, 1)
        jobTabFrame1Grid.addWidget(jobTabProcessorsRequestedLabel, 5, 0)
        jobTabFrame1Grid.addWidget(self.jobTabProcessorsRequestedLine, 5, 1)
        jobTabFrame1Grid.addWidget(jobTabCpuTimeLabel, 6, 0)
        jobTabFrame1Grid.addWidget(self.jobTabCpuTimeLine, 6, 1)
        jobTabFrame1Grid.addWidget(jobTabRusageMemLabel, 7, 0)
        jobTabFrame1Grid.addWidget(self.jobTabRusageMemLine, 7, 1)
        jobTabFrame1Grid.addWidget(jobTabMemLabel, 8, 0)
        jobTabFrame1Grid.addWidget(self.jobTabMemLine, 8, 1)

        self.jobTabFrame1.setLayout(jobTabFrame1Grid)

    def genJobTabFrame2(self):
        # self.jobTabFrame2
        self.jobTabJobInfoText = QTextEdit(self.jobTabFrame2)

        # self.jobTabFrame2 - Grid
        jobTabFrame2Grid = QGridLayout()
        jobTabFrame2Grid.addWidget(self.jobTabJobInfoText, 0, 0)
        self.jobTabFrame2.setLayout(jobTabFrame2Grid)

    def genJobTabFrame3(self):
        # self.jobTabFram3
        self.jobTabMemCurveLabel = QLabel('Job memory curve', self.jobTabFrame3)
        self.jobTabMemCurveLabel.setAlignment(Qt.AlignCenter)

        # self.jobTabFram3 - Grid
        jobTabFrame3Grid = QGridLayout()
        jobTabFrame3Grid.addWidget(self.jobTabMemCurveLabel, 0, 0)
        self.jobTabFrame3.setLayout(jobTabFrame3Grid)

    def checkJob(self):
        """
        Get job information with "bjobs -UF <jobId>", save the infomation into dict self.jobInfoDic.
        Update self.jobTabFrame1 and self.jobTabFrame3.
        """
        self.currentJob = self.jobTabJobLine.text().strip()
        print('* Checking job "' + str(self.currentJob) + '".')

        # Initicalization
        self.updateJobTabFrame1(init=True)
        self.updateJobTabFrame2(init=True)
        self.updateJobTabFrame3(init=True)

        # Job name must be a string of numbers.
        if not re.match('^[0-9]+$', self.currentJob):
            warningMessage = '*Warning*: No valid job is specified!'
            self.guiWarning(warningMessage)
            return

        # Get job info
        print('Getting job information for job "' + str(self.currentJob) + '".')
        self.jobInfoDic = openlava_common.getBjobsUfInfo(command='bjobs -UF ' + str(self.currentJob))

        # Update the related frames with the job info.
        self.updateJobTabFrame1()
        self.updateJobTabFrame2()
        self.updateJobTabFrame3()

    def updateJobTabFrame1(self, init=False):
        """
        Update self.jobTabFrame1 with job infos.
        """
        # For "User" item.
        if init:
            self.jobTabUserLine.setText('')
        else:
            self.jobTabUserLine.setText(self.jobInfoDic[self.currentJob]['user'])
            self.jobTabUserLine.setCursorPosition(0)

        # For "Status" item.
        if init:
            self.jobTabStatusLine.setText('')
        else:
            self.jobTabStatusLine.setText(self.jobInfoDic[self.currentJob]['status'])
            self.jobTabStatusLine.setCursorPosition(0)

        # For "Queue" item.
        if init:
            self.jobTabQueueLine.setText('')
        else:
            self.jobTabQueueLine.setText(self.jobInfoDic[self.currentJob]['queue'])
            self.jobTabQueueLine.setCursorPosition(0)

        # For "Host" item.
        if init:
            self.jobTabStartedOnLine.setText('')
        else:
            self.jobTabStartedOnLine.setText(self.jobInfoDic[self.currentJob]['startedOn'])
            self.jobTabStartedOnLine.setCursorPosition(0)

        # For "Processors" item.
        if init:
            self.jobTabProcessorsRequestedLine.setText('')
        else:
            self.jobTabProcessorsRequestedLine.setText(self.jobInfoDic[self.currentJob]['processorsRequested'])
            self.jobTabProcessorsRequestedLine.setCursorPosition(0)

        # For "Cpu Time" item.
        if init:
            self.jobTabCpuTimeLine.setText('')
        else:
            if self.jobInfoDic[self.currentJob]['cpuTime'] != '':
                self.jobTabCpuTimeLine.setText(self.jobInfoDic[self.currentJob]['cpuTime'] + ' s')
                self.jobTabCpuTimeLine.setCursorPosition(0)

        # For "Project" item.
        if init:
            self.jobTabProjectLine.setText('')
        else:
            self.jobTabProjectLine.setText(self.jobInfoDic[self.currentJob]['project'])
            self.jobTabProjectLine.setCursorPosition(0)

        # For "Rusage" item.
        if init:
            self.jobTabRusageMemLine.setText('')
        else:
            if self.jobInfoDic[self.currentJob]['rusageMem'] != '':
                self.jobTabRusageMemLine.setText(self.jobInfoDic[self.currentJob]['rusageMem'] + ' M')
                self.jobTabRusageMemLine.setCursorPosition(0)

        # For "Mem" item.
        if init:
            self.jobTabMemLine.setText('')
        else:
            if self.jobInfoDic[self.currentJob]['mem'] != '':
                self.jobTabMemLine.setText(self.jobInfoDic[self.currentJob]['mem'] + ' M')
                self.jobTabMemLine.setCursorPosition(0)

    def updateJobTabFrame2(self, init=False):
        """
        Show job detailed description info on self.jobTabFrame2/self.jobTabJobInfoText.
        """
        self.jobTabJobInfoText.clear()

        if not init:
            self.jobTabJobInfoText.insertPlainText(self.jobInfoDic[self.currentJob]['jobInfo'])
            pyqt5_common.textEditVisiblePosition(self.jobTabJobInfoText, 'Start')

    def updateJobTabFrame3(self, init=False):
        """
        Draw memory curve for current job, save the png picture and show it on self.jobTabFrame3.
        """
        self.jobTabMemCurveLabel.setText('Job memory curve')

        if not init:
            if self.jobInfoDic[self.currentJob]['status'] == 'PEND':
                warningMessage = '*Warning*: "' + str(self.currentJob) + '" is PEND job, cannot draw memory curve for it.'
                self.guiWarning(warningMessage)
            else:
                # Generate memory curve with the specified job id
                self.myDrawCurve.drawJobMemCurve(self.currentJob)
                memCurveFig = str(config.tmpPath) + '/' + str(user) + '_' + str(self.currentJob) + '.png'

                if os.path.exists(memCurveFig):
                    pixMap = QPixmap(memCurveFig).scaled(self.jobTabMemCurveLabel.width(), self.jobTabMemCurveLabel.height())
                    self.jobTabMemCurveLabel.setPixmap(pixMap)
                else:
                    warningMessage = '*Warning*: Not find memory curve fig "' + str(memCurveFig) + '".'
                    self.guiWarning(warningMessage)
## For job TAB (end) ## 


## For jobs TAB (start) ## 
    def genJobsTab(self):
        """
        Generate the jobs tab on openlavaMonitor GUI, show jobs informations.
        """
        # self.jobsTab
        self.jobsTabFrame0 = QFrame(self.jobsTab)
        self.jobsTabFrame0.setFrameShadow(QFrame.Raised)
        self.jobsTabFrame0.setFrameShape(QFrame.Box)

        self.jobsTabTable = QTableWidget(self.jobsTab)
        self.jobsTabTable.itemClicked.connect(self.jobsTabCheckClick)

        # self.jobsTab - Grid
        jobsTabGrid = QGridLayout()

        jobsTabGrid.addWidget(self.jobsTabFrame0, 0, 0)
        jobsTabGrid.addWidget(self.jobsTabTable, 1, 0)

        jobsTabGrid.setRowStretch(0, 1)
        jobsTabGrid.setRowStretch(1, 10)

        self.jobsTab.setLayout(jobsTabGrid)

        # Generate sub-frame
        self.genJobsTabFrame0()
        self.genJobsTabTable()

    def setJobsTabStatusCombo(self, statusList=['RUN', 'PEND', 'ALL']):
        """
        Set (initialize) self.jobsTabStatusCombo.
        """
        self.jobsTabStatusCombo.clear()
        for status in statusList:
            self.jobsTabStatusCombo.addItem(status)

    def setJobsTabQueueCombo(self, queueList=[]):
        """
        Set (initialize) self.jobsTabQueueCombo.
        """
        self.jobsTabQueueCombo.clear()
        if len(queueList) == 0:
            queueList = copy.deepcopy(self.queueList)
            queueList.insert(0, 'ALL')
        for queue in queueList:
            self.jobsTabQueueCombo.addItem(queue)

    def setJobsTabStartedOnCombo(self, hostList=[]):
        """
        Set (initialize) self.jobsTabStartedOnCombo.
        """
        self.jobsTabStartedOnCombo.clear()
        if len(hostList) == 0:
            hostList = copy.deepcopy(self.hostList)
            hostList.insert(0, 'ALL')
        for host in hostList:
            self.jobsTabStartedOnCombo.addItem(host)

    def genJobsTabFrame0(self):
        # self.jobsTabFrame0
        jobsTabUserLabel = QLabel('User', self.jobsTabFrame0)
        jobsTabUserLabel.setStyleSheet("font-weight: bold;")
        self.jobsTabUserLine = QLineEdit()

        jobsTabStatusLabel = QLabel('       Status', self.jobsTabFrame0)
        jobsTabStatusLabel.setStyleSheet("font-weight: bold;")
        self.jobsTabStatusCombo = QComboBox(self.jobsTabFrame0)
        self.setJobsTabStatusCombo()

        jobsTabQueueLabel = QLabel('       Queue', self.jobsTabFrame0)
        jobsTabQueueLabel.setStyleSheet("font-weight: bold;")
        self.jobsTabQueueCombo = QComboBox(self.jobsTabFrame0)
        self.setJobsTabQueueCombo()

        jobsTabStartedOnLabel = QLabel('       Host', self.jobsTabFrame0)
        jobsTabStartedOnLabel.setStyleSheet("font-weight: bold;")
        self.jobsTabStartedOnCombo = QComboBox(self.jobsTabFrame0)
        self.setJobsTabStartedOnCombo()

        self.jobsTabStatusCombo.currentIndexChanged.connect(self.genJobsTabTable)
        self.jobsTabQueueCombo.currentIndexChanged.connect(self.genJobsTabTable)
        self.jobsTabStartedOnCombo.currentIndexChanged.connect(self.genJobsTabTable)

        jobsTabCheckButton = QPushButton('Check', self.jobsTabFrame0)
        jobsTabCheckButton.clicked.connect(self.genJobsTabTable)

        # self.jobsTabFrame0 - Grid
        jobsTabFrame0Grid = QGridLayout()

        jobsTabFrame0Grid.addWidget(jobsTabUserLabel, 0, 0)
        jobsTabFrame0Grid.addWidget(self.jobsTabUserLine, 0, 1)
        jobsTabFrame0Grid.addWidget(jobsTabStatusLabel, 0, 2)
        jobsTabFrame0Grid.addWidget(self.jobsTabStatusCombo, 0, 3)
        jobsTabFrame0Grid.addWidget(jobsTabQueueLabel, 0, 4)
        jobsTabFrame0Grid.addWidget(self.jobsTabQueueCombo, 0, 5)
        jobsTabFrame0Grid.addWidget(jobsTabStartedOnLabel, 0, 6)
        jobsTabFrame0Grid.addWidget(self.jobsTabStartedOnCombo, 0, 7)
        jobsTabFrame0Grid.addWidget(jobsTabCheckButton, 0, 8)

        jobsTabFrame0Grid.setColumnStretch(1, 1)
        jobsTabFrame0Grid.setColumnStretch(3, 1)
        jobsTabFrame0Grid.setColumnStretch(5, 1)
        jobsTabFrame0Grid.setColumnStretch(7, 1)

        self.jobsTabFrame0.setLayout(jobsTabFrame0Grid)

    def genJobsTabTable(self):
        self.jobsTabTable.setShowGrid(True)
        self.jobsTabTable.setSortingEnabled(True)
        self.jobsTabTable.setColumnCount(12)
        self.jobsTabTable.setHorizontalHeaderLabels(['Job', 'User', 'Status', 'Queue', 'Host', 'Started', 'Project', 'Processers', 'cpuTime', 'Rusage (G)', 'Mem (G)', 'Command'])

        command = 'bjobs -UF '
        user = self.jobsTabUserLine.text().strip()

        if re.match('^\s*$', user):
            command = str(command) + ' -u all'
        else:
            command = str(command) + ' -u ' + str(user)

        queue = self.jobsTabQueueCombo.currentText().strip()

        if queue != 'ALL':
            command = str(command) + ' -q ' + str(queue)

        status = self.jobsTabStatusCombo.currentText().strip()

        if status == 'RUN':
            command = str(command) + ' -r'
        elif status == 'PEND':
            command = str(command) + ' -p'
        elif status == 'ALL':
            command = str(command) + ' -a'

        startedOn = self.jobsTabStartedOnCombo.currentText().strip()

        if startedOn != 'ALL':
            command = str(command) + ' -m ' + str(startedOn)

        jobDic = openlava_common.getBjobsUfInfo(command)

        self.jobsTabTable.setRowCount(len(jobDic.keys()))
        jobs = list(jobDic.keys())

        for i in range(len(jobs)):
            job = jobs[i]
            j = 0
            self.jobsTabTable.setItem(i, j, QTableWidgetItem(job))

            j = j+1
            item = QTableWidgetItem()
            item.setText(jobDic[job]['user'])
            self.jobsTabTable.setItem(i, j, item)

            j = j+1
            item = QTableWidgetItem()
            item.setText(jobDic[job]['status'])
            self.jobsTabTable.setItem(i, j, item)

            j = j+1
            item = QTableWidgetItem()
            item.setText(jobDic[job]['queue'])
            self.jobsTabTable.setItem(i, j, item)

            j = j+1
            item = QTableWidgetItem()
            item.setText(jobDic[job]['startedOn'])
            self.jobsTabTable.setItem(i, j, item)

            j = j+1
            item = QTableWidgetItem()
            item.setText(jobDic[job]['startedTime'])
            self.jobsTabTable.setItem(i, j, item)

            j = j+1
            if str(jobDic[job]['project']) != '':
                item = QTableWidgetItem()
                item.setData(Qt.DisplayRole, jobDic[job]['project'])
                self.jobsTabTable.setItem(i, j, item)

            j = j+1
            if str(jobDic[job]['processorsRequested']) != '':
                item = QTableWidgetItem()
                item.setData(Qt.DisplayRole, int(jobDic[job]['processorsRequested']))
                self.jobsTabTable.setItem(i, j, item)

            j = j+1
            if str(jobDic[job]['cpuTime']) != '':
                item = QTableWidgetItem()
                item.setData(Qt.DisplayRole, int(jobDic[job]['cpuTime']))
                self.jobsTabTable.setItem(i, j, item)

            j = j+1
            if str(jobDic[job]['rusageMem']) != '':
                item = QTableWidgetItem()
                rusageMemValue = int(jobDic[job]['rusageMem'])/1024
                item.setData(Qt.DisplayRole, int(rusageMemValue))
                self.jobsTabTable.setItem(i, j, item)

            j = j+1
            if str(jobDic[job]['mem']) != '':
                item = QTableWidgetItem()
                memValue = int(jobDic[job]['mem'])/1024
                item.setData(Qt.DisplayRole, int(memValue))
                self.jobsTabTable.setItem(i, j, item)

            j = j+1
            item = QTableWidgetItem()
            item.setText(jobDic[job]['command'])
            self.jobsTabTable.setItem(i, j, item)

    def jobsTabCheckClick(self, item=None):
        """
        With the clicked job, jump the the job Tab, show the job related infos.
        """
        if item != None:
            if item.column() == 0:
                currentRow = self.jobsTabTable.currentRow()
                job = self.jobsTabTable.item(currentRow, 0).text().strip()
                if job != '':
                    self.jobTabJobLine.setText(job)
                    self.checkJob()
                    self.mainTab.setCurrentWidget(self.jobTab)
## For jobs TAB (end) ## 


## For hosts TAB (start) ## 
    def genHostsTab(self):
        """
        Generate the hosts tab on openlavaMonitor GUI, show hosts informations.
        """
        # self.hostsTabTable
        self.hostsTabFrame0 = QFrame(self.hostsTab)
        self.hostsTabFrame0.setFrameShadow(QFrame.Raised)
        self.hostsTabFrame0.setFrameShape(QFrame.Box)

        self.hostsTabTable = QTableWidget(self.hostsTab)
        self.hostsTabTable.itemClicked.connect(self.hostsTabCheckClick)

        # self.hostsTabTable - Grid
        hostsTabGrid = QGridLayout()

        hostsTabGrid.addWidget(self.hostsTabFrame0, 0, 0)
        hostsTabGrid.addWidget(self.hostsTabTable, 1, 0)

        hostsTabGrid.setRowStretch(0, 1)
        hostsTabGrid.setRowStretch(1, 10)

        self.hostsTab.setLayout(hostsTabGrid)

        # Generate sub-fram
        self.genHostsTabFrame0()
        self.genHostsTabTable()

    def setHostsTabQueueCombo(self, queueList=[]):
        """
        Set (initialize) self.hostsTabQueueCombo.
        """
        self.hostsTabQueueCombo.clear()
        if len(queueList) == 0:
            queueList = copy.deepcopy(self.queueList)
            queueList.insert(0, 'ALL')
        for queue in queueList:
            self.hostsTabQueueCombo.addItem(queue)

    def genHostsTabFrame0(self):
        # self.hostsTabFrame0
        hostsTabQueueLabel = QLabel('       Queue', self.hostsTabFrame0)
        hostsTabQueueLabel.setStyleSheet("font-weight: bold;")
        self.hostsTabQueueCombo = QComboBox(self.hostsTabFrame0)
        self.setHostsTabQueueCombo()
        self.hostsTabQueueCombo.currentIndexChanged.connect(self.genHostsTabTable)
        hostsTabEmptyLabel = QLabel('')

        # self.hostsTabFrame0 - Grid
        hostsTabFrame0Grid = QGridLayout()

        hostsTabFrame0Grid.addWidget(hostsTabQueueLabel, 0, 1)
        hostsTabFrame0Grid.addWidget(self.hostsTabQueueCombo, 0, 2)
        hostsTabFrame0Grid.addWidget(hostsTabEmptyLabel, 0, 3)

        hostsTabFrame0Grid.setColumnStretch(1, 1)
        hostsTabFrame0Grid.setColumnStretch(2, 1)
        hostsTabFrame0Grid.setColumnStretch(3, 8)

        self.hostsTabFrame0.setLayout(hostsTabFrame0Grid)

    def genHostsTabTable(self):
        print('* Updating hosts information, please wait a moment ...')

        self.hostsTabTable.setShowGrid(True)
        self.hostsTabTable.setSortingEnabled(True)
        self.hostsTabTable.setColumnCount(10)
        self.hostsTabTable.setHorizontalHeaderLabels(['Host', 'Status', 'Queue', 'Njobs', 'Ncpus', 'Ut (%)', 'Mem (G)', 'Maxmem (G)', 'swp (G)', 'maxswp (G)'])

        queue = self.hostsTabQueueCombo.currentText().strip()

        bhostsDic  = openlava_common.getBhostsInfo()
        lshostsDic = openlava_common.getLshostsInfo()
        lsloadDic  = openlava_common.getLsloadInfo()
        hostQueueDic = openlava_common.getHostQueueInfo()

        # Get expected host list
        self.queueHostList = []

        if queue == 'ALL':
            self.queueHostList = self.hostList
        else:
            for host in self.hostList:
                if queue in hostQueueDic[host]:
                    self.queueHostList.append(host)

        self.hostsTabTable.setRowCount(len(self.queueHostList))

        for i in range(len(self.queueHostList)):
            host = self.queueHostList[i]

            j = 0
            self.hostsTabTable.setItem(i, j, QTableWidgetItem(host))

            j = j+1
            index = bhostsDic['HOST_NAME'].index(host)
            status = bhostsDic['STATUS'][index]
            item = QTableWidgetItem(status)
            if str(status) == 'closed':
                item.setFont(QFont('song', 10, QFont.Bold))
                item.setForeground(QBrush(Qt.red))
            self.hostsTabTable.setItem(i, j, item)

            j = j+1
            if host in hostQueueDic.keys():
                queues = ' '.join(hostQueueDic[host])
                item = QTableWidgetItem(queues)
                self.hostsTabTable.setItem(i, j, item)

            j = j+1
            index = bhostsDic['HOST_NAME'].index(host)
            njobs = bhostsDic['NJOBS'][index]
            if not re.match('^[0-9]+$', njobs):
                common.printWarning('*Warning*: host(' + str(host) + ') NJOBS info "' + str(njobs) + '": invalid value, reset it to "0".')
                njobs = 0
            item = QTableWidgetItem()
            item.setData(Qt.DisplayRole, int(njobs))
            self.hostsTabTable.setItem(i, j, item)

            j = j+1
            index = lshostsDic['HOST_NAME'].index(host)
            ncpus = lshostsDic['ncpus'][index]
            if not re.match('^[0-9]+$', ncpus):
                common.printWarning('*Warning*: host(' + str(host) + ') ncpus info "' + str(ncpus) + '": invalid value, reset it to "0".')
                ncpus = 0
            item = QTableWidgetItem()
            item.setData(Qt.DisplayRole, int(ncpus))
            self.hostsTabTable.setItem(i, j, item)

            j = j+1
            index = lsloadDic['HOST_NAME'].index(host)
            ut = lsloadDic['ut'][index]
            ut = re.sub('%', '', ut)
            if not re.match('^[0-9]+$', ut):
                common.printWarning('*Warning*: host(' + str(host) + ') ut info "' + str(ut) + '": invalid value, reset it to "0".')
                ut = 0
            item = QTableWidgetItem()
            item.setData(Qt.DisplayRole, int(ut))
            self.hostsTabTable.setItem(i, j, item)

            j = j+1
            index = lsloadDic['HOST_NAME'].index(host)
            mem = lsloadDic['mem'][index]
            if re.search('M', mem):
                mem = re.sub('M', '', mem)
                mem = int(mem)/1024
            elif re.search('G', mem):
                mem = re.sub('G', '', mem)
            else:
                common.printWarning('*Warning*: host(' + str(host) + ') mem info "' + str(mem) + '": unrecognized unit, reset it to "0".')
                mem = 0
            item = QTableWidgetItem()
            item.setData(Qt.DisplayRole, int(mem))
            self.hostsTabTable.setItem(i, j, item)

            j = j+1
            index = lshostsDic['HOST_NAME'].index(host)
            maxmem = lshostsDic['maxmem'][index]
            if re.search('M', maxmem):
                maxmem = re.sub('M', '', maxmem)
                maxmem = int(maxmem)/1024
            elif re.search('G', maxmem):
                maxmem = re.sub('G', '', maxmem)
            else:
                common.printWarning('*Warning*: host(' + str(host) + ') maxmem info "' + str(maxmem) + '": unrecognized unit, reset it to "0".')
                maxmem = 0
            item = QTableWidgetItem()
            item.setData(Qt.DisplayRole, int(maxmem))
            self.hostsTabTable.setItem(i, j, item)

            j = j+1
            index = lsloadDic['HOST_NAME'].index(host)
            swp = lsloadDic['swp'][index]
            if re.search('M', swp):
                swp = re.sub('M', '', swp)
                swp = int(swp)/1024
            elif re.search('G', swp):
                swp = re.sub('G', '', swp)
            else:
                common.printWarning('*Warning*: host(' + str(host) + ') swp info "' + str(swp) + '": unrecognized unit, reset it to "0".')
                swp = 0
            item = QTableWidgetItem()
            item.setData(Qt.DisplayRole, int(swp))
            self.hostsTabTable.setItem(i, j, item)

            j = j+1
            index = lshostsDic['HOST_NAME'].index(host)
            maxswp = lshostsDic['maxswp'][index]
            if re.search('M', maxswp):
                maxswp = re.sub('M', '', maxswp)
                maxswp = int(maxswp)/1024
            elif re.search('G', maxswp):
                maxswp = re.sub('G', '', maxswp)
            else:
                common.printWarning('*Warning*: host(' + str(host) + ') maxswp info "' + str(maxswp) + '": unrecognized unit, reset it to "0".')
                maxswp = 0
            item = QTableWidgetItem()
            item.setData(Qt.DisplayRole, int(maxswp))
            self.hostsTabTable.setItem(i, j, item)

    def hostsTabCheckClick(self, item=None):
        """
        If click the host name (or Njobs number), jump to the jobs Tab and show the host related jobs.
        """
        if item != None:
            currentRow = self.hostsTabTable.currentRow()
            host = self.hostsTabTable.item(currentRow, 0).text().strip()
            njobsNum = self.hostsTabTable.item(currentRow, 3).text().strip()

            if (item.column() == 0) or (item.column() == 3):
                if int(njobsNum) > 0:
                    self.jobsTabUserLine.setText('')
                    self.setJobsTabStatusCombo()
                    self.setJobsTabQueueCombo()

                    hostList = copy.deepcopy(self.queueHostList)
                    hostList.remove(host)
                    hostList.insert(0, host)
                    hostList.insert(1, 'ALL')
                    self.setJobsTabStartedOnCombo(hostList)

                    self.genJobsTabTable()
                    self.mainTab.setCurrentWidget(self.jobsTab)

                self.mainTab.setCurrentWidget(self.jobsTab)
## For hosts TAB (end) ## 


## For queues TAB (start) ## 
    def genQueuesTab(self):
        """
        Generate the queues tab on openlavaMonitor GUI, show queues informations.
        """
        # Init var
        self.bqueuesFilesDic = {}

        # self.queuesTab
        self.queuesTabTable = QTableWidget(self.queuesTab)
        self.queuesTabTable.itemClicked.connect(self.queuesTabCheckClick)

        self.queuesTabFrame0 = QFrame(self.queuesTab)
        self.queuesTabFrame0.setFrameShadow(QFrame.Raised)
        self.queuesTabFrame0.setFrameShape(QFrame.Box)

        self.queuesTabFrame1 = QFrame(self.queuesTab)
        self.queuesTabFrame1.setFrameShadow(QFrame.Raised)
        self.queuesTabFrame1.setFrameShape(QFrame.Box)

        # self.queuesTab - Grid
        queuesTabGrid = QGridLayout()

        queuesTabGrid.addWidget(self.queuesTabTable, 0, 0)
        queuesTabGrid.addWidget(self.queuesTabFrame0, 0, 1)
        queuesTabGrid.addWidget(self.queuesTabFrame1, 1, 0, 1, 2)

        queuesTabGrid.setRowStretch(0, 1)
        queuesTabGrid.setRowStretch(1, 10)
        queuesTabGrid.setColumnStretch(0, 1)
        queuesTabGrid.setColumnStretch(1, 10)

        queuesTabGrid.setRowMinimumHeight(0, 350)
        queuesTabGrid.setRowMinimumHeight(1, 150)
        queuesTabGrid.setColumnMinimumWidth(0, 328)
        queuesTabGrid.setColumnMinimumWidth(1, 500)

        self.queuesTab.setLayout(queuesTabGrid)

        # Generate sub-frame
        self.genQueuesTabTable()
        self.genQueuesTabFrame0()
        self.genQueuesTabFrame1()

    def genQueuesTabTable(self):
        self.queuesTabTable.setShowGrid(True)
        self.queuesTabTable.setColumnCount(3)
        self.queuesTabTable.setHorizontalHeaderLabels(['QUEUE', 'PEND', 'RUN'])

        # Hide the vertical header
        self.queuesTabTable.verticalHeader().setVisible(False)

        queuesDic = openlava_common.getBqueuesInfo()
        self.queuesTabTable.setRowCount(len(self.queueList))

        for i in range(len(self.queueList)):
            queue = self.queueList[i]
            index = queuesDic['QUEUE_NAME'].index(queue)

            j = 0
            item = QTableWidgetItem(queue)
            self.queuesTabTable.setItem(i, j, item)

            j = j+1
            pend = queuesDic['PEND'][index]
            item = QTableWidgetItem(pend)
            if int(pend) > 0:
                item.setFont(QFont('song', 10, QFont.Bold))
                item.setForeground(QBrush(Qt.red))
            self.queuesTabTable.setItem(i, j, item)

            j = j+1
            run = queuesDic['RUN'][index]
            item = QTableWidgetItem(run)
            self.queuesTabTable.setItem(i, j, item)

    def genQueuesTabFrame0(self):
        # self.queuesTabFrame0
        self.queuesTabJobNumCurveLabel = QLabel('queue (PEND/RUN) job number curve', self.queuesTabFrame0)
        self.queuesTabJobNumCurveLabel.setAlignment(Qt.AlignCenter)

        # self.queuesTabFrame0 - Grid
        queuesTabFrame0Grid = QGridLayout()
        queuesTabFrame0Grid.addWidget(self.queuesTabJobNumCurveLabel, 0, 0)
        self.queuesTabFrame0.setLayout(queuesTabFrame0Grid)

    def genQueuesTabFrame1(self):
        # self.queuesTabFrame1
        self.queuesTabText = QTextEdit(self.queuesTabFrame1)

        # self.queuesTabFrame1 - Grid
        queuesTabFrame1Grid = QGridLayout()
        queuesTabFrame1Grid.addWidget(self.queuesTabText, 0, 0)
        self.queuesTabFrame1.setLayout(queuesTabFrame1Grid)

    def queuesTabCheckClick(self, item=None):
        """
        If click the queue name, jump to the jobs Tab and show the queue related jobs.
        If click the PEND number, jump the jobs Tab and show the queue PEND related jobs.
        If click the RUN number, jump the jobs Tab and show the queue RUN related jobs.
        """
        if item != None:
            currentRow = self.queuesTabTable.currentRow()
            queue      = self.queuesTabTable.item(currentRow, 0).text().strip()
            pendNum    = self.queuesTabTable.item(currentRow, 1).text().strip()
            runNum     = self.queuesTabTable.item(currentRow, 2).text().strip()

            if item.column() == 0:
                print('* Checking queue "' + str(queue) + '".')
                self.updateQueueTabFrame0(queue)
                self.updateQueueTabFrame1(queue)
            elif item.column() == 1:
                if (pendNum != '') and (int(pendNum) > 0):
                    self.jobsTabUserLine.setText('')

                    statusList = ['PEND', 'RUN', 'ALL']
                    self.setJobsTabStatusCombo(statusList)

                    queueList = copy.deepcopy(self.queueList)
                    queueList.remove(queue)
                    queueList.insert(0, queue)
                    queueList.insert(1, 'ALL')
                    self.setJobsTabQueueCombo(queueList)

                    self.setJobsTabStartedOnCombo()
                    self.genJobsTabTable()
                    self.mainTab.setCurrentWidget(self.jobsTab)
            elif item.column() == 2:
                if (runNum != '') and (int(runNum) > 0):
                    self.jobsTabUserLine.setText('')

                    statusList = ['RUN', 'PEND', 'ALL']
                    self.setJobsTabStatusCombo(statusList)

                    queueList = copy.deepcopy(self.queueList)
                    queueList.remove(queue)
                    queueList.insert(0, queue)
                    queueList.insert(1, 'ALL')
                    self.setJobsTabQueueCombo(queueList)

                    self.setJobsTabStartedOnCombo()
                    self.genJobsTabTable()
                    self.mainTab.setCurrentWidget(self.jobsTab)

    def updateQueueTabFrame0(self, queue):
        """
        Draw queue (PEND/RUN) job number current job, save the png picture and show it on self.queuesTabFrame0.
        """
        self.queuesTabJobNumCurveLabel.setText('queue (PEND/RUN) job number curve')

        # Generate queue job number curve with the specified job id
        self.myDrawCurve.drawQueueJobNumCurve(queue)
        queueJobNumCurveFig = str(config.tmpPath) + '/' + str(user) + '_' + str(queue) + '_jobNum.png'

        if os.path.exists(queueJobNumCurveFig):
            pixMap = QPixmap(queueJobNumCurveFig).scaled(self.queuesTabJobNumCurveLabel.width(), self.queuesTabJobNumCurveLabel.height())
            self.queuesTabJobNumCurveLabel.setPixmap(pixMap)
        else:
            warningMessage = '*Warning*: Not find queue job number curve fig "' + str(queueJobNumCurveFig) + '".'
            self.guiWarning(warningMessage)

    def updateQueueTabFrame1(self, queue):
        """
        Show queue detailed informations on self.queuesTabText.
        """
        self.queuesTabText.clear()

        command = 'bqueues -l ' + str(queue)
        lines = os.popen(command).readlines()

        for line in lines:
            self.queuesTabText.insertPlainText(line)

        pyqt5_common.textEditVisiblePosition(self.queuesTabText, 'Start')
## For queues TAB (end) ## 

    def closeEvent(self, QCloseEvent):
        """
        When window close, post-process.
        """
        print('Bye')
コード例 #33
0
ファイル: channels.py プロジェクト: mattgaidica/ARBO_MATLAB
class Channels(QWidget):
    """Widget with information about channel groups.

    Attributes
    ----------
    parent : QMainWindow
        the main window
    config : ConfigChannels
        preferences for this widget

    filename : path to file
        file with the channel groups
    groups : list of dict
        each dict contains information about one channel group

    tabs : QTabWidget
        Widget that contains the tabs with channel groups
    """
    def __init__(self, parent):
        super().__init__()
        self.parent = parent
        self.config = ConfigChannels(lambda: None)

        self.filename = None
        self.groups = []

        self.tabs = None

        self.create()
        self.create_action()

    def create(self):
        """Create Channels Widget"""
        add_button = QPushButton('New')
        add_button.clicked.connect(self.new_group)
        color_button = QPushButton('Color')
        color_button.clicked.connect(self.color_group)
        del_button = QPushButton('Delete')
        del_button.clicked.connect(self.del_group)
        apply_button = QPushButton('Apply')
        apply_button.clicked.connect(self.apply)

        self.button_add = add_button
        self.button_color = color_button
        self.button_del = del_button
        self.button_apply = apply_button

        buttons = QGridLayout()
        buttons.addWidget(add_button, 0, 0)
        buttons.addWidget(color_button, 1, 0)
        buttons.addWidget(del_button, 0, 1)
        buttons.addWidget(apply_button, 1, 1)

        self.tabs = QTabWidget()

        layout = QVBoxLayout()
        layout.addLayout(buttons)
        layout.addWidget(self.tabs)

        self.setLayout(layout)

        self.setEnabled(False)
        self.button_color.setEnabled(False)
        self.button_del.setEnabled(False)
        self.button_apply.setEnabled(False)

    def create_action(self):
        """Create actions related to channel selection."""
        actions = {}

        act = QAction('Load Montage...', self)
        act.triggered.connect(self.load_channels)
        act.setEnabled(False)
        actions['load_channels'] = act

        act = QAction('Save Montage...', self)
        act.triggered.connect(self.save_channels)
        act.setEnabled(False)
        actions['save_channels'] = act

        self.action = actions

    def update(self):
        self.setEnabled(True)
        self.action['load_channels'].setEnabled(True)
        self.action['save_channels'].setEnabled(True)

    def new_group(self, checked=False, test_name=None):
        """Create a new channel group.

        Parameters
        ----------
        checked : bool
            comes from QAbstractButton.clicked
        test_name : str
            used for testing purposes to avoid modal window

        Notes
        -----
        Don't call self.apply() just yet, only if the user wants it.
        """
        chan_name = self.parent.labels.chan_name
        if chan_name is None:
            msg = 'No dataset loaded'
            self.parent.statusBar().showMessage(msg)
            lg.debug(msg)

        else:
            if test_name is None:
                new_name = QInputDialog.getText(self, 'New Channel Group',
                                                'Enter Name')
            else:
                new_name = [test_name, True]  # like output of getText

            if new_name[1]:
                s_freq = self.parent.info.dataset.header['s_freq']
                group = ChannelsGroup(chan_name, new_name[0],
                                      self.config.value, s_freq)
                self.tabs.addTab(group, new_name[0])
                self.tabs.setCurrentIndex(self.tabs.currentIndex() + 1)

                # activate buttons
                self.button_color.setEnabled(True)
                self.button_del.setEnabled(True)
                self.button_apply.setEnabled(True)

    def color_group(self, checked=False, test_color=None):
        """Change the color of the group."""
        group = self.tabs.currentWidget()
        if test_color is None:
            newcolor = QColorDialog.getColor(group.idx_color)
        else:
            newcolor = test_color
        group.idx_color = newcolor

        self.apply()

    def del_group(self):
        """Delete current group."""
        idx = self.tabs.currentIndex()
        self.tabs.removeTab(idx)

        self.apply()

    def apply(self):
        """Apply changes to the plots."""
        self.read_group_info()

        if self.tabs.count() == 0:
            # disactivate buttons
            self.button_color.setEnabled(False)
            self.button_del.setEnabled(False)
            self.button_apply.setEnabled(False)
        else:
            # activate buttons
            self.button_color.setEnabled(True)
            self.button_del.setEnabled(True)
            self.button_apply.setEnabled(True)

        if self.groups:
            self.parent.overview.update_position()
            self.parent.spectrum.update()
            self.parent.notes.enable_events()
        else:
            self.parent.traces.reset()
            self.parent.spectrum.reset()
            self.parent.notes.enable_events()

    def read_group_info(self):
        """Get information about groups directly from the widget."""
        self.groups = []
        for i in range(self.tabs.count()):
            one_group = self.tabs.widget(i).get_info()
            # one_group['name'] = self.tabs.tabText(i)
            self.groups.append(one_group)

    def load_channels(self, checked=False, test_name=None):
        """Load channel groups from file.

        Parameters
        ----------
        test_name : path to file
            when debugging the function, you can open a channels file from the
            command line
        """
        chan_name = self.parent.labels.chan_name

        if self.filename is not None:
            filename = self.filename
        elif self.parent.info.filename is not None:
            filename = (splitext(self.parent.info.filename)[0] +
                        '_channels.json')
        else:
            filename = None

        if test_name is None:
            filename, _ = QFileDialog.getOpenFileName(
                self, 'Open Channels Montage', filename,
                'Channels File (*.json)')
        else:
            filename = test_name

        if filename == '':
            return

        self.filename = filename
        with open(filename, 'r') as outfile:
            groups = load(outfile)

        s_freq = self.parent.info.dataset.header['s_freq']
        no_in_dataset = []
        for one_grp in groups:
            no_in_dataset.extend(set(one_grp['chan_to_plot']) - set(chan_name))
            chan_to_plot = set(chan_name) & set(one_grp['chan_to_plot'])
            ref_chan = set(chan_name) & set(one_grp['ref_chan'])

            group = ChannelsGroup(chan_name, one_grp['name'], one_grp, s_freq)
            group.highlight_channels(group.idx_l0, chan_to_plot)
            group.highlight_channels(group.idx_l1, ref_chan)
            self.tabs.addTab(group, one_grp['name'])

        if no_in_dataset:
            msg = 'Channels not present in the dataset: ' + ', '.join(
                no_in_dataset)
            self.parent.statusBar().showMessage(msg)
            lg.debug(msg)

        self.apply()

    def save_channels(self, checked=False, test_name=None):
        """Save channel groups to file."""
        self.read_group_info()

        if self.filename is not None:
            filename = self.filename
        elif self.parent.info.filename is not None:
            filename = (splitext(self.parent.info.filename)[0] +
                        '_channels.json')
        else:
            filename = None

        if test_name is None:
            filename, _ = QFileDialog.getSaveFileName(
                self, 'Save Channels Montage', filename,
                'Channels File (*.json)')
        else:
            filename = test_name

        if filename == '':
            return

        self.filename = filename

        groups = deepcopy(self.groups)
        for one_grp in groups:
            one_grp['color'] = one_grp['color'].rgba()

        with open(filename, 'w') as outfile:
            dump(groups, outfile, indent=' ')

    def reset(self):
        """Reset all the information of this widget."""
        self.filename = None
        self.groups = []

        self.tabs.clear()

        self.setEnabled(False)
        self.button_color.setEnabled(False)
        self.button_del.setEnabled(False)
        self.button_apply.setEnabled(False)
        self.action['load_channels'].setEnabled(False)
        self.action['save_channels'].setEnabled(False)
コード例 #34
0
class central(QWidget): #Cria widget para colocar na janela central onde as duas
    
    def __init__(self):
        super().__init__()
        self.setWindowIcon(QIcon("icons/icone_TCC.png"))
        self.UI()
    
    def UI(self):
        main = QVBoxLayout() #Widget principal, onde serão colocadas todas as abas
        self.unit_y = "Ângulo de deflexão (° graus)"
        self.unit_x = "Segundos (s)"
        self.lines = [] #Lista das linhas do listwidget reinicia
        self.tabela_param = 830
        self.passw = "lembrei"
        
        # Cria os principais layouts que serão inseridos nas 4 abas do software 
        self.main_tab = QHBoxLayout() #Layout para a aba principal
        db_tab = QVBoxLayout() #Layout para a aba dos dados
        rep_tab = QVBoxLayout() #Aba dos relatórios
        info_tab = QVBoxLayout() #Aba das informações
        
        """
        Widgets da primeira aba
        """
        fonte = QFont() #Cria a fonte em negrito
        fonte.setBold(True)
        #Cria o formulário dos parâmetros, controle e barra de progresso
        self.formulario = QVBoxLayout() #Cria o form das principais atividades 
        self.lbl_void = QLabel() #Label vazio para espaçar os dados
        self.lbl_imp = QLabel("Dir. do Sistema",self) #Label da importação do benchmark
        self.lbl_imp.setFont(fonte)
        #self.lbl_icon.setAlignment(Qt.AlignCenter)
        self.btn_bch = QPushButton("Benchmark")
        self.btn_bch.clicked.connect(self.bench)
        self.lbl_param = QLabel("Parametrização",self)
        self.lbl_param.setFont(fonte)
        self.lbl_font = QLabel("Fonte da OFC: ")
        self.cmb_font = QComboBox(self) #Cria o combobox do primeiro parâmetro
        self.cmb_font.addItems(font) #Carrega lista das fontes de perturbação
        self.cmb_font.currentTextChanged.connect(self.pdate_ampl)
        self.hbox_font = QHBoxLayout()
        self.hbox_font.addWidget(self.lbl_font)
        self.hbox_font.addWidget(self.cmb_font)
        self.lbl_type = QLabel("Tipo da OFC: ")
        self.cmb_type = QComboBox(self) #Cria o combobox do primeiro parâmetro
        self.cmb_type.addItems(type_ofc) #Carrega lista das fontes de perturbação
        self.hbox_type = QHBoxLayout()
        self.hbox_type.addWidget(self.lbl_type)
        self.hbox_type.addWidget(self.cmb_type)
        self.lbl_turb = QLabel("Turbulência: ")
        self.cmb_turb = QComboBox(self) #Cria o combobox do segundo parâmetro
        self.cmb_turb.addItems(turb)
        self.hbox_turb = QHBoxLayout()
        self.hbox_turb.addWidget(self.lbl_turb)
        self.hbox_turb.addWidget(self.cmb_turb)
        self.lbl_ctrl1 = QLabel("Tipo Controle: ")
        self.cmb_ctrl1 = QComboBox(self)#Cria o combobox do terceiro parâmetro
        self.cmb_ctrl1.addItems(ctrl)
        self.hbox_ctrl1 = QHBoxLayout()
        self.hbox_ctrl1.addWidget(self.lbl_ctrl1)
        self.hbox_ctrl1.addWidget(self.cmb_ctrl1)
        self.lbl_ampl = QLabel("Ampl(mm)/Bias(mm)/Freq(rad/s):")
        self.cmb_ampl = QComboBox(self) #Cria o combobox das unidades do eixo das abscissas
        self.cmb_ampl.addItems(ampl)
        self.cmb_bias = QComboBox(self) #Cria o combobox das unidades do eixo das abscissas
        self.cmb_bias.addItems(bias)
        self.cmb_freq = QComboBox(self) #Cria o combobox das unidades do eixo das oordenadas
        self.cmb_freq.addItems(freq)
        self.amp_bias_freq = QHBoxLayout()
        self.amp_bias_freq.addWidget(self.cmb_ampl,30)
        self.amp_bias_freq.addWidget(self.cmb_bias,30)
        self.amp_bias_freq.addWidget(self.cmb_freq,40)
        self.lbl_ctrl = QLabel("Painel de Controle",self)
        self.lbl_ctrl.setFont(fonte)
        self.lbl_bench = QLabel("Modelo .lsx Benchmark: ")
        self.cmb_bench = QComboBox(self) #Cria o combobox das unidades do eixo das oordenadas
        self.lbl_treino = QLabel("Modo de Treinamento: ")
        self.cmb_treino = QComboBox(self) #Cria o combobox das unidades do eixo das oordenadas
        self.cmb_treino.addItems(treino)
        self.lbl_time = QLabel("Tempo de Simulação: ")
        self.line_time = QLineEdit()
        self.line_time.setPlaceholderText("Segundos")
        self.hbox_time = QHBoxLayout()
        self.hbox_time.addWidget(self.lbl_time)
        self.hbox_time.addWidget(self.line_time)
        self.list_status = QListWidget()
        self.list_status.doubleClicked.connect(self.exp_rep)
        self.btn_start = QPushButton("Iniciar")
        self.btn_start.clicked.connect(self.start)
        self.btn_start.setDisabled(True)
        self.pbar = QProgressBar()
        self.pbar.setFont(fonte)
        #Insere no formulário os widgets:
        self.formulario.addStretch()
        cp = QDesktopWidget().availableGeometry().center()
        if cp.y()*2 >= 1030: #Se a resolução for alta, coloca o ícone da pontifícia
            self.tabela_param = 1385
            self.lbl_icon = QLabel() #Label que armazena o icone
            #Icone da pontifícia:
            icone_tcc = QPixmap("icons/TCC_Icon.png")#.scaled(50, 61, Qt.KeepAspectRatio, Qt.FastTransformation)
            self.lbl_icon.setPixmap(icone_tcc)
            self.lbl_icon.setAlignment(Qt.AlignCenter)
            self.formulario.addWidget(self.lbl_icon)
            self.passw = ""
            #self.benchmark_path = r"D:/PUCPR/TRABALHO DE CONCLUSAO DO CURSO - TCC/SOFT SENSORS"
            
        self.formulario.addWidget(self.lbl_imp)
        self.formulario.addWidget(self.btn_bch)
        self.formulario.addWidget(QHLine())#)#self.lbl_void) #Espaçamento
        self.formulario.addWidget(self.lbl_param)
        self.formulario.addLayout(self.hbox_font)
        self.formulario.addLayout(self.hbox_type)
        self.formulario.addLayout(self.hbox_turb)
        self.formulario.addLayout(self.hbox_ctrl1)
        self.formulario.addWidget(self.lbl_ampl)
        self.formulario.addLayout(self.amp_bias_freq)
        self.formulario.addWidget(QHLine())#self.lbl_void) #Espaçamento
        self.formulario.addWidget(self.lbl_ctrl)
        self.formulario.addWidget(self.lbl_bench)
        self.formulario.addWidget(self.cmb_bench)
        self.formulario.addWidget(self.lbl_treino)
        self.formulario.addWidget(self.cmb_treino)
        self.formulario.addLayout(self.hbox_time)
        self.formulario.addWidget(self.btn_start)
        self.formulario.addWidget(self.list_status)
        self.formulario.addWidget(self.pbar)
        self.formulario.setAlignment(Qt.AlignCenter)
        self.formulario.addStretch()
        
        #cria o gráfico
        self.grafico = PlotWidget()
        self.grafico.setBackground('#323232') #Coloca a cor de fundo igual a do restante da interface
        # Coloca título no gráfico
        self.grafico.setTitle("Simulação do Benchmark OFC: AirBus", color="#56fceb", size="20pt")
        self.styles = {"color": "#56fceb", "font-size": "16px"} #Cria os estilos de fonte do gráfico
        self.grafico.setLabel("left", self.unit_y, **self.styles) #Insere a unidade do eixo Oordenado
        self.grafico.setLabel("bottom", self.unit_x, **self.styles) #Insere a unidade do eixo das Abscissas
        self.grafico.addLegend() #Coloca legenda no gráfico
        self.grafico.showGrid(x=True, y=True) #Coloca as grids no gráfico
        
        #Cria as três curvas que serão periodicamente atualizadas
        #self.dx_falhas = ScatterPlotItem(name="Falhas: OFC", symbolSize=10,symbol='x',symbolBrush=("#fc031c"), 
        #                                 pen=mkPen(color="#fc031c", width=1))
        #self.grafico.addItem(self.dx_falhas)
        self.dx_comm = self.grafico.plot(name="Comando de Controle", symbolSize=5,symbolBrush=("#15bf48"), 
                                         pen=mkPen(color="#15bf48", width=2))
        self.dx_meas = self.grafico.plot(name="Deflexão Mensurada", symbolSize=5,symbolBrush=("#56fceb"), 
                                         pen=mkPen(color="#56fceb", width=2))
        self.dx_falhas = self.grafico.plot(name="Falhas: OFC", symbolSize=20,symbol='x',symbolBrush=("#fc031c"), 
                                           pen=mkPen(color="#323232", width=0.001))
        
        self.formulario.addStretch()
        #Insere os widgets na widget da aba
        self.main_tab.addLayout(self.formulario,13.5) #Adiciona a aba os parâmetros 
        self.main_tab.addWidget(self.grafico,86.5) #Adiciona o gráfico a aba principal
        
        """
        Cria os widgets da segunda tab
        """
        self.db_table = QTableView() #Cria tabela do banco de dados
        #Itens abaixo da tabela
        self.btn_consulta = QPushButton("Consultar o Número de itens mais Atuais")
        self.btn_consulta.clicked.connect(self.update_tb)
        self.n_itens = QLineEdit()
        self.n_itens.setPlaceholderText("N° Itens")
        self.status_itens = QLineEdit()
        self.status_itens.setPlaceholderText("Status do software:")
        self.status_itens.setDisabled(True)
        self.btn_pdate = QPushButton("Atualiza para os 1000 últimos dados registrados")
        self.btn_pdate.clicked.connect(self.update_tb_1000)
        self.btn_exp = QPushButton("Exportar tabela para Excel")
        self.btn_exp.clicked.connect(self.exp_dados_excel)
        self.pbar_db = QProgressBar()
        self.pbar_db.setFont(fonte)
        self.db_func = QHBoxLayout() #Layout dos botões abaixo da tabela
        self.db_func.addWidget(self.btn_consulta,28)
        self.db_func.addWidget(self.n_itens,4.5)
        self.db_func.addWidget(self.status_itens,8.5)
        self.db_func.addWidget(self.pbar_db,25)
        self.db_func.addWidget(self.btn_pdate,21)
        self.db_func.addWidget(self.btn_exp,12)
        #Insere abaixo da tabela os itens:
        db_tab.addWidget(self.db_table,93)
        db_tab.addLayout(self.db_func,7)
        db_tab.addStretch()
        
        """
        Cria os widgets da terceira aba
        """
        self.rep_table = QTableView() #Cria tabela do relatório
        #Itens abaixo da tabela
        self.btn_pdate_rep = QPushButton("Atualiza para todos os dados registrados")
        self.btn_pdate_rep.clicked.connect(self.update_rep)
        self.btn_rep = QPushButton("Atualiza para todos últimos 'N' dados registrados")
        self.btn_rep.clicked.connect(self.update_rep_n)
        self.btn_exp_rep = QPushButton("Exportar relatório para Excel")
        self.btn_exp_rep.clicked.connect(self.exp_rep_excel)
        self.n_itens_rep = QLineEdit()
        self.n_itens_rep.setPlaceholderText("N° Itens")
        self.status_itens = QLineEdit()
        self.pbar_rep = QProgressBar()
        self.pbar_rep.setFont(fonte)
        self.rep_func = QHBoxLayout() #Layout dos botões abaixo da tabela
        self.rep_func.addWidget(self.btn_pdate_rep,20)
        self.rep_func.addWidget(self.btn_rep,22)
        self.rep_func.addWidget(self.n_itens_rep,4.5)
        self.rep_func.addWidget(self.pbar_rep,38)
        self.rep_func.addWidget(self.btn_exp_rep,15.5)
        #Insere abaixo da tabela os itens:
        rep_tab.addStretch()
        rep_tab.addWidget(self.rep_table,90)
        rep_tab.addLayout(self.rep_func,10)
        rep_tab.addStretch()
        
        """
        Cria os widgets da aba informativa
        """
        #Cria a aba informativa do final
        self.mapa = QLabel() #
        self.mapa.setPixmap(QPixmap("icons/MAPA_MENTAL.png"))
        info_tab.addWidget(self.mapa)
        info_tab.setAlignment(Qt.AlignHCenter)

        ############################Criando abas##############################
        self.tabs = QTabWidget() #Widget das tabs que reune as 4
        self.tab1 = QWidget() #Tab de emulação do benchmark
        self.tab2 = QWidget() #Tab do banco de dados
        self.tab3 = QWidget() #Relatório de Falhas
        self.tab4 = QWidget() #Informações complementares
        self.tabs.addTab(self.tab1,"Simulação do Sistema")
        self.tabs.addTab(self.tab2,"Consulta Geral ao Banco de Dados")
        self.tabs.addTab(self.tab3,"Consultar Tabela do Relatório de Falhas")
        self.tabs.addTab(self.tab4,"Informações sobre o TCC: Mapa Mental")
        
        self.tab1.setLayout(self.main_tab) # Adicionando a aba de simulação
        self.tab2.setLayout(db_tab) # Adicionando adicionando aba do db
        self.tab3.setLayout(rep_tab) # Adicionando adcionando aba
        self.tab4.setLayout(info_tab) # Adicionando para a tab1
        
        #Adiciona ao box principal a estrutura de tabs
        main.addWidget(self.tabs) #Coloca a estrutura de tabs no layout principal
        self.setLayout(main)
    
    def plot(self, x, y, plotname, color):
        pen = mkPen(color=color)
        self.grafico.plot(x, y, name=plotname, pen=pen, symbolSize=5, symbolBrush=(color))
    
    def maria_conn(self):
        try:
            self.conn = mariadb.connect(
                user="******",
                password=self.passw,
                host="127.0.0.1",
                port=3306,
                database="db_ofc_tcc")
            self.cur = self.conn.cursor()
        except mariadb.Error as e:
            QMessageBox.warning(self,"Aviso",f"Sem conexão com o Banco de dados, devido ao erro: {e}")
    
        self.list_status.addItem("Conectado ao db_tcc")
        if "Conectado ao db_tcc" not in self.lines: #Se não estiver coloca
            self.lines.append("Conectado ao db_tcc")
        
    def bench(self):
        ask_dir = "Escolha o diretório onde o Benchmark se encontra"
        self.benchmark = str(QFileDialog.getExistingDirectory(None,ask_dir))
        self.list_status.clear() #Limpa a lista toda vez que o botão de benchmark é pressionado
        if self.benchmark != '': #Se não for vazio, continua
            arqs = os.listdir(self.benchmark)
            bench = [] #Reiniciado quando escolhida outra pasta
            self.lines = [] #Lista das linhas do listwidget reinicia
            
            for arq in arqs:
                if '.slx' in arq: #Se a extenção do arquivo for a mesma do simulink
                    bench.append(arq)
            
            if not(bench): #Se o vetor estiver vazio
                not_bench = f"Não foi encontrado arquivo do simulink no diretório selecionado {self.benchmark}!"
                QMessageBox.warning(self,"Aviso!",not_bench)
            else:
                self.list_status.addItem(f"Diretório: {self.benchmark}")
                self.lines.append("\n-------------------------------------------------------------\n")
                self.lines.append(f"Diretório: {self.benchmark}")
                self.cmb_bench.addItems(bench)
                self.maria_conn() #Inicia conexão com o banco de dados
                self.btn_start.setDisabled(False) #Habilita o botão para iniciar os testes
                self.pbar.setValue(10)#Coloca 10% na barra de progresso
    
    def get_param(self):
        
        print(self.line_time.text())
        #Valida o que o usuário digitou
        try: 
            if float(self.line_time.text()) < 0:
                QMessageBox.warning(None,"Erro!","Insira um valor numérico real não negativo no Tempo de Simulação!")
                return
            else:
                simu_time = float(self.line_time.text())
        except: 
            QMessageBox.warning(None,"Erro!","Insira um valor numérico real não negativo no Tempo de Simulação!")
            return
        
        #Define a função de turbulência da classe aircraft
        turb = self.cmb_turb.currentText()
        if turb == 'None':
            func_turb = "setNoTurbulence()"
        elif turb == 'Light':
            func_turb = "setLightTurbulence()"
        elif turb == 'Moderate':
            func_turb = "setModerateTurbulence()"
        elif turb == 'Severe':
            func_turb = "setSevereTurbulence()"
            
        param = [self.cmb_font.currentText(),self.cmb_type.currentText(),self.cmb_ampl.currentText(),
                 self.cmb_bias.currentText(),self.cmb_freq.currentText().replace("π","*pi"),func_turb,
                 self.cmb_ctrl1.currentIndex()+1,simu_time]
        print(param)
        
        return param
        
    def start(self):
        global Relatorio_TXT_Etapas, time, time_fail, delta_comm, delta_meas, ofc_falhas
        
        #Limpa variáveis globais
        time = []
        time_fail = []
        delta_comm = []
        delta_meas = []
        ofc_falhas = []

        #Treina os parâmetros
        simu = self.cmb_bench.currentText()
        self.system = self.benchmark+"/"+self.cmb_bench.currentText() #Caminho do sistema
        #monitora(system) #chama o simulink para emular o sistema
        quest = f"O sistema para emulação no Simulink é {self.system}?"
        if QMessageBox.question(self,"Tem certeza?",quest,QMessageBox.Yes|QMessageBox.No,
                                QMessageBox.No) == QMessageBox.Yes:
            self.metodo = self.cmb_treino.currentText() #Pega do combo o texto do modelo a treinar
            
            self.benchmark_simu = self.cmb_bench.currentText()
            
            self.parametros = self.get_param() #Recebe os parâmetros informados pelo usuário
            if not self.parametros:
                self.line_time.setFocus()
                return
            
            self.list_status.addItem(f"Treinando o modelo {simu} pelo método {self.metodo}")
            self.lines.append(f"Treinando o modelo {simu} pelo método {self.metodo}")
            self.pbar.setValue(15)
            
            #Chama a classe do treino
            tic_mdl = datetime.now()
            #Dá ao usuário a possibilidade de treinar ou carregar modelo
            quest2 = "Deseja treinar os dados? O não implica em carregar módulo default de treino"
            if QMessageBox.question(self,"Treinar ou não?",quest2,QMessageBox.Yes|QMessageBox.No,
                                QMessageBox.No) == QMessageBox.Yes and self.metodo != 'Support Vector Machine':
                self.modelo = treina_modelo(self.metodo,True)
                method = "Treinado"
            else: #Se for SVM, carrega o modelo pronto ao invez de treinar
                self.modelo = treina_modelo(self.metodo,False)
                method = "Carregado"
            
            self.list_status.addItem(f"Modelo {simu} foi {method} pelo método {self.metodo} em {datetime.now()-tic_mdl}")
            self.lines.append(f"Modelo {simu} foi {method} pelo método {self.metodo} em {datetime.now()-tic_mdl}")
            self.pbar.setValue(25)
            self.list_status.addItem(f"Iniciando {self.system} no Simulink")
            self.lines.append(f"Iniciando {self.system} no Simulink")
            #monitora(system) #Associa o monitoramento 
            
            self.list_status.addItem("Iniciando o MatLab (estimado: 13.6s)")
            self.lines.append("Iniciando o MatLab (estimado: 13.6s)")

            self.pbar.setValue(30)
            tic_matlab = datetime.now()
            
            self.eng = matlab.engine.start_matlab() #Background true para receber os valores
            self.list_status.addItem(f"O MatLab foi iniciado em {datetime.now()-tic_matlab}")
            self.lines.append(f"O MatLab foi iniciado em {datetime.now()-tic_matlab}")
            
            print(self.benchmark)
            self.eng.addpath(self.benchmark,nargout=0)
            
            #Função que carrega todas as variáveis necessárias pra se iniciar o simulink
            self.SimulinkPlant(self.parametros)
            self.list_status.addItem("Carregando modelo no SimuLink (estimado: 6.35s)")
            self.lines.append("Carregando modelo no SimuLink (estimado: 6.35s)")
            self.pbar.setValue(32.5)
            self.eng.eval(f"model = '{self.system}'",nargout=0)
            self.eng.eval(f"simulation.setSimulinkModel('{self.benchmark_simu}');",nargout=0)

            self.pbar.setValue(35)
            self.list_status.addItem("Carregando prâmetros ao modelo Simulink")
            self.lines.append("Carregando prâmetros ao modelo Simulink")
            
            tic_m = datetime.now()
            self.eng.eval("SimOut = sim(simulation.simulink_model, 'SrcWorkspace', 'current');",nargout=0)
            self.processo = self.eng.eval("""[SimOut.dx_comm SimOut.dx_meas SimOut.time];""")
            self.list_status.addItem(f"O Modelo {simu} foi treinado pelo método {self.metodo} em {datetime.now()-tic_m}")
            self.lines.append(f"O Modelo {simu} foi treinado pelo método {self.metodo} em {datetime.now()-tic_m}")

            self.pbar.setValue(40)
            self.list_status.addItem(f"Emulando {self.system} no Simulink")
            self.lines.append(f"Emulando {self.system} no Simulink")
            Relatorio_TXT_Etapas = self.lines
            #Emulação do sistema
            
            self.delta_comm = [] #Zera a lista de declara
            self.delta_meas = []
            self.ofc_fail = [] #Armazena dados das falhas encontradas
            self.time_fail = []
            self.time = []
            self.barra = 40
            self.janela = 40 #Tamanho da janela de dados a ser colatada
            self.i = 0 #Número da iteração
            self.total_itter = self.parametros[-1]*40 + 1 #Numero total de iterações
            #Loop do timar para plotar o gráfico
            self.timer = QTimer()
            self.timer.setInterval(10)
            self.timer.timeout.connect(self.update_graph)
            QMessageBox.information(self,"Aviso",f"O {self.system} será emulado")
            self.timer.start()
            
        else:
            pass
    
    def update_graph(self):
        
        global time, delta_comm, delta_meas, simulado, ofc_falhas, time_fail
        self.barra += (self.i/(self.total_itter) - 0.4*(self.i/self.total_itter))/(self.total_itter/200.4)

        #Recebe apenas os valores desejados, comando, medida e tempo
        self.delta_comm.append(self.processo[self.i][0])
        self.delta_meas.append(self.processo[self.i][1])
        self.time.append(self.processo[self.i][2])
        
        dat = [self.processo[self.i][0],self.processo[self.i][1],self.processo[self.i][2]]
        
        win = []
        for i in range(self.janela):
            if self.i < self.total_itter-self.janela:
                win.append(float(self.processo[i+self.i][0])) #Recebe o valor das janelas respectivas
            else:
                win.append(float(self.processo[randint(0,self.total_itter-1)][0])) #Revebe valor de indice aleatório
        
        w = array(win)
        result = int(self.modelo.predict(w.reshape(1,-1)).astype(int16)[0]) #Recebe 0 se não há falha e 1 se houver
        if result == 1: #Se é uma falha, acrescenta ao vetor o dado da falha
            self.ofc_fail.append(self.processo[self.i][1])
            self.time_fail.append(self.processo[self.i][2])
        
        reg = [dat[0],dat[1],dat[2],result,win] #Cria vetor com os dados e a classificação dos sinais
        self.update_db(reg,self.parametros) #Atualiza o banco de dados com a informação mais recente
        
        self.dx_comm.setData(self.time, self.delta_comm)
        self.dx_meas.setData(self.time, self.delta_meas)
        
        if self.ofc_fail: #Se houver dados nesse objeto
            self.dx_falhas.setData(self.time_fail, self.ofc_fail)
        else:
            self.dx_falhas.setData([0],[0])
        
        self.pbar.setValue(self.barra)#Coloca % na barra de progresso
        self.i += 1
        if self.i >= self.total_itter-1:
            print(self.barra)
            self.timer.stop()
            self.conn.commit()
            self.pbar.setValue(100)
            time = self.time
            delta_comm = self.delta_comm
            delta_meas = self.delta_meas
            ofc_falhas = self.ofc_fail
            time_fail = self.time_fail
            simulado = True #Variável que habilita impressão do gráfico
            QMessageBox.information(self,"Sucesso!",f"O processo {self.system} foi emulado com sucesso!")
            return
    
    def SimulinkPlant(self,param):
        """
        Essa função objetiva declarar as variáveis necessárias para desenvolvimento da simulação 
        
        Parameter
        ----------
        
        param: array
            Array com todos os parâmetros fornecidos pelo usuário    
        
        Returns
        -------
        None. Mas realiza inúmeros comandos para simular a planta e declarar as variáveis
    
        """
        
        #Iniciando o benchmark e carrega as principais variáveis ao console da API
        self.eng.eval("ofc_benchmark_init;",nargout=0)
        self.eng.eval("simulation.setSimulinkModel('ofc_benchmark_acquire');",nargout=0)
        #Carrega as variáveis: aircraft, ofc, servoModel, servoReal e simulation!
        
        self.eng.eval("servoReal.randomiseServoParameters()",nargout=0) #Faz o objeto servo real ficar aleatório
        self.eng.eval(f"ofc.setLocation('{param[0]}')",nargout=0)
        self.eng.eval(f"ofc.setType('{param[1]}')",nargout=0)
        self.eng.eval(f"ofc.setAmplitude({param[2]})",nargout=0)
        self.eng.eval(f"ofc.setBias({param[3]})",nargout=0)
        self.eng.eval(f"ofc.setFrequency({param[4]})",nargout=0)
        self.eng.eval("ofc.setPhase(0)",nargout=0)
        self.eng.eval("ofc.setStartTime(0)",nargout=0)
        self.eng.eval(f"aircraft.{param[5]}",nargout=0)
        
        #Cria sinal aleatório de controle
        self.eng.eval("""controls = {@(x)aircraft.setControlInput('FPA_control'), ...
                        @(x)aircraft.setControlInput('NZ_step', x(1), x(2), x(3)), ...
                        @(x)aircraft.setControlInput('NZ_sine', x(1), x(2), x(3), x(4)), ...
                        @(x)aircraft.setControlInput('NZ_chirp', x(1))};""",nargout=0)
        self.eng.eval("controls{"+str(param[6])+"}([10^randi([-1 1]),randi([10 25]),randi([35, 50]),randi([0, 10])])",
                        nargout=0)
        self.eng.eval(f"simulation.setStopTime({param[7]})",nargout=0) #Seta o tempo final de simulação
    
    def update_tb(self):
        global df
        
        self.pbar_db.setValue(0) #Zera a barra de progresso
        
        limite = self.n_itens.text()
        self.pbar_db.setValue(10)
        try:
            int(limite)
        except:
            QMessageBox.warning(self,"Atenção!","Insira um número inteiro!")
            return
        
        if int(limite) <= 0:
            QMessageBox.warning(self,"Atenção!","Insira um número positivo maior que zero!")
            return
        try:
            self.cur.execute(f"SELECT * FROM tb_ofc_dt ORDER BY id DESC LIMIT {limite};")
        except:
            self.maria_conn()
            self.cur.execute(f"SELECT * FROM tb_ofc_dt ORDER BY id DESC LIMIT {limite};")
        
        self.pbar_db.setValue(20)
        dados = self.cur.fetchall()
        #Convertendo os dados provenientes do banco de dados para um dataframe e  então envia para tabela
        self.df = DataFrame(dados, columns = ["id","data","Deflexão comando","Deflexão medida",
                                              "Tempo (s)","Falha","Parâmetros"])
        df = self.df
        self.pbar_db.setValue(30)
        
        self.db_table.setModel(pandasModel(self.df)) #Coloca os dados consultados na tabela
        self.db_table.setColumnWidth(0,45)
        self.db_table.setColumnWidth(1,120)
        self.db_table.setColumnWidth(2,105)
        self.db_table.setColumnWidth(3,105)
        self.db_table.setColumnWidth(4,65)
        self.db_table.setColumnWidth(5,42)
        self.db_table.setColumnWidth(6,self.tabela_param)
        self.pbar_db.setValue(100)
    
    def update_tb_1000(self):
        global Relatorio_TXT_Etapas, df
        
        try:
            self.cur.execute("SELECT * FROM tb_ofc_dt ORDER BY id DESC LIMIT 1000;")
        except:
            self.maria_conn()
            self.cur.execute("SELECT * FROM tb_ofc_dt ORDER BY id DESC LIMIT 1000;")
            
        falhas = self.cur.fetchall()
        self.list_status.addItem("O relatório de falhas foi gerado!")
        self.lines.append("O relatório de falhas foi gerado!")
        Relatorio_TXT_Etapas = self.lines
        
        self.df = DataFrame(falhas, columns = ["id","data","Deflexão comando","Deflexão medida",
                                              "Tempo (s)","Falha","Parâmetros"])
        df = self.df
        
        self.db_table.setModel(pandasModel(self.df))
        self.db_table.setColumnWidth(0,45)
        self.db_table.setColumnWidth(1,120)
        self.db_table.setColumnWidth(2,105)
        self.db_table.setColumnWidth(3,105)
        self.db_table.setColumnWidth(4,65)
        self.db_table.setColumnWidth(5,42)
        self.db_table.setColumnWidth(6,self.tabela_param)
        self.pbar_db.setValue(100)
    
    def update_db(self,dt,p):
        """
        Essa função cadastra um item no banco de dados

        Parameters
        ----------
        dt : tuple
            Linha proveniente do objeto de dados do matlab com três linhas (tempo, comando, medida e falha).
        p : list
            Lista dos parâmetros selecionados pelo usuário.
        Returns
        -------
        None.

        """
        global freq, ctrl, ampl
        fe = p[4].replace('*pi','π')
        pa = f"Metodo: {self.metodo}; F_OFC: {p[0]}; T_OFC: {p[1]}; Ampli.: {p[2]}; Bias: {p[3]}; Freq: {fe};"
        pa += f"Turb: {p[5].replace('()','')}; T_Ctrl: {ctrl[p[6]]}; t_simu: {p[7]}s; window: {dt[4]}"
        
        nw = datetime.now().strftime("%Y-%m-%d %H:%M:%S")#datetime.strftime(datetime.now(),"%d/%b/%Y - %H:%M")
        self.cur.execute("""INSERT INTO tb_ofc_dt (data,dx_comm,dx_meas,dt,falha,parametros) VALUES 
                         (?,?,?,?,?,?);""",[nw,dt[0],dt[1],dt[2],dt[3],pa])

    def exp_graph(self):
        """
        Essa função exporta o gráfico como está na tela em forma de imagem

        Returns
        -------
        None.

        """
        global time, delta_comm, delta_meas, simulado
        
        if simulado:
            ask_dir = "Escolha o diretório onde o deseja salvar o gráfico" #string que pergunta o diretório
            save = str(QFileDialog.getExistingDirectory(None,ask_dir)) #Pede ao usuário o diretório onde ele quer salvar
            self.grafico.plot(time,delta_comm, symbolSize=5,symbolBrush=("#15bf48"), 
                                                 pen=mkPen(color="#15bf48", width=2))
            self.grafico.plot(time,delta_meas, symbolSize=5,symbolBrush=("#56fceb"), 
                                                 pen=mkPen(color="#56fceb", width=2))
            self.grafico.plot(time_fail,ofc_falhas, symbolSize=15,symbol='x',symbolBrush=("#fc031c"), 
                                                     pen=mkPen(color="#323232", width=0.001))
            
            exporter = exporters.ImageExporter(self.grafico.plotItem) #Exporta o objeto do gráfico
            exporter.export(save+f'/graph_{int(datetime.timestamp(datetime.now()))}.png')  #Salva como png o gráfico
            QMessageBox.information(self,"Concluído!",f"Gráfico salvo com sucesso em: {save}")
        else:
            QMessageBox.warning(self,"Atenção!","O sistema ainda não foi emulado!")
    
    def exp_excel_all(self,aq):
        """
        Essa função exporta os dados adquiridos para uma planilha do excel

        Returns
        -------
        Não retorna parâmetros, apenas executa a ação de exportar para uma planilha

        """
        global df, dff
        
        if not(df.empty) or not(dff.empty): #Se um dos dois não for vazio
            salve = str(QFileDialog.getExistingDirectory(None, "Escolha o diretório onde quer salvar o relatório"))
            save = salve+"/Relatório_OFC_MFF.xlsx"
            
            if aq==0 and not(df.empty): #Se os dados foram coletados, gera dos dados
                df.to_excel(save,sheet_name="Relatório_OFC_MFF",index=False)
                info_save_excel = f"O relatório geral foi salvo em {save}!"
            elif aq==1 and not(dff.empty): #Se as falhas foram coletadas, gera as falhas
                dff.to_excel(save.replace("MFF","FALHAS_MFF"),sheet_name="Relatório_Falhas_OFC_MFF",index=False)
                info_save_excel = f"O relatório final das falhas de caráter oscilatória foi salvo em {save}!"
            elif aq==2 and (not(df.empty) or not(dff.empty)): #Salva ambos
                if not(df.empty):
                    df.to_excel(save,sheet_name="Relatório_OFC_MFF",index=False)
                    info_save_excel = f"O relatório geral foi salvo em {save}!"
                if not(dff.empty):
                    dff.to_excel(save.replace("MFF","FALHAS_MFF"),sheet_name="Relatório_Falhas_OFC_MFF",index=False)
                    info_save_excel = f"O relatório final das falhas de caráter oscilatória foi salvo em {save}!"

                if not(df.empty) and not(dff.empty):
                    info_save_excel = f"Os dois relatórios foram salvos em {save}!"

            QMessageBox.information(self,"Sucesso!",info_save_excel)
        else:
            info_not_save = "Nenhum dos dois relatórios foram gerados ainda!"
            QMessageBox.warning(self,"Atenção!",info_not_save)

    def exp_rep_excel(self):
        """
        Essa função exporta os dados adquiridos para uma planilha do excel

        Returns
        -------
        Não retorna parâmetros, apenas executa a ação de exportar para uma planilha

        """
        self.exp_excel_all(1)

    def exp_dados_excel(self):
        """
        Essa função exporta os dados adquiridos para uma planilha do excel

        Returns
        -------
        Não retorna parâmetros, apenas executa a ação de exportar para uma planilha

        """
        self.exp_excel_all(0)

    def exp_rep(self):
        """
        Exporta um relatório em txt com os dados de falhas é acionado ao clickar duas vezes na caixa com logs
        duplo click em 
        Returns
        -------
        None.

        """
        global Relatorio_TXT_Etapas #Insere na função a variável compartilhada entre classes
        if Relatorio_TXT_Etapas:
            dire = str(QFileDialog.getExistingDirectory(None, "Escolha o diretório para salvar o relatório em TXT!"))
            with open(dire+"/Relatorio_TXT_Etapas.txt",'w') as txt:
                txt.write("Relatório das etapas realizadas pelo software:\n")
                for line in Relatorio_TXT_Etapas: #Para cada linha, escreve no TXT
                    txt.write("\n"+str(line))
                    
            QMessageBox.information(None,"Feito!","O relatório com as etapas realizadas foi salvo com sucesso!")
        else:
            QMessageBox.warning(None,"Atenção!","O relatório com as etapas ainda não foi gerado!")
    
    def update_rep_n(self): #Essa função irá popular a tabela de dados
        global dff
        limit = self.n_itens_rep.text()
        self.pbar_rep.setValue(10) #Reseta o valor da barra de progresso para 10%
        try:
            int(limit)
        except:
            QMessageBox.warning(self,"Atenção!","Insira um número inteiro!")
            return
        
        try:
            self.cur.execute(f"SELECT * FROM tb_ofc_dt WHERE falha = 1 ORDER BY id DESC LIMIT {limit}")
        except:
            self.maria_conn()
            self.cur.execute(f"SELECT * FROM tb_ofc_dt WHERE falha = 1 ORDER BY id DESC LIMIT {limit}")

        falhas = self.cur.fetchall()
        self.dff = DataFrame(falhas, columns = ["id","data","Deflexão comando","Deflexão medida",
                                                "Tempo (s)","Falha","Parâmetros"])
        dff = self.dff
        self.rep_table.setModel(pandasModel(self.dff))
        self.rep_table.setColumnWidth(0,45)
        self.rep_table.setColumnWidth(1,120)
        self.rep_table.setColumnWidth(2,110)
        self.rep_table.setColumnWidth(3,100)
        self.rep_table.setColumnWidth(4,65)
        self.rep_table.setColumnWidth(5,42)
        self.rep_table.setColumnWidth(6,self.tabela_param)
        self.pbar_rep.setValue(100)
        
    def update_rep(self): #Essa função irá popular a tabela de dados
        global dff
        try:
            self.cur.execute("SELECT * FROM tb_ofc_dt WHERE falha = 1 ORDER BY id DESC")
        except:
            self.maria_conn()
            self.cur.execute("SELECT * FROM tb_ofc_dt WHERE falha = 1 ORDER BY id DESC")

        falhas = self.cur.fetchall()
        self.dff = DataFrame(falhas, columns = ["id","data","Deflexão comando","Deflexão medida",
                                                "Tempo (s)","Falha","Parâmetros"])
        dff = self.dff
        self.rep_table.setModel(pandasModel(self.dff))
        self.rep_table.setColumnWidth(0,45)
        self.rep_table.setColumnWidth(1,120)
        self.rep_table.setColumnWidth(2,110)
        self.rep_table.setColumnWidth(3,100)
        self.rep_table.setColumnWidth(4,65)
        self.rep_table.setColumnWidth(5,42)
        self.rep_table.setColumnWidth(6,self.tabela_param)
        self.pbar_rep.setValue(100)
    
    def pdate_ampl(self):
        if self.cmb_font.currentText() in ['sensor','cs_sensor']:
            self.lbl_ampl.setText("Ampl(mm)/Bias(mm)/Freq(rad/s):")
        else:
            self.lbl_ampl.setText("Ampl(mA)/Bias(mA)/Freq(rad/s):")
    
    def filed(self): #Abre o arquivo em forma de dicionário e retorna o caminho completo (posição 0)
        path = QFileDialog.getOpenFileName(self,"Abre um arquivo do excel","","All Files(*);;*xlsx *xls")
        
        if (".xls" in path[0]): #Se for um arquivo do excel
            modelo = ExcelFile(path[0]).parse(0,skiprows=1)# Carrega o template em um Excel e a planilha
            self.relatorio.setModel(pandasModel(modelo))
            self.tab2.setDisabled(False)
            self.tab2.update()
            self.update()
        else: #Se não for...
            QMessageBox.warning(self,"Arquivo incorreto","Escolha um arquivo do Excel (.xlsx ou .xls)!")
     
    def salva(self): #Salva o dataset do relatório em um arquivo excel
        global df, dff, Relatorio_TXT_Etapas, simulado
    
        if not(df.empty) or not(dff.empty) or Relatorio_TXT_Etapas or simulado: #Se tem algo para salvar, procede
            r1 = ""; r2 = ""; r3 = ""
            salve = str(QFileDialog.getExistingDirectory(None, "Escolha o diretório onde quer salvar o relatório"))
            save_total = salve+"/Relatório_OFC_MFF.xlsx"
            save_falhas = salve+"/Relatório_OFC_Falhas_MFF.xlsx"
            save_txt = salve+"/Relatorio_TXT_Etapas.txt"
            
            if not(df.empty): #Se o dataframe com os dados contar com mais de 0 codigos
                df.to_excel(save_total,sheet_name="Relatório_OFC_MFF",index=False)
                r1 = "Relatório_OFC_MFF,"
            if not(dff.empty): #Se as falhas foram coletadas, gera as falhas
                dff.to_excel(save_falhas,sheet_name="Relatório_Falhas_OFC_MFF",index=False)
                r2 = "Relatório_Falhas_OFC_MFF,"
            if len(Relatorio_TXT_Etapas) > 0: #Se o relatório txt não está vazio
                with open(save_txt,'w') as txt:
                    txt.write("Relatório das etapas realizadas pelo software:\n")
                    for line in Relatorio_TXT_Etapas: #Para cada linha, escreve no TXT
                        txt.write("\n"+str(line))
                r3 = "Relatorio_TXT_Etapas"
            
            duplas = (r1 or r2) or (r1 or r3) or (r2 or r3) #Uma dupla
            todos = (r1 and r2 and r3) #Todos
            solo = (r1 or r2 or r3) and not (duplas) #Apenas um
            
            if duplas: #Plural
                QMessageBox.information(self,"Sucesso!",f"Os relatórios: {r1}{r2}{r3} foram salvos!".replace(","," e "))
            elif todos:
                QMessageBox.information(self,"Sucesso!",f"Os relatórios: {r1}{r2}{r3} foram salvos!")
            elif solo: #Singular
                QMessageBox.information(self,"Sucesso!",f"O relatório: {r1}{r2}{r3} foi salvo!")
            if simulado:#Se foi simulado, exporta o gráfico
                if (QMessageBox.warning(self,"Aviso","Você gostaria de salvar o gráfico?",
                                        QMessageBox.Yes|QMessageBox.No,QMessageBox.No) == QMessageBox.Yes):
                    self.exp_graph()
        else:
            QMessageBox.warning(self,"Atenção!","Nenhum relatório foi gerado, portanto não há o que salvar!")
コード例 #35
0
class AdminDialog(QDialog):
    """
    Displays administrative related information and settings (logs, environment
    variables, third party packages etc...).
    """
    def __init__(self, parent=None):
        super().__init__(parent)
        self.microbit_widget = None
        self.package_widget = None
        self.envar_widget = None

    def setup(self, log, settings, packages, mode, device_list):
        self.setMinimumSize(600, 400)
        self.setWindowTitle(_("Mu Administration"))
        widget_layout = QVBoxLayout()
        self.setLayout(widget_layout)
        self.tabs = QTabWidget()
        widget_layout.addWidget(self.tabs)
        button_box = QDialogButtonBox(QDialogButtonBox.Ok
                                      | QDialogButtonBox.Cancel)
        button_box.accepted.connect(self.accept)
        button_box.rejected.connect(self.reject)
        widget_layout.addWidget(button_box)
        # Tabs
        self.log_widget = LogWidget(self)
        self.log_widget.setup(log)
        self.tabs.addTab(self.log_widget, _("Current Log"))
        if mode.short_name in ["python", "web", "pygamezero"]:
            self.envar_widget = EnvironmentVariablesWidget(self)
            self.envar_widget.setup(settings.get("envars", ""))
            self.tabs.addTab(self.envar_widget, _("Python3 Environment"))
        if mode.short_name == "microbit":
            self.microbit_widget = MicrobitSettingsWidget(self)
            self.microbit_widget.setup(
                settings.get("minify", False),
                settings.get("microbit_runtime", ""),
            )
            self.tabs.addTab(self.microbit_widget, _("BBC micro:bit Settings"))
        if mode.short_name in ["python", "web", "pygamezero"]:
            self.package_widget = PackagesWidget(self)
            self.package_widget.setup(packages)
            self.tabs.addTab(self.package_widget, _("Third Party Packages"))
        if mode.short_name == "esp":
            self.esp_widget = ESPFirmwareFlasherWidget(self)
            self.esp_widget.setup(mode, device_list)
            self.tabs.addTab(self.esp_widget, _("ESP Firmware flasher"))
        # Configure local.
        self.locale_widget = LocaleWidget(self)
        self.locale_widget.setup(settings.get("locale"))
        self.tabs.addTab(self.locale_widget, load_icon("language.svg"),
                         _("Select Language"))
        self.log_widget.log_text_area.setFocus()

    def settings(self):
        """
        Return a dictionary representation of the raw settings information
        generated by this dialog. Such settings will need to be processed /
        checked in the "logic" layer of Mu.
        """
        settings = {}
        if self.envar_widget:
            settings["envars"] = self.envar_widget.text_area.toPlainText()
        if self.microbit_widget:
            settings["minify"] = self.microbit_widget.minify.isChecked()
            settings[
                "microbit_runtime"] = self.microbit_widget.runtime_path.text()
        if self.package_widget:
            settings["packages"] = self.package_widget.text_area.toPlainText()
        settings["locale"] = self.locale_widget.get_locale()
        return settings
コード例 #36
0
ファイル: robot_jogger.py プロジェクト: jlloyd237/cri
class JoggerDialog(QDialog):
    """Robot jogger dialog allows user to connect/disconnect to/from robot,
    modify its settings (axes, linear speed, angular speed, blend radius,
    tcp and coordinate frame), and control its pose and joint angles.
    """
    class TabIndex:
        SETTINGS = 0
        POSE = 1
        JOINTS = 2

    ROBOTS = ("abb", "ur", "franka")

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

        self.robot = None

        QApplication.setStyle(QStyleFactory.create("Fusion"))
        QToolTip.setFont(QFont("SansSerif", 10))

        self.setFixedSize(800, 450)
        self.setWindowTitle("Robot Jogger")
        self.setWindowIcon(
            QIcon(os.path.join(os.path.dirname(__file__), "robot.png")))
        self.setToolTip("Robot jogger based on Common Robot Interface")

        self.robotLabel = QLabel("robot:")
        self.robotLabel.setFixedWidth(50)
        self.robotLabel.setFixedHeight(20)
        self.robotLabel.setAlignment(Qt.AlignRight | Qt.AlignVCenter)

        self.robotComboBox = QComboBox()
        self.robotComboBox.addItems(self.ROBOTS)
        self.robotComboBox.setCurrentText("abb")
        self.robotComboBox.setFixedWidth(70)
        self.robotComboBox.setFixedHeight(20)
        self.robotComboBox.setEnabled(True)

        self.ipLabel = QLabel("ip:")
        self.ipLabel.setFixedWidth(20)
        self.ipLabel.setFixedHeight(20)
        self.ipLabel.setAlignment(Qt.AlignRight | Qt.AlignVCenter)

        self.ipEditBox = LineEdit()
        self.ipEditBox.setFixedHeight(20)
        self.ipEditBox.setEnabled(True)

        self.portLabel = QLabel("port:")
        self.portLabel.setFixedWidth(40)
        self.portLabel.setFixedHeight(20)
        self.portLabel.setAlignment(Qt.AlignRight | Qt.AlignVCenter)

        self.portEditBox = LineEdit()
        self.portEditBox.setFixedWidth(60)
        self.portEditBox.setFixedHeight(20)
        self.portEditBox.setEnabled(True)

        self.connectPushButton = QPushButton("&Connect")
        self.connectPushButton.setFixedHeight(20)
        self.connectPushButton.setDefault(False)
        self.connectPushButton.setAutoDefault(True)
        self.connectPushButton.setEnabled(True)

        self.disconnectPushButton = QPushButton("&Disconnect")
        self.disconnectPushButton.setFixedHeight(20)
        self.disconnectPushButton.setDefault(False)
        self.disconnectPushButton.setAutoDefault(False)
        self.disconnectPushButton.setEnabled(False)

        topLayout = QGridLayout()
        topLayout.setHorizontalSpacing(20)
        topLayout.setVerticalSpacing(20)
        topLayout.setContentsMargins(10, 10, 10, 10)
        topLayout.addWidget(self.robotLabel, 0, 0)
        topLayout.addWidget(self.robotComboBox, 0, 1)
        topLayout.addWidget(self.ipLabel, 0, 2)
        topLayout.addWidget(self.ipEditBox, 0, 3)
        topLayout.addWidget(self.portLabel, 0, 4)
        topLayout.addWidget(self.portEditBox, 0, 5)
        topLayout.addWidget(self.connectPushButton, 0, 6)
        topLayout.addWidget(self.disconnectPushButton, 1, 6)

        robot = self.robotComboBox.currentText()
        self.createTabWidget(robot)
        self.tabWidget.setEnabled(False)

        mainLayout = QVBoxLayout()
        mainLayout.addLayout(topLayout)
        mainLayout.addWidget(self.tabWidget)

        self.setLayout(mainLayout)

        self.robotComboBox.currentIndexChanged[str].connect(
            self.onRobotChanged)
        self.ipEditBox.textEditingFinished.connect(self.onIPAddressChanged)
        self.portEditBox.textEditingFinished.connect(self.onPortChanged)
        self.connectPushButton.clicked.connect(self.onConnect)
        self.disconnectPushButton.clicked.connect(self.onDisconnect)

        self.axesComboBox.currentIndexChanged.connect(self.onAxesChanged)
        self.linearSpeedEditBox.textEditingFinished.connect(
            self.onLinearSpeedChanged)
        self.angularSpeedEditBox.textEditingFinished.connect(
            self.onAngularSpeedChanged)
        self.blendRadiusEditBox.textEditingFinished.connect(
            self.onBlendRadiusChanged)

        self.tcpEditWidget.editingFinished.connect(self.onTCPChanged)
        self.coordFrameEditWidget.editingFinished.connect(
            self.onCoordFrameChanged)

        self.poseControlWidget.valueChanged.connect(self.onPoseChanged)

        self.tabWidget.currentChanged.connect(self.onTabChanged)

    def createTabWidget(self, robot):
        self.tabWidget = QTabWidget()
        self.tabWidget.setSizePolicy(QSizePolicy.Preferred,
                                     QSizePolicy.Ignored)

        settingsTab = QWidget()
        self.createControlSettingsWidget()
        settingsTabLayout = QHBoxLayout()
        settingsTabLayout.setContentsMargins(5, 5, 5, 5)
        settingsTabLayout.addWidget(self.controlSettings)
        settingsTab.setLayout(settingsTabLayout)

        poseTab = QWidget()
        self.poseControlWidget = MultiSliderControlWidget(
            names=("x", "y", "z", "alpha", "beta", "gamma"),
            units=("mm", ) * 3 + ("°", ) * 3,
            ranges=((-1000, 1000), ) * 3 + ((-360, 360), ) * 3,
            values=(0, ) * 6,
        )
        poseTabLayout = QHBoxLayout()
        poseTabLayout.setContentsMargins(5, 5, 5, 5)
        poseTabLayout.addWidget(self.poseControlWidget)
        poseTab.setLayout(poseTabLayout)

        jointsTab = QWidget()  # widget content depends on robot type

        self.tabWidget.addTab(settingsTab, "&Settings")
        self.tabWidget.addTab(poseTab, "&Pose")
        self.tabWidget.addTab(jointsTab, "&Joints")

    def createControlSettingsWidget(self):
        self.controlSettings = QWidget()

        self.minLinearSpeed = 0.001
        self.maxLinearSpeed = 1000
        self.minAngularSpeed = 0.001
        self.maxAngularSpeed = 1000
        self.minBlendRadius = 0
        self.maxBlendRadius = 1000

        miscSettingsGroupBox = QGroupBox(title="Misc:")

        self.axesLabel = QLabel("axes:")
        self.axesLabel.setFixedWidth(50)
        self.axesLabel.setFixedHeight(20)

        self.axesComboBox = QComboBox()
        self.axesComboBox.addItems(SyncRobot.EULER_AXES)
        self.axesComboBox.setCurrentText("rxyz")
        self.axesComboBox.setFixedHeight(20)

        self.axisUnitsLabel = QLabel()
        self.axisUnitsLabel.setFixedWidth(40)
        self.axisUnitsLabel.setFixedHeight(20)

        self.linearSpeedLabel = QLabel("linear\nspeed:")
        self.linearSpeedLabel.setFixedWidth(50)
        self.linearSpeedLabel.setFixedHeight(40)

        self.linearSpeedEditBox = LineEdit()
        self.linearSpeedEditBox.setText("{:.1f}".format(0))
        self.linearSpeedEditBox.setFixedHeight(20)
        self.linearSpeedEditBox.setAlignment(Qt.AlignRight | Qt.AlignVCenter)

        self.linearSpeedUnitsLabel = QLabel("mm/s")
        self.linearSpeedUnitsLabel.setFixedWidth(40)
        self.linearSpeedUnitsLabel.setFixedHeight(20)

        self.angularSpeedLabel = QLabel("angular\nspeed:")
        self.angularSpeedLabel.setFixedWidth(50)
        self.angularSpeedLabel.setFixedHeight(40)

        self.angularSpeedEditBox = LineEdit()
        self.angularSpeedEditBox.setText("{:.1f}".format(0))
        self.angularSpeedEditBox.setFixedHeight(20)
        self.angularSpeedEditBox.setAlignment(Qt.AlignRight | Qt.AlignVCenter)

        self.angularSpeedUnitsLabel = QLabel("°/s")
        self.angularSpeedUnitsLabel.setFixedWidth(40)
        self.angularSpeedUnitsLabel.setFixedHeight(20)

        self.blendRadiusLabel = QLabel("blend\nradius:")
        self.blendRadiusLabel.setFixedWidth(50)
        self.blendRadiusLabel.setFixedHeight(40)

        self.blendRadiusEditBox = LineEdit()
        self.blendRadiusEditBox.setText("{:.1f}".format(0))
        self.blendRadiusEditBox.setFixedHeight(20)
        self.blendRadiusEditBox.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        self.blendRadiusEditBox.setEnabled(False)

        self.blendRadiusUnitsLabel = QLabel("mm")
        self.blendRadiusUnitsLabel.setFixedWidth(40)
        self.blendRadiusUnitsLabel.setFixedHeight(20)

        miscSettingsLayout = QGridLayout()
        miscSettingsLayout.setHorizontalSpacing(15)
        miscSettingsLayout.setVerticalSpacing(5)
        miscSettingsLayout.addWidget(self.axesLabel, 0, 0)
        miscSettingsLayout.addWidget(self.axesComboBox, 0, 1)
        miscSettingsLayout.addWidget(self.linearSpeedLabel, 1, 0)
        miscSettingsLayout.addWidget(self.linearSpeedEditBox, 1, 1)
        miscSettingsLayout.addWidget(self.linearSpeedUnitsLabel, 1, 2)
        miscSettingsLayout.addWidget(self.angularSpeedLabel, 2, 0)
        miscSettingsLayout.addWidget(self.angularSpeedEditBox, 2, 1)
        miscSettingsLayout.addWidget(self.angularSpeedUnitsLabel, 2, 2)
        miscSettingsLayout.addWidget(self.blendRadiusLabel, 3, 0)
        miscSettingsLayout.addWidget(self.blendRadiusEditBox, 3, 1)
        miscSettingsLayout.addWidget(self.blendRadiusUnitsLabel, 3, 2)
        miscSettingsGroupBox.setLayout(miscSettingsLayout)

        self.tcpEditWidget = MultiNumberEditWidget(
            names=("x", "y", "z", "alpha", "beta", "gamma"),
            units=("mm", ) * 3 + ("°", ) * 3,
            ranges=((-1000, 1000), ) * 3 + ((-360, 360), ) * 3,
            values=(0, ) * 6,
        )

        tcpGroupBox = QGroupBox(title="TCP:")
        tcpLayout = QVBoxLayout()
        tcpLayout.addWidget(self.tcpEditWidget)
        tcpGroupBox.setLayout(tcpLayout)

        self.coordFrameEditWidget = MultiNumberEditWidget(
            names=("x", "y", "z", "alpha", "beta", "gamma"),
            units=("mm", ) * 3 + ("°", ) * 3,
            ranges=((-1000, 1000), ) * 3 + ((-360, 360), ) * 3,
            values=(0, ) * 6,
        )

        coordFrameGroupBox = QGroupBox(title="Coordinate Frame:")
        coordFrameLayout = QVBoxLayout()
        coordFrameLayout.addWidget(self.coordFrameEditWidget)
        coordFrameGroupBox.setLayout(coordFrameLayout)

        controlSettingsLayout = QGridLayout()
        controlSettingsLayout.setHorizontalSpacing(15)
        controlSettingsLayout.setVerticalSpacing(5)
        controlSettingsLayout.addWidget(miscSettingsGroupBox, 0, 0)
        controlSettingsLayout.addWidget(tcpGroupBox, 0, 1)
        controlSettingsLayout.addWidget(coordFrameGroupBox, 0, 2)
        self.controlSettings.setLayout(controlSettingsLayout)

    def closeEvent(self, event):
        reply = QMessageBox.question(self, "Message",
                                     "Are you sure you want to quit?",
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)
        if reply == QMessageBox.Yes:
            if self.robot is not None:
                self.robot.close()
            event.accept()
        else:
            event.ignore()

    def onRobotChanged(self, value):
        logger.debug("JoggerDialog.onRobotChanged(value={})".format(value))
        if value == "franka":
            # No need to specify port for Franka arm
            self.portEditBox.setText("")
            self.portEditBox.setEnabled(False)
        elif value == "ur":
            # UR controller always listens on port 30004
            self.portEditBox.setText(str(30004))
            self.portEditBox.setEnabled(False)
        else:
            self.portEditBox.setEnabled(True)

    def onIPAddressChanged(self):
        ip = self.sender().text()
        logger.debug("JoggerDialog.onIPAddressChanged(text={})".format(ip))
        if not isValidIPAddress(ip):
            msg = QErrorMessage(self)
            msg.showMessage("Invalid IP address")
            msg.exec_()
            self.sender().setFocus()

    def onPortChanged(self):
        port = self.sender().text()
        logger.debug("JoggerDialog.onPortChanged(text={})".format(port))
        if not isValidPortNumber(port):
            msg = QErrorMessage(self)
            msg.showMessage("Invalid port number")
            msg.exec_()
            self.sender().setFocus()

    def onConnect(self):
        robot = self.robotComboBox.currentText()
        ip = self.ipEditBox.text()
        port = self.portEditBox.text()
        logger.debug("JoggerDialog.onConnect(robot={}, ip={}, port={})".format(
            robot, ip, port))

        if robot in ("abb", 'ur') and (not isValidIPAddress(ip)
                                       or not isValidPortNumber(port)):
            msg = QErrorMessage(self)
            msg.showMessage("Please specify valid IP address and port number")
            msg.exec_()
            self.sender().setFocus()
            return

        if robot == "franka" and not isValidIPAddress(
                ip):  # no need to specify port for Franka arm
            msg = QErrorMessage(self)
            msg.showMessage("Please specify valid IP address")
            msg.exec_()
            self.sender().setFocus()
            return

        try:
            if robot == "abb":
                port = int(port)
                self.robot = SyncRobot(ABBController(ip, port))
            elif robot == "ur":
                self.robot = SyncRobot(RTDEController(ip))
            elif robot == "franka":
                self.robot = SyncRobot(PyfrankaController(ip))
        except:
            msg = QErrorMessage(self)
            msg.showMessage("Failed to connect to server")
            msg.exec_()
        else:
            self.robotComboBox.setEnabled(False)
            self.ipEditBox.setEnabled(False)
            self.portEditBox.setEnabled(False)
            self.connectPushButton.setEnabled(False)
            self.disconnectPushButton.setEnabled(True)

            self.axesComboBox.setCurrentText(self.robot.axes)

            if robot == "franka":
                # Disable settings that don't apply to Franka arm
                self.linearSpeedEditBox.setText("n/a")
                self.angularSpeedEditBox.setText("n/a")
                self.blendRadiusEditBox.setText("n/a")
                self.linearSpeedEditBox.setEnabled(False)
                self.blendRadiusEditBox.setEnabled(False)
                self.angularSpeedEditBox.setEnabled(False)
            else:
                self.linearSpeedEditBox.setText("{:.1f}".format(
                    self.robot.linear_speed))
                self.angularSpeedEditBox.setText("{:.1f}".format(
                    self.robot.angular_speed))
                self.blendRadiusEditBox.setText("{:.1f}".format(
                    self.robot.blend_radius))
                self.linearSpeedEditBox.setEnabled(True)
                self.blendRadiusEditBox.setEnabled(True)
                self.angularSpeedEditBox.setEnabled(True)

            self.tcpEditWidget.value = self.robot.tcp
            self.coordFrameEditWidget.value = self.robot.coord_frame

            # Set up joint angles tab - need to do this dynamically now because layout depends on
            # whether ABB/UR5 robot is selected (6 joints), or Franka robot is selected (7 joints)
            jointsTab = QWidget()
            n_joints = 7 if robot == "franka" else 6
            self.jointControlWidget = MultiSliderControlWidget(
                names=["joint {}".format(i + 1) for i in range(n_joints)],
                units=("°", ) * n_joints,
                ranges=((-360, 360), ) * n_joints,
                values=(0, ) * n_joints,
            )
            self.jointControlWidget.valueChanged.connect(
                self.onJointAnglesChanged)
            jointsTabLayout = QHBoxLayout()
            jointsTabLayout.setContentsMargins(5, 5, 5, 5)
            jointsTabLayout.addWidget(self.jointControlWidget)
            jointsTab.setLayout(jointsTabLayout)
            self.tabWidget.removeTab(2)
            self.tabWidget.addTab(jointsTab, "&Joints")

            self.tabWidget.setCurrentIndex(self.TabIndex.SETTINGS)
            self.tabWidget.setEnabled(True)

    def onDisconnect(self):
        logger.debug("JoggerDialog.onDisconnect")
        self.robotComboBox.setEnabled(True)
        self.ipEditBox.setEnabled(True)
        robot = self.robotComboBox.currentText()
        if robot == "abb":
            self.portEditBox.setEnabled(True)
        elif robot in ("ur", "franka"):
            self.portEditBox.setEnabled(False)
        self.connectPushButton.setEnabled(True)
        self.disconnectPushButton.setEnabled(False)
        self.tabWidget.setCurrentIndex(self.TabIndex.SETTINGS)
        self.tabWidget.setEnabled(False)
        self.robot.close()
        self.robot = None

    def onAxesChanged(self):
        axes = self.sender().currentText()
        logger.debug("JoggerDialog.onAxesChanged(axes={})".format(axes))
        self.robot.axes = axes
        self.tcpEditWidget.value = self.robot.tcp
        self.coordFrameEditWidget.value = self.robot.coord_frame

    def onLinearSpeedChanged(self):
        linearSpeed = self.sender().text()
        logger.debug(
            "JoggerDialog.onLinearSpeedChanged(speed={})".format(linearSpeed))
        if isValidNumber(linearSpeed, self.minLinearSpeed,
                         self.maxLinearSpeed):
            linearSpeed = float(linearSpeed)
            self.sender().setText("{:.1f}".format(linearSpeed))
            self.robot.linear_speed = linearSpeed
        else:
            msg = QErrorMessage(self)
            msg.showMessage("Invalid or out of range [{}, {}] number".format(
                self.minLinearSpeed, self.maxLinearSpeed))
            msg.exec_()
            self.sender().setText("{:.1f}".format(0))
            self.sender().setFocus()

    def onAngularSpeedChanged(self):
        angularSpeed = self.sender().text()
        logger.debug("JoggerDialog.onAngularSpeedChanged(speed={})".format(
            angularSpeed))
        if isValidNumber(angularSpeed, self.minAngularSpeed,
                         self.maxAngularSpeed):
            angularSpeed = float(angularSpeed)
            self.sender().setText("{:.1f}".format(angularSpeed))
            self.robot.angular_speed = angularSpeed
        else:
            msg = QErrorMessage(self)
            msg.showMessage("Invalid or out of range [{}, {}] number".format(
                self.minAngularSpeed, self.maxAngularSpeed))
            msg.exec_()
            self.sender().setText("{:.1f}".format(0))
            self.sender().setFocus()

    def onBlendRadiusChanged(self):
        blendRadius = self.blendRadiusEditBox.text()
        logger.debug(
            "JoggerDialog.onBlendRadiusChanged(radius={})".format(blendRadius))
        if isValidNumber(blendRadius, self.minBlendRadius,
                         self.maxBlendRadius):
            blendRadius = float(blendRadius)
            self.sender().setText("{:.1f}".format(blendRadius))
            self.robot.blend_radius = blendRadius
        else:
            msg = QErrorMessage(self)
            msg.showMessage("Invalid or out of range [{}, {}] number".format(
                self.minBlendRadius, self.maxBlendRadius))
            msg.exec_()
            self.sender().setText("{:.1f}".format(0))
            self.sender().setFocus()

    def onTCPChanged(self):
        logger.debug("JoggerDialog.onTCPChanged(tcp={})".format(
            self.tcpEditWidget.value))
        self.robot.tcp = self.tcpEditWidget.value

    def onCoordFrameChanged(self):
        logger.debug("JoggerDialog.onCoordFrameChanged(frame={})".format(
            self.coordFrameEditWidget.value))
        self.robot.coord_frame = self.coordFrameEditWidget.value

    def onPoseChanged(self):
        logger.debug("JoggerDialog.onPoseChanged(pose={})".format(
            self.poseControlWidget.value))
        self.robot.move_linear(self.poseControlWidget.value)

    def onJointAnglesChanged(self):
        logger.debug("JoggerDialog.onJointAnglesChanged(angles={})".format(
            self.jointControlWidget.value))
        self.robot.move_joints(self.jointControlWidget.value)

    def onTabChanged(self, index):
        logger.debug("JoggerDialog.onTabChanged(index={}, text={})".format(
            index, self.tabWidget.tabText(index)))
        if index == self.TabIndex.POSE:
            self.poseControlWidget.value = self.robot.pose
        elif index == self.TabIndex.JOINTS:
            self.jointControlWidget.value = self.robot.joint_angles
コード例 #37
0
class ScoreWizardDialog(QDialog):

    pitchLanguageChanged = pyqtSignal(str)

    def __init__(self, mainwindow):
        super(ScoreWizardDialog, self).__init__(mainwindow)
        self.addAction(mainwindow.actionCollection.help_whatsthis)
        self._pitchLanguage = None

        layout = QVBoxLayout()
        self.setLayout(layout)

        self.tabs = QTabWidget()
        b = self.dialogButtons = QDialogButtonBox()
        b.setStandardButtons(QDialogButtonBox.Reset
                             | QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        b.accepted.connect(self.accept)
        b.rejected.connect(self.reject)
        userguide.addButton(b, "scorewiz")
        b.button(QDialogButtonBox.Reset).clicked.connect(self.reset)
        self.previewButton = b.addButton('', QDialogButtonBox.ActionRole)
        self.previewButton.clicked.connect(self.showPreview)
        layout.addWidget(self.tabs)
        layout.addWidget(b)

        self.header = Header(self)
        self.tabs.addTab(self.header, '')
        self.parts = Parts(self)
        self.tabs.addTab(self.parts, '')
        self.settings = Settings(self)
        self.tabs.addTab(self.settings, '')

        self.tabs.setCurrentIndex(0)
        self.tabs.widget(0).widget()  # activate it
        self.tabs.currentChanged.connect(self.slotCurrentChanged)
        qutil.saveDialogSize(self, "scorewiz/dialog/size")
        app.translateUI(self)
        self.accepted.connect(self.slotAccepted)

    def translateUI(self):
        self.setWindowTitle(app.caption(_("Score Setup Wizard")))
        for i in range(self.tabs.count()):
            self.tabs.setTabText(i, self.tabs.widget(i).title())
        self.dialogButtons.button(QDialogButtonBox.Reset).setText(_("Clear"))
        self.dialogButtons.button(QDialogButtonBox.Reset).setToolTip(
            _("Clears the current page of the Score Wizard."))
        self.previewButton.setText(_("Preview"))

    def slotCurrentChanged(self, i):
        """Lazy-loads the tab's page if shown for the first time."""
        self.tabs.widget(i).widget()

    def reset(self):
        self.tabs.currentWidget().widget().clear()

    def setPitchLanguage(self, language):
        if language != self._pitchLanguage:
            self._pitchLanguage = language
            self.pitchLanguageChanged.emit(language)

    def pitchLanguage(self):
        if self._pitchLanguage is None:
            # load setting; saving occurs in .settings.py
            lang = QSettings().value('scorewiz/lilypond/pitch_language', '',
                                     str)
            from .scoreproperties import keyNames
            if lang not in keyNames:
                lang = ''
            self._pitchLanguage = lang
        return self._pitchLanguage

    def slotAccepted(self):
        """Makes the score and puts it in the editor."""
        from . import build
        builder = build.Builder(self)  # get the builder
        text = builder.text()  # get the source text
        lydoc = ly.document.Document(text)  # temporarily store it in a lydoc
        cursor = ly.document.Cursor(lydoc)  # make a cursor selecting it
        indent.indenter().indent(cursor)  # indent it according to user prefs
        doc = app.openUrl(QUrl())  # get a new Frescobaldi document
        doc.setPlainText(lydoc.plaintext())  # write the text in it
        doc.setModified(False)  # make it "not modified"
        self.parent().setCurrentDocument(doc)

    def showPreview(self):
        """Shows a preview."""
        # get the document and fill in some example music
        from . import preview, build
        builder = build.Builder(self)
        doc = builder.document()
        preview.examplify(doc)
        # preview it
        import musicpreview
        dlg = musicpreview.MusicPreviewDialog(self)
        dlg.preview(builder.text(doc), _("Score Preview"))
        dlg.exec_()
        dlg.cleanup()
コード例 #38
0
class SelectFileDataWidget(QWidget):
    def __init__(self, outer_fk):
        super().__init__()
        self.outer_fk = outer_fk
        self.tabWidget = QTabWidget()
        self.vbox = QVBoxLayout()
        self.__files_tab = QWidget()
        self.__files_tab.setLayout(self.__create_files_tab_layout())
        self.tabWidget.addTab(self.__files_tab, 'Files List')
        self.__opened_files = {}
        self.vbox.addWidget(self.tabWidget)
        self.setLayout(self.vbox)

    def __create_files_tab_layout(self):
        self.hor_layout = QVBoxLayout()
        self.label = QLabel("SEISMOGRAM FILES")
        self.__open_folder_btn = QToolButton(self)
        __open_folder_btn_size_policy = QSizePolicy(QSizePolicy.Preferred,
                                                    QSizePolicy.Fixed)
        self.__open_folder_btn.setSizePolicy(__open_folder_btn_size_policy)
        self.__open_folder_btn.setDefaultAction(
            OpenFilesAction(self, self._load_data))
        self.hor_layout.addWidget(self.label)
        self.hor_layout.addWidget(self.__open_folder_btn)

        self.table = QTableWidget(self)
        self.table.setColumnCount(3)
        self.table.setHorizontalHeaderLabels(["File", "Type", "Fix"])
        self.table.cellClicked.connect(self.__cell_click)
        self.table_header = self.table.horizontalHeader()
        self.table_header.setSectionResizeMode(0, QHeaderView.Stretch)
        self.table_header.setSectionResizeMode(1, QHeaderView.ResizeToContents)
        self.table_header.setSectionResizeMode(2, QHeaderView.ResizeToContents)

        self.hor_layout.addWidget(self.table)
        return self.hor_layout

    def _load_data(self, path):
        for i in path[0]:
            _, name = os.path.split(i)

            if (not name in self.__opened_files.keys()):
                self.__opened_files[name] = i
                self.add_row(name)

    def get_open_file_dialog_load_data_func(self):
        return self._load_data

    def add_row(self, filename):
        row = self.table.rowCount()
        self.table.setRowCount(row + 1)
        cell = QTableWidgetItem(str(filename))
        qc = QComboBox()
        qchb = QHBoxLayout()
        qchb.addWidget(QCheckBox())
        qchb.setAlignment(Qt.AlignCenter)
        chkBoxItem = QTableWidgetItem()
        chkBoxItem.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
        chkBoxItem.setCheckState(Qt.Unchecked)

        qc.addItem("Null")
        qc.addItem("None")
        self.table.setItem(row, 0, cell)
        self.table.setCellWidget(row, 1, qc)
        self.table.setCellWidget(row, 2, WidgetWrapper.WidgetWrapper(qchb))
        # self.table.setItem(row, 2, chkBoxItem)

    def __cell_click(self, *args, **kwargs):
        if args[1] == 0:
            self.outer_fk(self.__opened_files[self.table.item(
                args[0], args[1]).text()])
コード例 #39
0
ファイル: addlink_ui.py プロジェクト: ypengit/persepolis
class AddLinkWindow_Ui(QWidget):
    def __init__(self, persepolis_setting):
        super().__init__()
        self.persepolis_setting = persepolis_setting

        # get icons name
        icons = ':/' + \
            str(self.persepolis_setting.value('settings/icons')) + '/'

        self.setMinimumSize(QtCore.QSize(520, 425))
        self.setWindowIcon(
            QIcon.fromTheme('persepolis', QIcon(':/persepolis.svg')))

        window_verticalLayout = QVBoxLayout()

        # add link tab widget
        self.add_link_tabWidget = QTabWidget(self)
        window_verticalLayout.addWidget(self.add_link_tabWidget)

        # link tab
        self.link_tab = QWidget()

        link_tab_verticalLayout = QVBoxLayout(self.link_tab)
        link_tab_verticalLayout.setContentsMargins(21, 21, 21, 81)

        self.link_frame = QFrame(self.link_tab)
        self.link_frame.setFrameShape(QFrame.StyledPanel)
        self.link_frame.setFrameShadow(QFrame.Raised)

        horizontalLayout_2 = QHBoxLayout(self.link_frame)

        self.link_verticalLayout = QVBoxLayout()

        # link ->
        self.link_horizontalLayout = QHBoxLayout()
        self.link_label = QLabel(self.link_frame)
        self.link_horizontalLayout.addWidget(self.link_label)

        self.link_lineEdit = QLineEdit(self.link_frame)
        self.link_horizontalLayout.addWidget(self.link_lineEdit)

        self.link_verticalLayout.addLayout(self.link_horizontalLayout)

        horizontalLayout_2.addLayout(self.link_verticalLayout)
        link_tab_verticalLayout.addWidget(self.link_frame)

        # add change_name field ->
        change_name_horizontalLayout = QHBoxLayout()
        self.change_name_checkBox = QCheckBox(self.link_frame)
        change_name_horizontalLayout.addWidget(self.change_name_checkBox)

        self.change_name_lineEdit = QLineEdit(self.link_frame)
        change_name_horizontalLayout.addWidget(self.change_name_lineEdit)

        self.link_verticalLayout.addLayout(change_name_horizontalLayout)

        # add_category ->
        queue_horizontalLayout = QHBoxLayout()

        self.queue_frame = QFrame(self)
        self.queue_frame.setFrameShape(QFrame.StyledPanel)
        self.queue_frame.setFrameShadow(QFrame.Raised)

        add_queue_horizontalLayout = QHBoxLayout(self.queue_frame)

        self.add_queue_label = QLabel(self.queue_frame)
        add_queue_horizontalLayout.addWidget(self.add_queue_label)

        self.add_queue_comboBox = QComboBox(self.queue_frame)
        add_queue_horizontalLayout.addWidget(self.add_queue_comboBox)

        queue_horizontalLayout.addWidget(self.queue_frame)
        queue_horizontalLayout.addStretch(1)

        self.size_label = QLabel(self)
        queue_horizontalLayout.addWidget(self.size_label)

        link_tab_verticalLayout.addLayout(queue_horizontalLayout)

        self.add_link_tabWidget.addTab(self.link_tab, '')

        # proxy tab
        self.proxy_tab = QWidget(self)

        proxy_verticalLayout = QVBoxLayout(self.proxy_tab)
        proxy_verticalLayout.setContentsMargins(21, 21, 21, 171)

        proxy_horizontalLayout = QHBoxLayout()

        self.proxy_checkBox = QCheckBox(self.proxy_tab)
        self.detect_proxy_pushButton = QPushButton(self.proxy_tab)
        self.detect_proxy_label = QLabel(self.proxy_tab)

        proxy_horizontalLayout.addWidget(self.proxy_checkBox)
        proxy_horizontalLayout.addWidget(self.detect_proxy_label)
        proxy_horizontalLayout.addWidget(self.detect_proxy_pushButton)

        proxy_verticalLayout.addLayout(proxy_horizontalLayout)

        self.proxy_frame = QFrame(self.proxy_tab)
        self.proxy_frame.setFrameShape(QFrame.StyledPanel)
        self.proxy_frame.setFrameShadow(QFrame.Raised)

        gridLayout = QGridLayout(self.proxy_frame)

        self.ip_label = QLabel(self.proxy_frame)
        gridLayout.addWidget(self.ip_label, 0, 0, 1, 1)

        self.ip_lineEdit = QLineEdit(self.proxy_frame)
        self.ip_lineEdit.setInputMethodHints(QtCore.Qt.ImhNone)
        gridLayout.addWidget(self.ip_lineEdit, 0, 1, 1, 1)

        self.port_label = QLabel(self.proxy_frame)
        gridLayout.addWidget(self.port_label, 0, 2, 1, 1)

        self.port_spinBox = QSpinBox(self.proxy_frame)
        self.port_spinBox.setMaximum(65535)
        self.port_spinBox.setSingleStep(1)
        gridLayout.addWidget(self.port_spinBox, 0, 3, 1, 1)

        self.proxy_user_label = QLabel(self.proxy_frame)
        gridLayout.addWidget(self.proxy_user_label, 2, 0, 1, 1)

        self.proxy_user_lineEdit = QLineEdit(self.proxy_frame)
        gridLayout.addWidget(self.proxy_user_lineEdit, 2, 1, 1, 1)

        self.proxy_pass_label = QLabel(self.proxy_frame)
        gridLayout.addWidget(self.proxy_pass_label, 2, 2, 1, 1)

        self.proxy_pass_lineEdit = QLineEdit(self.proxy_frame)
        self.proxy_pass_lineEdit.setEchoMode(QLineEdit.Password)
        gridLayout.addWidget(self.proxy_pass_lineEdit, 2, 3, 1, 1)

        proxy_verticalLayout.addWidget(self.proxy_frame)

        self.add_link_tabWidget.addTab(self.proxy_tab, '')

        # more options tab
        self.more_options_tab = QWidget(self)

        more_options_tab_verticalLayout = QVBoxLayout(self.more_options_tab)

        # download UserName & Password ->
        download_horizontalLayout = QHBoxLayout()
        download_horizontalLayout.setContentsMargins(-1, 10, -1, -1)

        download_verticalLayout = QVBoxLayout()
        self.download_checkBox = QCheckBox(self.more_options_tab)
        download_verticalLayout.addWidget(self.download_checkBox)

        self.download_frame = QFrame(self.more_options_tab)
        self.download_frame.setFrameShape(QFrame.StyledPanel)
        self.download_frame.setFrameShadow(QFrame.Raised)

        gridLayout_2 = QGridLayout(self.download_frame)

        self.download_user_lineEdit = QLineEdit(self.download_frame)
        gridLayout_2.addWidget(self.download_user_lineEdit, 0, 1, 1, 1)

        self.download_user_label = QLabel(self.download_frame)
        gridLayout_2.addWidget(self.download_user_label, 0, 0, 1, 1)

        self.download_pass_label = QLabel(self.download_frame)
        gridLayout_2.addWidget(self.download_pass_label, 1, 0, 1, 1)

        self.download_pass_lineEdit = QLineEdit(self.download_frame)
        self.download_pass_lineEdit.setEchoMode(QLineEdit.Password)
        gridLayout_2.addWidget(self.download_pass_lineEdit, 1, 1, 1, 1)
        download_verticalLayout.addWidget(self.download_frame)
        download_horizontalLayout.addLayout(download_verticalLayout)

        # select folder ->
        self.folder_frame = QFrame(self.more_options_tab)
        self.folder_frame.setFrameShape(QFrame.StyledPanel)
        self.folder_frame.setFrameShadow(QFrame.Raised)

        gridLayout_3 = QGridLayout(self.folder_frame)

        self.download_folder_lineEdit = QLineEdit(self.folder_frame)
        gridLayout_3.addWidget(self.download_folder_lineEdit, 2, 0, 1, 1)

        self.folder_pushButton = QPushButton(self.folder_frame)
        gridLayout_3.addWidget(self.folder_pushButton, 3, 0, 1, 1)
        self.folder_pushButton.setIcon(QIcon(icons + 'folder'))

        self.folder_label = QLabel(self.folder_frame)
        self.folder_label.setAlignment(QtCore.Qt.AlignCenter)
        gridLayout_3.addWidget(self.folder_label, 1, 0, 1, 1)
        download_horizontalLayout.addWidget(self.folder_frame)
        more_options_tab_verticalLayout.addLayout(download_horizontalLayout)

        # start time ->
        time_limit_horizontalLayout = QHBoxLayout()
        time_limit_horizontalLayout.setContentsMargins(-1, 10, -1, -1)

        start_verticalLayout = QVBoxLayout()
        self.start_checkBox = QCheckBox(self.more_options_tab)
        start_verticalLayout.addWidget(self.start_checkBox)

        self.start_frame = QFrame(self.more_options_tab)
        self.start_frame.setFrameShape(QFrame.StyledPanel)
        self.start_frame.setFrameShadow(QFrame.Raised)

        horizontalLayout_5 = QHBoxLayout(self.start_frame)

        self.start_time_qDataTimeEdit = QDateTimeEdit(self.start_frame)
        self.start_time_qDataTimeEdit.setDisplayFormat('H:mm')
        horizontalLayout_5.addWidget(self.start_time_qDataTimeEdit)

        start_verticalLayout.addWidget(self.start_frame)
        time_limit_horizontalLayout.addLayout(start_verticalLayout)

        # end time ->
        end_verticalLayout = QVBoxLayout()

        self.end_checkBox = QCheckBox(self.more_options_tab)
        end_verticalLayout.addWidget(self.end_checkBox)

        self.end_frame = QFrame(self.more_options_tab)
        self.end_frame.setFrameShape(QFrame.StyledPanel)
        self.end_frame.setFrameShadow(QFrame.Raised)

        horizontalLayout_6 = QHBoxLayout(self.end_frame)

        self.end_time_qDateTimeEdit = QDateTimeEdit(self.end_frame)
        self.end_time_qDateTimeEdit.setDisplayFormat('H:mm')
        horizontalLayout_6.addWidget(self.end_time_qDateTimeEdit)

        end_verticalLayout.addWidget(self.end_frame)
        time_limit_horizontalLayout.addLayout(end_verticalLayout)

        # limit Speed ->
        limit_verticalLayout = QVBoxLayout()

        self.limit_checkBox = QCheckBox(self.more_options_tab)
        limit_verticalLayout.addWidget(self.limit_checkBox)

        self.limit_frame = QFrame(self.more_options_tab)
        self.limit_frame.setFrameShape(QFrame.StyledPanel)
        self.limit_frame.setFrameShadow(QFrame.Raised)

        horizontalLayout_4 = QHBoxLayout(self.limit_frame)

        self.limit_spinBox = QDoubleSpinBox(self.limit_frame)
        self.limit_spinBox.setMinimum(1)
        self.limit_spinBox.setMaximum(1023)
        horizontalLayout_4.addWidget(self.limit_spinBox)

        self.limit_comboBox = QComboBox(self.limit_frame)
        self.limit_comboBox.addItem("")
        self.limit_comboBox.addItem("")
        horizontalLayout_4.addWidget(self.limit_comboBox)
        limit_verticalLayout.addWidget(self.limit_frame)
        time_limit_horizontalLayout.addLayout(limit_verticalLayout)
        more_options_tab_verticalLayout.addLayout(time_limit_horizontalLayout)

        # number of connections ->
        connections_horizontalLayout = QHBoxLayout()
        connections_horizontalLayout.setContentsMargins(-1, 10, -1, -1)

        self.connections_frame = QFrame(self.more_options_tab)
        self.connections_frame.setFrameShape(QFrame.StyledPanel)
        self.connections_frame.setFrameShadow(QFrame.Raised)

        horizontalLayout_3 = QHBoxLayout(self.connections_frame)
        self.connections_label = QLabel(self.connections_frame)
        horizontalLayout_3.addWidget(self.connections_label)

        self.connections_spinBox = QSpinBox(self.connections_frame)
        self.connections_spinBox.setMinimum(1)
        self.connections_spinBox.setMaximum(16)
        self.connections_spinBox.setProperty("value", 16)
        horizontalLayout_3.addWidget(self.connections_spinBox)
        connections_horizontalLayout.addWidget(self.connections_frame)
        connections_horizontalLayout.addStretch(1)

        more_options_tab_verticalLayout.addLayout(connections_horizontalLayout)

        self.add_link_tabWidget.addTab(self.more_options_tab, '')

        # ok cancel download_later buttons ->
        buttons_horizontalLayout = QHBoxLayout()
        buttons_horizontalLayout.addStretch(1)

        self.download_later_pushButton = QPushButton(self)
        self.download_later_pushButton.setIcon(QIcon(icons + 'stop'))

        self.cancel_pushButton = QPushButton(self)
        self.cancel_pushButton.setIcon(QIcon(icons + 'remove'))

        self.ok_pushButton = QPushButton(self)
        self.ok_pushButton.setIcon(QIcon(icons + 'ok'))

        buttons_horizontalLayout.addWidget(self.download_later_pushButton)
        buttons_horizontalLayout.addWidget(self.cancel_pushButton)
        buttons_horizontalLayout.addWidget(self.ok_pushButton)

        window_verticalLayout.addLayout(buttons_horizontalLayout)

        self.setLayout(window_verticalLayout)

        # labels ->
        self.setWindowTitle("Enter Your Link")

        self.link_label.setText("Download Link : ")

        self.add_queue_label.setText("Add to category : ")

        self.change_name_checkBox.setText("Change File Name : ")

        self.detect_proxy_pushButton.setText("Detect system proxy setting")
        self.proxy_checkBox.setText("Proxy")
        self.proxy_pass_label.setText("Proxy PassWord : "******"IP : ")
        self.proxy_user_label.setText("Proxy UserName : "******"Port:")

        self.download_checkBox.setText("Download UserName and PassWord")
        self.download_user_label.setText("Download UserName : "******"Download PassWord : "******"Change Download Folder")
        self.folder_label.setText("Download Folder : ")

        self.start_checkBox.setText("Start Time")
        self.end_checkBox.setText("End Time")

        self.limit_checkBox.setText("Limit Speed")
        self.limit_comboBox.setItemText(0, "KB/S")
        self.limit_comboBox.setItemText(1, "MB/S")

        self.connections_label.setText("Number Of Connections :")

        self.cancel_pushButton.setText("Cancel")
        self.ok_pushButton.setText("OK")

        self.download_later_pushButton.setText("Download later")

        self.add_link_tabWidget.setTabText(
            self.add_link_tabWidget.indexOf(self.link_tab), "Link")

        self.add_link_tabWidget.setTabText(
            self.add_link_tabWidget.indexOf(self.proxy_tab), "Proxy")

        self.add_link_tabWidget.setTabText(
            self.add_link_tabWidget.indexOf(self.more_options_tab),
            "More Options")

    def changeIcon(self, icons):
        icons = ':/' + str(icons) + '/'

        self.folder_pushButton.setIcon(QIcon(icons + 'folder'))
        self.download_later_pushButton.setIcon(QIcon(icons + 'stop'))
        self.cancel_pushButton.setIcon(QIcon(icons + 'remove'))
        self.ok_pushButton.setIcon(QIcon(icons + 'ok'))
コード例 #40
0
    def initGUI(self):
        self.setWindowTitle('БиоРАСКАН-24')
        self.setWindowIcon(QIcon('Рисунок1.png'))

        self.settingsWidget = SettingsWidget(self)

        mainLayout = QGridLayout()
        self.setLayout(mainLayout)

        leftLayout = QVBoxLayout()
        leftLayout.setSpacing(20)
        mainLayout.addLayout(leftLayout, 1, 1, Qt.AlignCenter)

        tabWidget = QTabWidget()

        mainLayout.addWidget(tabWidget, 1, 3, Qt.AlignCenter)

        mainLayout.setRowStretch(0, 2)  # empty space above ui
        mainLayout.setRowStretch(1, 1)  # ui
        mainLayout.setRowStretch(2, 2)  # console
        mainLayout.setRowStretch(3, 2)  # empty space below ui
        mainLayout.setColumnStretch(0, 2)  # empty space to the right from ui
        mainLayout.setColumnStretch(
            2, 1)  # empty space between left layout and right layout
        mainLayout.setColumnStretch(4, 2)  # empty space to the left from ui

        # console output
        self.console = ConsoleWidget(self)
        self.console.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.console.setReadOnly(True)
        mainLayout.addWidget(self.console, 2, 1, 1, 3)

        # settings layout
        settingsLayout = QGridLayout()
        leftLayout.addLayout(settingsLayout)

        lengthSettingsText = QLabel('Длительность эксперимента')
        self.lengthSettingsEdit = QLineEdit('1')
        self.lengthSettingsEdit.setValidator(MyIntValidator(1, 30))
        lmin = QLabel('мин')
        lmin.setObjectName("secondary")

        settingsLayout.addWidget(lengthSettingsText, 0, 0)
        settingsLayout.addWidget(self.lengthSettingsEdit, 0, 2)
        settingsLayout.addWidget(lmin, 0, 3)

        settingsLayout.setColumnMinimumWidth(
            1, 30)  # middle column to add some sapace

        intervalLayoutText = QLabel('Интервал расчета')
        self.intervalLayoutEdit = QLineEdit('10')
        self.intervalLayoutEdit.setValidator(MyIntValidator(10, 300))
        imin = QLabel('сек')
        imin.setObjectName("secondary")
        settingsLayout.addWidget(intervalLayoutText, 1, 0)
        settingsLayout.addWidget(self.intervalLayoutEdit, 1, 2)
        settingsLayout.addWidget(imin, 1, 3)

        self.comBox = QComboBox(self)
        COMLayoutText = QLabel('Выбор COM-порта')
        COM_list = serial_ports()
        self.comBox.addItems(COM_list)
        settingsLayout.addWidget(COMLayoutText, 2, 0)
        settingsLayout.addWidget(self.comBox, 2, 2)

        # back to main layout

        settingsLayout.setRowMinimumHeight(3, 20)  # add some space vertically

        self.soundCheckBox = QCheckBox('Звуковое оповещение')
        settingsLayout.addWidget(self.soundCheckBox, 4, 0)

        self.settingsButton = QPushButton('ДОПОЛНИТЕЛЬНО')
        self.settingsButton.setObjectName('secondary')
        settingsLayout.addWidget(self.settingsButton, 4, 2, 1, 2, Qt.AlignLeft)
        self.settingsButton.clicked.connect(lambda: self.settingsWidget.open())

        self.timeLabel = QLabel('00:00:00')
        self.timeLabel.setObjectName('timeLabel')
        leftLayout.addWidget(self.timeLabel)
        leftLayout.setAlignment(self.timeLabel, Qt.AlignHCenter)

        infoLayout = QHBoxLayout()
        infoLayout.setSpacing(20)
        leftLayout.addLayout(infoLayout)
        infoLayout.addStretch()

        chss = QLabel('ЧСС')
        chss.setObjectName('leftBar')
        infoLayout.addWidget(chss)

        self.heartRateText = QLabel('0')
        self.heartRateText.setObjectName('primary')
        self.heartRateText.setAlignment(Qt.AlignRight)
        infoLayout.addWidget(self.heartRateText)

        udm = QLabel('уд/мин')
        udm.setObjectName('secondary')
        infoLayout.addWidget(udm)

        infoLayout.addSpacing(40)

        chd = QLabel('ЧД')
        chd.setObjectName('leftBar')
        infoLayout.addWidget(chd)

        self.breathRateText = QLabel('0')
        self.breathRateText.setObjectName('primary')
        self.breathRateText.setAlignment(Qt.AlignRight)
        infoLayout.addWidget(self.breathRateText)

        vdm = QLabel('вдох/мин')
        vdm.setObjectName('secondary')
        infoLayout.addWidget(vdm)

        infoLayout.addStretch()

        buttonLayout = QHBoxLayout()
        leftLayout.addLayout(buttonLayout)
        self.startStopButton = QPushButton('ЗАПУСК')
        self.startStopButton.setCheckable(True)
        self.saveButton = QPushButton('ЗАПИСЬ')
        self.saveButton.setCheckable(True)
        buttonLayout.addWidget(self.startStopButton)
        buttonLayout.addSpacing(20)
        buttonLayout.addWidget(self.saveButton)

        self.saveButton.toggled.connect(self.onSaveButtonClicked)
        self.startStopButton.toggled.connect(self.onButtonClick)

        # firs tab
        tabOneWidget = QWidget()
        tabOneLayout = QVBoxLayout()
        tabOneWidget.setLayout(tabOneLayout)
        tabWidget.addTab(tabOneWidget, "Сигнал локатора")

        self.locatorPlotWidget = PlotWidget(300, 20, 2)
        tabOneLayout.addWidget(self.locatorPlotWidget)

        tabOneButtonsLayout = QGridLayout()
        tabOneLayout.addLayout(tabOneButtonsLayout)
        locatorLeftCheckBox = QCheckBox('1-ая квадратура')
        tabOneButtonsLayout.addWidget(locatorLeftCheckBox, 0, 3)
        locatorRightCheckBox = QCheckBox('2-ая квадратура')
        tabOneButtonsLayout.addWidget(locatorRightCheckBox, 1, 3)
        locatorLeftCheckBox.setChecked(True)
        locatorRightCheckBox.setChecked(True)
        locatorLeftCheckBox.stateChanged.connect(
            lambda state: self.locatorPlotWidget.hideCurve(
                0, False if state == 1 or state == 2 else True))
        locatorRightCheckBox.stateChanged.connect(
            lambda state: self.locatorPlotWidget.hideCurve(
                1, False if state == 1 or state == 2 else True))

        # second tab
        tabTwoWidget = QWidget()
        tabTwoLayout = QVBoxLayout()
        tabTwoLayout.setContentsMargins(0, 0, 0, 0)
        tabTwoWidget.setLayout(tabTwoLayout)
        tabWidget.addTab(tabTwoWidget, "ЧСС/ЧД")

        self.heartRatePlotWidget = PlotWidget(30, 10000, 1)

        self.breathRatePlotWidget = PlotWidget(30, 10000, 1)
        tabTwoLayout.addWidget(self.heartRatePlotWidget)
        tabTwoLayout.addWidget(self.breathRatePlotWidget)

        # third tab
        tabThreeWidget = QWidget()
        tabThreeLayout = QVBoxLayout()
        tabThreeWidget.setLayout(tabThreeLayout)
        tabWidget.addTab(tabThreeWidget, "Отфильтрованный сигнал")

        self.heartFilteredPlotWidget = PlotWidget(300, 100, 2)
        self.breathFilteredPlotWidget = PlotWidget(300, 100, 2)
        tabThreeLayout.addWidget(self.heartFilteredPlotWidget)
        tabThreeLayout.addWidget(self.breathFilteredPlotWidget)
コード例 #41
0
class ResultsGUI(QWidget):

    def __init__(self, key_value, column_headers, method, parent=None):
        super(ResultsGUI, self).__init__(parent)

        # set window dimension and center it
        screen = QApplication.desktop().screenGeometry()
        width = int(screen.width() * 0.5)
        height = int(screen.height() * 0.5)
        xpos = screen.width() // 2 - width // 2
        ypos = screen.height() // 2 - height // 2
        self.setGeometry(xpos, ypos, width, height)

        # Initialize tabs
        self.tabs = QTabWidget(self)
        self.tab1 = QWidget(self)
        self.tab2 = QWidget(self)
        self.tab3 = QWidget(self)
        self.tab1.layoutVertical = QVBoxLayout(self.tab1)
        self.tab2.layoutVertical = QVBoxLayout(self.tab2)
        self.tab3.layoutVertical = QVBoxLayout(self.tab3)
        self.tab1.setLayout(self.tab1.layoutVertical)
        self.tab2.setLayout(self.tab2.layoutVertical)
        self.tab3.setLayout(self.tab3.layoutVertical)
        self.tabs.addTab(self.tab1, 'Alg 1')
        self.tabs.addTab(self.tab2, 'Alg 2')
        self.tabs.addTab(self.tab3, 'Alg 3')

        # table view 1
        self.tab1.tableView = table_view_factory(self.tab1)
        self.tab1.model = QStandardItemModel(self.tab1)
        self.tab1.tableView.setModel(self.tab1.model)
        self.tab1.layoutVertical.addWidget(self.tab1.tableView)

        # table view 2
        self.tab2.tableView = table_view_factory(self.tab2)
        self.tab2.model = self.tab1.model
        self.tab2.tableView.setModel(self.tab2.model)
        self.tab2.layoutVertical.addWidget(self.tab2.tableView)

        # table view 3
        self.tab3.tableView = table_view_factory(self.tab3)
        self.tab3.model = self.tab1.model
        self.tab3.tableView.setModel(self.tab3.model)
        self.tab3.layoutVertical.addWidget(self.tab3.tableView)

        self.tab1.model.setHorizontalHeaderLabels(column_headers)

        if method == "cb":
            data = get_recommendation_content_based(key_value)
        else:
            data = get_recommendation_collaborative_based(key_value)

        for rank, row in enumerate(data, start=1):
            items = [
                QStandardItem(str(field)) for field in row
            ]
            items.insert(0, QStandardItem(str(rank)))
            self.tab1.model.appendRow(items)

        self.layout = QVBoxLayout(self)
        self.layout.addWidget(self.tabs)
        self.setLayout(self.layout)
コード例 #42
0
class Example(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):

        self.radius = 10
        self.color = 'r'

        self.circles = Circles()

        # Initialize tab screen
        self.tabs = QTabWidget()
        self.tab1 = QWidget()
        self.tab2 = QWidget()
        self.tabs.resize(3000, 2000)

        # Add tabs
        self.tabs.addTab(self.tab1, "Edit")
        self.tabs.addTab(self.tab2, "Model")
        #self.setMouseTracking(True)
        self.figure = plt.figure()
        self.figureEarth = plt.figure()
        self.canvas = FigureCanvas(self.figure)
        self.canvasEarth = FigureCanvas(self.figureEarth)
        self.canvas.mpl_connect('motion_notify_event', self.mouseMoveEvent)
        self.canvas.mpl_connect('button_press_event', self.mousePrintEvent)

        self.button_group = QtWidgets.QButtonGroup()  # Number group
        self.r0 = QtWidgets.QRadioButton("verlet")
        self.button_group.addButton(self.r0)
        self.r1 = QtWidgets.QRadioButton("scipy")
        self.button_group.addButton(self.r1)
        self.r2 = QtWidgets.QRadioButton("threading")
        self.button_group.addButton(self.r2)
        self.r3 = QtWidgets.QRadioButton("multiprocessing")
        self.button_group.addButton(self.r3)
        self.r4 = QtWidgets.QRadioButton("compare all")
        self.button_group.addButton(self.r4)
        self.button_group.buttonClicked.connect(self.RadioButtonClicked)

        self.ax = self.figure.add_subplot(111)  # create an axis
        self.ax.set_xlim([-100, 100])
        self.ax.set_ylim([-100, 100])

        self.axEarth = self.figureEarth.add_subplot(111)  # create an axis
        self.axEarth.set_xlim([-2.0 * (10**11), 2.0 * (10**11)])
        self.axEarth.set_ylim([-2.0 * (10**11), 2.0 * (10**11)])

        # Just some button connected to  method
        self.buttonPlus = QPushButton('+')
        self.buttonPlus.clicked.connect(self.IncreaseAxes)
        self.buttonPlus.resize(self.buttonPlus.sizeHint())
        self.buttonPlus.move(50, 50)

        self.buttonMinus = QPushButton('-')
        self.buttonMinus.clicked.connect(self.DecreaseAxes)
        self.buttonMinus.resize(self.buttonMinus.sizeHint())
        self.buttonMinus.move(70, 70)

        self.buttonSave = QPushButton('Save to xml file', self)
        self.buttonSave.move(10, 10)
        self.buttonSave.clicked.connect(self.saveFileDialog)

        self.buttonOpen = QPushButton('Load from xml file', self)
        self.buttonOpen.clicked.connect(self.openFileDialog)
        self.buttonOpen.resize(self.buttonMinus.sizeHint())
        self.buttonOpen.move(70, 70)

        self.buttonColor = QPushButton('Open color dialog', self)
        self.buttonColor.setToolTip('Opens color dialog')
        self.buttonColor.move(10, 10)
        self.buttonColor.clicked.connect(self.openColorDialog)

        self.textboxX = QLineEdit(self)
        self.textboxX.move(20, 20)
        self.textboxX.resize(120, 40)
        #self.textboxX.setText('0')

        self.textboxY = QLineEdit(self)
        self.textboxY.move(220, 20)
        self.textboxY.resize(120, 40)
        #self.textboxY.setText('0')

        self.sld = QSlider(Qt.Horizontal, self)
        self.sld.setFocusPolicy(Qt.NoFocus)
        self.sld.setGeometry(30, 40, 100, 30)
        self.sld.setRange(1.0, 100.0)
        self.sld.setValue(10.0)
        self.sld.valueChanged.connect(self.changeSliderRadius)

        self.textboxSld = QLineEdit(self)
        self.textboxSld.move(420, 20)
        self.textboxSld.resize(120, 40)
        self.textboxSld.setText("10")
        self.textboxSld.textChanged.connect(self.changeTextRadius)

        # set the layout
        self.layout = QVBoxLayout(self)

        self.tab1.layout = QVBoxLayout(self)
        self.tab1.layout.addWidget(self.textboxX)
        self.tab1.layout.addWidget(self.textboxY)
        self.tab1.layout.addWidget(self.buttonColor)
        self.tab1.layout.addWidget(self.sld)
        self.tab1.layout.addWidget(self.textboxSld)
        self.tab1.layout.addWidget(self.canvas)
        self.tab1.layout.addWidget(self.buttonPlus)
        self.tab1.layout.addWidget(self.buttonMinus)
        self.tab1.layout.addWidget(self.buttonOpen)
        self.tab1.layout.addWidget(self.buttonSave)
        self.tab1.setLayout(self.tab1.layout)

        self.tab2.layout = QVBoxLayout(self)
        self.tab2.layout.addWidget(self.r0)
        self.tab2.layout.addWidget(self.r1)
        self.tab2.layout.addWidget(self.r2)
        self.tab2.layout.addWidget(self.r3)
        self.tab2.layout.addWidget(self.r4)
        self.tab2.layout.addWidget(self.canvasEarth)
        self.tab2.setLayout(self.tab2.layout)

        self.layout.addWidget(self.tabs)
        self.setLayout(self.layout)

        #self.setLayout(layout)
        self.canvas.draw()
        self.canvasEarth.draw()

        #btn = QPushButton('Button', self)
        #btn.setToolTip('This is a <b>QuitButton</b> widget')
        #btn.clicked.connect(self.changeButtonName)
        #btn.resize(btn.sizeHint())
        #btn.move(50, 50)

        self.setGeometry(300, 300, 1000, 1000)
        self.setWindowTitle('Circles')
        self.show()

    def changeSliderRadius(self, value):
        self.radius = value
        print(value)
        self.textboxSld.setText(str(self.radius))

    def changeTextRadius(self, value):
        if value != '' and self.IsFloat(value):
            radius = float(value)
            self.radius = radius
            print(value)
            if radius < self.sld.minimum():
                self.textboxSld.setText(str(self.sld.minimum()))
                self.radius = self.sld.minimum()
            elif radius > self.sld.maximum():
                self.textboxSld.setText(str(self.sld.maximum()))
                self.radius = self.sld.maximum()
            self.sld.setValue(int(radius))

    def openColorDialog(self):
        color = QColorDialog.getColor()
        self.color = color.name()
        if color.isValid():
            print(color.name())

    def mouseMoveEvent(self, e):

        print('mouseEvent')
        #print(e)
        if (e.inaxes):
            x = e.xdata
            y = e.ydata
            self.textboxX.setText("{0}".format(x))
            self.textboxY.setText("{0}".format(y))

    def changeButtonName(self):

        self.setWindowTitle(Circle.CircleName())

    def IncreaseAxes(self):
        xlim = self.ax.get_xlim()
        self.ax.set_xlim(np.multiply(xlim, 1.5))
        ylim = self.ax.get_ylim()
        self.ax.set_ylim(np.multiply(ylim, 1.5))
        self.canvas.draw()
        self.sld.setMaximum(self.sld.maximum() * 1.5)
        self.sld.setMinimum(self.sld.minimum() * 1.5)

    def DecreaseAxes(self):
        xlim = self.ax.get_xlim()
        self.ax.set_xlim(np.divide(xlim, 1.5))
        ylim = self.ax.get_ylim()
        self.ax.set_ylim(np.divide(ylim, 1.5))
        self.canvas.draw()
        self.sld.setMaximum(self.sld.maximum() / 1.5)
        self.sld.setMinimum(self.sld.minimum() / 1.5)

    def mousePrintEvent(self, event):
        #if event.button() == QtCore.Qt.LeftButton:
        #    print("Press!")
        #super(GraphicsView, self).mousePressEvent(event)
        print('circle')
        #Circle.Draw(0, 0, self.radius, self.color, self.figure)
        circle1 = MyCircle(event.xdata, event.ydata, self.radius, self.color)
        self.ax.add_artist(circle1)
        self.canvas.draw()
        self.circles.Add(circle1)

    def CreateXMLRoot(self):
        root = ET.Element("root")
        doc = ET.SubElement(root, "doc")

        fig = ET.SubElement(doc, "figure")
        ET.SubElement(fig, "X").text = str(self.ax.get_xlim()[1])
        ET.SubElement(fig, "Y").text = str(self.ax.get_ylim()[1])
        ET.SubElement(fig, "Color").text = self.color

        slider = ET.SubElement(doc, "slider")
        ET.SubElement(slider, "Max").text = str(self.sld.maximum())
        ET.SubElement(slider, "Min").text = str(self.sld.minimum())
        ET.SubElement(slider, "Radius").text = str(self.radius)

        circles = ET.SubElement(doc, "circles")
        i = 0
        for element in self.circles.elements:
            el = ET.SubElement(circles, "circle{0}".format(i))
            ET.SubElement(el, "X").text = str(element.x)
            ET.SubElement(el, "Y").text = str(element.y)
            ET.SubElement(el, "radius").text = str(element.radius)
            ET.SubElement(el, "color").text = str(element.color)
            i += 1
        return root

    def saveFileDialog(self):
        tree = ET.ElementTree(self.CreateXMLRoot())

        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getSaveFileName(
            self,
            "Save File as",
            "",
            "All Files (*);;Python Files (*.py)",
            options=options)
        if fileName:
            print(fileName)
        tree.write(fileName)

    def ParseXMLFile(self, filename):
        tree = ET.ElementTree(file=filename)
        for elem in tree.iter(tag="figure"):
            x = float(elem.find("X").text)
            y = float(elem.find("Y").text)
            self.color = elem.find("Color").text
            self.ax.set_xlim([-x, x])
            self.ax.set_ylim([-y, y])
        for elem in tree.iter(tag="slider"):
            max = float(elem.find("Max").text)
            min = float(elem.find("Min").text)
            self.sld.setRange(min, max)
            self.radius = int(float(elem.find("Radius").text))
            self.sld.setValue(self.radius)
            self.textboxSld.setText(str(self.radius))
        self.ax.clear()
        for elem in tree.iter(tag="circles"):
            for el in elem:
                x1 = float(el.find("X").text)
                y1 = float(el.find("Y").text)
                r = float(el.find("radius").text)
                col = el.find("color").text
                print('circle')
                circle1 = MyCircle(x1, y1, r, col)
                self.ax.add_artist(circle1)
                self.canvas.draw()
                self.circles.Add(circle1)

    def openFileDialog(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(
            self,
            "Open File",
            "",
            "All Files (*);;Text Files (*.txt)",
            options=options)
        if fileName:
            print(fileName)
            self.ParseXMLFile(fileName)

    def RadioButtonClicked(self, button):
        #self.axEarth.set_xlim([-2.0* (10**11), 2.0* (10**11)])
        #self.axEarth.set_ylim([-2.0* (10**11), 2.0* (10**11)])
        MEarth = 5.9724 * (10**24)
        MMoon = 7.34767309 * (10**22)
        MSun = 1988500 * (10**24)
        if (self.r0.isChecked()):
            N = 40000
            dt = 1200
            #Tn = np.linspace(0, 40*1200, 40)
            Earth = Cosmic(N, MEarth, 0, -1.496 * (10**11), 29.783 * (10**3),
                           0, 0, 0, [])
            Moon = Cosmic(N, MMoon, 0, -1.496 * (10**11) - 384.467 * (10**6),
                          29.783 * (10**3) + 1022, 0, 0, 0, [])
            Sun = Cosmic(N, MSun, 0, 0, 0, 0, 0, 0, [])
            cosmics = [Sun, Earth, Moon]
            for obj in cosmics:
                for interactionObj in cosmics:
                    if (not interactionObj is obj):
                        obj.Interactions.append(
                            (interactionObj.M, interactionObj.R))
            #verlet = Verlet(N, dt, cosmics)
            #verlet.VerletMain()
            verlet = VerletOpenCL(N, dt, cosmics)
            verlet.VerletMain()
            print("Verlet calculated")
            self.axEarth.clear()
            Tn = np.linspace(0, 4, 40001)
            ani = SubplotAnimation(self.figureEarth, self.axEarth, Tn,
                                   Sun.R[0, :], Sun.R[1, :], Earth.R[0, :],
                                   Earth.R[1, :], Moon.R[0, :], Moon.R[1, :])
            self.canvasEarth.draw()

        if (self.r1.isChecked()):
            p = [
                6.67408 * (10**(-11)), 1988500 * (10**24), 5.9724 * (10**24),
                7.34767309 * (10**22)
            ]
            w0 = [
                0, 0, 0, 0, 0, 0, 0, 29.783 * (10**3), -1.496 * (10**11), 0, 0,
                0, 0, 29.783 * (10**3) + 1022,
                -1.496 * (10**11) - 384.467 * (10**6), 0, 0, 0
            ]
            t = [1200 * float(i) for i in range(40000)]
            wsol = odeint(vectorfield, w0, t, args=(p, ))
            xSun = wsol[:, 0]
            ySun = wsol[:, 2]
            xEarth = wsol[:, 6]
            yEarth = wsol[:, 8]
            xMoon = wsol[:, 12]
            yMoon = wsol[:, 14]
            print(5)
            self.axEarth.clear()
            Tn = np.linspace(0, 4, 40000)
            ani = SubplotAnimation(self.figureEarth, self.axEarth, Tn, xSun,
                                   ySun, xEarth, yEarth, xMoon, yMoon)
            self.canvasEarth.draw()

        if (self.r2.isChecked()):
            N = 40000
            dt = 1200
            Earth = Cosmic(N, MEarth, 0, -1.496 * (10**11), 29.783 * (10**3),
                           0, 0, 0, [])
            Moon = Cosmic(N, MMoon, 0, -1.496 * (10**11) - 384.467 * (10**6),
                          29.783 * (10**3) + 1022, 0, 0, 0, [])
            Sun = Cosmic(N, MSun, 0, 0, 0, 0, 0, 0, [])
            cosmics = [Sun, Earth, Moon]
            for obj in cosmics:
                for interactionObj in cosmics:
                    if (not interactionObj is obj):
                        obj.Interactions.append(
                            (interactionObj.M, interactionObj.R))
            verlet = VerletThreads(N, dt, cosmics)
            verlet.VerletMain()
            self.figureEarth.clear()
            Tn = np.linspace(0, 4, 40001)
            ani = SubplotAnimation(self.figureEarth, self.axEarth, Tn,
                                   Sun.R[0, :], Sun.R[1, :], Earth.R[0, :],
                                   Earth.R[1, :], Moon.R[0, :], Moon.R[1, :])
            self.canvasEarth.draw()

        if (self.r3.isChecked()):
            N = 40000
            dt = 1200
            Earth = CosmicMulti(N, MEarth, 0, -1.496 * (10**11),
                                29.783 * (10**3), 0, 0, 0, [])
            Moon = CosmicMulti(N, MMoon, 0,
                               -1.496 * (10**11) - 384.467 * (10**6),
                               29.783 * (10**3) + 1022, 0, 0, 0, [])
            Sun = CosmicMulti(N, MSun, 0, 0, 0, 0, 0, 0, [])
            cosmics = [Sun, Earth, Moon]
            for obj in cosmics:
                for interactionObj in cosmics:
                    if (not interactionObj is obj):
                        obj.Interactions.append(
                            (interactionObj.M, interactionObj.R))
            verlet = VerletMultiProcessing(N, dt, cosmics)
            verlet.VerletMain()
            print("Verlet calculated")
            self.figureEarth.clear()
            Tn = np.linspace(0, 4, 40001)
            ani = SubplotAnimation(self.figureEarth, self.axEarth, Tn,
                                   Sun.bR[0, :], Sun.bR[1, :], Earth.bR[0, :],
                                   Earth.bR[1, :], Moon.bR[0, :],
                                   Moon.bR[1, :])
            self.canvasEarth.draw()

        if (self.r4.isChecked()):
            #TimesAll()

            TimesAllKBodies(50)

            #verlet = VerletThreads(400000,120)
            #verlet.REarth[0,0] = 0
            #verlet.REarth[1,0] = -1.496*(10**11)
            #verlet.VEarth[0,0] = 29.783*(10**3)

            #verlet.RMoon[1,0] = -1.496*(10**11) - 384.467*(10**6)
            #verlet.VMoon[0,0] = 29.783*(10**3) + 1022
            #verlet.VerletMain()
            #print(5)
            #self.axEarth.plot(verlet.REarth[0,:], verlet.REarth[1, :], color = 'blue')
            #self.axEarth.plot(verlet.RMoon[0,:], verlet.RMoon[1, :], color = 'gray')
            #print(6)
            #self.canvasEarth.draw()

    def IsFloat(self, value):
        try:
            float(value)
            return True
        except:
            return False
コード例 #43
0
class App(QWidget):
    def __init__(self):
        super().__init__()
        self.title = 'Algoritmos evolutivos'
        self.left = 50
        self.top = 50
        self.width = 720
        self.height = 540
        self.initUI()

    def initUI(self):
        self.layout = QVBoxLayout(self)
        self.tabs = QTabWidget()
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.tabs.resize(300, 200)
        self.tabs.addTab(UIEvolutionary(), 'Evolutionary')
        self.tabs.addTab(UIImmune(), 'Immune')
        self.tabs.addTab(UIPhysical(), 'Physical')
        self.tabs.addTab(UIProbabilistic(), 'Probabilistic')
        self.tabs.addTab(UIStochastic(), 'Stochastic')
        self.tabs.addTab(UISwarm(), 'Swarm')
        self.tabs.addTab(UIParallel(), 'Parallel')
        self.layout.addWidget(self.tabs)
        self.setLayout(self.layout)
コード例 #44
0
ファイル: about_ui.py プロジェクト: MrSmiler/persepolis
class AboutWindow_Ui(QWidget):
    def __init__(self,persepolis_setting):
        super().__init__()

        self.persepolis_setting = persepolis_setting

        # add support for other languages
        locale = str(self.persepolis_setting.value('settings/locale'))
        QLocale.setDefault(QLocale(locale))
        self.translator = QTranslator()
        if self.translator.load(':/translations/locales/ui_' + locale, 'ts'):
            QCoreApplication.installTranslator(self.translator)

        # set ui direction
        ui_direction = self.persepolis_setting.value('ui_direction')

        if ui_direction == 'rtl':
            self.setLayoutDirection(Qt.RightToLeft)
        
        elif ui_direction in 'ltr':
            self.setLayoutDirection(Qt.LeftToRight)


        icons = ':/' + \
            str(self.persepolis_setting.value('settings/icons')) + '/'

        self.setMinimumSize(QSize(545, 375))
        self.setWindowIcon(QIcon.fromTheme('persepolis', QIcon(':/persepolis.svg')))

        verticalLayout = QVBoxLayout(self)

        self.about_tabWidget = QTabWidget(self)

        # about tab
        self.about_tab = QWidget(self)

        about_tab_horizontalLayout = QHBoxLayout(self.about_tab)

        about_tab_verticalLayout = QVBoxLayout()
        

        # persepolis icon
        if qtsvg_available:
            persepolis_icon_verticalLayout = QVBoxLayout()
            self.persepolis_icon = QtSvg.QSvgWidget(':/persepolis.svg')
            self.persepolis_icon.setFixedSize(QSize(64, 64))

            persepolis_icon_verticalLayout.addWidget(self.persepolis_icon)
            persepolis_icon_verticalLayout.addStretch(1)

            about_tab_horizontalLayout.addLayout(persepolis_icon_verticalLayout)

        self.title_label = QLabel(self.about_tab)
        font = QFont()
        font.setBold(True)
        font.setWeight(75)
        self.title_label.setFont(font)
        self.title_label.setAlignment(Qt.AlignCenter)
        about_tab_verticalLayout.addWidget(self.title_label)

        self.version_label = QLabel(self.about_tab)
        self.version_label.setAlignment(Qt.AlignCenter)

        about_tab_verticalLayout.addWidget(self.version_label)

        self.site2_label = QLabel(self.about_tab)
        self.site2_label.setTextFormat(Qt.RichText)
        self.site2_label.setAlignment(Qt.AlignCenter)
        self.site2_label.setOpenExternalLinks(True)
        self.site2_label.setTextInteractionFlags(
            Qt.TextBrowserInteraction)
        about_tab_verticalLayout.addWidget(self.site2_label)

        self.telegram_label = QLabel(self.about_tab)
        self.telegram_label.setTextFormat(Qt.RichText)
        self.telegram_label.setAlignment(Qt.AlignCenter)
        self.telegram_label.setOpenExternalLinks(True)
        self.telegram_label.setTextInteractionFlags(
            Qt.TextBrowserInteraction)
        about_tab_verticalLayout.addWidget(self.telegram_label)

        self.twitter_label = QLabel(self.about_tab)
        self.twitter_label.setTextFormat(Qt.RichText)
        self.twitter_label.setAlignment(Qt.AlignCenter)
        self.twitter_label.setOpenExternalLinks(True)
        self.twitter_label.setTextInteractionFlags(
            Qt.TextBrowserInteraction)
        about_tab_verticalLayout.addWidget(self.twitter_label)

        about_tab_verticalLayout.addStretch(1)

        about_tab_horizontalLayout.addLayout(about_tab_verticalLayout)


        # developers_tab
        self.developers_tab = QWidget(self)
        developers_verticalLayout = QVBoxLayout(self.developers_tab)

        self.developers_title_label = QLabel(self.developers_tab)
        font.setBold(True)
        font.setWeight(75)
        self.developers_title_label.setFont(font)
        self.developers_title_label.setAlignment(Qt.AlignCenter)
        developers_verticalLayout.addWidget(self.developers_title_label)
 

        self.name_label = QLabel(self.developers_tab)
        self.name_label.setAlignment(Qt.AlignCenter)

        developers_verticalLayout.addWidget(self.name_label)

        developers_verticalLayout.addStretch(1)

        # translators tab
        self.translators_tab = QWidget(self)
        translators_tab_verticalLayout = QVBoxLayout(self.translators_tab)

        # chinese translators
        self.chinese_translators_label = QLabel(self.translators_tab)
        self.chinese_translators_label.setFont(font)
        self.chinese_translators_label.setAlignment(Qt.AlignCenter)
        translators_tab_verticalLayout.addWidget(self.chinese_translators_label)

        self.chinese_translatos_name_label = QLabel(self.translators_tab)
        self.chinese_translatos_name_label.setAlignment(Qt.AlignCenter)
        translators_tab_verticalLayout.addWidget(self.chinese_translatos_name_label)

        # persian translators
        self.persian_translators_label = QLabel(self.translators_tab)
        self.persian_translators_label.setFont(font)
        self.persian_translators_label.setAlignment(Qt.AlignCenter)

        translators_tab_verticalLayout.addWidget(self.persian_translators_label)

        self.persian_translatos_name_label = QLabel(self.translators_tab)
        self.persian_translatos_name_label.setAlignment(Qt.AlignCenter)
        translators_tab_verticalLayout.addWidget(self.persian_translatos_name_label)


        translators_tab_verticalLayout.addStretch(1)
   
        # License tab
        self.license_tab = QWidget(self)
        license_tab_verticalLayout = QVBoxLayout(self.license_tab)

        self.license_text = QTextEdit(self.license_tab)
        self.license_text.setReadOnly(True)

        license_tab_verticalLayout.addWidget(self.license_text)



        verticalLayout.addWidget(self.about_tabWidget)

        # buttons
        button_horizontalLayout = QHBoxLayout()
        button_horizontalLayout.addStretch(1)

        self.pushButton = QPushButton(self)
        self.pushButton.setIcon(QIcon(icons + 'ok'))
        self.pushButton.clicked.connect(self.close)

        button_horizontalLayout.addWidget(self.pushButton)

        verticalLayout.addLayout(button_horizontalLayout)

        self.setWindowTitle(QCoreApplication.translate("about_ui_tr", "About Persepolis"))

        # about_tab
        self.title_label.setText(QCoreApplication.translate("about_ui_tr", "Persepolis Download Manager"))
        self.version_label.setText(QCoreApplication.translate("about_ui_tr", "Version 3.0.1"))
        self.site2_label.setText(QCoreApplication.translate("about_ui_tr", 
            "<a href=https://persepolisdm.github.io>https://persepolisdm.github.io</a>",
            "TRANSLATORS NOTE: YOU REALLY DON'T NEED TO TRANSLATE THIS PART!"))

        self.telegram_label.setText(QCoreApplication.translate("about_ui_tr", 
            "<a href=https://telegram.me/persepolisdm>https://telegram.me/persepolisdm</a>",
            "TRANSLATORS NOTE: YOU REALLY DON'T NEED TO TRANSLATE THIS PART!"))

        self.twitter_label.setText(QCoreApplication.translate("about_ui_tr", 
            "<a href=https://twitter.com/persepolisdm>https://twitter.com/persepolisdm</a>",
            "TRANSLATORS NOTE: YOU REALLY DON'T NEED TO TRANSLATE THIS PART!"))

        #developers_tab
        self.developers_title_label.setText(QCoreApplication.translate('about_ui_tr', 'Developers:'))

        self.name_label.setText(QCoreApplication.translate("about_ui_tr", 
            "\nAliReza AmirSamimi\nMohammadreza Abdollahzadeh\nSadegh Alirezaie\nMostafa Asadi\nMohammadAmin Vahedinia\nJafar Akhondali\nH.Rostami",
            "TRANSLATORS NOTE: YOU REALLY DON'T NEED TO TRANSLATE THIS PART!"))

        # translators_tab
        self.persian_translators_label.setText(QCoreApplication.translate("about_ui_tr", "Persian translators:"))

        self.persian_translatos_name_label.setText(QCoreApplication.translate("about_ui_tr", "H.Rostami\nMostafa Asadi"))

        self.chinese_translators_label.setText(QCoreApplication.translate("about_ui_tr", "Chinese translators:"))

        self.chinese_translatos_name_label.setText(QCoreApplication.translate("about_ui_tr", "Davinma\n210hcl\nleoxxx"))

        # License
        self.license_text.setPlainText("""
            This program is free software: you can redistribute it and/or modify
            it under the terms of the GNU General Public License as published by
            the Free Software Foundation, either version 3 of the License, or
            (at your option) any later version.

            This program is distributed in the hope that it will be useful,
            but WITHOUT ANY WARRANTY; without even the implied warranty of
            MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
            GNU General Public License for more details.

            You should have received a copy of the GNU General Public License
            along with this program.  If not, see http://www.gnu.org/licenses/.
            """)


        # tabs
        self.about_tabWidget.addTab(self.about_tab, QCoreApplication.translate("about_ui_tr", "About Persepolis"))
        self.about_tabWidget.addTab(self.developers_tab, QCoreApplication.translate("about_ui_tr", "Developers"))
        self.about_tabWidget.addTab(self.translators_tab, QCoreApplication.translate("about_ui_tr", "Translators"))
        self.about_tabWidget.addTab(self.license_tab, QCoreApplication.translate("about_ui_tr", "License"))

        # button
        self.pushButton.setText(QCoreApplication.translate("about_ui_tr", "OK"))
コード例 #45
0
class WeatherDataGapfiller(QMainWindow):

    ConsoleSignal = QSignal(str)

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

        self._corrcoeff_update_inprogress = False
        self._pending_corrcoeff_update = None
        self._loading_data_inprogress = False

        self.__initUI__()

        # Setup the DataGapfillManager.
        self.gapfill_manager = DataGapfillManager()
        self.gapfill_manager.sig_task_progress.connect(
            self.progressbar.setValue)
        self.gapfill_manager.sig_status_message.connect(
            self.set_statusbar_text)

    def __initUI__(self):
        self.setWindowIcon(get_icon('master'))

        # Setup the toolbar at the bottom.
        self.btn_fill = QPushButton('Gapfill Data')
        self.btn_fill.setIcon(get_icon('fill_data'))
        self.btn_fill.setIconSize(get_iconsize('small'))
        self.btn_fill.setToolTip(
            "Fill the gaps in the daily weather data of the selected "
            "weather station.")
        self.btn_fill.clicked.connect(self._handle_gapfill_btn_clicked)

        widget_toolbar = QFrame()
        grid_toolbar = QGridLayout(widget_toolbar)
        grid_toolbar.addWidget(self.btn_fill, 0, 0)
        grid_toolbar.setContentsMargins(0, 0, 0, 0)
        grid_toolbar.setColumnStretch(0, 100)

        # ---- Target Station groupbox
        self.target_station = QComboBox()
        self.target_station.currentIndexChanged.connect(
            self._handle_target_station_changed)

        self.target_station_info = QTextEdit()
        self.target_station_info.setReadOnly(True)
        self.target_station_info.setMaximumHeight(110)

        self.btn_refresh_staList = QToolButton()
        self.btn_refresh_staList.setIcon(get_icon('refresh'))
        self.btn_refresh_staList.setToolTip(
            'Force the reloading of the weather data files')
        self.btn_refresh_staList.setIconSize(get_iconsize('small'))
        self.btn_refresh_staList.setAutoRaise(True)
        self.btn_refresh_staList.clicked.connect(
            lambda: self.load_data_dir_content(force_reload=True))

        self.btn_delete_data = QToolButton()
        self.btn_delete_data.setIcon(get_icon('delete_data'))
        self.btn_delete_data.setEnabled(False)
        self.btn_delete_data.setAutoRaise(True)
        self.btn_delete_data.setToolTip(
            'Remove the currently selected dataset and delete the input '
            'datafile. However, raw datafiles will be kept.')
        self.btn_delete_data.clicked.connect(self.delete_current_dataset)

        # Generate the layout for the target station group widget.
        self.target_widget = QWidget()
        target_station_layout = QGridLayout(self.target_widget)
        target_station_layout.setHorizontalSpacing(1)
        target_station_layout.setColumnStretch(0, 1)
        target_station_layout.setContentsMargins(0, 0, 0, 0)

        widgets = [self.target_station, self.btn_refresh_staList,
                   self.btn_delete_data]
        target_station_layout.addWidget(self.target_station, 1, 0)
        for col, widget in enumerate(widgets):
            target_station_layout.addWidget(widget, 1, col)

        # Setup the gapfill dates.
        label_From = QLabel('From :  ')
        self.date_start_widget = QDateEdit()
        self.date_start_widget.setDisplayFormat('dd / MM / yyyy')
        self.date_start_widget.setEnabled(False)
        self.date_start_widget.dateChanged.connect(
            self._update_corrcoeff_table)

        label_To = QLabel('To :  ')
        self.date_end_widget = QDateEdit()
        self.date_end_widget.setEnabled(False)
        self.date_end_widget.setDisplayFormat('dd / MM / yyyy')
        self.date_end_widget.dateChanged.connect(
            self._update_corrcoeff_table)

        self.fillDates_widg = QWidget()
        gapfilldates_layout = QGridLayout(self.fillDates_widg)
        gapfilldates_layout.addWidget(label_From, 0, 0)
        gapfilldates_layout.addWidget(self.date_start_widget, 0, 1)
        gapfilldates_layout.addWidget(label_To, 1, 0)
        gapfilldates_layout.addWidget(self.date_end_widget, 1, 1)
        gapfilldates_layout.setColumnStretch(2, 1)
        gapfilldates_layout.setContentsMargins(0, 0, 0, 0)

        # Create the gapfill target station groupbox.
        target_groupbox = QGroupBox("Fill data for weather station")
        target_layout = QGridLayout(target_groupbox)
        target_layout.addWidget(self.target_widget, 0, 0)
        target_layout.addWidget(self.target_station_info, 1, 0)
        target_layout.addWidget(self.fillDates_widg, 2, 0)

        # Setup the left panel.
        self._regression_model_groupbox = (
            self._create_regression_model_settings())
        self._station_selection_groupbox = (
            self._create_station_selection_criteria())

        self.left_panel = QFrame()
        left_panel_layout = QGridLayout(self.left_panel)
        left_panel_layout.addWidget(target_groupbox, 0, 0)
        left_panel_layout.addWidget(self._station_selection_groupbox, 3, 0)
        left_panel_layout.addWidget(self._regression_model_groupbox, 4, 0)
        left_panel_layout.addWidget(widget_toolbar, 5, 0)
        left_panel_layout.setRowStretch(6, 1)
        left_panel_layout.setContentsMargins(0, 0, 0, 0)

        # Setup the right panel.
        self.corrcoeff_textedit = QTextEdit()
        self.corrcoeff_textedit.setReadOnly(True)
        self.corrcoeff_textedit.setMinimumWidth(700)
        self.corrcoeff_textedit.setFrameStyle(0)
        self.corrcoeff_textedit.document().setDocumentMargin(10)

        self.sta_display_summary = QTextEdit()
        self.sta_display_summary.setReadOnly(True)
        self.sta_display_summary.setFrameStyle(0)
        self.sta_display_summary.document().setDocumentMargin(10)

        self.right_panel = QTabWidget()
        self.right_panel.addTab(
            self.corrcoeff_textedit, 'Correlation Coefficients')
        self.right_panel.addTab(
            self.sta_display_summary, 'Data Overview')

        # Setup the progressbar.
        self.progressbar = QProgressBar()
        self.progressbar.setValue(0)
        self.progressbar.hide()

        self.statustext = QLabel()
        self.statustext.setStyleSheet(
            "QLabel {background-color: transparent; padding: 0 0 0 3px;}")
        self.statustext.setMinimumHeight(self.progressbar.minimumHeight())

        # Setup the main widget.
        main_widget = QWidget()
        main_grid = QGridLayout(main_widget)
        main_grid.addWidget(self.left_panel, 0, 0)
        main_grid.addWidget(self.right_panel, 0, 1)
        main_grid.addWidget(self.progressbar, 1, 0, 1, 2)
        main_grid.addWidget(self.statustext, 1, 0, 1, 2)
        main_grid.setColumnStretch(1, 500)
        main_grid.setRowStretch(0, 500)
        self.setCentralWidget(main_widget)

    def _create_station_selection_criteria(self):
        Nmax_label = QLabel('Nbr. of stations :')
        self.Nmax = QSpinBox()
        self.Nmax.setRange(0, 99)
        self.Nmax.setMinimum(1)
        self.Nmax.setValue(CONF.get('gapfill_data', 'nbr_of_station', 4))
        self.Nmax.setAlignment(Qt.AlignCenter)

        ttip = ('<p>Distance limit beyond which neighboring stations'
                ' are excluded from the gapfilling procedure.</p>'
                '<p>This condition is ignored if set to -1.</p>')
        distlimit_label = QLabel('Max. Distance :')
        distlimit_label.setToolTip(ttip)
        self.distlimit = QSpinBox()
        self.distlimit.setRange(-1, 9999)
        self.distlimit.setSingleStep(1)
        self.distlimit.setValue(
            CONF.get('gapfill_data', 'max_horiz_dist', 100))
        self.distlimit.setToolTip(ttip)
        self.distlimit.setSuffix(' km')
        self.distlimit.setAlignment(Qt.AlignCenter)
        self.distlimit.valueChanged.connect(self._update_corrcoeff_table)

        ttip = ('<p>Altitude difference limit over which neighboring '
                ' stations are excluded from the gapfilling procedure.</p>'
                '<p>This condition is ignored if set to -1.</p>')
        altlimit_label = QLabel('Max. Elevation Diff. :')
        altlimit_label.setToolTip(ttip)
        self.altlimit = QSpinBox()
        self.altlimit.setRange(-1, 9999)
        self.altlimit.setSingleStep(1)
        self.altlimit.setValue(
            CONF.get('gapfill_data', 'max_vert_dist', 350))
        self.altlimit.setToolTip(ttip)
        self.altlimit.setSuffix(' m')
        self.altlimit.setAlignment(Qt.AlignCenter)
        self.altlimit.valueChanged.connect(self._update_corrcoeff_table)

        # Setup the main widget.
        widget = QGroupBox('Stations Selection Criteria')
        layout = QGridLayout(widget)

        layout.addWidget(Nmax_label, 0, 0)
        layout.addWidget(self.Nmax, 0, 1)
        layout.addWidget(distlimit_label, 1, 0)
        layout.addWidget(self.distlimit, 1, 1)
        layout.addWidget(altlimit_label, 2, 0)
        layout.addWidget(self.altlimit, 2, 1)
        layout.setColumnStretch(0, 1)

        return widget

    def _create_advanced_settings(self):
        self.full_error_analysis = QCheckBox('Full Error Analysis.')
        self.full_error_analysis.setChecked(True)

        fig_opt_layout = QGridLayout()
        fig_opt_layout.addWidget(QLabel("Figure output format : "), 0, 0)
        fig_opt_layout.addWidget(self.fig_format, 0, 2)
        fig_opt_layout.addWidget(QLabel("Figure labels language : "), 1, 0)
        fig_opt_layout.addWidget(self.fig_language, 1, 2)

        fig_opt_layout.setContentsMargins(0, 0, 0, 0)
        fig_opt_layout.setColumnStretch(1, 100)

        # Setup the main layout.
        widget = QFrame()
        layout = QGridLayout(widget)
        layout.addWidget(self.full_error_analysis, 0, 0)
        layout.addLayout(fig_opt_layout, 2, 0)
        layout.setRowStretch(layout.rowCount(), 100)
        layout.setContentsMargins(10, 0, 10, 0)

        return widget

    def _create_regression_model_settings(self):
        self.RMSE_regression = QRadioButton('Ordinary Least Squares')
        self.RMSE_regression.setChecked(
            CONF.get('gapfill_data', 'regression_model', 'OLS') == 'OLS')

        self.ABS_regression = QRadioButton('Least Absolute Deviations')
        self.ABS_regression.setChecked(
            CONF.get('gapfill_data', 'regression_model', 'OLS') == 'LAD')

        widget = QGroupBox('Regression Model')
        layout = QGridLayout(widget)
        layout.addWidget(self.RMSE_regression, 0, 0)
        layout.addWidget(self.ABS_regression, 1, 0)

        return widget

    def set_statusbar_text(self, text):
        self.statustext.setText(text)

    @property
    def workdir(self):
        return self._workdir

    def set_workdir(self, dirname):
        """
        Set the working directory to dirname.
        """
        self._workdir = dirname
        self.gapfill_manager.set_workdir(dirname)
        self.load_data_dir_content()

    def delete_current_dataset(self):
        """
        Delete the current dataset source file and force a reload of the input
        daily weather datafiles.
        """
        current_index = self.target_station.currentIndex()
        if current_index != -1:
            basename = self.gapfill_manager.worker().wxdatasets.fnames[
                current_index]
            filename = os.path.join(self.workdir, basename)
            delete_file(filename)
            self.load_data_dir_content()

    def _handle_target_station_changed(self):
        """Handle when the target station is changed by the user."""
        self.btn_delete_data.setEnabled(
            self.target_station.currentIndex() != -1)
        self.update_corrcoeff()

    def get_dataset_names(self):
        """
        Return a list of the names of the dataset that are loaded in
        memory and listed in the target station dropdown menu.
        """
        return [self.target_station.itemText(i) for i in
                range(self.target_station.count())]

    # ---- Correlation coefficients
    def update_corrcoeff(self):
        """
        Calculate the correlation coefficients and display the results
        in the GUI.
        """
        if self.target_station.currentIndex() != -1:
            station_id = self.target_station.currentData()
            if self._corrcoeff_update_inprogress is True:
                self._pending_corrcoeff_update = station_id
            else:
                self._corrcoeff_update_inprogress = True
                self.corrcoeff_textedit.setText('')
                self.gapfill_manager.set_target_station(
                    station_id, callback=self._handle_corrcoeff_updated)

    def _handle_corrcoeff_updated(self):
        self._corrcoeff_update_inprogress = False
        if self._pending_corrcoeff_update is None:
            self._update_corrcoeff_table()
        else:
            self._pending_corrcoeff_update = None
            self.update_corrcoeff()

    def _update_corrcoeff_table(self):
        """
        This method plot the correlation coefficient table in the display area.

        It is separated from the method "update_corrcoeff" because red
        numbers and statistics regarding missing data for the selected
        time period can be updated in the table when the user changes the
        values without having to recalculate the correlation coefficient
        each time.
        """
        if self.target_station.currentIndex() != -1:
            table, target_info = (
                self.gapfill_manager.worker().generate_correlation_html_table(
                    self.get_gapfill_parameters()))
            self.corrcoeff_textedit.setText(table)
            self.target_station_info.setText(target_info)

    # ---- Load Data
    def load_data_dir_content(self, force_reload=False):
        """
        Load weater data from valid files contained in the working directory.
        """
        self._pending_corrcoeff_update = None
        self._loading_data_inprogress = True
        self.left_panel.setEnabled(False)
        self.right_panel.setEnabled(False)

        self.corrcoeff_textedit.setText('')
        self.target_station_info.setText('')
        self.target_station.clear()

        self.gapfill_manager.load_data(
            force_reload=force_reload,
            callback=self._handle_data_dir_content_loaded)

    def _handle_data_dir_content_loaded(self):
        """
        Handle when data finished loaded from valid files contained in
        the working directory.
        """
        self.left_panel.setEnabled(True)
        self.right_panel.setEnabled(True)

        self.target_station.blockSignals(True)
        station_names = self.gapfill_manager.get_station_names()
        station_ids = self.gapfill_manager.get_station_ids()
        for station_name, station_id in zip(station_names, station_ids):
            self.target_station.addItem(
                '{} ({})'.format(station_name, station_id),
                userData=station_id)
        self.target_station.blockSignals(False)

        self.sta_display_summary.setHtml(
            self.gapfill_manager.worker().generate_html_summary_table())

        if len(station_names) > 0:
            self._setup_fill_and_save_dates()
            self.target_station.blockSignals(True)
            self.target_station.setCurrentIndex(0)
            self.target_station.blockSignals(False)
        self._handle_target_station_changed()
        self._loading_data_inprogress = False

    def _setup_fill_and_save_dates(self):
        """
        Set first and last dates of the 'Fill data for weather station'.
        """
        if self.gapfill_manager.count():
            self.date_start_widget.setEnabled(True)
            self.date_end_widget.setEnabled(True)

            mindate = (
                self.gapfill_manager.worker()
                .wxdatasets.metadata['first_date'].min())
            maxdate = (
                self.gapfill_manager.worker()
                .wxdatasets.metadata['last_date'].max())

            qdatemin = QDate(mindate.year, mindate.month, mindate.day)
            qdatemax = QDate(maxdate.year, maxdate.month, maxdate.day)

            self.date_start_widget.blockSignals(True)
            self.date_start_widget.setDate(qdatemin)
            self.date_start_widget.setMinimumDate(qdatemin)
            self.date_start_widget.setMaximumDate(qdatemax)
            self.date_start_widget.blockSignals(False)

            self.date_end_widget.blockSignals(True)
            self.date_end_widget.setDate(qdatemax)
            self.date_end_widget.setMinimumDate(qdatemin)
            self.date_end_widget.setMaximumDate(qdatemax)
            self.date_end_widget.blockSignals(False)

    # ---- Gapfill Data
    def get_gapfill_parameters(self):
        """
        Return a dictionary containing the parameters that are set in the GUI
        for gapfilling weather data.
        """
        return {
            'limitDist': self.distlimit.value(),
            'limitAlt': self.altlimit.value(),
            'date_start': self.date_start_widget.date().toString('dd/MM/yyyy'),
            'date_end': self.date_end_widget.date().toString('dd/MM/yyyy')
            }

    def _handle_gapfill_btn_clicked(self):
        """
        Handle when the user clicked on the gapfill button.
        """
        if self.gapfill_manager.count() == 0:
            QMessageBox.warning(
                self, 'Warning', "There is no data to fill.", QMessageBox.Ok)
            return

        # Check for dates errors.
        datetime_start = datetime_from_qdatedit(self.date_start_widget)
        datetime_end = datetime_from_qdatedit(self.date_end_widget)
        if datetime_start > datetime_end:
            QMessageBox.warning(
                self, 'Warning',
                ("<i>From</i> date is set to a later time than "
                 "the <i>To</i> date."),
                QMessageBox.Ok)
            return
        if self.target_station.currentIndex() == -1:
            QMessageBox.warning(
                self, 'Warning',
                "No weather station is currently selected",
                QMessageBox.Ok)
            return

        self.start_gapfill_target()

    def _handle_gapfill_target_finished(self):
        """
        Method initiated from an automatic return from the gapfilling
        process in batch mode. Iterate over the station list and continue
        process normally.
        """
        self.btn_fill.setIcon(get_icon('fill_data'))
        self.btn_fill.setEnabled(True)

        self.target_widget.setEnabled(True)
        self.fillDates_widg.setEnabled(True)
        self._regression_model_groupbox.setEnabled(True)
        self._station_selection_groupbox.setEnabled(True)
        self.progressbar.setValue(0)
        QApplication.processEvents()
        self.progressbar.hide()

    def start_gapfill_target(self):
        # Update the gui.
        self.btn_fill.setEnabled(False)
        self.fillDates_widg.setEnabled(False)
        self.target_widget.setEnabled(False)
        self._regression_model_groupbox.setEnabled(False)
        self._station_selection_groupbox.setEnabled(False)
        self.progressbar.show()

        # Start the gapfill thread.
        self.gapfill_manager.gapfill_data(
            time_start=datetime_from_qdatedit(self.date_start_widget),
            time_end=datetime_from_qdatedit(self.date_end_widget),
            max_neighbors=self.Nmax.value(),
            hdist_limit=self.distlimit.value(),
            vdist_limit=self.altlimit.value(),
            regression_mode=self.RMSE_regression.isChecked(),
            callback=self._handle_gapfill_target_finished
            )

    def close(self):
        CONF.set('gapfill_data', 'nbr_of_station', self.Nmax.value())
        CONF.set('gapfill_data', 'max_horiz_dist', self.distlimit.value())
        CONF.set('gapfill_data', 'max_vert_dist', self.altlimit.value())
        CONF.set('gapfill_data', 'regression_model',
                 'OLS' if self.RMSE_regression.isChecked() else 'LAD')
        super().close()
コード例 #46
0
class Zstopwatch(QWidget):
    """Zstopwatch class"""
    def __init__(self):
        super().__init__()
        self.create_widgets()

    def create_widgets(self):
        """create_widgets"""
        self.seconds = 0
        self.current_seconds = 0

        #vbox_main
        self.vbox_main = QVBoxLayout()
        self.vbox_main.setContentsMargins(2, 2, 2, 2)
        self.setLayout(self.vbox_main)

        #hbox_tools
        self.hbox_tools = QHBoxLayout()
        self.vbox_main.addLayout(self.hbox_tools)
        #button_start
        self.button_start = QPushButton('Start')
        self.button_start.setIcon(QIcon(':/start_icon.png'))
        self.button_start.setFixedSize(80, 30)
        self.button_start.setCursor(Qt.PointingHandCursor)
        self.button_start.setStyleSheet(styles.get_button_style())
        self.button_start.clicked.connect(self.press_start_button)
        self.hbox_tools.addWidget(self.button_start)
        #
        self.hbox_tools.addStretch()
        #button_stop
        self.button_stop = QPushButton('Stop')
        self.button_stop.setIcon(QIcon(':/stop_icon.png'))
        self.button_stop.setFixedSize(80, 30)
        self.button_stop.setCursor(Qt.PointingHandCursor)
        self.button_stop.setStyleSheet(styles.get_button_style())
        self.button_stop.clicked.connect(self.press_stop_button)
        self.hbox_tools.addWidget(self.button_stop)

        #frame_labels
        self.frame_labels = QFrame()
        self.frame_labels.setStyleSheet("QFrame{border:1px solid silver;}")
        self.vbox_main.addWidget(self.frame_labels)
        #vbox_labels
        self.vbox_labels = QVBoxLayout()
        self.frame_labels.setLayout(self.vbox_labels)
        #label_timer
        self.label_timer = QLabel()
        self.label_timer.setAlignment(Qt.AlignCenter)
        self.label_timer.setStyleSheet(
            "QLabel{font-size:48px; border:1px solid transparent;}")
        self.vbox_labels.addWidget(self.label_timer)
        #label_current_time
        self.label_current_time = QLabel()
        self.label_current_time.setAlignment(Qt.AlignCenter)
        self.label_current_time.setStyleSheet("""QLabel{
													font-size:24px; 
													color:#609dff; 
													border:1px solid transparent;
												}""")
        self.vbox_labels.addWidget(self.label_current_time)

        #tabber
        self.tabber = QTabWidget()
        self.tabber.setIconSize(QSize(35, 35))
        self.vbox_main.addWidget(self.tabber)

        #add tabs
        #clock
        self.clock_tab = clock_tab.Clock_tab()
        self.tabber.addTab(self.clock_tab, QIcon(':/clock_icon.png'), '')
        #plan
        self.plan_tab = plan_tab.Plan_tab()
        self.tabber.addTab(self.plan_tab, QIcon(':/plan_icon.png'), '')
        #config
        self.config_tab = config_tab.Config_tab()
        self.tabber.addTab(self.config_tab, QIcon(':/config_icon.png'), '')
        #about
        self.about_tab = about.About()
        self.tabber.addTab(self.about_tab, QIcon(':/about_icon.png'), '')

        #main_timer
        self.main_timer = QTimer()
        self.main_timer.setInterval(1000)
        self.main_timer.timeout.connect(self.timer_out)

        #current_timer
        self.current_timer = QTimer()
        self.current_timer.setInterval(1000)
        self.current_timer.timeout.connect(self.current_timer_out)

        ###
        self.setWindowTitle('ZVVStopWatch')
        self.setWindowIcon(QIcon(':/app_icon.png'))
        self.setFixedSize(400, 550)
        self.show()

        #AUTORUN
        self.set_default_time()

#######################################################################

    def set_default_time(self):
        """Set default time"""
        #main_timer
        self.seconds = 0
        self.set_time(self.seconds)
        #current_timer
        self.current_seconds = 0
        self.set_current_time(self.current_seconds)

    def press_start_button(self):
        """Press start button"""
        if self.clock_tab.table_widget.rowCount() > 0:
            self.clock_tab.table_widget.setRowCount(0)
        self.main_timer.start()
        self.check_plan_task()
        QSound.play('./sounds/click.wav')

    def press_stop_button(self):
        """Press start button"""
        self.main_timer.stop()
        self.current_timer.stop()
        self.set_default_time()

    def timer_out(self):
        """Timer out"""
        self.seconds += 1
        self.set_time(self.seconds)
        self.play_main_seconds_sound(self.seconds)

    def set_time(self, seconds):
        """Set seconds"""
        time_info = datetime.timedelta(seconds=seconds)
        self.label_timer.setText(str(time_info))

    def check_plan_task(self):
        """Check plan task"""
        if self.plan_tab.table_widget.rowCount() > 0:
            self.current_seconds = int(
                self.plan_tab.table_widget.item(0, 1).TASK_TIME)
            self.set_current_time(self.current_seconds)
            self.current_timer.start()
        else:
            if self.config_tab.checkbox_end_all_tasks.isChecked():
                if self.clock_tab.table_widget.rowCount() > 0:
                    self.press_stop_button()

    def current_timer_out(self):
        """Current time out"""
        self.current_seconds -= 1
        self.set_current_time(self.current_seconds)
        if self.current_seconds <= 0:
            #delete plan row, get new task and start task
            if self.plan_tab.table_widget.rowCount() > 0:
                name = self.plan_tab.table_widget.item(0, 0).TASK_NAME
                time_text = self.plan_tab.table_widget.item(0, 1).TASK_TIME
                self.clock_tab.add_one_row(name, time_text)
            QSound.play('./sounds/finish.wav')
            self.current_timer.stop()
            self.plan_tab.remove_row(0)
            self.check_plan_task()

    def set_current_time(self, current_seconds):
        """Set current_seconds"""
        time_info = datetime.timedelta(seconds=current_seconds)
        self.label_current_time.setText(str(time_info)[2:])

    def play_main_seconds_sound(self, seconds):
        """Play main seconds sounds"""
        time_min = self.config_tab.spinbox_min_task.value()
        time_sec = self.config_tab.spinbox_sec_task.value()
        if time_min > 0 or time_sec > 0:
            full_time = (time_min * 60) + time_sec
            if seconds % full_time == 0:
                QSound.play('./sounds/normal.wav')
コード例 #47
0
class Setting_Ui(QWidget):
    def __init__(self, persepolis_setting):
        super().__init__()
        icon = QtGui.QIcon()

        # add support for other languages
        locale = str(persepolis_setting.value('settings/locale'))
        QLocale.setDefault(QLocale(locale))
        self.translator = QTranslator()
        if self.translator.load(':/translations/locales/ui_' + locale, 'ts'):
            QCoreApplication.installTranslator(self.translator)

        self.setWindowIcon(
            QIcon.fromTheme('persepolis', QIcon(':/persepolis.svg')))
        self.setWindowTitle(
            QCoreApplication.translate("setting_ui_tr", 'Preferences'))

        # set ui direction
        ui_direction = persepolis_setting.value('ui_direction')

        if ui_direction == 'rtl':
            self.setLayoutDirection(Qt.RightToLeft)

        elif ui_direction in 'ltr':
            self.setLayoutDirection(Qt.LeftToRight)

        global icons
        icons = ':/' + str(persepolis_setting.value('settings/icons')) + '/'

        self.verticalLayout_2 = QVBoxLayout(self)
        self.setting_tabWidget = QTabWidget(self)
        # download_options_tab
        self.download_options_tab = QWidget()
        self.layoutWidget = QWidget(self.download_options_tab)
        self.download_options_verticalLayout = QVBoxLayout(self.layoutWidget)
        self.download_options_verticalLayout.setContentsMargins(21, 21, 0, 0)
        self.download_options_verticalLayout.setObjectName(
            "download_options_verticalLayout")
        self.horizontalLayout_5 = QHBoxLayout()
        # tries_label
        self.tries_label = QLabel(self.layoutWidget)
        self.horizontalLayout_5.addWidget(self.tries_label)
        # tries_spinBox
        self.tries_spinBox = QSpinBox(self.layoutWidget)
        self.tries_spinBox.setMinimum(1)

        self.horizontalLayout_5.addWidget(self.tries_spinBox)
        self.download_options_verticalLayout.addLayout(self.horizontalLayout_5)
        self.horizontalLayout_4 = QHBoxLayout()
        # wait_label
        self.wait_label = QLabel(self.layoutWidget)
        self.horizontalLayout_4.addWidget(self.wait_label)
        # wait_spinBox
        self.wait_spinBox = QSpinBox(self.layoutWidget)
        self.horizontalLayout_4.addWidget(self.wait_spinBox)

        self.download_options_verticalLayout.addLayout(self.horizontalLayout_4)
        self.horizontalLayout_3 = QHBoxLayout()
        # time_out_label
        self.time_out_label = QLabel(self.layoutWidget)
        self.horizontalLayout_3.addWidget(self.time_out_label)
        # time_out_spinBox
        self.time_out_spinBox = QSpinBox(self.layoutWidget)
        self.horizontalLayout_3.addWidget(self.time_out_spinBox)

        self.download_options_verticalLayout.addLayout(self.horizontalLayout_3)
        self.horizontalLayout_2 = QHBoxLayout()
        # connections_label
        self.connections_label = QLabel(self.layoutWidget)
        self.horizontalLayout_2.addWidget(self.connections_label)
        # connections_spinBox
        self.connections_spinBox = QSpinBox(self.layoutWidget)
        self.connections_spinBox.setMinimum(1)
        self.connections_spinBox.setMaximum(16)
        self.horizontalLayout_2.addWidget(self.connections_spinBox)

        self.download_options_verticalLayout.addLayout(self.horizontalLayout_2)
        # rpc_port_label
        self.rpc_port_label = QLabel(self.layoutWidget)
        self.rpc_horizontalLayout = QHBoxLayout()
        self.rpc_horizontalLayout.addWidget(self.rpc_port_label)
        # rpc_port_spinbox
        self.rpc_port_spinbox = QSpinBox(self.layoutWidget)
        self.rpc_port_spinbox.setMinimum(1024)
        self.rpc_port_spinbox.setMaximum(65535)
        self.rpc_horizontalLayout.addWidget(self.rpc_port_spinbox)

        self.download_options_verticalLayout.addLayout(
            self.rpc_horizontalLayout)

        # wait_queue
        wait_queue_horizontalLayout = QHBoxLayout()

        self.wait_queue_label = QLabel(self.layoutWidget)
        wait_queue_horizontalLayout.addWidget(self.wait_queue_label)

        self.wait_queue_time = QDateTimeEdit(self.layoutWidget)
        self.wait_queue_time.setDisplayFormat('H:mm')
        wait_queue_horizontalLayout.addWidget(self.wait_queue_time)

        self.download_options_verticalLayout.addLayout(
            wait_queue_horizontalLayout)

        # change aria2 path
        aria2_path_verticalLayout = QVBoxLayout()

        self.aria2_path_checkBox = QCheckBox(self.layoutWidget)
        aria2_path_verticalLayout.addWidget(self.aria2_path_checkBox)

        aria2_path_horizontalLayout = QHBoxLayout()

        self.aria2_path_lineEdit = QLineEdit(self.layoutWidget)
        aria2_path_horizontalLayout.addWidget(self.aria2_path_lineEdit)

        self.aria2_path_pushButton = QPushButton(self.layoutWidget)
        aria2_path_horizontalLayout.addWidget(self.aria2_path_pushButton)

        aria2_path_verticalLayout.addLayout(aria2_path_horizontalLayout)

        self.download_options_verticalLayout.addLayout(
            aria2_path_verticalLayout)

        self.setting_tabWidget.addTab(self.download_options_tab, "")
        # save_as_tab
        self.save_as_tab = QWidget()

        self.layoutWidget1 = QWidget(self.save_as_tab)

        self.save_as_verticalLayout = QVBoxLayout(self.layoutWidget1)
        self.save_as_verticalLayout.setContentsMargins(20, 30, 0, 0)

        self.download_folder_horizontalLayout = QHBoxLayout()
        # download_folder_label
        self.download_folder_label = QLabel(self.layoutWidget1)
        self.download_folder_horizontalLayout.addWidget(
            self.download_folder_label)
        # download_folder_lineEdit
        self.download_folder_lineEdit = QLineEdit(self.layoutWidget1)
        self.download_folder_horizontalLayout.addWidget(
            self.download_folder_lineEdit)
        # download_folder_pushButton
        self.download_folder_pushButton = QPushButton(self.layoutWidget1)
        self.download_folder_horizontalLayout.addWidget(
            self.download_folder_pushButton)

        self.save_as_verticalLayout.addLayout(
            self.download_folder_horizontalLayout)
        self.temp_horizontalLayout = QHBoxLayout()
        # temp_download_label
        self.temp_download_label = QLabel(self.layoutWidget1)
        self.temp_horizontalLayout.addWidget(self.temp_download_label)
        # temp_download_lineEdit
        self.temp_download_lineEdit = QLineEdit(self.layoutWidget1)
        self.temp_horizontalLayout.addWidget(self.temp_download_lineEdit)
        # temp_download_pushButton
        self.temp_download_pushButton = QPushButton(self.layoutWidget1)
        self.temp_horizontalLayout.addWidget(self.temp_download_pushButton)

        self.save_as_verticalLayout.addLayout(self.temp_horizontalLayout)

        # create subfolder checkBox
        self.subfolder_checkBox = QCheckBox(self.layoutWidget1)
        self.save_as_verticalLayout.addWidget(self.subfolder_checkBox)

        self.setting_tabWidget.addTab(self.save_as_tab, "")
        # notifications_tab
        self.notifications_tab = QWidget()
        self.layoutWidget2 = QWidget(self.notifications_tab)
        self.verticalLayout_4 = QVBoxLayout(self.layoutWidget2)
        self.verticalLayout_4.setContentsMargins(21, 21, 0, 0)
        # enable_notifications_checkBox
        self.enable_notifications_checkBox = QCheckBox(self.layoutWidget2)
        self.verticalLayout_4.addWidget(self.enable_notifications_checkBox)
        # sound_frame
        self.sound_frame = QFrame(self.layoutWidget2)
        self.sound_frame.setFrameShape(QFrame.StyledPanel)
        self.sound_frame.setFrameShadow(QFrame.Raised)

        self.verticalLayout = QVBoxLayout(self.sound_frame)
        # volume_label
        self.volume_label = QLabel(self.sound_frame)
        self.verticalLayout.addWidget(self.volume_label)
        # volume_dial
        self.volume_dial = QDial(self.sound_frame)
        self.volume_dial.setProperty("value", 100)
        self.verticalLayout.addWidget(self.volume_dial)

        self.verticalLayout_4.addWidget(self.sound_frame)
        self.setting_tabWidget.addTab(self.notifications_tab, "")
        # style_tab
        self.style_tab = QWidget()
        self.layoutWidget3 = QWidget(self.style_tab)
        self.verticalLayout_3 = QVBoxLayout(self.layoutWidget3)
        self.verticalLayout_3.setContentsMargins(21, 21, 0, 0)
        self.horizontalLayout_8 = QHBoxLayout()
        # style_label
        self.style_label = QLabel(self.layoutWidget3)
        self.horizontalLayout_8.addWidget(self.style_label)
        # style_comboBox
        self.style_comboBox = QComboBox(self.layoutWidget3)
        self.horizontalLayout_8.addWidget(self.style_comboBox)

        self.verticalLayout_3.addLayout(self.horizontalLayout_8)
        self.horizontalLayout_7 = QHBoxLayout()
        # language_combox
        self.lang_label = QLabel(self.layoutWidget3)
        self.horizontalLayout_7.addWidget(self.lang_label)
        self.lang_comboBox = QComboBox(self.layoutWidget3)
        self.horizontalLayout_7.addWidget(self.lang_comboBox)

        # language_label
        self.verticalLayout_3.addLayout(self.horizontalLayout_7)
        self.horizontalLayout_7 = QHBoxLayout()
        self.lang_label.setText(
            QCoreApplication.translate("setting_ui_tr", "language :"))
        # color_label
        self.color_label = QLabel(self.layoutWidget3)
        self.horizontalLayout_7.addWidget(self.color_label)
        # color_comboBox
        self.color_comboBox = QComboBox(self.layoutWidget3)
        self.horizontalLayout_7.addWidget(self.color_comboBox)

        self.verticalLayout_3.addLayout(self.horizontalLayout_7)
        # icon_label
        self.horizontalLayout_12 = QHBoxLayout()
        self.icon_label = QLabel(self.layoutWidget3)
        self.horizontalLayout_12.addWidget(self.icon_label)

        # icon_comboBox
        self.icon_comboBox = QComboBox(self.layoutWidget3)
        self.horizontalLayout_12.addWidget(self.icon_comboBox)

        self.verticalLayout_3.addLayout(self.horizontalLayout_12)

        # icons_size_comboBox
        self.icons_size_horizontalLayout = QHBoxLayout()
        self.icons_size_label = QLabel(self.layoutWidget3)
        self.icons_size_horizontalLayout.addWidget(self.icons_size_label)

        self.icons_size_comboBox = QComboBox(self.layoutWidget3)
        self.icons_size_horizontalLayout.addWidget(self.icons_size_comboBox)

        self.verticalLayout_3.addLayout(self.icons_size_horizontalLayout)

        self.horizontalLayout_6 = QHBoxLayout()
        # notification_label
        self.horizontalLayout_13 = QHBoxLayout()
        self.notification_label = QLabel(self.layoutWidget3)
        self.horizontalLayout_13.addWidget(self.notification_label)
        # notification_comboBox
        self.notification_comboBox = QComboBox(self.layoutWidget3)
        self.horizontalLayout_13.addWidget(self.notification_comboBox)
        self.verticalLayout_3.addLayout(self.horizontalLayout_13)
        # font_checkBox
        self.font_checkBox = QCheckBox(self.layoutWidget3)
        self.horizontalLayout_6.addWidget(self.font_checkBox)
        # fontComboBox
        self.fontComboBox = QFontComboBox(self.layoutWidget3)
        self.horizontalLayout_6.addWidget(self.fontComboBox)
        # font_size_label
        self.font_size_label = QLabel(self.layoutWidget3)
        self.horizontalLayout_6.addWidget(self.font_size_label)
        # font_size_spinBox
        self.font_size_spinBox = QSpinBox(self.layoutWidget3)
        self.font_size_spinBox.setMinimum(1)
        self.horizontalLayout_6.addWidget(self.font_size_spinBox)

        self.verticalLayout_3.addLayout(self.horizontalLayout_6)
        self.setting_tabWidget.addTab(self.style_tab, "")
        self.verticalLayout_2.addWidget(self.setting_tabWidget)
        self.horizontalLayout = QHBoxLayout()
        spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                 QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        # Enable system tray icon
        self.enable_system_tray_checkBox = QCheckBox(self.layoutWidget3)
        self.verticalLayout_3.addWidget(self.enable_system_tray_checkBox)
        # after_download dialog
        self.after_download_checkBox = QCheckBox()
        self.verticalLayout_3.addWidget(self.after_download_checkBox)

        # show_menubar_checkbox
        self.show_menubar_checkbox = QCheckBox()
        self.verticalLayout_3.addWidget(self.show_menubar_checkbox)

        # show_sidepanel_checkbox
        self.show_sidepanel_checkbox = QCheckBox()
        self.verticalLayout_3.addWidget(self.show_sidepanel_checkbox)

        # hide progress window
        self.show_progress_window_checkbox = QCheckBox()
        self.verticalLayout_3.addWidget(self.show_progress_window_checkbox)

        # add persepolis to startup
        self.startup_checkbox = QCheckBox()
        self.verticalLayout_3.addWidget(self.startup_checkbox)

        # keep system awake
        self.keep_awake_checkBox = QCheckBox()
        self.verticalLayout_3.addWidget(self.keep_awake_checkBox)

        # columns_tab
        self.columns_tab = QWidget()
        layoutWidget4 = QWidget(self.columns_tab)

        column_verticalLayout = QVBoxLayout(layoutWidget4)
        column_verticalLayout.setContentsMargins(21, 21, 0, 0)

        # creating checkBox for columns
        self.show_column_label = QLabel()
        self.column0_checkBox = QCheckBox()
        self.column1_checkBox = QCheckBox()
        self.column2_checkBox = QCheckBox()
        self.column3_checkBox = QCheckBox()
        self.column4_checkBox = QCheckBox()
        self.column5_checkBox = QCheckBox()
        self.column6_checkBox = QCheckBox()
        self.column7_checkBox = QCheckBox()
        self.column10_checkBox = QCheckBox()
        self.column11_checkBox = QCheckBox()
        self.column12_checkBox = QCheckBox()

        column_verticalLayout.addWidget(self.show_column_label)
        column_verticalLayout.addWidget(self.column0_checkBox)
        column_verticalLayout.addWidget(self.column1_checkBox)
        column_verticalLayout.addWidget(self.column2_checkBox)
        column_verticalLayout.addWidget(self.column3_checkBox)
        column_verticalLayout.addWidget(self.column4_checkBox)
        column_verticalLayout.addWidget(self.column5_checkBox)
        column_verticalLayout.addWidget(self.column6_checkBox)
        column_verticalLayout.addWidget(self.column7_checkBox)
        column_verticalLayout.addWidget(self.column10_checkBox)
        column_verticalLayout.addWidget(self.column11_checkBox)
        column_verticalLayout.addWidget(self.column12_checkBox)

        self.setting_tabWidget.addTab(self.columns_tab, '')

        # youtube_tab
        self.youtube_tab = QWidget()
        self.layoutWidgetYTD = QWidget(self.youtube_tab)
        self.youtube_layout = QVBoxLayout(self.layoutWidgetYTD)
        self.youtube_layout.setContentsMargins(20, 30, 0, 0)

        self.youtube_verticalLayout = QVBoxLayout()

        # Whether to enable video link capturing.
        self.enable_ytd_checkbox = QCheckBox(self.layoutWidgetYTD)
        self.youtube_layout.addWidget(self.enable_ytd_checkbox)

        # If we should hide videos with no audio
        self.hide_no_audio_checkbox = QCheckBox(self.layoutWidgetYTD)
        self.youtube_verticalLayout.addWidget(self.hide_no_audio_checkbox)

        # If we should hide audios without video
        self.hide_no_video_checkbox = QCheckBox(self.layoutWidgetYTD)
        self.youtube_verticalLayout.addWidget(self.hide_no_video_checkbox)

        self.max_links_horizontalLayout = QHBoxLayout()

        # max_links_label
        self.max_links_label = QLabel(self.layoutWidgetYTD)

        self.max_links_horizontalLayout.addWidget(self.max_links_label)
        # max_links_spinBox
        self.max_links_spinBox = QSpinBox(self.layoutWidgetYTD)
        self.max_links_spinBox.setMinimum(1)
        self.max_links_spinBox.setMaximum(16)
        self.max_links_horizontalLayout.addWidget(self.max_links_spinBox)
        self.youtube_verticalLayout.addLayout(self.max_links_horizontalLayout)

        self.youtube_dl_path_horizontalLayout = QHBoxLayout()

        self.youtube_frame = QFrame(self.youtube_tab)
        self.youtube_frame.setLayout(self.youtube_verticalLayout)

        self.youtube_layout.addWidget(self.youtube_frame)

        self.setting_tabWidget.addTab(self.youtube_tab, "")

        # defaults_pushButton
        self.defaults_pushButton = QPushButton(self)
        self.horizontalLayout.addWidget(self.defaults_pushButton)
        # cancel_pushButton
        self.cancel_pushButton = QPushButton(self)
        self.cancel_pushButton.setIcon(QIcon(icons + 'remove'))
        self.horizontalLayout.addWidget(self.cancel_pushButton)
        # ok_pushButton
        self.ok_pushButton = QPushButton(self)
        self.ok_pushButton.setIcon(QIcon(icons + 'ok'))
        self.horizontalLayout.addWidget(self.ok_pushButton)

        self.verticalLayout_2.addLayout(self.horizontalLayout)
        self.setting_tabWidget.setCurrentIndex(3)

        self.setWindowTitle(
            QCoreApplication.translate("setting_ui_tr", "Preferences"))

        self.tries_label.setToolTip(
            QCoreApplication.translate(
                "setting_ui_tr",
                "<html><head/><body><p>Set number of tries if download failed.</p></body></html>"
            ))
        self.tries_label.setText(
            QCoreApplication.translate("setting_ui_tr", "Number of tries : "))
        self.tries_spinBox.setToolTip(
            QCoreApplication.translate(
                "setting_ui_tr",
                "<html><head/><body><p>Set number of tries if download failed.</p></body></html>"
            ))

        self.wait_label.setToolTip(
            QCoreApplication.translate(
                "setting_ui_tr",
                "<html><head/><body><p>Set the seconds to wait between retries. Download manager will  retry  downloads  when  the  HTTP  server  returns  a  503 response.</p></body></html>"
            ))
        self.wait_label.setText(
            QCoreApplication.translate("setting_ui_tr",
                                       "Wait between retries (seconds) : "))
        self.wait_spinBox.setToolTip(
            QCoreApplication.translate(
                "setting_ui_tr",
                "<html><head/><body><p>Set the seconds to wait between retries. Download manager will  retry  downloads  when  the  HTTP  server  returns  a  503 response.</p></body></html>"
            ))

        self.time_out_label.setToolTip(
            QCoreApplication.translate(
                "setting_ui_tr",
                "<html><head/><body><p>Set timeout in seconds. </p></body></html>"
            ))
        self.time_out_label.setText(
            QCoreApplication.translate("setting_ui_tr",
                                       "Time out (seconds) : "))
        self.time_out_spinBox.setToolTip(
            QCoreApplication.translate(
                "setting_ui_tr",
                "<html><head/><body><p>Set timeout in seconds. </p></body></html>"
            ))

        self.connections_label.setToolTip(
            QCoreApplication.translate(
                "setting_ui_tr",
                "<html><head/><body><p>Using multiple connections can help speed up your download.</p></body></html>"
            ))
        self.connections_label.setText(
            QCoreApplication.translate("setting_ui_tr",
                                       "Number of connections : "))
        self.connections_spinBox.setToolTip(
            QCoreApplication.translate(
                "setting_ui_tr",
                "<html><head/><body><p>Using multiple connections can help speed up your download.</p></body></html>"
            ))

        self.rpc_port_label.setText(
            QCoreApplication.translate("setting_ui_tr", "RPC port number : "))
        self.rpc_port_spinbox.setToolTip(
            QCoreApplication.translate(
                "setting_ui_tr",
                "<html><head/><body><p> Specify a port number for JSON-RPC/XML-RPC server to listen to. Possible Values: 1024 - 65535 Default: 6801 </p></body></html>"
            ))

        self.wait_queue_label.setText(
            QCoreApplication.translate(
                "setting_ui_tr", 'Wait between every downloads in queue:'))

        self.aria2_path_checkBox.setText(
            QCoreApplication.translate("setting_ui_tr",
                                       'Change aria2 default path'))
        self.aria2_path_pushButton.setText(
            QCoreApplication.translate("setting_ui_tr", 'Change'))
        aria2_path_tooltip = QCoreApplication.translate(
            "setting_ui_tr",
            "<html><head/><body><p>Attention: Wrong path may have caused problem! Do it carefully or don't change default setting!</p></body></html>"
        )
        self.aria2_path_checkBox.setToolTip(aria2_path_tooltip)
        self.aria2_path_lineEdit.setToolTip(aria2_path_tooltip)
        self.aria2_path_pushButton.setToolTip(aria2_path_tooltip)

        self.setting_tabWidget.setTabText(
            self.setting_tabWidget.indexOf(self.download_options_tab),
            QCoreApplication.translate("setting_ui_tr", "Download Options"))

        self.download_folder_label.setText(
            QCoreApplication.translate("setting_ui_tr", "Download Folder : "))
        self.download_folder_pushButton.setText(
            QCoreApplication.translate("setting_ui_tr", "Change"))

        self.temp_download_label.setText(
            QCoreApplication.translate("setting_ui_tr",
                                       "Temporary Download Folder : "))
        self.temp_download_pushButton.setText(
            QCoreApplication.translate("setting_ui_tr", "Change"))

        self.subfolder_checkBox.setText(
            QCoreApplication.translate(
                "setting_ui_tr",
                "Create subfolders for Music,Videos,... in default download folder"
            ))

        self.setting_tabWidget.setTabText(
            self.setting_tabWidget.indexOf(self.save_as_tab),
            QCoreApplication.translate("setting_ui_tr", "Save as"))

        self.enable_notifications_checkBox.setText(
            QCoreApplication.translate("setting_ui_tr",
                                       "Enable notification sounds"))

        self.volume_label.setText(
            QCoreApplication.translate("setting_ui_tr", "Volume : "))

        self.setting_tabWidget.setTabText(
            self.setting_tabWidget.indexOf(self.notifications_tab),
            QCoreApplication.translate("setting_ui_tr", "Notifications"))

        self.style_label.setText(
            QCoreApplication.translate("setting_ui_tr", "Style : "))
        self.color_label.setText(
            QCoreApplication.translate("setting_ui_tr", "Color scheme : "))
        self.icon_label.setText(
            QCoreApplication.translate("setting_ui_tr", "Icons : "))

        self.icons_size_label.setText(
            QCoreApplication.translate("setting_ui_tr",
                                       "ToolBar's icons size : "))

        self.notification_label.setText(
            QCoreApplication.translate("setting_ui_tr",
                                       "Notification type : "))

        self.font_checkBox.setText(
            QCoreApplication.translate("setting_ui_tr", "Font : "))
        self.font_size_label.setText(
            QCoreApplication.translate("setting_ui_tr", "Size : "))

        self.enable_system_tray_checkBox.setText(
            QCoreApplication.translate("setting_ui_tr",
                                       "Enable system tray icon."))
        self.after_download_checkBox.setText(
            QCoreApplication.translate(
                "setting_ui_tr",
                "Show download complete dialog,when download has finished."))

        self.show_menubar_checkbox.setText(
            QCoreApplication.translate("setting_ui_tr", "Show menubar."))
        self.show_sidepanel_checkbox.setText(
            QCoreApplication.translate("setting_ui_tr", "Show side panel."))
        self.show_progress_window_checkbox.setText(
            QCoreApplication.translate("setting_ui_tr",
                                       "Show download's progress window"))

        self.startup_checkbox.setText(
            QCoreApplication.translate("setting_ui_tr",
                                       "Run Persepolis at startup"))

        self.keep_awake_checkBox.setText(
            QCoreApplication.translate("setting_ui_tr", "Keep system awake!"))
        self.keep_awake_checkBox.setToolTip(
            QCoreApplication.translate(
                "setting_ui_tr",
                "<html><head/><body><p>This option is preventing system from going to sleep.\
            This is necessary if your power manager is suspending system automatically. </p></body></html>"
            ))

        self.wait_queue_time.setToolTip(
            QCoreApplication.translate(
                "setting_ui_tr",
                "<html><head/><body><p>Format HH:MM</p></body></html>"))

        self.setting_tabWidget.setTabText(
            self.setting_tabWidget.indexOf(self.style_tab),
            QCoreApplication.translate("setting_ui_tr", "Preferences"))

        # columns_tab
        self.show_column_label.setText(
            QCoreApplication.translate("setting_ui_tr", 'Show this columns:'))
        self.column0_checkBox.setText(
            QCoreApplication.translate("setting_ui_tr", 'File Name'))
        self.column1_checkBox.setText(
            QCoreApplication.translate("setting_ui_tr", 'Status'))
        self.column2_checkBox.setText(
            QCoreApplication.translate("setting_ui_tr", 'Size'))
        self.column3_checkBox.setText(
            QCoreApplication.translate("setting_ui_tr", 'Downloaded'))
        self.column4_checkBox.setText(
            QCoreApplication.translate("setting_ui_tr", 'Percentage'))
        self.column5_checkBox.setText(
            QCoreApplication.translate("setting_ui_tr", 'Connections'))
        self.column6_checkBox.setText(
            QCoreApplication.translate("setting_ui_tr", 'Transfer rate'))
        self.column7_checkBox.setText(
            QCoreApplication.translate("setting_ui_tr", 'Estimated time left'))
        self.column10_checkBox.setText(
            QCoreApplication.translate("setting_ui_tr", 'First try date'))
        self.column11_checkBox.setText(
            QCoreApplication.translate("setting_ui_tr", 'Last try date'))
        self.column12_checkBox.setText(
            QCoreApplication.translate("setting_ui_tr", 'Category'))

        self.setting_tabWidget.setTabText(
            self.setting_tabWidget.indexOf(self.columns_tab),
            QCoreApplication.translate("setting_ui_tr",
                                       "Columns customization"))

        # Video Finder options tab
        self.setting_tabWidget.setTabText(
            self.setting_tabWidget.indexOf(self.youtube_tab),
            QCoreApplication.translate("setting_ui_tr",
                                       "Video Finder Options"))

        self.enable_ytd_checkbox.setText(
            QCoreApplication.translate("setting_ui_tr", 'Enable Video Finder'))

        self.hide_no_audio_checkbox.setText(
            QCoreApplication.translate("setting_ui_tr",
                                       'Hide videos with no audio'))

        self.hide_no_video_checkbox.setText(
            QCoreApplication.translate("setting_ui_tr",
                                       'Hide audios with no video'))
        self.max_links_label.setText(
            QCoreApplication.translate(
                "setting_ui_tr", 'Maximum number of links to capture :<br/>'
                '<small>(If browser sends multiple video links at a time)</small>'
            ))

        # window buttons
        self.defaults_pushButton.setText(
            QCoreApplication.translate("setting_ui_tr", "Defaults"))
        self.cancel_pushButton.setText(
            QCoreApplication.translate("setting_ui_tr", "Cancel"))
        self.ok_pushButton.setText(
            QCoreApplication.translate("setting_ui_tr", "OK"))
コード例 #48
0
ファイル: solar_main.py プロジェクト: xj361685640/gpvdm
class solar_main(QWidget):

    update = pyqtSignal()

    def __init__(self, path):
        self.path = path
        self.export_file_name = os.path.join(self.path, "spectra.inp")
        super().__init__()
        self.resize(1200, 600)
        self.setWindowIcon(icon_get("weather-few-clouds"))

        self.vbox = QVBoxLayout()

        self.ribbon = ribbon_solar()
        self.vbox.addWidget(self.ribbon)

        self.ribbon.run.triggered.connect(self.callback_run)

        self.ribbon.export.triggered.connect(self.callback_export)

        self.setWindowTitle(
            _("Solar Spectrum Generator") + " (https://www.gpvdm.com)")
        self.center()

        self.notebook = QTabWidget()

        self.vbox.addWidget(self.notebook)

        earth = planet(self.export_file_name)
        earth.set_earth(True)
        earth.init()
        self.notebook.addTab(earth, "Earth")

        #mercury = planet(self.export_file_name)
        #mercury.set_mercury(True)
        #mercury.set_orbitalpoint(True)
        #mercury.init()
        #self.notebook.addTab(mercury,"Mercury")

        #venus = planet(self.export_file_name)
        #venus.set_venus(True)
        #venus.set_orbitalpoint(True)
        #venus.init()
        #self.notebook.addTab(venus,"Venus")

        #mars = planet(self.export_file_name)
        #mars.set_mars(True)
        #mars.set_orbitalpoint(True)
        #mars.init()
        #self.notebook.addTab(mars,"Mars")

        #ceres = planet(self.export_file_name)
        #ceres.set_ceres(True)
        #ceres.set_orbitalpoint(True)
        #ceres.init()
        #self.notebook.addTab(ceres, "Ceres (Dwarf Planet)")

        #europa = planet(self.export_file_name)
        #europa.set_europa(True)
        #europa.set_orbitalpoint(True)
        #europa.init()
        #self.notebook.addTab(europa, "Europa (moon of Jupiter)")

        #halley = planet(self.export_file_name)
        #halley.set_halley(True)
        #halley.set_orbitalpoint(True)
        #halley.init()
        #self.notebook.addTab(halley, "Halley's Comet")

        #pluto = planet(self.export_file_name)
        #pluto.set_pluto(True)
        #pluto.set_orbitalpoint(True)
        #pluto.init()
        #self.notebook.addTab(pluto, "Pluto")

        self.setLayout(self.vbox)

    def callback_run(self):
        tab = self.notebook.currentWidget()
        tab.update()

    def callback_export(self):
        tab = self.notebook.currentWidget()
        tab.export()
        self.update.emit()

    def save(self):
        self.notebook.currentWidget().save()

    def copy(self):
        self.notebook.currentWidget().copy2clip()

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())
コード例 #49
0
    def __init__(self):
        super().__init__()
        self.setLayout(QVBoxLayout())
        self.setWindowTitle(i18n("Export settings"))
        buttons = QDialogButtonBox(QDialogButtonBox.Ok
                                   | QDialogButtonBox.Cancel)

        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)
        mainWidget = QTabWidget()
        self.layout().addWidget(mainWidget)
        self.layout().addWidget(buttons)

        # Set basic crop settings
        # Set which layers to remove before export.
        mainExportSettings = QWidget()
        mainExportSettings.setLayout(QVBoxLayout())
        groupExportCrop = QGroupBox(i18n("Crop settings"))
        formCrop = QFormLayout()
        groupExportCrop.setLayout(formCrop)
        self.chk_toOutmostGuides = QCheckBox(i18n("Crop to outmost guides"))
        self.chk_toOutmostGuides.setChecked(True)
        self.chk_toOutmostGuides.setToolTip(
            i18n(
                "This will crop to the outmost guides if possible and otherwise use the underlying crop settings."
            ))
        formCrop.addRow("", self.chk_toOutmostGuides)
        btn_fromSelection = QPushButton(
            i18n("Set margins from active selection"))
        btn_fromSelection.clicked.connect(self.slot_set_margin_from_selection)
        # This doesn't work.
        formCrop.addRow("", btn_fromSelection)
        self.spn_marginLeft = QSpinBox()
        self.spn_marginLeft.setMaximum(99999)
        self.spn_marginLeft.setSuffix(" px")
        formCrop.addRow(i18n("Left:"), self.spn_marginLeft)
        self.spn_marginTop = QSpinBox()
        self.spn_marginTop.setMaximum(99999)
        self.spn_marginTop.setSuffix(" px")
        formCrop.addRow(i18n("Top:"), self.spn_marginTop)
        self.spn_marginRight = QSpinBox()
        self.spn_marginRight.setMaximum(99999)
        self.spn_marginRight.setSuffix(" px")
        formCrop.addRow(i18n("Right:"), self.spn_marginRight)
        self.spn_marginBottom = QSpinBox()
        self.spn_marginBottom.setMaximum(99999)
        self.spn_marginBottom.setSuffix(" px")
        formCrop.addRow(i18n("Bottom:"), self.spn_marginBottom)
        groupExportLayers = QGroupBox(i18n("Layers"))
        formLayers = QFormLayout()
        groupExportLayers.setLayout(formLayers)
        self.cmbLabelsRemove = labelSelector()
        formLayers.addRow(i18n("Label for removal:"), self.cmbLabelsRemove)
        self.ln_text_layer_name = QLineEdit()
        self.ln_text_layer_name.setToolTip(
            i18n(
                "These are keywords that can be used to identify text layers. A layer only needs to contain the keyword to be recognised. Keywords should be comma seperated."
            ))
        self.ln_panel_layer_name = QLineEdit()
        self.ln_panel_layer_name.setToolTip(
            i18n(
                "These are keywords that can be used to identify panel layers. A layer only needs to contain the keyword to be recognised. Keywords should be comma seperated."
            ))
        formLayers.addRow(i18n("Text Layer Key:"), self.ln_text_layer_name)
        formLayers.addRow(i18n("Panel Layer Key:"), self.ln_panel_layer_name)

        mainExportSettings.layout().addWidget(groupExportCrop)
        mainExportSettings.layout().addWidget(groupExportLayers)
        mainWidget.addTab(mainExportSettings, i18n("General"))

        # CBZ, crop, resize, which metadata to add.
        CBZexportSettings = QWidget()
        CBZexportSettings.setLayout(QVBoxLayout())
        self.CBZactive = QCheckBox(i18n("Export to CBZ"))
        CBZexportSettings.layout().addWidget(self.CBZactive)
        self.CBZgroupResize = comic_export_resize_widget("CBZ")
        CBZexportSettings.layout().addWidget(self.CBZgroupResize)
        self.CBZactive.clicked.connect(self.CBZgroupResize.setEnabled)
        CBZgroupMeta = QGroupBox(i18n("Metadata to add"))
        # CBZexportSettings.layout().addWidget(CBZgroupMeta)
        CBZgroupMeta.setLayout(QFormLayout())

        mainWidget.addTab(CBZexportSettings, "CBZ")

        # ACBF, crop, resize, creator name, version history, panel layer, text layers.
        ACBFExportSettings = QWidget()
        ACBFform = QFormLayout()
        ACBFExportSettings.setLayout(QVBoxLayout())
        ACBFdocInfo = QGroupBox()
        ACBFdocInfo.setTitle(i18n("ACBF Document Info"))
        ACBFdocInfo.setLayout(ACBFform)
        self.lnACBFSource = QLineEdit()
        self.lnACBFSource.setToolTip(
            i18n(
                "Whether the acbf file is an adaption of an existing source, and if so, how to find information about that source. So for example, for an adapted webcomic, the official website url should go here."
            ))
        self.lnACBFID = QLabel()
        self.lnACBFID.setToolTip(
            i18n(
                "By default this will be filled with a generated universal unique identifier. The ID by itself is merely so that comic book library management programs can figure out if this particular comic is already in their database and whether it has been rated. Of course, the UUID can be changed into something else by manually changing the json, but this is advanced usage."
            ))
        self.spnACBFVersion = QSpinBox()
        self.ACBFhistoryModel = QStandardItemModel()
        acbfHistoryList = QListView()
        acbfHistoryList.setModel(self.ACBFhistoryModel)
        btn_add_history = QPushButton(i18n("Add history entry"))
        btn_add_history.clicked.connect(self.slot_add_history_item)
        self.chkIncludeTranslatorComments = QCheckBox()
        self.chkIncludeTranslatorComments.setText(
            i18n("Include Translator's Comments"))
        self.chkIncludeTranslatorComments.setToolTip(
            i18n(
                "A PO file can contain translator's comments. If this is checked, the translations comments will be added as references into the ACBF file."
            ))
        self.lnTranslatorHeader = QLineEdit()

        ACBFform.addRow(i18n("Source:"), self.lnACBFSource)
        ACBFform.addRow(i18n("ACBF UID:"), self.lnACBFID)
        ACBFform.addRow(i18n("Version:"), self.spnACBFVersion)
        ACBFform.addRow(i18n("Version History:"), acbfHistoryList)
        ACBFform.addRow("", btn_add_history)
        ACBFform.addRow("", self.chkIncludeTranslatorComments)
        ACBFform.addRow(i18n("Translator Header:"), self.lnTranslatorHeader)

        ACBFAuthorInfo = QWidget()
        acbfAVbox = QVBoxLayout(ACBFAuthorInfo)
        infoLabel = QLabel(
            i18n(
                "The people responsible for the generation of the CBZ/ACBF files."
            ))
        infoLabel.setWordWrap(True)
        ACBFAuthorInfo.layout().addWidget(infoLabel)
        self.ACBFauthorModel = QStandardItemModel(0, 6)
        labels = [
            i18n("Nick Name"),
            i18n("Given Name"),
            i18n("Middle Name"),
            i18n("Family Name"),
            i18n("Email"),
            i18n("Homepage")
        ]
        self.ACBFauthorModel.setHorizontalHeaderLabels(labels)
        self.ACBFauthorTable = QTableView()
        acbfAVbox.addWidget(self.ACBFauthorTable)
        self.ACBFauthorTable.setModel(self.ACBFauthorModel)
        self.ACBFauthorTable.verticalHeader().setDragEnabled(True)
        self.ACBFauthorTable.verticalHeader().setDropIndicatorShown(True)
        self.ACBFauthorTable.verticalHeader().setSectionsMovable(True)
        self.ACBFauthorTable.verticalHeader().sectionMoved.connect(
            self.slot_reset_author_row_visual)
        AuthorButtons = QHBoxLayout()
        btn_add_author = QPushButton(i18n("Add author"))
        btn_add_author.clicked.connect(self.slot_add_author)
        AuthorButtons.addWidget(btn_add_author)
        btn_remove_author = QPushButton(i18n("Remove author"))
        btn_remove_author.clicked.connect(self.slot_remove_author)
        AuthorButtons.addWidget(btn_remove_author)
        acbfAVbox.addLayout(AuthorButtons)

        ACBFStyle = QWidget()
        ACBFStyle.setLayout(QHBoxLayout())
        self.ACBFStylesModel = QStandardItemModel()
        self.ACBFStyleClass = QListView()
        self.ACBFStyleClass.setModel(self.ACBFStylesModel)
        ACBFStyle.layout().addWidget(self.ACBFStyleClass)
        ACBFStyleEdit = QWidget()
        ACBFStyleEditVB = QVBoxLayout(ACBFStyleEdit)
        self.ACBFfontCombo = QFontComboBox()
        self.ACBFdefaultFont = QComboBox()
        self.ACBFdefaultFont.addItems(
            ["sans-serif", "serif", "monospace", "cursive", "fantasy"])
        self.ACBFBold = QCheckBox(i18n("Bold"))
        self.ACBFItal = QCheckBox(i18n("Italic"))
        self.ACBFStyleClass.clicked.connect(self.slot_set_style)
        self.ACBFStyleClass.selectionModel().selectionChanged.connect(
            self.slot_set_style)
        self.ACBFStylesModel.itemChanged.connect(self.slot_set_style)
        self.ACBFfontCombo.currentFontChanged.connect(
            self.slot_font_current_style)
        self.ACBFfontCombo.setEditable(False)
        self.ACBFBold.toggled.connect(self.slot_font_current_style)
        self.ACBFItal.toggled.connect(self.slot_font_current_style)
        colorWidget = QGroupBox(self)
        colorWidget.setTitle(i18n("Text Colors"))
        colorWidget.setLayout(QVBoxLayout())
        self.regularColor = QColorDialog()
        self.invertedColor = QColorDialog()
        self.btn_acbfRegColor = QPushButton(i18n("Regular Text"), self)
        self.btn_acbfRegColor.clicked.connect(self.slot_change_regular_color)
        self.btn_acbfInvColor = QPushButton(i18n("Inverted Text"), self)
        self.btn_acbfInvColor.clicked.connect(self.slot_change_inverted_color)
        colorWidget.layout().addWidget(self.btn_acbfRegColor)
        colorWidget.layout().addWidget(self.btn_acbfInvColor)
        ACBFStyleEditVB.addWidget(colorWidget)
        ACBFStyleEditVB.addWidget(self.ACBFfontCombo)
        ACBFStyleEditVB.addWidget(self.ACBFdefaultFont)
        ACBFStyleEditVB.addWidget(self.ACBFBold)
        ACBFStyleEditVB.addWidget(self.ACBFItal)
        ACBFStyleEditVB.addStretch()
        ACBFStyle.layout().addWidget(ACBFStyleEdit)

        ACBFTabwidget = QTabWidget()
        ACBFTabwidget.addTab(ACBFdocInfo, i18n("Document Info"))
        ACBFTabwidget.addTab(ACBFAuthorInfo, i18n("Author Info"))
        ACBFTabwidget.addTab(ACBFStyle, i18n("Style Sheet"))
        ACBFExportSettings.layout().addWidget(ACBFTabwidget)
        mainWidget.addTab(ACBFExportSettings, i18n("ACBF"))

        # Epub export, crop, resize, other questions.
        EPUBexportSettings = QWidget()
        EPUBexportSettings.setLayout(QVBoxLayout())
        self.EPUBactive = QCheckBox(i18n("Export to EPUB"))
        EPUBexportSettings.layout().addWidget(self.EPUBactive)
        self.EPUBgroupResize = comic_export_resize_widget("EPUB")
        EPUBexportSettings.layout().addWidget(self.EPUBgroupResize)
        self.EPUBactive.clicked.connect(self.EPUBgroupResize.setEnabled)
        mainWidget.addTab(EPUBexportSettings, "EPUB")

        # For Print. Crop, no resize.
        TIFFExportSettings = QWidget()
        TIFFExportSettings.setLayout(QVBoxLayout())
        self.TIFFactive = QCheckBox(i18n("Export to TIFF"))
        TIFFExportSettings.layout().addWidget(self.TIFFactive)
        self.TIFFgroupResize = comic_export_resize_widget("TIFF")
        TIFFExportSettings.layout().addWidget(self.TIFFgroupResize)
        self.TIFFactive.clicked.connect(self.TIFFgroupResize.setEnabled)
        mainWidget.addTab(TIFFExportSettings, "TIFF")
コード例 #50
0
    def getUi(self):
        self.font = QFont('微软雅黑', 16)
        self.setFont(self.font)
        self.setWindowTitle("CTA交易系统")
        self.setWindowIcon(QIcon('material\\icon.png'))
        self.setGeometry(200, 50, 1500, 1000)
        # 内部框架
        vbox0 = QVBoxLayout()
        gbox1 = QGroupBox('频段')
        gbox2 = QGroupBox('基本日志记录')
        vbox0.addWidget(gbox1, stretch=2)
        vbox0.addWidget(gbox2, stretch=1)
        # 频段
        tab = QTabWidget()
        self.TableFreqDuo = {}
        self.TableFreqKong = {}
        self.TableFreqPosition = {}
        self.TableFreqOrder = {}
        self.TableFreqTrade = {}
        for eachFreq in listFreq:
            tabSub = QTabWidget()
            #region 做多与做空
            tabSub1 = QWidget()
            tableDuo = QTableWidget(0, len(listDuoKong), self)
            self.TableFreqDuo[eachFreq] = tableDuo
            tableDuo.setHorizontalHeaderLabels(listDuoKong)
            tableDuo.verticalHeader().setVisible(False)
            tableDuo.setFont(self.font)
            tableDuo.resizeColumnsToContents()
            tableKong = QTableWidget(0, len(listDuoKong), self)
            self.TableFreqKong[eachFreq] = tableKong
            tableKong.setHorizontalHeaderLabels(listDuoKong)
            tableKong.verticalHeader().setVisible(False)
            tableKong.setFont(self.font)
            tableKong.resizeColumnsToContents()
            vbox = QVBoxLayout()
            vbox.addWidget(QLabel('做多', self))
            vbox.addWidget(tableDuo)
            vbox.addWidget(QLabel('做空', self))
            vbox.addWidget(tableKong)
            tabSub1.setLayout(vbox)
            #endregion
            #region 频段的持仓
            tabSub2 = QWidget()
            tablePosition = QTableWidget(0, len(listFreqPosition), self)
            tablePosition.setHorizontalHeaderLabels(listFreqPosition)
            for num in range(len(listFreqPosition)):
                tablePosition.horizontalHeaderItem(num).setFont(self.font)
            tablePosition.setFont(self.font)
            tablePosition.resizeColumnsToContents()
            tablePosition.verticalHeader().setVisible(False)
            self.TableFreqPosition[eachFreq] = tablePosition
            hbox = QHBoxLayout()
            hbox.addWidget(tablePosition)
            tabSub2.setLayout(hbox)
            #endregion
            #region 频段的成交
            tabSub3 = QWidget()
            tableTrade = QTableWidget(0, len(listTrade), self)
            tableTrade.setHorizontalHeaderLabels(listTrade)
            for num in range(len(listTrade)):
                tableTrade.horizontalHeaderItem(num).setFont(self.font)
            tableTrade.setFont(self.font)
            tableTrade.resizeColumnsToContents()
            tableTrade.verticalHeader().setVisible(False)
            self.TableFreqTrade[eachFreq] = tableTrade
            hbox = QHBoxLayout()
            hbox.addWidget(tableTrade)
            tabSub3.setLayout(hbox)
            #endregion
            #region 频段的委托
            tabSub4 = QWidget()
            tableOrder = QTableWidget(0, len(listOrder), self)
            tableOrder.setHorizontalHeaderLabels(listOrder)
            for num in range(len(listOrder)):
                tableOrder.horizontalHeaderItem(num).setFont(self.font)
            tableOrder.setFont(self.font)
            tableOrder.resizeColumnsToContents()
            tableOrder.verticalHeader().setVisible(False)
            self.TableFreqOrder[eachFreq] = tableOrder
            hbox = QHBoxLayout()
            hbox.addWidget(tableOrder)
            tabSub4.setLayout(hbox)
            #endregion
            tabSub.addTab(tabSub1, '做多与做空')
            tabSub.addTab(tabSub2, '频段持仓')
            tabSub.addTab(tabSub3, '频段成交')
            tabSub.addTab(tabSub4, '频段委托')
            tab.addTab(tabSub, 'CTA' + str(eachFreq))
        hbox = QHBoxLayout()
        hbox.addWidget(tab)
        gbox1.setLayout(hbox)
        # 日志输出与总持仓显示
        self.txtLog = QTextEdit(self)
        self.txtLog.setEnabled(True)
        hbox = QHBoxLayout()
        tab2 = QTabWidget()
        self.txtLog = QTextEdit(self)
        self.txtLog.setEnabled(True)
        tab2.addTab(self.txtLog, '程序日志')
        self.tabPosition = QWidget()
        self.tabPosition.setLayout(self.tabPositionUi())
        tab2.addTab(self.tabPosition, '账户持仓')
        self.tabAccount = QWidget()
        self.tabAccount.setLayout(self.tabAccountUi())
        tab2.addTab(self.tabAccount, '账户资金')
        tab2.currentChanged.connect(self.switchTab2)
        hbox.addWidget(tab2)
        gbox2.setLayout(hbox)
        #region 菜单栏
        menu_root = self.menuBar()
        menu_root.setFont(self.font)
        orderhandle = menu_root.addMenu('手动下单操作')
        ordering = QAction('下单', self)
        ordering.setFont(self.font)
        ordering.triggered.connect(self.orderShow)
        orderhandle.addAction(ordering)

        orderingCancel = QAction('撤单', self)
        orderingCancel.setFont(self.font)
        orderingCancel.triggered.connect(self.orderCancelShow)
        orderhandle.addAction(orderingCancel)

        orderingPark = QAction('预下单', self)
        orderingPark.setFont(self.font)
        orderingPark.triggered.connect(self.orderParkShow)
        orderhandle.addAction(orderingPark)

        init = menu_root.addMenu('初始化操作')
        self.initItem = QAction('初始化开始', self)
        self.initItem.setFont(self.font)
        self.initItem.triggered.connect(self.getInit)
        init.addAction(self.initItem)

        start = menu_root.addMenu('交易中操作')
        self.startItem = QAction('交易开始', self)
        self.startItem.setFont(self.font)
        self.startItem.triggered.connect(self.getTrade)
        start.addAction(self.startItem)
        deleteDb = menu_root.addMenu('删除数据')
        self.dltItem = QAction('删除本交易日数据(含夜盘)', self)
        self.dltItem.setFont(self.font)
        self.dltItem.triggered.connect(self.theDlt)
        self.dltItem1 = QAction('删除本交易日数据(不含夜盘)', self)
        self.dltItem1.setFont(self.font)
        self.dltItem1.triggered.connect(self.theDlt1)
        self.dltItem2 = QAction('删除指定时间数据', self)
        self.dltItem2.setFont(self.font)
        self.dltItem2.triggered.connect(self.theDlt2)
        deleteDb.addAction(self.dltItem)
        deleteDb.addAction(self.dltItem1)
        deleteDb.addAction(self.dltItem2)
        #endregion
        # 总布局
        widget = QWidget()
        widget.setLayout(vbox0)
        self.setCentralWidget(widget)
コード例 #51
0
class EditStructure(ToolInstance):

    help = "https://github.com/QChASM/SEQCROW/wiki/Structure-Modification-Tool"
    SESSION_ENDURING = True
    SESSION_SAVE = True

    def __init__(self, session, name):       
        super().__init__(session, name)
        
        self.settings = _EditStructureSettings(session, "Structure Modification")
        
        self.tool_window = MainToolWindow(self)        

        self.close_previous_bool = self.settings.modify

        self._build_ui()

    def _build_ui(self):
        layout = QGridLayout()
        
        self.alchemy_tabs = QTabWidget()
        
        #substitute
        substitute_tab = QWidget()
        substitute_layout = QGridLayout(substitute_tab) 

        sublabel = QLabel("substituent name:")
        substitute_layout.addWidget(sublabel, 0, 0, Qt.AlignVCenter)
        
        self.subname = QLineEdit()
        # self.subname.setText("Et")
        sub_completer = NameCompleter(Substituent.list(), self.subname)
        self.subname.setCompleter(sub_completer)
        self.subname.setToolTip("name of substituent in the AaronTools library or your personal library\nseparate names with commas and uncheck 'modify selected structure' to create several structures")
        substitute_layout.addWidget(self.subname, 0, 1, Qt.AlignVCenter)
        
        open_sub_lib = QPushButton("from library...")
        open_sub_lib.clicked.connect(self.open_sub_selector)
        substitute_layout.addWidget(open_sub_lib, 0, 2, Qt.AlignTop)        
        
        substitute_layout.addWidget(QLabel("modify selected structure:"), 1, 0, 1, 1, Qt.AlignVCenter)
        
        self.close_previous_sub = QCheckBox()
        self.close_previous_sub.setToolTip("checked: selected structure will be modified\nunchecked: new model will be created for the modified structure")
        self.close_previous_sub.setChecked(self.settings.modify)
        self.close_previous_sub.stateChanged.connect(self.close_previous_change)
        substitute_layout.addWidget(self.close_previous_sub, 1, 1, 1, 2, Qt.AlignTop)    
        
        substitute_layout.addWidget(QLabel("relax substituent:"), 2, 0, 1, 1, Qt.AlignVCenter)
        
        self.minimize = QCheckBox()
        self.minimize.setToolTip("spin the added substituents to try to minimize the LJ potential energy")
        self.minimize.setChecked(self.settings.minimize)
        substitute_layout.addWidget(self.minimize, 2, 1, 1, 1, Qt.AlignTop)
        
        substitute_layout.addWidget(QLabel("guess previous substituent:"), 3, 0, 1, 1, Qt.AlignVCenter)
        
        self.guess_old = QCheckBox()
        self.guess_old.setToolTip("checked: leave the longest connected fragment in the residue\nunchecked: previous substituent must be selected")
        self.guess_old.setChecked(self.settings.guess)
        self.guess_old.stateChanged.connect(lambda state, settings=self.settings: settings.__setattr__("guess", True if state == Qt.Checked else False))
        substitute_layout.addWidget(self.guess_old, 3, 1, 1, 2, Qt.AlignTop)
        
        substitute_layout.addWidget(QLabel("new residue:"), 5, 0, 1, 1, Qt.AlignVCenter)

        self.new_residue = QCheckBox()
        self.new_residue.setToolTip("put the new substituent in its own residue instead\nof adding it to the residue of the old substituent")
        self.new_residue.setChecked(self.settings.new_residue)
        self.new_residue.stateChanged.connect(lambda state, settings=self.settings: settings.__setattr__("new_residue", True if state == Qt.Checked else False))
        substitute_layout.addWidget(self.new_residue, 5, 1, 1, 2, Qt.AlignTop)
        
        substitute_layout.addWidget(QLabel("use distance names:"), 4, 0, 1, 1, Qt.AlignVCenter)
        
        self.use_greek = QCheckBox()
        self.use_greek.setChecked(self.settings.use_greek)
        self.use_greek.setToolTip("indicate distance from point of attachment with atom name")
        substitute_layout.addWidget(self.use_greek, 4, 1, 1, 1, Qt.AlignTop)

        substitute_layout.addWidget(QLabel("change residue name:"), 6, 0, 1, 1, Qt.AlignVCenter)
        
        self.new_sub_name = QLineEdit()
        self.new_sub_name.setToolTip("change name of modified residues")
        self.new_sub_name.setPlaceholderText("leave blank to keep current")
        substitute_layout.addWidget(self.new_sub_name, 6, 1, 1, 2, Qt.AlignTop)

        substitute_button = QPushButton("substitute current selection")
        substitute_button.clicked.connect(self.do_substitute)
        substitute_layout.addWidget(substitute_button, 7, 0, 1, 3, Qt.AlignTop)
        self.substitute_button = substitute_button
        
        substitute_layout.setRowStretch(0, 0)
        substitute_layout.setRowStretch(1, 0)
        substitute_layout.setRowStretch(2, 0)
        substitute_layout.setRowStretch(3, 0)
        substitute_layout.setRowStretch(4, 0)
        substitute_layout.setRowStretch(5, 0)
        substitute_layout.setRowStretch(6, 0)
        substitute_layout.setRowStretch(7, 1)
        
        
        #map ligand
        maplig_tab = QWidget()
        maplig_layout = QGridLayout(maplig_tab)
        
        liglabel = QLabel("ligand name:")
        maplig_layout.addWidget(liglabel, 0, 0, Qt.AlignVCenter)
        
        self.ligname = QLineEdit()
        lig_completer = NameCompleter(Component.list(), self.ligname)
        self.ligname.setCompleter(lig_completer)
        self.ligname.setToolTip("name of ligand in the AaronTools library or your personal library\nseparate names with commas and uncheck 'modify selected structure' to create several structures")
        maplig_layout.addWidget(self.ligname, 0, 1, Qt.AlignVCenter)
        
        open_lig_lib = QPushButton("from library...")
        open_lig_lib.clicked.connect(self.open_lig_selector)
        maplig_layout.addWidget(open_lig_lib, 0, 2, Qt.AlignTop)        
        
        maplig_layout.addWidget(QLabel("modify selected structure:"), 1, 0, 1, 1, Qt.AlignVCenter)
        
        self.close_previous_lig = QCheckBox()
        self.close_previous_lig.setToolTip("checked: selected structure will be modified\nunchecked: new model will be created for the modified structure")
        self.close_previous_lig.setChecked(self.settings.modify)
        self.close_previous_lig.stateChanged.connect(self.close_previous_change)
        maplig_layout.addWidget(self.close_previous_lig, 1, 1, 1, 2, Qt.AlignTop)

        maplig_button = QPushButton("swap ligand with selected coordinating atoms")
        maplig_button.clicked.connect(self.do_maplig)
        maplig_layout.addWidget(maplig_button, 2, 0, 1, 3, Qt.AlignTop)
        self.maplig_button = maplig_button

        start_structure_button = QPushButton("place in:")
        self.lig_model_selector = ModelComboBox(self.session, addNew=True)
        start_structure_button.clicked.connect(self.do_new_lig)
        maplig_layout.addWidget(start_structure_button, 3, 0, 1, 1, Qt.AlignTop)
        maplig_layout.addWidget(self.lig_model_selector, 3, 1, 1, 2, Qt.AlignTop)

        maplig_layout.setRowStretch(0, 0)
        maplig_layout.setRowStretch(1, 0)
        maplig_layout.setRowStretch(2, 0)
        maplig_layout.setRowStretch(3, 1)
        
        
        #close ring
        closering_tab = QWidget()
        closering_layout = QGridLayout(closering_tab)
        
        ringlabel = QLabel("ring name:")
        closering_layout.addWidget(ringlabel, 0, 0, Qt.AlignVCenter)
        
        self.ringname = QLineEdit()
        ring_completer = NameCompleter(Ring.list(), self.ringname)
        self.ringname.setCompleter(ring_completer)
        self.ringname.setToolTip("name of ring in the AaronTools library or your personal library\nseparate names with commas and uncheck 'modify selected structure' to create several structures")
        closering_layout.addWidget(self.ringname, 0, 1, Qt.AlignVCenter)
        
        open_ring_lib = QPushButton("from library...")
        open_ring_lib.clicked.connect(self.open_ring_selector)
        closering_layout.addWidget(open_ring_lib, 0, 2, Qt.AlignTop)        
        
        closering_layout.addWidget(QLabel("modify selected structure:"), 1, 0, 1, 1, Qt.AlignVCenter) 
        
        self.close_previous_ring = QCheckBox()
        self.close_previous_ring.setToolTip("checked: selected structure will be modified\nunchecked: new model will be created for the modified structure")
        self.close_previous_ring.setChecked(self.settings.modify)
        self.close_previous_ring.stateChanged.connect(self.close_previous_change)
        closering_layout.addWidget(self.close_previous_ring, 1, 1, 1, 2, Qt.AlignTop)

        closering_layout.addWidget(QLabel("try multiple:"), 2, 0, 1, 1, Qt.AlignVCenter)

        self.minimize_ring = QCheckBox()
        self.minimize_ring.setToolTip("try to use other versions of this ring in the library to find the one that fits best")
        self.minimize_ring.setChecked(self.settings.minimize_ring)
        closering_layout.addWidget(self.minimize_ring, 2, 1, 1, 2, Qt.AlignTop)

        closering_layout.addWidget(QLabel("new residue name:"), 3, 0, 1, 1, Qt.AlignVCenter)
        
        self.new_ring_name = QLineEdit()
        self.new_ring_name.setToolTip("change name of modified residues")
        self.new_ring_name.setPlaceholderText("leave blank to keep current")
        closering_layout.addWidget(self.new_ring_name, 3, 1, 1, 2, Qt.AlignTop)

        closering_button = QPushButton("put a ring on current selection")
        closering_button.clicked.connect(self.do_fusering)

        closering_layout.addWidget(closering_button, 4, 0, 1, 3, Qt.AlignTop)
        self.closering_button = closering_button

        start_structure_button = QPushButton("place in:")
        self.ring_model_selector = ModelComboBox(self.session, addNew=True)
        start_structure_button.clicked.connect(self.do_new_ring)
        closering_layout.addWidget(start_structure_button, 5, 0, 1, 1, Qt.AlignTop)
        closering_layout.addWidget(self.ring_model_selector, 5, 1, 1, 2, Qt.AlignTop)

        closering_layout.setRowStretch(0, 0)
        closering_layout.setRowStretch(1, 0)
        closering_layout.setRowStretch(2, 0)
        closering_layout.setRowStretch(3, 0)
        closering_layout.setRowStretch(4, 0)
        closering_layout.setRowStretch(5, 1)


        #change element
        changeelement_tab = QWidget()
        changeelement_layout = QFormLayout(changeelement_tab)
        
        self.element = QPushButton("C")
        self.element.setMinimumWidth(int(1.3*self.element.fontMetrics().boundingRect("QQ").width()))
        self.element.setMaximumWidth(int(1.3*self.element.fontMetrics().boundingRect("QQ").width()))
        self.element.setMinimumHeight(int(1.5*self.element.fontMetrics().boundingRect("QQ").height()))
        self.element.setMaximumHeight(int(1.5*self.element.fontMetrics().boundingRect("QQ").height()))
        ele_color = tuple(list(element_color(ELEMENTS.index("C")))[:-1])
        self.element.setStyleSheet(
            "QPushButton { background: rgb(%i, %i, %i); color: %s; font-weight: bold; }" % (
                *ele_color,
                'white' if sum(
                    int(x < 130) - int(x > 225) for x in ele_color
                ) - int(ele_color[1] > 225) +
                int(ele_color[2] > 200) >= 2 else 'black'
            )
        )
        self.element.clicked.connect(self.open_ptable)
        changeelement_layout.addRow("element:", self.element)
        
        self.vsepr = QComboBox()
        self.vsepr.addItems([
            "do not change",                  # 0
            
            "linear (1 bond)",                # 1
            
            "linear (2 bonds)",               # 2 
            "trigonal planar (2 bonds)",      # 3
            "tetrahedral (2 bonds)",          # 4 
            
            "trigonal planar",                # 5
            "tetrahedral (3 bonds)",          # 6
            "T-shaped",                       # 7
            
            "trigonal pyramidal",             # 8
            "tetrahedral",                    # 9
            "sawhorse",                       #10
            "seesaw",                         #11
            "square planar",                  #12
            
            "trigonal bipyramidal",           #13
            "square pyramidal",               #14
            "pentagonal",                     #15
            
            "octahedral",                     #16
            "hexagonal",                      #17
            "trigonal prismatic",             #18
            "pentagonal pyramidal",           #19
            
            "capped octahedral",              #20
            "capped trigonal prismatic",      #21
            "heptagonal",                     #22
            "hexagonal pyramidal",            #23
            "pentagonal bipyramidal",         #24
            
            "biaugmented trigonal prismatic", #25
            "cubic",                          #26
            "elongated trigonal bipyramidal", #27
            "hexagonal bipyramidal",          #28
            "heptagonal pyramidal",           #29
            "octagonal",                      #30
            "square antiprismatic",           #31
            "trigonal dodecahedral",          #32
            
            "capped cube",                    #33
            "capped square antiprismatic",    #34
            "enneagonal",                     #35
            "heptagonal bipyramidal",         #36
            "hula-hoop",                      #37
            "triangular cupola",              #38
            "tridiminished icosahedral",      #39
            "muffin",                         #40
            "octagonal pyramidal",            #41
            "tricapped trigonal prismatic",   #42
        ])
        
        self.vsepr.setCurrentIndex(9)
        
        self.vsepr.insertSeparator(33)
        self.vsepr.insertSeparator(25)
        self.vsepr.insertSeparator(20)
        self.vsepr.insertSeparator(16)
        self.vsepr.insertSeparator(13)
        self.vsepr.insertSeparator(8)
        self.vsepr.insertSeparator(5)
        self.vsepr.insertSeparator(2)
        self.vsepr.insertSeparator(1)
        self.vsepr.insertSeparator(0)
        changeelement_layout.addRow("geometry:", self.vsepr)
        
        self.change_bonds = QCheckBox()
        self.change_bonds.setChecked(self.settings.change_bonds)
        changeelement_layout.addRow("adjust bond lengths:", self.change_bonds)
        
        change_element_button = QPushButton("change selected elements")
        change_element_button.clicked.connect(self.do_change_element)
        changeelement_layout.addRow(change_element_button)
        self.change_element_button = change_element_button

        start_structure_button = QPushButton("place in:")
        self.model_selector = ModelComboBox(self.session, addNew=True)
        start_structure_button.clicked.connect(self.do_new_atom)
        changeelement_layout.addRow(start_structure_button, self.model_selector)
        
        delete_atoms_button = QPushButton("delete selected atoms")
        delete_atoms_button.clicked.connect(self.delete_atoms)
        changeelement_layout.addRow(delete_atoms_button)

        self.alchemy_tabs.addTab(substitute_tab, "substitute")
        self.alchemy_tabs.addTab(maplig_tab, "swap ligand")
        self.alchemy_tabs.addTab(closering_tab, "fuse ring")
        self.alchemy_tabs.addTab(changeelement_tab, "change element")

        layout.addWidget(self.alchemy_tabs)

        self.tool_window.ui_area.setLayout(layout)

        self.tool_window.manage(None)
    
    def close_previous_change(self, state):
        if state == Qt.Checked:
            self.settings.modify = True
            for checkbox in [self.close_previous_lig, self.close_previous_sub, self.close_previous_ring]:
                checkbox.setChecked(True)
            self.close_previous_bool = True
        else:
            self.settings.modify = False
            for checkbox in [self.close_previous_lig, self.close_previous_sub, self.close_previous_ring]:
                checkbox.setChecked(False)
            self.close_previous_bool = False
    
    def do_substitute(self):
        subnames = self.subname.text()
        
        new_name = self.new_sub_name.text()

        use_attached = not self.guess_old.isChecked()
        
        minimize = self.minimize.isChecked()
        
        new_residue = self.new_residue.isChecked()

        use_greek = self.use_greek.isChecked()
        
        self.settings.minimize = minimize
        self.settings.use_greek = use_greek

        if len(new_name.strip()) > 0:
            run(
                self.session, 
                "substitute sel substituents %s newName %s guessAttachment %s modify %s minimize %s useRemoteness %s newResidue %s" %
                (
                    subnames,
                    new_name,
                    not use_attached,
                    self.close_previous_bool,
                    minimize,
                    use_greek,
                    new_residue,
                )
            )

        else:
            run(
                self.session,
                "substitute sel substituents %s guessAttachment %s modify %s minimize %s useRemoteness %s newResidue %s" %
                (
                    subnames,
                    not use_attached,
                    self.close_previous_bool,
                    minimize,
                    use_greek,
                    new_residue,
                )
            )

    def open_sub_selector(self):
        self.tool_window.create_child_window("select substituents", window_class=SubstituentSelection, textBox=self.subname)

    def do_maplig(self):
        lignames = self.ligname.text()
        selection = selected_atoms(self.session)
        
        if len(selection) < 1:
            raise RuntimeWarning("nothing selected")
        
        models = {}
        for atom in selection:
            if atom.structure not in models:
                models[atom.structure] = [AtomSpec(atom.atomspec)]
            else:
                models[atom.structure].append(AtomSpec(atom.atomspec))        
        
        first_pass = True
        new_structures = []
        for ligname in lignames.split(','):
            ligname = ligname.strip()
            lig = Component(ligname)
            for model in models:
                if self.close_previous_bool and first_pass:
                    rescol = ResidueCollection(model)
                elif self.close_previous_bool and not first_pass:
                    raise RuntimeError("only the first model can be replaced")
                else:
                    model_copy = model.copy()
                    rescol = ResidueCollection(model_copy)
                    for i, atom in enumerate(model.atoms):
                        rescol.atoms[i].atomspec = atom.atomspec
                        rescol.atoms[i].add_tag(atom.atomspec)
                        rescol.atoms[i].chix_atom = atom

                target = rescol.find(models[model])
                if len(target) % len(lig.key_atoms) == 0:
                    k = 0
                    ligands = []
                    while k != len(target):
                        res_lig = ResidueCollection(lig.copy(), comment=lig.comment)
                        res_lig.parse_comment()
                        res_lig = Component(res_lig, key_atoms = ",".join([str(k + 1) for k in res_lig.other["key_atoms"]]))
                        ligands.append(res_lig)
                        k += len(lig.key_atoms)
                else:
                    raise RuntimeError("number of key atoms no not match: %i now, new ligand has %i" % (len(target), len(lig.key_atoms)))
                
                rescol.map_ligand(ligands, target)

                for center_atom in rescol.center:
                    center_atom.connected = set([])
                    for atom in rescol.atoms:
                        if atom not in rescol.center:
                            if center_atom.is_connected(atom):
                                atom.connected.add(center_atom)
                                center_atom.connected.add(atom)
                
                if self.close_previous_bool:    
                    rescol.update_chix(model)
                else:
                    struc = rescol.get_chimera(self.session)
                    new_structures.append(struc)
            
            first_pass = False
        
        if not self.close_previous_bool:
            self.session.models.add(new_structures)

    def open_lig_selector(self):
        self.tool_window.create_child_window("select ligands", window_class=LigandSelection, textBox=self.ligname)
    
    def do_fusering(self):
        ring_names = self.ringname.text()
        
        new_name = self.new_ring_name.text()

        minimize_ring = self.minimize_ring.isChecked()
        self.settings.minimize_ring = minimize_ring

        if len(new_name.strip()) > 0:
            run(
                self.session,
                "fuseRing sel rings %s newName %s modify %s minimize %s" % (
                    ring_names,
                    new_name,
                    self.close_previous_bool,
                    minimize_ring,
                )
            )

        else:
            run(
                self.session,
                "fuseRing sel rings %s modify %s minimize %s" % (
                    ring_names,
                    self.close_previous_bool,
                    minimize_ring,
                )
            )

    def open_ring_selector(self):
        self.tool_window.create_child_window("select rings", window_class=RingSelection, textBox=self.ringname)

    def open_ptable(self):
        self.tool_window.create_child_window("select element", window_class=_PTable, button=self.element)
    
    def display_help(self):
        """Show the help for this tool in the help viewer."""
        from chimerax.core.commands import run
        run(self.session,
            'open %s' % self.help if self.help is not None else "")
    
    def do_change_element(self):
        element = self.element.text()
        adjust_bonds = self.change_bonds.isChecked()
        self.settings.change_bonds = adjust_bonds
        vsepr = self.vsepr.currentText()
        
        if vsepr == "do not change":
            vsepr = False
        elif vsepr == "linear (1 bond)":
            vsepr = "linear 1"
            goal = 1
        elif vsepr == "linear (2 bonds)":
            vsepr = "linear 2"
            goal = 2
        elif vsepr == "trigonal planar (2 bonds)":
            vsepr = "bent 2 planar"
            goal = 2
        elif vsepr == "tetrahedral (2 bonds)":
            vsepr = "bent 2 tetrahedral"
            goal = 2
        elif vsepr == "trigonal planar":
            goal = 3
        elif vsepr == "tetrahedral (3 bonds)":
            vsepr = "bent 3 tetrahedral"
            goal = 3
        else:
            goal = len(Atom.get_shape(vsepr)) - 1
        
        sel = selected_atoms(self.session)
        models, _ = guessAttachmentTargets(sel, self.session, allow_adjacent=False)
        for model in models:
            conv_res = list(models[model].keys())
            for res in models[model]:
                for target in models[model][res]:
                    for neighbor in target.neighbors:
                        if neighbor.residue not in conv_res:
                            conv_res.append(neighbor.residue)
            
                    for pbg in self.session.models.list(type=PseudobondGroup):
                        for pbond in pbg.pseudobonds:
                            if target in pbond.atoms and all(atom.structure is model for atom in pbond.atoms):
                                other_atom = pbond.other_atom(target)
                                if other_atom.residue not in conv_res:
                                    conv_res.append(other_atom.residue)
            
            rescol = ResidueCollection(model, convert_residues=conv_res)
            for res in models[model]:
                residue = [resi for resi in rescol.residues if resi.chix_residue is res][0]
                
                for target in models[model][res]:
                    targ = rescol.find_exact(AtomSpec(target.atomspec))[0]
                    adjust_hydrogens = vsepr
                    if vsepr is not False:
                        cur_bonds = len(targ.connected)
                        change_Hs = goal - cur_bonds
                        adjust_hydrogens = (change_Hs, vsepr)

                    residue.change_element(targ, 
                                           element, 
                                           adjust_bonds=adjust_bonds, 
                                           adjust_hydrogens=adjust_hydrogens,
                    )
                
                residue.update_chix(res)    
    
    def do_new_ring(self):
        rings = self.ringname.text()
        
        for ring in rings.split(","):
            ring = ring.strip()
            
            rescol = ResidueCollection(Ring(ring))
        
            model = self.ring_model_selector.currentData()
            if model is None:
                chix = rescol.get_chimera(self.session)
                self.session.models.add([chix])
                apply_seqcrow_preset(chix, fallback="Ball-Stick-Endcap")
                self.ring_model_selector.setCurrentIndex(self.ring_model_selector.count()-1)
    
            else:
                res = model.new_residue("new", "a", len(model.residues)+1)
                rescol.residues[0].update_chix(res)
                run(self.session, "select add %s" % " ".join([atom.atomspec for atom in res.atoms]))
    
    def do_new_lig(self):
        ligands = self.ligname.text()
        
        for lig in ligands.split(","):
            lig = lig.strip()
            
            rescol = ResidueCollection(Component(lig))
        
            model = self.lig_model_selector.currentData()
            if model is None:
                chix = rescol.get_chimera(self.session)
                self.session.models.add([chix])
                apply_seqcrow_preset(chix, fallback="Ball-Stick-Endcap")
                self.lig_model_selector.setCurrentIndex(self.lig_model_selector.count()-1)
    
            else:
                res = model.new_residue("new", "a", len(model.residues)+1)
                rescol.residues[0].update_chix(res)
                run(self.session, "select add %s" % " ".join([atom.atomspec for atom in res.atoms]))

    def do_new_atom(self):
        element = self.element.text()
        adjust_bonds = self.change_bonds.isChecked()
        self.settings.change_bonds = adjust_bonds
        vsepr = self.vsepr.currentText()
        
        if vsepr == "do not change":
            vsepr = False
        elif vsepr == "linear (1 bond)":
            vsepr = "linear 1"
        elif vsepr == "linear (2 bonds)":
            vsepr = "linear 2"
        elif vsepr == "trigonal planar (2 bonds)":
            vsepr = "bent 2 planar"
        elif vsepr == "tetrahedral (2 bonds)":
            vsepr = "bent 2 tetrahedral"
        elif vsepr == "tetrahedral (3 bonds)":
            vsepr = "bent 3 tetrahedral"
        
        if vsepr:
            atoms = Atom.get_shape(vsepr)
            atoms[0].element = element
            for atom in atoms[1:]:
                atom.element = "H"
            if adjust_bonds:
                # this works b/c all atoms are 1 angstrom from the center
                # just multiply by the distance we want
                expected_dist = RADII[element] + RADII["H"]
                for atom in atoms[1:]:
                    atom.coords *= expected_dist
            for atom in atoms[1:]:
                atoms[0].connected.add(atom)
                atom.connected.add(atoms[0])
        else:
            atoms = [Atom(element=element, coords=np.zeros(3))]

        rescol = ResidueCollection(atoms, name="new", refresh_connected=False)

        model = self.model_selector.currentData()
        if model is None:
            chix = rescol.get_chimera(self.session)
            self.session.models.add([chix])
            apply_seqcrow_preset(chix, fallback="Ball-Stick-Endcap")
            self.model_selector.setCurrentIndex(self.model_selector.count()-1)

        else:
            res = model.new_residue("new", "a", len(model.residues)+1)
            rescol.residues[0].update_chix(res)
            run(self.session, "select add %s" % " ".join([atom.atomspec for atom in res.atoms]))
    
    def delete_atoms(self, *args):
        atoms = selected_atoms(self.session)
        for atom in atoms:
            atom.delete()
    
    def delete(self):
        self.ring_model_selector.deleteLater()
        self.lig_model_selector.deleteLater()
        self.model_selector.deleteLater()

        return super().delete()    
    
    def close(self):
        self.ring_model_selector.deleteLater()
        self.lig_model_selector.deleteLater()
        self.model_selector.deleteLater()

        return super().close()
コード例 #52
0
ファイル: main_window.py プロジェクト: ahmtcnn/Easy-Scanner
class Window(QWidget):
    def __init__(self, statusBar, menubar):
        super().__init__()
        self.statusbar = statusBar
        self.menubar = menubar
        self.url_without_schema = ""
        self.url = ""
        self.login_form = None
        self.threadpool = QThreadPool()

        self.init_ui()

    def init_ui(self):
        self.hbox = QHBoxLayout(self)
        self.set_frames()
        self.set_input_and_buttons()
        self.set_combobox()
        self.start_resource_monitor()
        self.set_menu()
        self.show()

    def start_on_click(self):
        if self.is_url_valid:
            self.clear_result_list()
            self.clear_infobox()
            self.disable_enable_options(True)
            self.start_action()
            pass
        else:
            self.print_error("[×] URL format is not correct")

    def stop_on_click(self):
        self.disable_enable_options(False)

    def print_error(self, message):
        self.information_list.addItem(message)

    def print_info(self, message):
        self.information_list.addItem(message)

    def print_result(self, message):
        self.result_list.addItem(message)

    def clear_infobox(self):
        self.information_list.clear()

    def clear_result_list(self):
        self.result_list.clear()

    def finish_control(self):
        self.disable_enable_options(False)

    def start_action(self):
        option_value = self.options_combobox.currentText()
        option_list = {
            'Information Gather': self.start_information_gathering,
            'Crawler': self.start_crawler,
            'Port Scanner': self.start_port_scanner,
            'Directory Scanner': self.start_directory_scanner,
            'Subdomain Scanner': self.start_subdomain_scanner,
            'Header Analysis': self.start_header_scanner,
            'Xss Scanner': self.start_xss_scanner,
            'SQLi Scanner': self.start_sqli_scanner,
            'LFi/RFi Scanner': self.start_lfi_scanner,
            'File Upload Scanner': self.start_fileupload_scanner,
        }
        option_list[option_value]()

    def start_information_gathering(self):
        self.print_info("[✔] Information Gathering started!")
        self.information_scanner = InfoCollector(self.url)
        self.information_scanner.signals.result_list.connect(self.print_result)
        self.information_scanner.signals.finish_control.connect(
            self.finish_control)
        self.information_scanner.signals.info_box.connect(self.print_info)
        self.threadpool.start(self.information_scanner)

    def start_crawler(self):
        self.print_info("[✔] Crawler started!")
        self.crawler = Crawler(self.url, self.login_form)
        self.crawler.signals.result_list.connect(self.print_result)
        self.crawler.signals.finish_control.connect(self.finish_control)
        self.crawler.signals.info_box.connect(self.print_info)
        self.threadpool.start(self.crawler)

    def start_port_scanner(self):
        self.print_info("[✔] Port Scanner started!")
        self.port_scanner = PortScanner(self.url_without_schema)
        self.port_scanner.signals.finish_control.connect(self.finish_control)
        self.port_scanner.signals.info_box.connect(self.print_info)
        self.port_scanner.signals.result_list.connect(self.print_result)
        self.threadpool.start(self.port_scanner)

    def start_directory_scanner(self):
        self.print_info("[✔] Directory Scanner started!")
        self.dir_scanner = DirScanner(self.url)
        self.dir_scanner.signals.finish_control.connect(self.finish_control)
        self.dir_scanner.signals.info_box.connect(self.print_info)
        self.dir_scanner.signals.result_list.connect(self.print_result)
        self.threadpool.start(self.dir_scanner)

    def start_subdomain_scanner(self):
        self.print_info("[✔] Subdomain Scanner started!")
        self.subdomain_scanner = SubdomainScanner(self.url_without_schema)
        self.subdomain_scanner.signals.finish_control.connect(
            self.finish_control)
        self.subdomain_scanner.signals.info_box.connect(self.print_info)
        self.subdomain_scanner.signals.result_list.connect(self.print_result)
        self.threadpool.start(self.subdomain_scanner)

    def start_header_scanner(self):
        self.print_info("[✔] Header Scanner started!")
        self.header_analysis = HeaderAnalyzer(self.url)
        self.header_analysis.signals.result_list.connect(self.print_result)
        self.header_analysis.signals.finish_control.connect(
            self.finish_control)
        self.header_analysis.signals.info_box.connect(self.print_info)
        self.threadpool.start(self.header_analysis)

    def start_xss_scanner(self):
        self.print_info("[✔] XSS Scanner started!")

        self.xss_scanner = XssScanner(self.url, self.login_form)
        self.xss_scanner.signals.info_box.connect(self.print_info)
        self.xss_scanner.signals.result_list.connect(self.print_result)
        self.xss_scanner.signals.finish_control.connect(self.finish_control)
        self.threadpool.start(self.xss_scanner)

    def start_sqli_scanner(self):
        self.print_info("[✔] SQLi Scanner started!")
        self.sqli_scanner = SqliScanner(self.url, self.login_form)
        self.sqli_scanner.signals.result_list.connect(self.print_result)
        self.sqli_scanner.signals.info_box.connect(self.print_info)
        self.sqli_scanner.signals.finish_control.connect(self.finish_control)
        self.threadpool.start(self.sqli_scanner)

    def start_lfi_scanner(self):
        self.print_info("[✔] File Inclusion Scanner started!")
        self.file_inclusion_Scanner = FileInclusionScanner(
            self.url, self.login_form)
        self.file_inclusion_Scanner.signals.result_list.connect(
            self.print_result)
        self.file_inclusion_Scanner.signals.info_box.connect(self.print_info)
        self.file_inclusion_Scanner.signals.finish_control.connect(
            self.finish_control)
        self.threadpool.start(self.file_inclusion_Scanner)

    def start_fileupload_scanner(self):
        self.print_info("[✔] File Upload Scanner started!")

    def start_resource_monitor(self):
        pid = os.getpid()
        self.resource_monitor = ResourceMonitor(pid)
        self.resource_monitor.signals.status.connect(self.set_statusbar)
        self.threadpool.start(self.resource_monitor)

    def set_statusbar(self, cpu_value, mem_value):
        text = "CPU Usage: %{} - Memory Usage: %{}".format(
            cpu_value, mem_value)
        self.statusbar.showMessage(text)

    def set_menu(self):
        settingsmenu = self.menubar.addMenu('Settings')
        settingsAct = QAction('Settings', self)
        settingsAct.setShortcut("Ctrl+S")
        settingsAct.setStatusTip('Set Scanner Settings')
        settingsAct.triggered.connect(self.show_settings_window)

        settingsmenu.addAction(settingsAct)

        exitmenu = self.menubar.addMenu('Exit')
        exitAct = QAction('Exit', self)
        exitmenu.addAction(exitAct)

    def set_login_settings(self):
        user_input_name = self.form_input_name_user.text()
        user_input_value = self.form_input_value_user.text()

        password_input_name = self.form_input_name_password.text()
        password_input_value = self.form_input_value_password.text()

        form_address = self.form_url_address_line.text()
        form_action = self.form_action_url_line.text()

        self.login_form = {}
        self.login_form['user_name_field'] = user_input_name
        self.login_form['user_value_field'] = user_input_value
        self.login_form['password_name_field'] = password_input_name
        self.login_form['password_value_field'] = password_input_value
        self.login_form['url'] = form_address
        self.login_form['action'] = form_action

    def show_settings_window(self):
        self.dlg = QDialog(self)
        self.dlg.setFixedSize(400, 250)
        self.dlg.setWindowTitle("Settings")

        # Initialize tab screen
        self.tabs = QTabWidget(self.dlg)
        self.general_settings_tab = QWidget()
        self.login_tab = QWidget()
        self.tabs.resize(400, 270)

        # Add tabs
        self.tabs.addTab(self.general_settings_tab, "General Settings")
        self.tabs.addTab(self.login_tab, "Login Settings")

        # Create first tab
        self.general_settings_tab.layout = QVBoxLayout(self.dlg)
        self.pushButton1 = QPushButton("PyQt5 button",
                                       self.general_settings_tab)

        self.label_login_information = QLabel(self.login_tab)
        self.label_login_information.setText('Login Form Informations')
        self.label_login_information.move(10, 10)

        self.label_input_name_user = QLabel(self.login_tab)
        self.label_input_name_user.setText('Input Name: ')
        self.label_input_name_user.move(20, 50)

        self.label_input_name_password = QLabel(self.login_tab)
        self.label_input_name_password.setText('Input Name: ')
        self.label_input_name_password.move(20, 80)

        self.label_input_value_user = QLabel(self.login_tab)
        self.label_input_value_user.setText('Input Value: ')
        self.label_input_value_user.move(210, 50)

        self.label_input_value_password = QLabel(self.login_tab)
        self.label_input_value_password.setText('Input Value: ')
        self.label_input_value_password.move(210, 80)

        self.form_input_name_user = QLineEdit(self.login_tab)
        self.form_input_name_user.resize(100, 18)
        self.form_input_name_user.move(100, 50)

        self.form_input_name_password = QLineEdit(self.login_tab)
        self.form_input_name_password.resize(100, 18)
        self.form_input_name_password.move(100, 80)

        self.form_input_value_user = QLineEdit(self.login_tab)
        self.form_input_value_user.resize(100, 18)
        self.form_input_value_user.move(285, 50)

        self.form_input_value_password = QLineEdit(self.login_tab)
        self.form_input_value_password.resize(100, 18)
        self.form_input_value_password.move(285, 80)

        self.form_url_address_label = QLabel(self.login_tab)
        self.form_url_address_label.setText("Form URL address : ")
        self.form_url_address_label.move(20, 120)

        self.form_url_address_line = QLineEdit(self.login_tab)
        self.form_url_address_line.resize(200, 18)
        self.form_url_address_line.move(138, 120)

        self.form_action_url_label = QLabel(self.login_tab)
        self.form_action_url_label.setText("Form Action URL   : ")
        self.form_action_url_label.move(20, 150)

        self.form_action_url_line = QLineEdit(self.login_tab)
        self.form_action_url_line.resize(200, 18)
        self.form_action_url_line.move(138, 150)

        self.save_button = QPushButton('Save', self.login_tab)
        self.save_button.move(280, 180)
        self.save_button.clicked.connect(self.set_login_settings)

        self.dlg.exec_()

    @property
    def is_url_valid(self):
        # Get user input
        url = self.address_text.text()

        # Validation check
        result = validators.url(url)

        # Get url without schema
        if result:
            self.url = url
            parser = urlparse(url)
            self.url_without_schema = parser.netloc

        return result

    def disable_enable_options(self, is_disabled):
        self.address_text.setDisabled(is_disabled)
        self.start_button.setDisabled(is_disabled)
        self.options_combobox.setDisabled(is_disabled)
        self.stop_button.setDisabled(not is_disabled)

    def set_input_and_buttons(self):
        self.address_text = QLineEdit(self.top_frame)
        self.address_text.setPlaceholderText("https://example.com")
        self.address_text.move(20, 20)
        self.address_text.resize(300, 40)

        self.start_button = QPushButton('Start Scan', self.top_frame)
        self.start_button.clicked.connect(self.start_on_click)
        self.start_button.move(177, 70)
        self.start_button.resize(70, 23)

        self.stop_button = QPushButton('Stop Scan', self.top_frame)
        self.stop_button.clicked.connect(self.stop_on_click)
        self.stop_button.move(250, 70)
        self.stop_button.resize(70, 23)
        self.stop_button.setDisabled(True)

        self.information_label = QLabel("Information Box ", self.top_frame)
        self.information_label.setGeometry(400, 3, 100, 10)

        self.information_list = QListWidget(self.info_frame)
        self.information_list.setMinimumSize(20, 20)

        self.result_list = QListWidget(self.bottom_frame)
        self.result_list.setMinimumSize(580, 375)

    def set_frames(self):
        self.top_frame = QFrame(self)
        self.top_frame.resize(50, 150)

        self.info_frame = QFrame(self.top_frame)
        self.info_frame.setFrameShape(QFrame.StyledPanel)
        self.info_frame.setGeometry(340, 18, 220, 80)

        self.bottom_frame = QFrame(self)
        self.bottom_frame.resize(500, 550)

        self.top_frame.setFrameShape(QFrame.StyledPanel)
        self.bottom_frame.setFrameShape(QFrame.StyledPanel)

        self.splitter1 = QSplitter(Qt.Vertical, frameShape=QFrame.StyledPanel)
        self.splitter1.addWidget(self.top_frame)
        self.splitter1.addWidget(self.bottom_frame)

        self.hbox.addWidget(self.splitter1)

    def set_combobox(self):
        self.options_combobox = QComboBox(self.top_frame)
        option_list = [
            'Information Gather',
            'Crawler',
            'Port Scanner',
            'Directory Scanner',
            'Subdomain Scanner',
            'Header Analysis',
            'Xss Scanner',
            'SQLi Scanner',
            'LFi/RFi Scanner',
            'File Upload Scanner',
        ]

        self.options_combobox.addItems(option_list)
        self.options_combobox.move(20, 70)
コード例 #53
0
class SubwindowMisc(QWidget):
    """Show subwindow with miscellaneous settings."""

    current_tab = -1

    def createWindow(self, mainWindow, tab=''):
        """Create subwindow with miscellaneous settings."""
        try:
            parent = None
            super().__init__(parent)
            # self.setWindowFlags(Qt.WindowStaysOnTopHint)

            self.setWindowIcon(
                QIcon(scctool.settings.getResFile('settings.png')))
            self.setWindowModality(Qt.ApplicationModal)
            self.mainWindow = mainWindow
            self.passEvent = False
            self.controller = mainWindow.controller
            self.__dataChanged = False

            self.createButtonGroup()
            self.createTabs(tab)

            mainLayout = QVBoxLayout()

            mainLayout.addWidget(self.tabs)
            mainLayout.addLayout(self.buttonGroup)

            self.setLayout(mainLayout)

            self.resize(
                QSize(mainWindow.size().width() * 0.9,
                      self.sizeHint().height()))
            relativeChange = QPoint(mainWindow.size().width() / 2,
                                    mainWindow.size().height() / 3)\
                - QPoint(self.size().width() / 2,
                         self.size().height() / 3)
            self.move(mainWindow.pos() + relativeChange)

            self.setWindowTitle(_("Miscellaneous Settings"))

        except Exception:
            module_logger.exception("message")

    def createTabs(self, tab=''):
        """Create tabs."""
        self.tabs = QTabWidget()

        self.createMapsBox()
        self.createFavBox()
        self.createAliasBox()
        self.createOcrBox()
        self.createAlphaBox()
        self.createSC2ClientAPIBox()
        self.createAligulacTab()
        self.createCounterTab()

        # Add tabs
        self.tabs.addTab(self.mapsBox, _("Map Manager"))
        self.tabs.addTab(self.favBox, _("Favorites"))
        self.tabs.addTab(self.aliasBox, _("Alias"))
        self.tabs.addTab(self.ocrBox, _("OCR"))
        self.tabs.addTab(self.alphaBox, _("AlphaTL && Ingame Score"))
        self.tabs.addTab(self.clientapiBox, _("SC2 Client API"))
        self.tabs.addTab(self.aligulacTab, _("Aligulac"))
        self.tabs.addTab(self.counterTab, _("Countdown"))

        table = dict()
        table['mapmanager'] = 0
        table['favorites'] = 1
        table['alias'] = 2
        table['ocr'] = 3
        table['alphatl'] = 4
        table['sc2clientapi'] = 5
        table['aligulac'] = 6
        table['counter'] = 7
        self.tabs.setCurrentIndex(table.get(tab, SubwindowMisc.current_tab))
        self.tabs.currentChanged.connect(self.tabChanged)

    @classmethod
    def tabChanged(cls, idx):
        """Save the current tab index."""
        SubwindowMisc.current_tab = idx

    def changed(self):
        """Handle changes."""
        self.__dataChanged = True

    def createAlphaBox(self):
        """Create Alpha QWidget."""
        self.alphaBox = QWidget()
        mainLayout = QVBoxLayout()

        box = QGroupBox(_("AlphaTL"))
        layout = QHBoxLayout()

        self.cb_trans_banner = QCheckBox(
            " " + _("Download transparent Banner of the Match"))
        self.cb_trans_banner.setChecked(
            scctool.settings.config.parser.getboolean(
                "SCT", "transparent_match_banner"))
        self.cb_trans_banner.stateChanged.connect(self.changed)

        layout.addWidget(self.cb_trans_banner)
        box.setLayout(layout)

        mainLayout.addWidget(box)

        box = QGroupBox(_("Set Ingame Score Task"))
        layout = QVBoxLayout()

        self.cb_ctrlx = QCheckBox(" " +
                                  _('Automatically press Ctrl+X to apply the'
                                    ' correct player order ingame'))
        self.cb_ctrlx.setToolTip(
            _("This will ensure that the player of the first team is always"
              " on the left/top in the ingame Observer UI."))
        self.cb_ctrlx.setChecked(
            scctool.settings.config.parser.getboolean("SCT", "CtrlX"))
        self.cb_ctrlx.stateChanged.connect(self.changed)
        layout.addWidget(self.cb_ctrlx)

        self.cb_ctrln = QCheckBox(" " + _('Automatically press Ctrl+N before'
                                          ' OCR to display player names'))
        self.cb_ctrln.setToolTip(
            _("This is recommended for Standard and Gawliq Observer UI."))
        self.cb_ctrln.setChecked(
            scctool.settings.config.parser.getboolean("SCT", "CtrlN"))
        self.cb_ctrln.stateChanged.connect(self.changed)
        layout.addWidget(self.cb_ctrln)

        self.cb_ctrlshifts = QCheckBox(
            " " + _('Automatically press Ctrl+Shift+S to display'
                    ' the ingame score'))
        self.cb_ctrlshifts.setToolTip(
            _("Ctrl+Shift+S is needed for the WCS-Gameheart Oberserver"
              " Overlay, but disables the sound for other overlays."))
        self.cb_ctrlshifts.setChecked(
            scctool.settings.config.parser.getboolean("SCT", "CtrlShiftS"))
        self.cb_ctrlshifts.stateChanged.connect(self.changed)
        layout.addWidget(self.cb_ctrlshifts)

        self.cb_ctrlshiftc = QCheckBox(
            " " + _('Automatically press Ctrl+Shift+C to toogle the clan tag'))
        self.cb_ctrlshiftc.setChecked(
            scctool.settings.config.parser.getboolean("SCT", "CtrlShiftC"))
        self.cb_ctrlshiftc.stateChanged.connect(self.changed)
        layout.addWidget(self.cb_ctrlshiftc)

        container = QHBoxLayout()
        self.cb_ctrlshiftr = QComboBox()
        self.cb_ctrlshiftr.addItem("0")
        self.cb_ctrlshiftr.addItem("1")
        self.cb_ctrlshiftr.addItem("2")
        try:
            self.cb_ctrlshiftr.setCurrentIndex(
                scctool.settings.config.parser.getint("SCT", "CtrlShiftR"))
        except Exception:
            self.cb_ctrlshiftr.setCurrentIndex(0)
        self.cb_ctrlshiftr.setMaximumWidth(40)
        self.cb_ctrlshiftr.currentIndexChanged.connect(self.changed)
        container.addWidget(
            QLabel(
                _('Automatically press Ctrl+Shift+R to toogle the race icon '))
        )
        container.addWidget(self.cb_ctrlshiftr)
        container.addWidget(QLabel(_(' time(s)')))
        layout.addLayout(container)

        self.cb_blacklist = QCheckBox(" " + _('Activate Blacklist for'
                                              ' Ingame Score'))
        self.cb_blacklist.setChecked(
            scctool.settings.config.parser.getboolean("SCT", "blacklist_on"))
        self.cb_blacklist.stateChanged.connect(self.changed)
        layout.addWidget(self.cb_blacklist)

        box.setLayout(layout)

        mainLayout.addWidget(box)

        box = QGroupBox(_("Blacklist for Ingame Score"))
        layout = QVBoxLayout()

        blacklistDesc = _("Enter your SC2 client usernames to deactivate"
                          " automatically setting the ingame score and"
                          " toogling the production tab when you are playing"
                          " yourself. Replays are exempt.")
        label = QLabel(blacklistDesc)
        label.setAlignment(Qt.AlignJustify)
        label.setWordWrap(True)
        layout.addWidget(label)

        self.list_blacklist = ListTable(4,
                                        scctool.settings.config.getBlacklist())
        self.list_blacklist.dataModified.connect(self.changed)
        self.list_blacklist.setFixedHeight(50)
        layout.addWidget(self.list_blacklist)
        box.setLayout(layout)

        mainLayout.addWidget(box)

        mainLayout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding))

        self.alphaBox.setLayout(mainLayout)

    def createFavBox(self):
        """Create favorites box."""
        self.favBox = QWidget()
        mainLayout = QVBoxLayout()

        box = QGroupBox(_("Players"))
        layout = QHBoxLayout()

        self.list_favPlayers = ListTable(
            4, scctool.settings.config.getMyPlayers())
        self.list_favPlayers.dataModified.connect(self.changed)
        self.list_favPlayers.setFixedHeight(150)
        layout.addWidget(self.list_favPlayers)
        box.setLayout(layout)

        mainLayout.addWidget(box)

        box = QGroupBox(_("Teams"))
        layout = QVBoxLayout()

        self.list_favTeams = ListTable(3, scctool.settings.config.getMyTeams())
        self.list_favTeams.dataModified.connect(self.changed)
        self.list_favTeams.setFixedHeight(100)
        layout.addWidget(self.list_favTeams)
        self.cb_swapTeams = QCheckBox(
            _('Swap my favorite team always to the left'))
        self.cb_swapTeams.setChecked(
            scctool.settings.config.parser.getboolean("SCT", "swap_myteam"))
        self.cb_swapTeams.stateChanged.connect(self.changed)
        layout.addWidget(self.cb_swapTeams)
        box.setLayout(layout)
        mainLayout.addWidget(box)

        mainLayout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding))

        self.favBox.setLayout(mainLayout)

    def createAliasBox(self):
        """Create favorites box."""
        self.aliasBox = QWidget()
        mainLayout = QGridLayout()

        aliasDesc = _(
            'Player and team aliases are replaced by the actual name when' +
            ' encountered by the match grabber. Additionally, SC2 player' +
            ' names listed as aliases are replaced in the intros' +
            ' and used to identify players by the automatic' +
            ' background tasks "Auto Score Update" and "Set Ingame Score".')
        label = QLabel(aliasDesc)
        label.setAlignment(Qt.AlignJustify)
        label.setWordWrap(True)

        mainLayout.addWidget(label, 1, 0, 1, 2)

        box = QGroupBox(_("Player Aliases"))
        layout = QVBoxLayout()
        self.list_aliasPlayers = AliasTreeView(self)
        self.list_aliasPlayers.aliasRemoved.connect(
            self.controller.aliasManager.removePlayerAlias)
        layout.addWidget(self.list_aliasPlayers)
        addButton = QPushButton(_("Add Alias"))
        addButton.clicked.connect(
            lambda: self.addAlias(self.list_aliasPlayers, _('Player Name')))
        layout.addWidget(addButton)
        box.setLayout(layout)
        mainLayout.addWidget(box, 0, 0)

        box = QGroupBox(_("Team Aliases"))
        layout = QVBoxLayout()
        self.list_aliasTeams = AliasTreeView(self)
        self.list_aliasTeams.aliasRemoved.connect(
            self.controller.aliasManager.removeTeamAlias)
        layout.addWidget(self.list_aliasTeams)
        addButton = QPushButton(_("Add Alias"))
        addButton.clicked.connect(
            lambda: self.addAlias(self.list_aliasTeams, _('Team Name')))
        layout.addWidget(addButton)
        box.setLayout(layout)
        mainLayout.addWidget(box, 0, 1)

        alias_list = self.controller.aliasManager.playerAliasList()
        for player, aliases in alias_list.items():
            self.list_aliasPlayers.insertAliasList(player, aliases)

        alias_list = self.controller.aliasManager.teamAliasList()
        for team, aliases in alias_list.items():
            self.list_aliasTeams.insertAliasList(team, aliases)

        self.aliasBox.setLayout(mainLayout)

    def addAlias(self, widget, scope, name=""):
        """Add an alias."""
        name, ok = QInputDialog.getText(self, scope, scope + ':', text=name)
        if not ok:
            return

        name = name.strip()
        alias, ok = QInputDialog.getText(self,
                                         _('Alias'),
                                         _('Alias of {}').format(name) + ':',
                                         text="")

        alias = alias.strip()
        if not ok:
            return

        try:
            if widget == self.list_aliasPlayers:
                self.controller.aliasManager.addPlayerAlias(name, alias)
            elif widget == self.list_aliasTeams:
                self.controller.aliasManager.addTeamAlias(name, alias)
            widget.insertAlias(name, alias, True)
        except Exception as e:
            module_logger.exception("message")
            QMessageBox.critical(self, _("Error"), str(e))

    def createSC2ClientAPIBox(self):
        """Create form for SC2 Client API config."""
        self.clientapiBox = QWidget()

        mainLayout = QVBoxLayout()

        box = QGroupBox(_("SC2 Client API Address"))

        layout = QGridLayout()

        self.cb_usesc2listener = QCheckBox(
            " " + _("Listen to SC2 Client API running"
                    " on a different PC in the network."))
        self.cb_usesc2listener.setChecked(
            scctool.settings.config.parser.getboolean(
                "SCT", "sc2_network_listener_enabled"))
        self.cb_usesc2listener.stateChanged.connect(self.changed)

        self.listener_address = MonitoredLineEdit()
        self.listener_address.setAlignment(Qt.AlignCenter)
        self.listener_address.setText(
            scctool.settings.config.parser.get("SCT",
                                               "sc2_network_listener_address"))
        self.listener_address.textModified.connect(self.changed)
        # self.tesseract.setAlignment(Qt.AlignCenter)
        self.listener_address.setPlaceholderText("[Your SC2 PC IP]:6119")
        self.listener_address.setToolTip(
            _('IP address and port of machine running SC2.'))
        ip_port = (
            r"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)" +
            r"{3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):[0-9]+$")
        self.listener_address.setValidator(QRegExpValidator(QRegExp(ip_port)))

        self.test_listener = QPushButton(" " +
                                         _("Test SC2 Client API Connection") +
                                         " ")
        self.test_listener.clicked.connect(self.testClientAPI)

        text = _("Activate this option if you are using a two computer "
                 "setup with StarCraft Casting Tool running on a different"
                 " PC than your SC2 client. Open the Battle.net launcher "
                 "on the latter PC, click 'Options', 'Game Settings', and "
                 "under SC2, check 'Additional Command Line Arguments', and "
                 "enter '-clientapi 6119'. Finally set as network"
                 " address below: '[Your SC2 PC IP]:6119'.")

        label = QLabel(text)
        label.setAlignment(Qt.AlignJustify)
        label.setOpenExternalLinks(True)
        label.setWordWrap(True)
        label.setMargin(5)
        layout.addWidget(label, 1, 0, 1, 3)

        layout.addWidget(self.cb_usesc2listener, 0, 0, 1, 3)
        layout.addWidget(QLabel(_("Network Address") + ": "), 3, 0)
        layout.addWidget(self.listener_address, 3, 1)
        layout.addWidget(self.test_listener, 3, 2)

        box.setLayout(layout)
        mainLayout.addWidget(box)
        mainLayout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding))
        self.clientapiBox.setLayout(mainLayout)

    def testClientAPI(self):
        """Test for connection to sc2 client api."""
        QApplication.setOverrideCursor(Qt.WaitCursor)
        address = self.listener_address.text().strip()
        url = "http://{}/ui".format(address)
        try:
            r = requests.get(url, timeout=10)
            r.raise_for_status()
            successfull = True
        except Exception:
            successfull = False
            module_logger.error("message")
        finally:
            QApplication.restoreOverrideCursor()

        title = _("Connection Test")

        if successfull:
            QMessageBox.information(
                self, title, _('Connection to SC2 client API established!'))
        else:
            QMessageBox.warning(
                self, title,
                _('Unable to connect to SC2 client API.'
                  ' Please make sure that SC2 is currently'
                  ' running on that machine.'))

    def createOcrBox(self):
        """Create forms for OCR."""
        self.ocrBox = QWidget()

        mainLayout = QVBoxLayout()

        box = QGroupBox(
            _("Optical Character Recognition for"
              " Automatic Setting of Ingame Score"))

        layout = QGridLayout()

        self.cb_useocr = QCheckBox(" " +
                                   _("Activate Optical Character Recognition"))
        self.cb_useocr.setChecked(
            scctool.settings.config.parser.getboolean("SCT", "use_ocr"))
        self.cb_useocr.stateChanged.connect(self.changed)

        self.tesseract = MonitoredLineEdit()
        self.tesseract.setText(
            scctool.settings.config.parser.get("SCT", "tesseract"))
        self.tesseract.textModified.connect(self.changed)
        # self.tesseract.setAlignment(Qt.AlignCenter)
        self.tesseract.setPlaceholderText(
            "C:\\Program Files (x86)\\Tesseract-OCR\\tesseract")
        self.tesseract.setReadOnly(True)
        self.tesseract.setToolTip(_('Tesseract-OCR Executable'))

        self.browse = QPushButton(_("Browse..."))
        self.browse.clicked.connect(self.selectTesseract)

        text = _(
            "Sometimes the order of players given by the SC2-Client-API"
            " differs from the order in the Observer-UI resulting in a"
            " swapped match score. To correct this via Optical Character"
            " Recognition you have to download {} and install and select the"
            " exectuable below, if it is not detected automatically.")
        url = 'https://github.com/UB-Mannheim/tesseract' + \
            '/wiki#tesseract-at-ub-mannheim'
        href = "<a href='{}'>" + "Tesseract-OCR" + "</a>"
        href = href.format(url)

        label = QLabel(text.format(href))
        label.setAlignment(Qt.AlignJustify)
        label.setOpenExternalLinks(True)
        label.setWordWrap(True)
        label.setMargin(5)
        layout.addWidget(label, 1, 0, 1, 2)

        layout.addWidget(self.cb_useocr, 0, 0, 1, 2)
        layout.addWidget(QLabel(_("Tesseract-OCR Executable") + ":"), 2, 0)
        layout.addWidget(self.tesseract, 3, 0)
        layout.addWidget(self.browse, 3, 1)

        box.setLayout(layout)
        mainLayout.addWidget(box)
        mainLayout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding))
        self.ocrBox.setLayout(mainLayout)

        if (not scctool.settings.windows):
            self.cb_useocr.setEnabled(False)
            self.cb_useocr.setAttribute(Qt.WA_AlwaysShowToolTips)
            self.cb_useocr.setToolTip(
                _("This feature is only available in Windows."))
            self.tesseract.setEnabled(False)
            self.tesseract.setAttribute(Qt.WA_AlwaysShowToolTips)
            self.tesseract.setToolTip(
                _("This feature is only available in Windows."))
            self.browse.setEnabled(False)
            self.browse.setAttribute(Qt.WA_AlwaysShowToolTips)
            self.browse.setToolTip(
                _("This feature is only available in Windows."))

    def selectTesseract(self):
        """Create forms for tesseract."""
        old_exe = self.tesseract.text()
        default = scctool.settings.config.findTesserAct(old_exe)
        exe, ok = QFileDialog.getOpenFileName(
            self, _("Select Tesseract-OCR Executable"), default,
            _("Tesseract-OCR Executable") + " (tesseract.exe);; " +
            _("Executable") + " (*.exe);; " + _("All files") + " (*)")
        if (ok and exe != old_exe):
            self.tesseract.setText(exe)
            self.changed()

    def createAligulacTab(self):
        """Create the aligulac tab."""
        self.aligulacTab = QWidget()

        layout = QGridLayout()
        self.aligulacTreeview = AligulacTreeView(
            self, self.controller.aligulacManager)

        layout.addWidget(self.aligulacTreeview, 0, 0, 3, 1)

        self.pb_addAligulacID = QPushButton(_("Add Aligluac ID"))
        self.pb_addAligulacID.clicked.connect(
            lambda x, self=self: self.addAligulacID())
        layout.addWidget(self.pb_addAligulacID, 1, 1)

        self.pb_removeAligulacID = QPushButton(_("Remove Aligulac ID"))
        self.pb_removeAligulacID.clicked.connect(self.removeAligulacID)
        layout.addWidget(self.pb_removeAligulacID, 2, 1)

        layout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Minimum), 0, 1)

        self.aligulacTab.setLayout(layout)

    def addAligulacID(self, name='', aligulac_id=1):
        """Add an aligulac ID."""
        text, ok = QInputDialog.getText(self,
                                        _('Player Name'),
                                        _('Player Name') + ':',
                                        text=name)
        text = text.strip()
        if not ok or not text:
            return
        aligulac_id, ok = QInputDialog.getInt(self,
                                              _('Aligulac ID'),
                                              _('Aligulac ID') + ':',
                                              value=aligulac_id,
                                              min=1)
        if not ok:
            return

        self.aligulacTreeview.insertItem(text, aligulac_id)

    def removeAligulacID(self):
        """Remove an selected aligulac ID."""
        self.aligulacTreeview.removeSelected()

    def createCounterTab(self):
        """Create the aligulac tab."""
        self.counterTab = QWidget()

        layout = QFormLayout()
        self.le_countdown_replacement = QLineEdit()
        self.le_countdown_replacement.setText(
            scctool.settings.config.parser.get("Countdown", "replacement"))
        self.le_countdown_replacement.textChanged.connect(self.changed)
        layout.addRow(QLabel(_('Replacement Text')),
                      self.le_countdown_replacement)
        self.cb_counter_matchgrabber_update = QCheckBox('')
        self.cb_counter_matchgrabber_update.setChecked(
            scctool.settings.config.parser.getboolean("Countdown",
                                                      "matchgrabber_update"))
        self.cb_counter_matchgrabber_update.stateChanged.connect(self.changed)
        layout.addRow(QLabel(_('Update Static Countdown via MatchGrabber')),
                      self.cb_counter_matchgrabber_update)
        self.counter_pretext = QPlainTextEdit()
        self.counter_pretext.setPlainText(
            scctool.settings.config.parser.get("Countdown", "pre_txt"))
        self.counter_pretext.textChanged.connect(self.changed)
        self.counter_posttext = QPlainTextEdit()
        self.counter_posttext.setPlainText(
            scctool.settings.config.parser.get("Countdown", "post_txt"))
        self.counter_posttext.textChanged.connect(self.changed)
        layout.addRow(QLabel('Pre-Text (in countdown.txt)'),
                      self.counter_pretext)
        layout.addRow(QLabel('Post-Text (in countdown.txt)'),
                      self.counter_posttext)

        self.counterTab.setLayout(layout)

    def createMapsBox(self):
        """Create box for map manager."""
        self.mapsize = 300

        self.mapsBox = QWidget()

        layout = QGridLayout()

        self.maplist = QListWidget()
        self.maplist.setSortingEnabled(True)
        for sc2map in scctool.settings.maps:
            self.maplist.addItem(QListWidgetItem(sc2map))
        self.maplist.setCurrentItem(self.maplist.item(0))
        self.maplist.currentItemChanged.connect(self.changePreview)
        # self.maplist.setFixedHeight(self.mapsize)
        self.maplist.setMinimumWidth(150)

        layout.addWidget(self.maplist, 0, 1, 2, 1)
        self.mapPreview = QLabel()
        self.mapPreview.setFixedWidth(self.mapsize)
        self.mapPreview.setFixedHeight(self.mapsize)
        self.mapPreview.setAlignment(Qt.AlignCenter)
        layout.addWidget(self.mapPreview, 0, 0)
        self.mapInfo = QLabel()
        self.mapInfo.setIndent(10)
        layout.addWidget(self.mapInfo, 1, 0)

        self.pb_addMapLiquipedia = QPushButton(_("Add from Liquipedia"))
        self.pb_addMapLiquipedia.clicked.connect(self.addFromLquipedia)
        self.pb_addMap = QPushButton(_("Add from File"))
        self.pb_addMap.clicked.connect(self.addMap)
        self.pb_renameMap = QPushButton(_("Rename"))
        self.pb_renameMap.clicked.connect(self.renameMap)
        self.pb_changeMap = QPushButton(_("Change Image"))
        self.pb_changeMap.clicked.connect(self.changeMap)
        self.pb_removeMap = QPushButton(_("Remove"))
        self.pb_removeMap.clicked.connect(self.deleteMap)

        self.sc_removeMap = QShortcut(QKeySequence("Del"), self.maplist)
        self.sc_removeMap.setAutoRepeat(False)
        self.sc_removeMap.setContext(Qt.WidgetWithChildrenShortcut)
        self.sc_removeMap.activated.connect(self.deleteMap)

        box = QWidget()
        container = QHBoxLayout()

        container.addWidget(self.pb_addMapLiquipedia, 0)
        container.addWidget(self.pb_addMap, 0)
        container.addWidget(QLabel(), 4)
        container.addWidget(self.pb_renameMap, 0)
        container.addWidget(self.pb_changeMap, 0)
        container.addWidget(self.pb_removeMap, 0)
        box.setLayout(container)

        layout.addWidget(box, 2, 0, 1, 2)

        layout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding), 3,
            0, 1, 2)

        self.changePreview()
        self.mapsBox.setLayout(layout)

    def renameMap(self):
        """Rename maps."""
        item = self.maplist.currentItem()
        mapname = item.text()
        text, ok = QInputDialog.getText(self,
                                        _('Map Name'),
                                        _('Map Name') + ':',
                                        text=mapname)
        if not ok:
            return
        text = text.strip()
        if (text == mapname):
            return
        if text.lower() == 'tbd':
            QMessageBox.critical(
                self, _("Error"),
                _('"{}" is not a valid map name.').format(text))
            return
        if (text in scctool.settings.maps):
            buttonReply = QMessageBox.warning(
                self, _("Duplicate Entry"),
                _("Map is already in list! Overwrite?"),
                QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if buttonReply == QMessageBox.No:
                return

        self.controller.addMap(self.controller.getMapImg(mapname, True), text)
        self.controller.deleteMap(mapname)
        item.setText(text)

    def changeMap(self):
        """Change a map."""
        current_map = self.maplist.currentItem().text()
        fileName, ok = QFileDialog.getOpenFileName(
            self, _("Select Map Image (> 500x500px recommended)"), "",
            _("Supported Images") + " (*.png *.jpg *.jpeg)")
        if ok:
            base = os.path.basename(fileName)
            name, __ = os.path.splitext(base)
            name = name.replace("_", " ")
            self.controller.deleteMap(current_map)
            self.controller.addMap(fileName, current_map)
            self.changePreview()

    def addMap(self):
        """Add a map."""
        fileName, ok = QFileDialog.getOpenFileName(
            self, _("Select Map Image (> 500x500px recommended)"), "",
            _("Supported Images") + " (*.png *.jpg  *.jpeg)")
        if ok:
            base = os.path.basename(fileName)
            name, __ = os.path.splitext(base)
            name = name.replace("_", " ")
            map_name, ok = QInputDialog.getText(self,
                                                _('Map Name'),
                                                _('Map Name') + ':',
                                                text=name)
            map_name = map_name.strip()
            if ok:
                if map_name.lower() == 'tbd':
                    QMessageBox.critical(
                        self, _("Error"),
                        _('"{}" is not a valid map name.').format(map_name))
                    return

                if (map_name in scctool.settings.maps):
                    buttonReply = QMessageBox.warning(
                        self, _("Duplicate Entry"),
                        _("Map is already in list! Overwrite?"),
                        QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                    if buttonReply == QMessageBox.No:
                        return
                    else:
                        self.controller.deleteMap(map_name)

                self.controller.addMap(fileName, map_name)
                items = self.maplist.findItems(map_name, Qt.MatchExactly)
                if len(items) == 0:
                    item = QListWidgetItem(map_name)
                    self.maplist.addItem(item)
                    self.maplist.setCurrentItem(item)
                else:
                    self.maplist.setCurrentItem(items[0])
                self.changePreview()

    def addFromLquipedia(self):
        """Add a map from Liquipedia."""
        grabber = LiquipediaGrabber()
        search_str = ''
        while True:
            search_str, ok = QInputDialog.getText(self,
                                                  _('Map Name'),
                                                  _('Map Name') + ':',
                                                  text=search_str)
            search_str.strip()
            try:
                if ok and search_str:
                    if search_str.lower() == 'tbd':
                        QMessageBox.critical(
                            self, _("Error"),
                            _('"{}" is not a valid map name.').format(
                                search_str))
                        continue
                    try:
                        QApplication.setOverrideCursor(Qt.WaitCursor)
                        sc2map = grabber.get_map(search_str)
                    except MapNotFound:
                        QMessageBox.critical(
                            self, _("Map not found"),
                            _('"{}" was not found on Liquipedia.').format(
                                search_str))
                        continue
                    finally:
                        QApplication.restoreOverrideCursor()
                    map_name = sc2map.get_name()

                    if (map_name in scctool.settings.maps):
                        buttonReply = QMessageBox.warning(
                            self, _("Duplicate Entry"),
                            _("Map {} is already in list! Overwrite?".format(
                                map_name)), QMessageBox.Yes | QMessageBox.No,
                            QMessageBox.No)
                        if buttonReply == QMessageBox.No:
                            break
                        else:
                            self.controller.deleteMap(map_name)

                    try:
                        QApplication.setOverrideCursor(Qt.WaitCursor)
                        images = grabber.get_images(sc2map.get_map_images())
                        image = ""
                        for size in sorted(images):
                            if not image or size <= 2500 * 2500:
                                image = images[size]
                        url = grabber._base_url + image

                        downloader = MapDownloader(self, map_name, url)
                        downloader.download()
                        if map_name not in scctool.settings.maps:
                            scctool.settings.maps.append(map_name)
                        items = self.maplist.findItems(map_name,
                                                       Qt.MatchExactly)
                        if len(items) == 0:
                            item = QListWidgetItem(map_name)
                            self.maplist.addItem(item)
                            self.maplist.setCurrentItem(item)
                        else:
                            self.maplist.setCurrentItem(items[0])
                        self.changePreview()
                    except Exception:
                        raise
                    finally:
                        QApplication.restoreOverrideCursor()
            except Exception as e:
                module_logger.exception("message")
                QMessageBox.critical(self, _("Error"), str(e))
            break

    def deleteMap(self):
        """Delete a map."""
        item = self.maplist.currentItem()
        mapname = item.text()
        buttonReply = QMessageBox.question(
            self, _('Delete map?'),
            _("Delete '{}' permanently?").format(mapname),
            QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if buttonReply == QMessageBox.Yes:
            self.controller.deleteMap(mapname)
            self.maplist.takeItem(self.maplist.currentRow())

    def changePreview(self):
        """Change the map preview."""
        if self.maplist.count() < 1:
            return

        mapname = self.maplist.currentItem().text()
        if (mapname == "TBD"):
            self.pb_renameMap.setEnabled(False)
            self.pb_removeMap.setEnabled(False)
            self.sc_removeMap.setEnabled(False)
        else:
            self.pb_removeMap.setEnabled(True)
            self.pb_renameMap.setEnabled(True)
            self.sc_removeMap.setEnabled(True)

        file = self.controller.getMapImg(mapname, True)
        pixmap = QPixmap(file)
        height = pixmap.height()
        width = pixmap.width()
        ext = os.path.splitext(file)[1].replace(".", "").upper()
        size = humanize.naturalsize(os.path.getsize(file))
        pixmap = QPixmap(file).scaled(self.mapsize, self.mapsize,
                                      Qt.KeepAspectRatio)
        self.mapPreview.setPixmap(pixmap)
        text = f"{width}x{height}px, {size}, {ext}"
        self.mapInfo.setText(text)

    def createButtonGroup(self):
        """Create buttons."""
        try:
            layout = QHBoxLayout()

            layout.addWidget(QLabel(""))

            buttonCancel = QPushButton(_('Cancel'))
            buttonCancel.clicked.connect(self.closeWindow)
            layout.addWidget(buttonCancel)

            buttonSave = QPushButton(_('&Save && Close'))
            buttonSave.setToolTip(_("Shortcut: {}").format("Ctrl+S"))
            self.shortcut = QShortcut(QKeySequence("Ctrl+S"), self)
            self.shortcut.setAutoRepeat(False)
            self.shortcut.activated.connect(self.saveCloseWindow)
            buttonSave.clicked.connect(self.saveCloseWindow)
            layout.addWidget(buttonSave)

            self.buttonGroup = layout
        except Exception:
            module_logger.exception("message")

    def saveData(self):
        """Save the data."""
        if (self.__dataChanged):
            scctool.settings.config.parser.set(
                "SCT", "myteams", ", ".join(self.list_favTeams.getData()))
            scctool.settings.config.parser.set(
                "SCT", "commonplayers",
                ", ".join(self.list_favPlayers.getData()))
            scctool.settings.config.parser.set("SCT", "tesseract",
                                               self.tesseract.text().strip())
            scctool.settings.config.parser.set("SCT", "use_ocr",
                                               str(self.cb_useocr.isChecked()))
            scctool.settings.config.parser.set(
                "SCT", "transparent_match_banner",
                str(self.cb_trans_banner.isChecked()))
            scctool.settings.config.parser.set(
                "SCT", "CtrlShiftS", str(self.cb_ctrlshifts.isChecked()))
            scctool.settings.config.parser.set(
                "SCT", "CtrlShiftC", str(self.cb_ctrlshiftc.isChecked()))
            scctool.settings.config.parser.set(
                "SCT", "swap_myteam", str(self.cb_swapTeams.isChecked()))
            scctool.settings.config.parser.set("SCT", "CtrlN",
                                               str(self.cb_ctrln.isChecked()))
            scctool.settings.config.parser.set("SCT", "CtrlX",
                                               str(self.cb_ctrlx.isChecked()))
            scctool.settings.config.parser.set(
                "SCT", "CtrlShiftR", str(self.cb_ctrlshiftr.currentText()))
            scctool.settings.config.parser.set(
                "SCT", "blacklist_on", str(self.cb_blacklist.isChecked()))
            scctool.settings.config.parser.set(
                "SCT", "blacklist", ", ".join(self.list_blacklist.getData()))
            scctool.settings.config.parser.set(
                "SCT", "sc2_network_listener_address",
                self.listener_address.text().strip())
            scctool.settings.config.parser.set(
                "SCT", "sc2_network_listener_enabled",
                str(self.cb_usesc2listener.isChecked()))
            scctool.settings.config.parser.set(
                "Countdown", "matchgrabber_update",
                str(self.cb_counter_matchgrabber_update.isChecked()))
            scctool.settings.config.parser.set(
                "Countdown", "replacement",
                self.le_countdown_replacement.text())
            scctool.settings.config.parser.set(
                "Countdown", "pre_txt", self.counter_pretext.toPlainText())
            scctool.settings.config.parser.set(
                "Countdown", "post_txt", self.counter_posttext.toPlainText())
            self.controller.refreshButtonStatus()
            # self.controller.setCBS()
            self.__dataChanged = False

    def saveCloseWindow(self):
        """Save and close window."""
        self.saveData()
        self.passEvent = True
        self.close()

    def closeWindow(self):
        """Close window."""
        self.passEvent = True
        self.close()

    def closeEvent(self, event):
        """Handle close event."""
        try:
            self.mainWindow.updateAllMapCompleters()
            if (not self.__dataChanged):
                event.accept()
                return
            if (not self.passEvent):
                if (self.isMinimized()):
                    self.showNormal()
                buttonReply = QMessageBox.question(
                    self, _('Save data?'), _("Save data?"),
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                if buttonReply == QMessageBox.Yes:
                    self.saveData()
            event.accept()
        except Exception:
            module_logger.exception("message")
コード例 #54
0
    def __init__(self, window, plugin, keystore, device_id):
        title = _("{} Settings").format(plugin.device)
        super(SettingsDialog, self).__init__(window, title)
        self.setMaximumWidth(540)

        devmgr = plugin.device_manager()
        config = devmgr.config
        handler = keystore.handler
        thread = keystore.thread

        def invoke_client(method, *args, **kw_args):
            unpair_after = kw_args.pop('unpair_after', False)

            def task():
                client = devmgr.client_by_id(device_id)
                if not client:
                    raise RuntimeError("Device not connected")
                if method:
                    getattr(client, method)(*args, **kw_args)
                if unpair_after:
                    devmgr.unpair_id(device_id)
                return client.features

            thread.add(task, on_success=update)

        def update(features):
            self.features = features
            set_label_enabled()
            bl_hash = bh2u(features.bootloader_hash)
            bl_hash = "\n".join([bl_hash[:32], bl_hash[32:]])
            noyes = [_("No"), _("Yes")]
            endis = [_("Enable Passphrases"), _("Disable Passphrases")]
            disen = [_("Disabled"), _("Enabled")]
            setchange = [_("Set a PIN"), _("Change PIN")]

            version = "%d.%d.%d" % (features.major_version,
                                    features.minor_version,
                                    features.patch_version)
            coins = ", ".join(coin.coin_name for coin in features.coins)

            device_label.setText(features.label)
            pin_set_label.setText(noyes[features.pin_protection])
            passphrases_label.setText(disen[features.passphrase_protection])
            bl_hash_label.setText(bl_hash)
            label_edit.setText(features.label)
            device_id_label.setText(features.device_id)
            initialized_label.setText(noyes[features.initialized])
            version_label.setText(version)
            coins_label.setText(coins)
            clear_pin_button.setVisible(features.pin_protection)
            clear_pin_warning.setVisible(features.pin_protection)
            pin_button.setText(setchange[features.pin_protection])
            pin_msg.setVisible(not features.pin_protection)
            passphrase_button.setText(endis[features.passphrase_protection])
            language_label.setText(features.language)

        def set_label_enabled():
            label_apply.setEnabled(label_edit.text() != self.features.label)

        def rename():
            invoke_client('change_label', label_edit.text())

        def toggle_passphrase():
            title = _("Confirm Toggle Passphrase Protection")
            currently_enabled = self.features.passphrase_protection
            if currently_enabled:
                msg = _("After disabling passphrases, you can only pair this "
                        "Electrum wallet if it had an empty passphrase.  "
                        "If its passphrase was not empty, you will need to "
                        "create a new wallet with the install wizard.  You "
                        "can use this wallet again at any time by re-enabling "
                        "passphrases and entering its passphrase.")
            else:
                msg = _("Your current Electrum wallet can only be used with "
                        "an empty passphrase.  You must create a separate "
                        "wallet with the install wizard for other passphrases "
                        "as each one generates a new set of addresses.")
            msg += "\n\n" + _("Are you sure you want to proceed?")
            if not self.question(msg, title=title):
                return
            invoke_client('toggle_passphrase', unpair_after=currently_enabled)

        def set_pin():
            invoke_client('set_pin', remove=False)

        def clear_pin():
            invoke_client('set_pin', remove=True)

        def wipe_device():
            wallet = window.wallet
            if wallet and sum(wallet.get_balance()):
                title = _("Confirm Device Wipe")
                msg = _("Are you SURE you want to wipe the device?\n"
                        "Your wallet still has viacoins in it!")
                if not self.question(
                        msg, title=title, icon=QMessageBox.Critical):
                    return
            invoke_client('wipe_device', unpair_after=True)

        def slider_moved():
            mins = timeout_slider.sliderPosition()
            timeout_minutes.setText(_("{:2d} minutes").format(mins))

        def slider_released():
            config.set_session_timeout(timeout_slider.sliderPosition() * 60)

        # Information tab
        info_tab = QWidget()
        info_layout = QVBoxLayout(info_tab)
        info_glayout = QGridLayout()
        info_glayout.setColumnStretch(2, 1)
        device_label = QLabel()
        pin_set_label = QLabel()
        passphrases_label = QLabel()
        version_label = QLabel()
        device_id_label = QLabel()
        bl_hash_label = QLabel()
        bl_hash_label.setWordWrap(True)
        coins_label = QLabel()
        coins_label.setWordWrap(True)
        language_label = QLabel()
        initialized_label = QLabel()
        rows = [
            (_("Device Label"), device_label),
            (_("PIN set"), pin_set_label),
            (_("Passphrases"), passphrases_label),
            (_("Firmware Version"), version_label),
            (_("Device ID"), device_id_label),
            (_("Bootloader Hash"), bl_hash_label),
            (_("Supported Coins"), coins_label),
            (_("Language"), language_label),
            (_("Initialized"), initialized_label),
        ]
        for row_num, (label, widget) in enumerate(rows):
            info_glayout.addWidget(QLabel(label), row_num, 0)
            info_glayout.addWidget(widget, row_num, 1)
        info_layout.addLayout(info_glayout)

        # Settings tab
        settings_tab = QWidget()
        settings_layout = QVBoxLayout(settings_tab)
        settings_glayout = QGridLayout()

        # Settings tab - Label
        label_msg = QLabel(
            _("Name this {}.  If you have multiple devices "
              "their labels help distinguish them.").format(plugin.device))
        label_msg.setWordWrap(True)
        label_label = QLabel(_("Device Label"))
        label_edit = QLineEdit()
        label_edit.setMinimumWidth(150)
        label_edit.setMaxLength(plugin.MAX_LABEL_LEN)
        label_apply = QPushButton(_("Apply"))
        label_apply.clicked.connect(rename)
        label_edit.textChanged.connect(set_label_enabled)
        settings_glayout.addWidget(label_label, 0, 0)
        settings_glayout.addWidget(label_edit, 0, 1, 1, 2)
        settings_glayout.addWidget(label_apply, 0, 3)
        settings_glayout.addWidget(label_msg, 1, 1, 1, -1)

        # Settings tab - PIN
        pin_label = QLabel(_("PIN Protection"))
        pin_button = QPushButton()
        pin_button.clicked.connect(set_pin)
        settings_glayout.addWidget(pin_label, 2, 0)
        settings_glayout.addWidget(pin_button, 2, 1)
        pin_msg = QLabel(
            _("PIN protection is strongly recommended.  "
              "A PIN is your only protection against someone "
              "stealing your viacoins if they obtain physical "
              "access to your {}.").format(plugin.device))
        pin_msg.setWordWrap(True)
        pin_msg.setStyleSheet("color: red")
        settings_glayout.addWidget(pin_msg, 3, 1, 1, -1)

        # Settings tab - Session Timeout
        timeout_label = QLabel(_("Session Timeout"))
        timeout_minutes = QLabel()
        timeout_slider = QSlider(Qt.Horizontal)
        timeout_slider.setRange(1, 60)
        timeout_slider.setSingleStep(1)
        timeout_slider.setTickInterval(5)
        timeout_slider.setTickPosition(QSlider.TicksBelow)
        timeout_slider.setTracking(True)
        timeout_msg = QLabel(
            _("Clear the session after the specified period "
              "of inactivity.  Once a session has timed out, "
              "your PIN and passphrase (if enabled) must be "
              "re-entered to use the device."))
        timeout_msg.setWordWrap(True)
        timeout_slider.setSliderPosition(config.get_session_timeout() // 60)
        slider_moved()
        timeout_slider.valueChanged.connect(slider_moved)
        timeout_slider.sliderReleased.connect(slider_released)
        settings_glayout.addWidget(timeout_label, 6, 0)
        settings_glayout.addWidget(timeout_slider, 6, 1, 1, 3)
        settings_glayout.addWidget(timeout_minutes, 6, 4)
        settings_glayout.addWidget(timeout_msg, 7, 1, 1, -1)
        settings_layout.addLayout(settings_glayout)
        settings_layout.addStretch(1)

        # Advanced tab
        advanced_tab = QWidget()
        advanced_layout = QVBoxLayout(advanced_tab)
        advanced_glayout = QGridLayout()

        # Advanced tab - clear PIN
        clear_pin_button = QPushButton(_("Disable PIN"))
        clear_pin_button.clicked.connect(clear_pin)
        clear_pin_warning = QLabel(
            _("If you disable your PIN, anyone with physical access to your "
              "{} device can spend your viacoins.").format(plugin.device))
        clear_pin_warning.setWordWrap(True)
        clear_pin_warning.setStyleSheet("color: red")
        advanced_glayout.addWidget(clear_pin_button, 0, 2)
        advanced_glayout.addWidget(clear_pin_warning, 1, 0, 1, 5)

        # Advanced tab - toggle passphrase protection
        passphrase_button = QPushButton()
        passphrase_button.clicked.connect(toggle_passphrase)
        passphrase_msg = WWLabel(PASSPHRASE_HELP)
        passphrase_warning = WWLabel(PASSPHRASE_NOT_PIN)
        passphrase_warning.setStyleSheet("color: red")
        advanced_glayout.addWidget(passphrase_button, 3, 2)
        advanced_glayout.addWidget(passphrase_msg, 4, 0, 1, 5)
        advanced_glayout.addWidget(passphrase_warning, 5, 0, 1, 5)

        # Advanced tab - wipe device
        wipe_device_button = QPushButton(_("Wipe Device"))
        wipe_device_button.clicked.connect(wipe_device)
        wipe_device_msg = QLabel(
            _("Wipe the device, removing all data from it.  The firmware "
              "is left unchanged."))
        wipe_device_msg.setWordWrap(True)
        wipe_device_warning = QLabel(
            _("Only wipe a device if you have the recovery seed written down "
              "and the device wallet(s) are empty, otherwise the viacoins "
              "will be lost forever."))
        wipe_device_warning.setWordWrap(True)
        wipe_device_warning.setStyleSheet("color: red")
        advanced_glayout.addWidget(wipe_device_button, 6, 2)
        advanced_glayout.addWidget(wipe_device_msg, 7, 0, 1, 5)
        advanced_glayout.addWidget(wipe_device_warning, 8, 0, 1, 5)
        advanced_layout.addLayout(advanced_glayout)
        advanced_layout.addStretch(1)

        tabs = QTabWidget(self)
        tabs.addTab(info_tab, _("Information"))
        tabs.addTab(settings_tab, _("Settings"))
        tabs.addTab(advanced_tab, _("Advanced"))
        dialog_vbox = QVBoxLayout(self)
        dialog_vbox.addWidget(tabs)
        dialog_vbox.addLayout(Buttons(CloseButton(self)))

        # Update information
        invoke_client(None)
コード例 #55
0
class LibGeneratorUI(QDialog):

    num_of_funcs = 0

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

        self.layout = QGridLayout(self)
        self.workspace = os.path.dirname(os.path.realpath(__file__))  # current working folder

        self.tabs = QTabWidget()
        self.tab1 = QWidget()
        self.tab2 = QWidget()
        self.tabs.resize(1000, 200)

        # Add tabs
        self.tabs.addTab(self.tab1, 'Function')
        self.tabs.addTab(self.tab2, 'Defines and variables')

        self.tab1_layout = QVBoxLayout()
        self.tab1_layout.setSpacing(10)

        # Create first tab
        self.functions_list = []

        self.create_functions_tab()
        #self.createDefinesTab()

        # Add tabs to widget
        self.tab1.setLayout(self.tab1_layout)

        self.layout.addWidget(self.tabs)
        self.addGenerateButton()

        self.setLayout(self.layout)
        self.setGeometry(700, 400, 400, 50)
        self.setWindowTitle('MCU Library Generator v1.0.0')
        self.setStyle('Fusion')

    def setStyle(self, styleName):
        QApplication.setStyle(QStyleFactory.create(styleName))
        QApplication.setPalette(QApplication.palette())

    def create_functions_tab(self):

        self.conf_box = QGroupBox('Configurations')
        self.confs_layout = QGridLayout()
        self.createConfBox()


        self.functions_box = QGroupBox('Functions')
        self.functions_layout = QGridLayout()

        add_func_button = QPushButton('Add function')
        add_func_button.setIcon(QtGui.QIcon('img/add.jpg'))
        add_func_button.clicked.connect(self.addFunction)
        self.functions_layout.addWidget(add_func_button, 0, 0)

        self.addFunction()

        self.tab1_layout.addWidget(self.conf_box)
        self.tab1_layout.addWidget(self.functions_box)

    def createConfBox(self):

        lbl_username = QLabel('Creators Full Name')
        txt_username = QLineEdit()

        lbl_dir = QLabel('Project Directory')

        bt_dir = QPushButton("...")
        bt_dir.setFixedSize(30, 20)
        bt_dir.clicked.connect(self.get_work_dir)

        # to use in get_work_dir function
        self.txt_dir = QLineEdit()
        self.txt_dir.setText(self.workspace)
        self.txt_dir.setCursorPosition(0)

        ######################################

        lbl_file_name = QLabel('Module (Library) name: ')
        txt_file_name = QLineEdit()
        txt_file_name.setText('sim800')

        self.config = Configuration(txt_username, self.txt_dir, txt_file_name)

        self.confs_layout.addWidget(lbl_username, 0, 0)
        self.confs_layout.addWidget(txt_username, 0, 1, 1, 20)
        self.confs_layout.addWidget(lbl_dir, 1, 0)
        self.confs_layout.addWidget(self.txt_dir, 1, 1, 1, 20)
        self.confs_layout.addWidget(bt_dir, 1, 21)
        self.confs_layout.addWidget(lbl_file_name, 2, 0)
        self.confs_layout.addWidget(txt_file_name, 2, 1, 1, 20)

        self.conf_box.setLayout(self.confs_layout)

    def get_work_dir(self):
        self.workspace = str(QFileDialog.getExistingDirectory(self, 'Select Directory'))
        self.txt_dir.setText(self.workspace)
        self.txt_dir.setCursorPosition(0)

    def addFunction(self):

        lbls = [QLabel('Return Type'), QLabel('Scope'), QLabel('Function Name'), QLabel('Arguments')]

        for lbl in lbls:
            lbl.setAlignment(Qt.AlignCenter)

        type = QComboBox(self.functions_box)
        type.addItems(['void', 'int', 'char *', 'bool', 'uint32_t'])
        type.setEditable(True)

        visibility = QComboBox(self.functions_box)
        visibility.addItems(['private', 'public'])
        visibility.setFixedWidth(100)

        name = QLineEdit()
        #arg_cnt = QSpinBox(self.functions_box)
        argv = QLineEdit()

        self.functions_list.append(Function(self.functions_layout, type, visibility, name, argv))

        self.functions_layout.addWidget(lbls[0], 1, 0)
        self.functions_layout.addWidget(lbls[1], 1, 1)
        self.functions_layout.addWidget(lbls[2], 1, 4)
        self.functions_layout.addWidget(lbls[3], 1, 18)

        self.functions_layout.addWidget(type, 2 + self.num_of_funcs, 0)
        self.functions_layout.addWidget(visibility, 2 + self.num_of_funcs, 1)
        self.functions_layout.addWidget(name, 2 + self.num_of_funcs, 2, 1, 6)
        self.functions_layout.addWidget(argv, 2 + self.num_of_funcs, 8, 1, 20)

        self.num_of_funcs += 1
        self.functions_box.setLayout(self.functions_layout)

    def addGenerateButton(self):
        generateButton = QPushButton(' Generate')
        generateButton.clicked.connect(self.generateCode)
        generateButton.setIcon(QtGui.QIcon('img/generate.jpg'))

        hbox = QHBoxLayout()
        hbox.addStretch(1)
        hbox.addWidget(generateButton)

        vbox = QVBoxLayout()
        vbox.addStretch(1)
        vbox.addLayout(hbox)

        self.layout.addLayout(vbox, 1, 0)

    def generateCode(self):
        generator.generateModule(self.config, self.functions_list, [], [])
コード例 #56
0
    def __init__(self, parent: 'ElectrumWindow', config: 'SimpleConfig'):
        WindowModalDialog.__init__(self, parent, _('Preferences'))
        self.config = config
        self.window = parent
        self.need_restart = False
        self.fx = self.window.fx
        self.wallet = self.window.wallet
        
        vbox = QVBoxLayout()
        tabs = QTabWidget()
        gui_widgets = []
        tx_widgets = []
        oa_widgets = []

        # language
        lang_help = _('Select which language is used in the GUI (after restart).')
        lang_label = HelpLabel(_('Language') + ':', lang_help)
        lang_combo = QComboBox()
        lang_combo.addItems(list(languages.values()))
        lang_keys = list(languages.keys())
        lang_cur_setting = self.config.get("language", '')
        try:
            index = lang_keys.index(lang_cur_setting)
        except ValueError:  # not in list
            index = 0
        lang_combo.setCurrentIndex(index)
        if not self.config.is_modifiable('language'):
            for w in [lang_combo, lang_label]: w.setEnabled(False)
        def on_lang(x):
            lang_request = list(languages.keys())[lang_combo.currentIndex()]
            if lang_request != self.config.get('language'):
                self.config.set_key("language", lang_request, True)
                self.need_restart = True
        lang_combo.currentIndexChanged.connect(on_lang)
        gui_widgets.append((lang_label, lang_combo))

        nz_help = _('Number of zeros displayed after the decimal point. For example, if this is set to 2, "1." will be displayed as "1.00"')
        nz_label = HelpLabel(_('Zeros after decimal point') + ':', nz_help)
        nz = QSpinBox()
        nz.setMinimum(0)
        nz.setMaximum(self.config.decimal_point)
        nz.setValue(self.config.num_zeros)
        if not self.config.is_modifiable('num_zeros'):
            for w in [nz, nz_label]: w.setEnabled(False)
        def on_nz():
            value = nz.value()
            if self.config.num_zeros != value:
                self.config.num_zeros = value
                self.config.set_key('num_zeros', value, True)
                self.window.need_update.set()
        nz.valueChanged.connect(on_nz)
        gui_widgets.append((nz_label, nz))

        use_rbf = bool(self.config.get('use_rbf', True))
        use_rbf_cb = QCheckBox(_('Use Replace-By-Fee'))
        use_rbf_cb.setChecked(use_rbf)
        use_rbf_cb.setToolTip(
            _('If you check this box, your transactions will be marked as non-final,') + '\n' + \
            _('and you will have the possibility, while they are unconfirmed, to replace them with transactions that pay higher fees.') + '\n' + \
            _('Note that some merchants do not accept non-final transactions until they are confirmed.'))
        def on_use_rbf(x):
            self.config.set_key('use_rbf', bool(x))
            batch_rbf_cb.setEnabled(bool(x))
        use_rbf_cb.stateChanged.connect(on_use_rbf)
        tx_widgets.append((use_rbf_cb, None))

        batch_rbf_cb = QCheckBox(_('Batch RBF transactions'))
        batch_rbf_cb.setChecked(bool(self.config.get('batch_rbf', False)))
        batch_rbf_cb.setEnabled(use_rbf)
        batch_rbf_cb.setToolTip(
            _('If you check this box, your unconfirmed transactions will be consolidated into a single transaction.') + '\n' + \
            _('This will save fees.'))
        def on_batch_rbf(x):
            self.config.set_key('batch_rbf', bool(x))
        batch_rbf_cb.stateChanged.connect(on_batch_rbf)
        tx_widgets.append((batch_rbf_cb, None))

        # lightning
        lightning_widgets = []

        help_recov = _(messages.MSG_RECOVERABLE_CHANNELS)
        recov_cb = QCheckBox(_("Create recoverable channels"))
        enable_toggle_use_recoverable_channels = bool(self.wallet.lnworker and self.wallet.lnworker.can_have_recoverable_channels())
        recov_cb.setEnabled(enable_toggle_use_recoverable_channels)
        recov_cb.setToolTip(messages.to_rtf(help_recov))
        recov_cb.setChecked(bool(self.config.get('use_recoverable_channels', True)) and enable_toggle_use_recoverable_channels)
        def on_recov_checked(x):
            self.config.set_key('use_recoverable_channels', bool(x))
        recov_cb.stateChanged.connect(on_recov_checked)
        lightning_widgets.append((recov_cb, None))

        help_trampoline = _(messages.MSG_HELP_TRAMPOLINE)
        trampoline_cb = QCheckBox(_("Use trampoline routing (disable gossip)"))
        trampoline_cb.setToolTip(messages.to_rtf(help_trampoline))
        trampoline_cb.setChecked(not bool(self.config.get('use_gossip', False)))
        def on_trampoline_checked(use_trampoline):
            use_gossip = not bool(use_trampoline)
            self.config.set_key('use_gossip', use_gossip)
            if use_gossip:
                self.window.network.start_gossip()
            else:
                self.window.network.run_from_another_thread(
                    self.window.network.stop_gossip())
            util.trigger_callback('ln_gossip_sync_progress')
            # FIXME: update all wallet windows
            util.trigger_callback('channels_updated', self.wallet)
        trampoline_cb.stateChanged.connect(on_trampoline_checked)
        lightning_widgets.append((trampoline_cb, None))

        help_remote_wt = ' '.join([
            _("A watchtower is a daemon that watches your channels and prevents the other party from stealing funds by broadcasting an old state."),
            _("If you have private a watchtower, enter its URL here."),
            _("Check our online documentation if you want to configure Electrum as a watchtower."),
        ])
        remote_wt_cb = QCheckBox(_("Use a remote watchtower"))
        remote_wt_cb.setToolTip('<p>'+help_remote_wt+'</p>')
        remote_wt_cb.setChecked(bool(self.config.get('use_watchtower', False)))
        def on_remote_wt_checked(x):
            self.config.set_key('use_watchtower', bool(x))
            self.watchtower_url_e.setEnabled(bool(x))
        remote_wt_cb.stateChanged.connect(on_remote_wt_checked)
        watchtower_url = self.config.get('watchtower_url')
        self.watchtower_url_e = QLineEdit(watchtower_url)
        self.watchtower_url_e.setEnabled(self.config.get('use_watchtower', False))
        def on_wt_url():
            url = self.watchtower_url_e.text() or None
            watchtower_url = self.config.set_key('watchtower_url', url)
        self.watchtower_url_e.editingFinished.connect(on_wt_url)
        lightning_widgets.append((remote_wt_cb, self.watchtower_url_e))

        msg = _('OpenAlias record, used to receive coins and to sign payment requests.') + '\n\n'\
              + _('The following alias providers are available:') + '\n'\
              + '\n'.join(['https://cryptoname.co/', 'http://xmr.link']) + '\n\n'\
              + 'For more information, see https://openalias.org'
        alias_label = HelpLabel(_('OpenAlias') + ':', msg)
        alias = self.config.get('alias','')
        self.alias_e = QLineEdit(alias)
        self.set_alias_color()
        self.alias_e.editingFinished.connect(self.on_alias_edit)
        oa_widgets.append((alias_label, self.alias_e))

        msat_cb = QCheckBox(_("Show amounts with msat precision"))
        msat_cb.setChecked(bool(self.config.get('amt_precision_post_satoshi', False)))
        def on_msat_checked(v):
            prec = 3 if v == Qt.Checked else 0
            if self.config.amt_precision_post_satoshi != prec:
                self.config.amt_precision_post_satoshi = prec
                self.config.set_key('amt_precision_post_satoshi', prec)
                self.window.need_update.set()
        msat_cb.stateChanged.connect(on_msat_checked)
        lightning_widgets.append((msat_cb, None))

        # units
        units = base_units_list
        msg = (_('Base unit of your wallet.')
               + '\n1 GRLC = 1000 mGRLC. 1 mGRLC = 1000 uGRLC. 1 uGRLC = 100 sat.\n'
               + _('This setting affects the Send tab, and all balance related fields.'))
        unit_label = HelpLabel(_('Base unit') + ':', msg)
        unit_combo = QComboBox()
        unit_combo.addItems(units)
        unit_combo.setCurrentIndex(units.index(self.window.base_unit()))
        def on_unit(x, nz):
            unit_result = units[unit_combo.currentIndex()]
            if self.window.base_unit() == unit_result:
                return
            edits = self.window.amount_e, self.window.receive_amount_e
            amounts = [edit.get_amount() for edit in edits]
            self.config.set_base_unit(unit_result)
            nz.setMaximum(self.config.decimal_point)
            self.window.update_tabs()
            for edit, amount in zip(edits, amounts):
                edit.setAmount(amount)
            self.window.update_status()
        unit_combo.currentIndexChanged.connect(lambda x: on_unit(x, nz))
        gui_widgets.append((unit_label, unit_combo))

        thousandsep_cb = QCheckBox(_("Add thousand separators to bitcoin amounts"))
        thousandsep_cb.setChecked(bool(self.config.get('amt_add_thousands_sep', False)))
        def on_set_thousandsep(v):
            checked = v == Qt.Checked
            if self.config.amt_add_thousands_sep != checked:
                self.config.amt_add_thousands_sep = checked
                self.config.set_key('amt_add_thousands_sep', checked)
                self.window.need_update.set()
        thousandsep_cb.stateChanged.connect(on_set_thousandsep)
        gui_widgets.append((thousandsep_cb, None))

        qr_combo = QComboBox()
        qr_combo.addItem("Default", "default")
        msg = (_("For scanning QR codes.") + "\n"
               + _("Install the zbar package to enable this."))
        qr_label = HelpLabel(_('Video Device') + ':', msg)
        from .qrreader import find_system_cameras
        system_cameras = find_system_cameras()
        for cam_desc, cam_path in system_cameras.items():
            qr_combo.addItem(cam_desc, cam_path)
        index = qr_combo.findData(self.config.get("video_device"))
        qr_combo.setCurrentIndex(index)
        on_video_device = lambda x: self.config.set_key("video_device", qr_combo.itemData(x), True)
        qr_combo.currentIndexChanged.connect(on_video_device)
        gui_widgets.append((qr_label, qr_combo))

        colortheme_combo = QComboBox()
        colortheme_combo.addItem(_('Light'), 'default')
        colortheme_combo.addItem(_('Dark'), 'dark')
        index = colortheme_combo.findData(self.config.get('qt_gui_color_theme', 'default'))
        colortheme_combo.setCurrentIndex(index)
        colortheme_label = QLabel(_('Color theme') + ':')
        def on_colortheme(x):
            self.config.set_key('qt_gui_color_theme', colortheme_combo.itemData(x), True)
            self.need_restart = True
        colortheme_combo.currentIndexChanged.connect(on_colortheme)
        gui_widgets.append((colortheme_label, colortheme_combo))

        updatecheck_cb = QCheckBox(_("Automatically check for software updates"))
        updatecheck_cb.setChecked(bool(self.config.get('check_updates', False)))
        def on_set_updatecheck(v):
            self.config.set_key('check_updates', v == Qt.Checked, save=True)
        updatecheck_cb.stateChanged.connect(on_set_updatecheck)
        gui_widgets.append((updatecheck_cb, None))

        filelogging_cb = QCheckBox(_("Write logs to file"))
        filelogging_cb.setChecked(bool(self.config.get('log_to_file', False)))
        def on_set_filelogging(v):
            self.config.set_key('log_to_file', v == Qt.Checked, save=True)
            self.need_restart = True
        filelogging_cb.stateChanged.connect(on_set_filelogging)
        filelogging_cb.setToolTip(_('Debug logs can be persisted to disk. These are useful for troubleshooting.'))
        gui_widgets.append((filelogging_cb, None))

        preview_cb = QCheckBox(_('Advanced preview'))
        preview_cb.setChecked(bool(self.config.get('advanced_preview', False)))
        preview_cb.setToolTip(_("Open advanced transaction preview dialog when 'Pay' is clicked."))
        def on_preview(x):
            self.config.set_key('advanced_preview', x == Qt.Checked)
        preview_cb.stateChanged.connect(on_preview)
        tx_widgets.append((preview_cb, None))

        usechange_cb = QCheckBox(_('Use change addresses'))
        usechange_cb.setChecked(self.window.wallet.use_change)
        if not self.config.is_modifiable('use_change'): usechange_cb.setEnabled(False)
        def on_usechange(x):
            usechange_result = x == Qt.Checked
            if self.window.wallet.use_change != usechange_result:
                self.window.wallet.use_change = usechange_result
                self.window.wallet.db.put('use_change', self.window.wallet.use_change)
                multiple_cb.setEnabled(self.window.wallet.use_change)
        usechange_cb.stateChanged.connect(on_usechange)
        usechange_cb.setToolTip(_('Using change addresses makes it more difficult for other people to track your transactions.'))
        tx_widgets.append((usechange_cb, None))

        def on_multiple(x):
            multiple = x == Qt.Checked
            if self.wallet.multiple_change != multiple:
                self.wallet.multiple_change = multiple
                self.wallet.db.put('multiple_change', multiple)
        multiple_change = self.wallet.multiple_change
        multiple_cb = QCheckBox(_('Use multiple change addresses'))
        multiple_cb.setEnabled(self.wallet.use_change)
        multiple_cb.setToolTip('\n'.join([
            _('In some cases, use up to 3 change addresses in order to break '
              'up large coin amounts and obfuscate the recipient address.'),
            _('This may result in higher transactions fees.')
        ]))
        multiple_cb.setChecked(multiple_change)
        multiple_cb.stateChanged.connect(on_multiple)
        tx_widgets.append((multiple_cb, None))

        def fmt_docs(key, klass):
            lines = [ln.lstrip(" ") for ln in klass.__doc__.split("\n")]
            return '\n'.join([key, "", " ".join(lines)])

        choosers = sorted(coinchooser.COIN_CHOOSERS.keys())
        if len(choosers) > 1:
            chooser_name = coinchooser.get_name(self.config)
            msg = _('Choose coin (UTXO) selection method.  The following are available:\n\n')
            msg += '\n\n'.join(fmt_docs(*item) for item in coinchooser.COIN_CHOOSERS.items())
            chooser_label = HelpLabel(_('Coin selection') + ':', msg)
            chooser_combo = QComboBox()
            chooser_combo.addItems(choosers)
            i = choosers.index(chooser_name) if chooser_name in choosers else 0
            chooser_combo.setCurrentIndex(i)
            def on_chooser(x):
                chooser_name = choosers[chooser_combo.currentIndex()]
                self.config.set_key('coin_chooser', chooser_name)
            chooser_combo.currentIndexChanged.connect(on_chooser)
            tx_widgets.append((chooser_label, chooser_combo))

        def on_unconf(x):
            self.config.set_key('confirmed_only', bool(x))
        conf_only = bool(self.config.get('confirmed_only', False))
        unconf_cb = QCheckBox(_('Spend only confirmed coins'))
        unconf_cb.setToolTip(_('Spend only confirmed inputs.'))
        unconf_cb.setChecked(conf_only)
        unconf_cb.stateChanged.connect(on_unconf)
        tx_widgets.append((unconf_cb, None))

        def on_outrounding(x):
            self.config.set_key('coin_chooser_output_rounding', bool(x))
        enable_outrounding = bool(self.config.get('coin_chooser_output_rounding', True))
        outrounding_cb = QCheckBox(_('Enable output value rounding'))
        outrounding_cb.setToolTip(
            _('Set the value of the change output so that it has similar precision to the other outputs.') + '\n' +
            _('This might improve your privacy somewhat.') + '\n' +
            _('If enabled, at most 100 satoshis might be lost due to this, per transaction.'))
        outrounding_cb.setChecked(enable_outrounding)
        outrounding_cb.stateChanged.connect(on_outrounding)
        tx_widgets.append((outrounding_cb, None))

        block_explorers = sorted(util.block_explorer_info().keys())
        BLOCK_EX_CUSTOM_ITEM = _("Custom URL")
        if BLOCK_EX_CUSTOM_ITEM in block_explorers:  # malicious translation?
            block_explorers.remove(BLOCK_EX_CUSTOM_ITEM)
        block_explorers.append(BLOCK_EX_CUSTOM_ITEM)
        msg = _('Choose which online block explorer to use for functions that open a web browser')
        block_ex_label = HelpLabel(_('Online Block Explorer') + ':', msg)
        block_ex_combo = QComboBox()
        block_ex_custom_e = QLineEdit(str(self.config.get('block_explorer_custom') or ''))
        block_ex_combo.addItems(block_explorers)
        block_ex_combo.setCurrentIndex(
            block_ex_combo.findText(util.block_explorer(self.config) or BLOCK_EX_CUSTOM_ITEM))
        def showhide_block_ex_custom_e():
            block_ex_custom_e.setVisible(block_ex_combo.currentText() == BLOCK_EX_CUSTOM_ITEM)
        showhide_block_ex_custom_e()
        def on_be_combo(x):
            if block_ex_combo.currentText() == BLOCK_EX_CUSTOM_ITEM:
                on_be_edit()
            else:
                be_result = block_explorers[block_ex_combo.currentIndex()]
                self.config.set_key('block_explorer_custom', None, False)
                self.config.set_key('block_explorer', be_result, True)
            showhide_block_ex_custom_e()
        block_ex_combo.currentIndexChanged.connect(on_be_combo)
        def on_be_edit():
            val = block_ex_custom_e.text()
            try:
                val = ast.literal_eval(val)  # to also accept tuples
            except:
                pass
            self.config.set_key('block_explorer_custom', val)
        block_ex_custom_e.editingFinished.connect(on_be_edit)
        block_ex_hbox = QHBoxLayout()
        block_ex_hbox.setContentsMargins(0, 0, 0, 0)
        block_ex_hbox.setSpacing(0)
        block_ex_hbox.addWidget(block_ex_combo)
        block_ex_hbox.addWidget(block_ex_custom_e)
        block_ex_hbox_w = QWidget()
        block_ex_hbox_w.setLayout(block_ex_hbox)
        tx_widgets.append((block_ex_label, block_ex_hbox_w))

        # Fiat Currency
        hist_checkbox = QCheckBox()
        hist_capgains_checkbox = QCheckBox()
        fiat_address_checkbox = QCheckBox()
        ccy_combo = QComboBox()
        ex_combo = QComboBox()

        def update_currencies():
            if not self.window.fx: return
            currencies = sorted(self.fx.get_currencies(self.fx.get_history_config()))
            ccy_combo.clear()
            ccy_combo.addItems([_('None')] + currencies)
            if self.fx.is_enabled():
                ccy_combo.setCurrentIndex(ccy_combo.findText(self.fx.get_currency()))

        def update_history_cb():
            if not self.fx: return
            hist_checkbox.setChecked(self.fx.get_history_config())
            hist_checkbox.setEnabled(self.fx.is_enabled())

        def update_fiat_address_cb():
            if not self.fx: return
            fiat_address_checkbox.setChecked(self.fx.get_fiat_address_config())

        def update_history_capgains_cb():
            if not self.fx: return
            hist_capgains_checkbox.setChecked(self.fx.get_history_capital_gains_config())
            hist_capgains_checkbox.setEnabled(hist_checkbox.isChecked())

        def update_exchanges():
            if not self.fx: return
            b = self.fx.is_enabled()
            ex_combo.setEnabled(b)
            if b:
                h = self.fx.get_history_config()
                c = self.fx.get_currency()
                exchanges = self.fx.get_exchanges_by_ccy(c, h)
            else:
                exchanges = self.fx.get_exchanges_by_ccy('USD', False)
            ex_combo.blockSignals(True)
            ex_combo.clear()
            ex_combo.addItems(sorted(exchanges))
            ex_combo.setCurrentIndex(ex_combo.findText(self.fx.config_exchange()))
            ex_combo.blockSignals(False)

        def on_currency(hh):
            if not self.fx: return
            b = bool(ccy_combo.currentIndex())
            ccy = str(ccy_combo.currentText()) if b else None
            self.fx.set_enabled(b)
            if b and ccy != self.fx.ccy:
                self.fx.set_currency(ccy)
            update_history_cb()
            update_exchanges()
            self.window.update_fiat()

        def on_exchange(idx):
            exchange = str(ex_combo.currentText())
            if self.fx and self.fx.is_enabled() and exchange and exchange != self.fx.exchange.name():
                self.fx.set_exchange(exchange)

        def on_history(checked):
            if not self.fx: return
            self.fx.set_history_config(checked)
            update_exchanges()
            self.window.history_model.refresh('on_history')
            if self.fx.is_enabled() and checked:
                self.fx.trigger_update()
            update_history_capgains_cb()

        def on_history_capgains(checked):
            if not self.fx: return
            self.fx.set_history_capital_gains_config(checked)
            self.window.history_model.refresh('on_history_capgains')

        def on_fiat_address(checked):
            if not self.fx: return
            self.fx.set_fiat_address_config(checked)
            self.window.address_list.refresh_headers()
            self.window.address_list.update()

        update_currencies()
        update_history_cb()
        update_history_capgains_cb()
        update_fiat_address_cb()
        update_exchanges()
        ccy_combo.currentIndexChanged.connect(on_currency)
        hist_checkbox.stateChanged.connect(on_history)
        hist_capgains_checkbox.stateChanged.connect(on_history_capgains)
        fiat_address_checkbox.stateChanged.connect(on_fiat_address)
        ex_combo.currentIndexChanged.connect(on_exchange)

        fiat_widgets = []
        fiat_widgets.append((QLabel(_('Fiat currency')), ccy_combo))
        fiat_widgets.append((QLabel(_('Source')), ex_combo))
        fiat_widgets.append((QLabel(_('Show history rates')), hist_checkbox))
        fiat_widgets.append((QLabel(_('Show capital gains in history')), hist_capgains_checkbox))
        fiat_widgets.append((QLabel(_('Show Fiat balance for addresses')), fiat_address_checkbox))

        tabs_info = [
            (gui_widgets, _('General')),
            (tx_widgets, _('Transactions')),
            (lightning_widgets, _('Lightning')),
            (fiat_widgets, _('Fiat')),
            (oa_widgets, _('OpenAlias')),
        ]
        for widgets, name in tabs_info:
            tab = QWidget()
            tab_vbox = QVBoxLayout(tab)
            grid = QGridLayout()
            for a,b in widgets:
                i = grid.rowCount()
                if b:
                    if a:
                        grid.addWidget(a, i, 0)
                    grid.addWidget(b, i, 1)
                else:
                    grid.addWidget(a, i, 0, 1, 2)
            tab_vbox.addLayout(grid)
            tab_vbox.addStretch(1)
            tabs.addTab(tab, name)

        vbox.addWidget(tabs)
        vbox.addStretch(1)
        vbox.addLayout(Buttons(CloseButton(self)))
        self.setLayout(vbox)
コード例 #57
0
class SubwindowBrowserSources(QWidget):
    """Show connections settings sub window."""
    current_tab = -1

    def createWindow(self, mainWindow, tab=''):
        """Create window."""
        try:
            parent = None
            super().__init__(parent)
            # self.setWindowFlags(Qt.WindowStaysOnTopHint)

            self.setWindowIcon(
                QIcon(scctool.settings.getResFile('browser.png')))
            self.setWindowModality(Qt.ApplicationModal)
            self.mainWindow = mainWindow
            self.passEvent = False
            self.controller = mainWindow.controller
            self.__dataChanged = False

            self.createButtonGroup()
            self.createTabs(tab)

            mainLayout = QVBoxLayout()

            mainLayout.addWidget(self.tabs)
            mainLayout.addLayout(self.buttonGroup)

            self.setLayout(mainLayout)

            self.resize(
                QSize(int(mainWindow.size().width() * 0.8),
                      self.sizeHint().height()))
            relativeChange = QPoint(int(mainWindow.size().width() / 2),
                                    int(mainWindow.size().height() / 3)) -\
                QPoint(int(self.size().width() / 2),
                       int(self.size().height() / 3))
            self.move(mainWindow.pos() + relativeChange)

            self.setWindowTitle(_("Browser Sources"))

        except Exception:
            module_logger.exception("message")

    def createTabs(self, tab):
        """Create tabs."""
        self.tabs = QTabWidget()

        self.createFormGroupIntro()
        self.createFormGroupMapstats()
        self.createFormGroupMapBox()
        self.createFormGroupMapLandscape()
        self.createFormGroupVetoes()

        # Add tabs
        self.tabs.addTab(self.formGroupIntro, _("Intros"))
        self.tabs.addTab(self.formGroupMapstats, _("Mapstats"))

        self.tabs.addTab(self.formGroupMapBox, _("Box Map Icons"))
        self.tabs.addTab(self.formGroupMapLandscape, _("Landscape Map Icons"))
        self.tabs.addTab(self.formGroupVetoes, _("Veto Icons"))

        table = dict()
        table['intro'] = 0
        table['mapstats'] = 1
        table['mapicons_box'] = 2
        table['mapicons_landscape'] = 3
        table['vetoes'] = 4
        self.tabs.setCurrentIndex(
            table.get(tab, SubwindowBrowserSources.current_tab))
        self.tabs.currentChanged.connect(self.tabChanged)

    @classmethod
    def tabChanged(cls, idx):
        """Save the current tab."""
        SubwindowBrowserSources.current_tab = idx

    def addHotkey(self, ident, label):
        """Add a hotkey to the layout."""
        element = HotkeyLayout(
            self, ident, label,
            scctool.settings.config.parser.get("Intros", ident))
        self.hotkeys[ident] = element
        return element

    def connectHotkeys(self):
        """Connect the hotkeys."""
        for ident, key in self.hotkeys.items():
            if ident == 'hotkey_debug':
                for ident2, key2 in self.hotkeys.items():
                    if ident == ident2:
                        continue
                    key.modified.connect(key2.check_dublicate)
            key.modified.connect(self.hotkeyChanged)

    def hotkeyChanged(self, key, ident):
        """Handle change of hotkeys."""
        self.changed()

        if (ident == 'hotkey_player1' and self.cb_single_hotkey.isChecked()):
            self.hotkeys['hotkey_player2'].setData(
                self.hotkeys['hotkey_player1'].getKey())

        if not key:
            return

        if ((ident == 'hotkey_player1'
             and key == self.hotkeys['hotkey_player2'].getKey()['name']) or
            (ident == 'hotkey_player2'
             and key == self.hotkeys['hotkey_player1'].getKey()['name'])):
            self.cb_single_hotkey.setChecked(True)

        if (ident in ['hotkey_player1', 'hotkey_player2']
                and key == self.hotkeys['hotkey_debug'].getKey()['name']):
            self.hotkeys['hotkey_debug'].clear()

    def singleHotkeyChanged(self):
        """Handle single hotkey changed event."""
        checked = self.cb_single_hotkey.isChecked()
        self.hotkeys['hotkey_player2'].setDisabled(checked)
        if checked:
            self.hotkeys['hotkey_player2'].setData(
                self.hotkeys['hotkey_player1'].getKey())
        elif (self.hotkeys['hotkey_player1'].getKey() ==
              self.hotkeys['hotkey_player2'].getKey()):
            self.hotkeys['hotkey_player2'].clear()

    def createFormGroupMapstats(self):
        """Create the form group for mapstats."""
        self.formGroupMapstats = QWidget()
        mainLayout = QVBoxLayout()

        box = QGroupBox(_("General"))
        layout = QFormLayout()

        container = QHBoxLayout()
        self.qb_boxStyle = StyleComboBox(
            scctool.settings.casting_html_dir + "/src/css/mapstats",
            "mapstats")
        self.qb_boxStyle.connect2WS(self.controller, 'mapstats')
        label = QLabel(_("Style:"))
        label.setMinimumWidth(120)
        button = QPushButton(_("Show in Browser"))
        button.clicked.connect(lambda: self.openHTML(
            scctool.settings.casting_html_dir + "/mapstats.html"))
        container.addWidget(self.qb_boxStyle, 2)
        container.addWidget(button, 1)
        layout.addRow(label, container)

        self.cb_mappool = QComboBox()
        self.cb_mappool.addItem(_("Current Ladder Map Pool"))
        self.cb_mappool.addItem(_("Custom Map Pool (defined below)"))
        self.cb_mappool.addItem(_("Currently entered Maps only"))
        self.cb_mappool.setCurrentIndex(
            self.controller.mapstatsManager.getMapPoolType())
        self.cb_mappool.currentIndexChanged.connect(self.changed)
        layout.addRow(QLabel(_("Map Pool:")), self.cb_mappool)

        self.cb_autoset_map = QCheckBox(_("Select the next map automatically"))
        self.cb_autoset_map.setChecked(
            scctool.settings.config.parser.getboolean("Mapstats",
                                                      "autoset_next_map"))
        self.cb_autoset_map.stateChanged.connect(self.changed)
        label = QLabel(_("Next Map:"))
        label.setMinimumWidth(120)
        layout.addRow(label, self.cb_autoset_map)

        self.cb_mark_played = QCheckBox(_("Mark already played maps"))
        self.cb_mark_played.setChecked(
            scctool.settings.config.parser.getboolean("Mapstats",
                                                      "mark_played"))
        self.cb_mark_played.stateChanged.connect(self.changed)
        label = QLabel(_("Mark:"))
        label.setMinimumWidth(120)
        layout.addRow(label, self.cb_mark_played)

        self.cb_mark_vetoed = QCheckBox(_("Mark vetoed maps"))
        self.cb_mark_vetoed.setChecked(
            scctool.settings.config.parser.getboolean("Mapstats",
                                                      "mark_vetoed"))
        self.cb_mark_vetoed.stateChanged.connect(self.changed)

        label = QLabel(" ")
        label.setMinimumWidth(120)
        layout.addRow(label, self.cb_mark_vetoed)

        self.cb_sort_maps = QCheckBox(_("Sort currently entered maps"))
        self.cb_sort_maps.setChecked(
            scctool.settings.config.parser.getboolean("Mapstats", "sort_maps"))
        self.cb_sort_maps.stateChanged.connect(self.changed)

        label = QLabel(_("Sort:"))
        label.setMinimumWidth(120)
        layout.addRow(label, self.cb_sort_maps)

        box.setLayout(layout)
        mainLayout.addWidget(box)

        box = QGroupBox(_("Custom Map Pool"))
        layout = QGridLayout()
        self.maplist = QListWidget()
        self.maplist.setSortingEnabled(True)

        ls = list(self.controller.mapstatsManager.getCustomMapPool())
        self.maplist.addItems(ls)
        self.maplist.setCurrentItem(self.maplist.item(0))

        layout.addWidget(self.maplist, 0, 0, 3, 1)

        qb_add = QPushButton()
        pixmap = QIcon(scctool.settings.getResFile('add.png'))
        qb_add.setIcon(pixmap)
        qb_add.clicked.connect(self.addMap)
        layout.addWidget(qb_add, 0, 1)

        qb_remove = QPushButton()
        pixmap = QIcon(scctool.settings.getResFile('delete.png'))
        qb_remove.clicked.connect(self.removeMap)
        qb_remove.setIcon(pixmap)
        layout.addWidget(qb_remove, 1, 1)

        self.sc_removeMap = QShortcut(QKeySequence("Del"), self)
        self.sc_removeMap.setAutoRepeat(False)
        self.sc_removeMap.activated.connect(self.removeMap)

        box.setLayout(layout)
        mainLayout.addWidget(box)

        mainLayout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding))
        self.formGroupMapstats.setLayout(mainLayout)

    def addMap(self):
        """Add a map to the list."""
        maplist = list(scctool.settings.maps)
        for i in range(self.maplist.count()):
            sc2map = str(self.maplist.item(i).text())
            if sc2map in maplist:
                maplist.remove(sc2map)

        if len(maplist) > 0:
            sc2map, ok = QInputDialog.getItem(self,
                                              _('Add Map'),
                                              _('Please select a map') + ':',
                                              maplist,
                                              editable=False)

            if ok:
                self.__dataChanged = True
                item = QListWidgetItem(sc2map)
                self.maplist.addItem(item)
                self.maplist.setCurrentItem(item)
        else:
            QMessageBox.information(
                self, _("No maps available"),
                _('All available maps have already been added.'))

    def removeMap(self):
        """Remove a map from the list."""
        item = self.maplist.currentItem()
        if item:
            self.maplist.takeItem(self.maplist.currentRow())
            self.__dataChanged = True

    def createFormGroupMapBox(self):
        """Create a QWidget for boxed map icons."""
        self.formGroupMapBox = QWidget()
        mainLayout = QVBoxLayout()
        box = QGroupBox(_("General"))
        layout = QFormLayout()

        container = QHBoxLayout()
        self.qb_boxStyle = StyleComboBox(
            scctool.settings.casting_html_dir + "/src/css/mapicons_box",
            "mapicons_box")
        self.qb_boxStyle.connect2WS(self.controller, 'mapicons_box')
        label = QLabel(_("Style:"))
        label.setMinimumWidth(120)
        button = QPushButton(_("Show in Browser"))
        button.clicked.connect(lambda: self.openHTML(
            scctool.settings.casting_html_dir + "/mapicons_box_1.html"))
        container.addWidget(self.qb_boxStyle, 2)
        container.addWidget(button, 1)
        layout.addRow(label, container)

        self.sb_padding_box = QDoubleSpinBox()
        self.sb_padding_box.setRange(0, 50)
        self.sb_padding_box.setDecimals(1)
        self.sb_padding_box.setValue(
            scctool.settings.config.parser.getfloat("MapIcons", "padding_box"))
        self.sb_padding_box.setSuffix(" " + _("Pixel"))
        self.sb_padding_box.valueChanged.connect(
            lambda x: self.changePadding('box', x))
        layout.addRow(QLabel(_("Icon Padding:") + " "), self.sb_padding_box)
        box.setLayout(layout)
        mainLayout.addWidget(box)

        options = self.controller.matchControl.scopes
        self.scope_box = dict()
        for idx in range(3):
            self.scope_box[idx] = ScopeGroupBox(
                _("Icon Set {} Scope".format(idx + 1)), options,
                f'box_{idx + 1}', self.controller, self)
            self.scope_box[idx].dataModified.connect(self.changed)
            mainLayout.addWidget(self.scope_box[idx])

        mainLayout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding))
        self.formGroupMapBox.setLayout(mainLayout)

    def createFormGroupVetoes(self):
        """Create a QWidget for veto icons."""
        self.formGroupVetoes = QWidget()
        mainLayout = QVBoxLayout()
        box = QGroupBox(_("General"))
        layout = QFormLayout()

        container = QHBoxLayout()
        self.qb_boxStyle = StyleComboBox(
            scctool.settings.casting_html_dir + "/src/css/vetoes", "vetoes")
        self.qb_boxStyle.connect2WS(self.controller, 'vetoes')
        label = QLabel(_("Style:"))
        label.setMinimumWidth(120)
        button = QPushButton(_("Show in Browser"))
        button.clicked.connect(lambda: self.openHTML(
            scctool.settings.casting_html_dir + "/vetoes.html"))
        container.addWidget(self.qb_boxStyle, 2)
        container.addWidget(button, 1)
        layout.addRow(label, container)

        self.sb_padding_box = QDoubleSpinBox()
        self.sb_padding_box.setRange(0, 50)
        self.sb_padding_box.setDecimals(1)
        self.sb_padding_box.setValue(
            scctool.settings.config.parser.getfloat("Vetoes", "padding"))
        self.sb_padding_box.setSuffix(" " + _("Pixel"))
        self.sb_padding_box.valueChanged.connect(
            lambda x: self.changePadding('vetoes', x))
        layout.addRow(QLabel(_("Icon Padding:") + " "), self.sb_padding_box)
        box.setLayout(layout)
        mainLayout.addWidget(box)

        mainLayout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding))
        self.formGroupVetoes.setLayout(mainLayout)

    def createFormGroupMapLandscape(self):
        """Create a QWidget for the landscape map icons."""
        self.formGroupMapLandscape = QWidget()
        mainLayout = QVBoxLayout()
        box = QGroupBox(_("General"))
        layout = QFormLayout()

        container = QHBoxLayout()
        self.qb_boxStyle = StyleComboBox(
            scctool.settings.casting_html_dir + "/src/css/mapicons_landscape",
            "mapicons_landscape")
        self.qb_boxStyle.connect2WS(self.controller, 'mapicons_landscape')
        label = QLabel(_("Style:"))
        label.setMinimumWidth(120)
        button = QPushButton(_("Show in Browser"))
        button.clicked.connect(lambda: self.openHTML(
            scctool.settings.casting_html_dir + "/mapicons_landscape_1.html"))
        container.addWidget(self.qb_boxStyle, 2)
        container.addWidget(button, 1)
        layout.addRow(label, container)

        self.sb_padding_landscape = QDoubleSpinBox()
        self.sb_padding_landscape.setRange(0, 50)
        self.sb_padding_landscape.setDecimals(1)
        self.sb_padding_landscape.setValue(
            scctool.settings.config.parser.getfloat("MapIcons",
                                                    "padding_landscape"))
        self.sb_padding_landscape.setSuffix(" " + _("Pixel"))
        self.sb_padding_landscape.valueChanged.connect(
            lambda x: self.changePadding('landscape', x))
        layout.addRow(QLabel(_("Icon Padding:") + " "),
                      self.sb_padding_landscape)
        box.setLayout(layout)
        mainLayout.addWidget(box)

        options = self.controller.matchControl.scopes
        self.scope_landscape = dict()
        for idx in range(3):
            self.scope_landscape[idx] = ScopeGroupBox(
                _("Icon Set {} Scope".format(idx + 1)), options,
                f'landscape_{idx + 1}', self.controller, self)
            self.scope_landscape[idx].dataModified.connect(self.changed)
            mainLayout.addWidget(self.scope_landscape[idx])

        mainLayout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding))
        self.formGroupMapLandscape.setLayout(mainLayout)

    def createFormGroupIntro(self):
        """Create forms for websocket connection to intro."""
        self.formGroupIntro = QWidget()
        mainLayout = QVBoxLayout()

        box = QGroupBox(_("Style"))
        layout = QHBoxLayout()
        styleqb = StyleComboBox(
            scctool.settings.casting_html_dir + "/src/css/intro", "intro")
        styleqb.connect2WS(self.controller, 'intro')
        button = QPushButton(_("Show in Browser"))
        button.clicked.connect(lambda: self.openHTML(
            scctool.settings.casting_html_dir + "/intro.html"))
        layout.addWidget(styleqb, 2)
        layout.addWidget(button, 1)
        box.setLayout(layout)
        mainLayout.addWidget(box)

        self.behaviorIntroBox = QGroupBox(_("Behavior"))
        layout = QVBoxLayout()
        self.cb_hardcode_players = QCheckBox(
            _("Read player names and order in 1vs1 mode from SCCT instead of SC2"
              ))
        self.cb_hardcode_players.setChecked(
            scctool.settings.config.parser.getboolean("Intros",
                                                      "hardcode_players"))
        self.cb_hardcode_players.stateChanged.connect(self.changed)
        layout.addWidget(self.cb_hardcode_players)
        self.behaviorIntroBox.setLayout(layout)
        mainLayout.addWidget(self.behaviorIntroBox)

        self.hotkeyBox = QGroupBox(_("Hotkeys"))
        layout = QVBoxLayout()
        self.controller.websocketThread.unregister_hotkeys(force=True)

        self.cb_single_hotkey = QCheckBox(
            _("Use a single hotkey for both players"))
        self.cb_single_hotkey.stateChanged.connect(self.singleHotkeyChanged)
        layout.addWidget(self.cb_single_hotkey)

        self.hotkeys = dict()
        layout.addLayout(self.addHotkey("hotkey_player1", _("Player 1")))
        layout.addLayout(self.addHotkey("hotkey_player2", _("Player 2")))
        layout.addLayout(self.addHotkey("hotkey_debug", _("Debug")))

        self.cb_single_hotkey.setChecked(self.hotkeys['hotkey_player1'].getKey(
        ) == self.hotkeys['hotkey_player2'].getKey())
        self.connectHotkeys()
        label = QLabel(
            _("Player 1 is always the player your observer"
              " camera is centered on at start of a game."))
        layout.addWidget(label)
        self.hotkeyBox.setLayout(layout)
        mainLayout.addWidget(self.hotkeyBox)

        self.introBox = QGroupBox(_("Animation"))
        layout = QFormLayout()
        self.cb_animation = QComboBox()
        animation = scctool.settings.config.parser.get("Intros", "animation")
        currentIdx = 0
        idx = 0
        options = dict()
        options['Fly-In'] = _("Fly-In")
        options['Slide'] = _("Slide")
        options['Fanfare'] = _("Fanfare")
        for key, item in options.items():
            self.cb_animation.addItem(item, key)
            if (key == animation):
                currentIdx = idx
            idx += 1
        self.cb_animation.setCurrentIndex(currentIdx)
        self.cb_animation.currentIndexChanged.connect(self.changed)
        label = QLabel(_("Animation:") + " ")
        label.setMinimumWidth(120)
        layout.addRow(label, self.cb_animation)
        self.sb_displaytime = QDoubleSpinBox()
        self.sb_displaytime.setRange(0, 10)
        self.sb_displaytime.setDecimals(1)
        self.sb_displaytime.setValue(
            scctool.settings.config.parser.getfloat("Intros", "display_time"))
        self.sb_displaytime.setSuffix(" " + _("Seconds"))
        self.sb_displaytime.valueChanged.connect(self.changed)
        layout.addRow(QLabel(_("Display Duration:") + " "),
                      self.sb_displaytime)
        self.sl_sound = QSlider(Qt.Horizontal)
        self.sl_sound.setMinimum(0)
        self.sl_sound.setMaximum(20)
        self.sl_sound.setValue(
            scctool.settings.config.parser.getint("Intros", "sound_volume"))
        self.sl_sound.setTickPosition(QSlider.TicksBothSides)
        self.sl_sound.setTickInterval(1)
        self.sl_sound.valueChanged.connect(self.changed)
        layout.addRow(QLabel(_("Sound Volume:") + " "), self.sl_sound)
        self.introBox.setLayout(layout)
        mainLayout.addWidget(self.introBox)

        self.ttsBox = QGroupBox(_("Text-to-Speech"))
        layout = QFormLayout()

        self.cb_tts_active = QCheckBox()
        self.cb_tts_active.setChecked(
            scctool.settings.config.parser.getboolean("Intros", "tts_active"))
        self.cb_tts_active.stateChanged.connect(self.changed)
        label = QLabel(_("Activate Text-to-Speech:") + " ")
        label.setMinimumWidth(120)
        layout.addRow(label, self.cb_tts_active)

        self.icons = {}
        self.icons['MALE'] = QIcon(scctool.settings.getResFile('male.png'))
        self.icons['FEMALE'] = QIcon(scctool.settings.getResFile('female.png'))
        self.cb_tts_voice = QComboBox()

        currentIdx = 0
        idx = 0
        tts_voices = self.controller.tts.getVoices()
        tts_voice = scctool.settings.config.parser.get("Intros", "tts_voice")
        for voice in tts_voices:
            self.cb_tts_voice.addItem(self.icons[voice['ssmlGender']],
                                      '   ' + voice['name'], voice['name'])
            if (voice['name'] == tts_voice):
                currentIdx = idx
            idx += 1
        self.cb_tts_voice.setCurrentIndex(currentIdx)
        self.cb_tts_voice.currentIndexChanged.connect(self.changed)
        layout.addRow(QLabel(_("Voice:") + " "), self.cb_tts_voice)
        self.ttsBox.setStyleSheet("QComboBox { combobox-popup: 0; }")
        self.ttsBox.setLayout(layout)
        mainLayout.addWidget(self.ttsBox)

        self.sb_tts_pitch = QDoubleSpinBox()
        self.sb_tts_pitch.setRange(-20, 20)
        self.sb_tts_pitch.setDecimals(2)
        self.sb_tts_pitch.setValue(
            scctool.settings.config.parser.getfloat("Intros", "tts_pitch"))
        self.sb_tts_pitch.valueChanged.connect(self.changed)
        layout.addRow(QLabel(_("Pitch:") + " "), self.sb_tts_pitch)

        self.sb_tts_rate = QDoubleSpinBox()
        self.sb_tts_rate.setRange(0.25, 4.00)
        self.sb_tts_rate.setSingleStep(0.1)
        self.sb_tts_rate.setDecimals(2)
        self.sb_tts_rate.setValue(
            scctool.settings.config.parser.getfloat("Intros", "tts_rate"))
        self.sb_tts_rate.valueChanged.connect(self.changed)
        layout.addRow(QLabel(_("Rate:") + " "), self.sb_tts_rate)

        self.cb_tts_scope = QComboBox()
        scope = scctool.settings.config.parser.get("Intros", "tts_scope")
        currentIdx = 0
        idx = 0
        options = self.controller.tts.getOptions()
        for key, item in options.items():
            self.cb_tts_scope.addItem(item['desc'], key)
            if (key == scope):
                currentIdx = idx
            idx += 1
        self.cb_tts_scope.setCurrentIndex(currentIdx)
        self.cb_tts_scope.currentIndexChanged.connect(self.changed)
        layout.addRow(QLabel(_("Line:") + " "), self.cb_tts_scope)

        self.sl_tts_sound = QSlider(Qt.Horizontal)
        self.sl_tts_sound.setMinimum(0)
        self.sl_tts_sound.setMaximum(20)
        self.sl_tts_sound.setValue(
            scctool.settings.config.parser.getint("Intros", "tts_volume"))
        self.sl_tts_sound.setTickPosition(QSlider.TicksBothSides)
        self.sl_tts_sound.setTickInterval(1)
        self.sl_tts_sound.valueChanged.connect(self.changed)
        layout.addRow(QLabel(_("Sound Volume:") + " "), self.sl_tts_sound)

        text = _(
            "Text-to-Speech provided by Google-Cloud is paid for "
            "by StarCraft Casting Tool Patrons. To keep this service up "
            "consider becoming a <a href='{patreon}'>Patron</a> yourself. "
            "You can test all voices at {tts}.")

        patreon = 'https://www.patreon.com/StarCraftCastingTool'

        url = 'https://cloud.google.com/text-to-speech/'
        tts = "<a href='{}'>cloud.google.com/text-to-speech</a>"
        tts = tts.format(url)

        label = QLabel(text.format(patreon=patreon, tts=tts))
        label.setAlignment(Qt.AlignJustify)
        label.setOpenExternalLinks(True)
        label.setWordWrap(True)
        label.setMargin(5)
        layout.addRow(label)

        mainLayout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding))
        self.formGroupIntro.setLayout(mainLayout)

    def createButtonGroup(self):
        """Create buttons."""
        try:
            layout = QHBoxLayout()

            layout.addWidget(QLabel(""))

            buttonCancel = QPushButton(_('Cancel'))
            buttonCancel.clicked.connect(self.closeWindow)
            layout.addWidget(buttonCancel)

            buttonSave = QPushButton(_('&Save && Close'))
            buttonSave.setToolTip(_("Shortcut: {}").format("Ctrl+S"))
            self.shortcut = QShortcut(QKeySequence("Ctrl+S"), self)
            self.shortcut.setAutoRepeat(False)
            self.shortcut.activated.connect(self.saveCloseWindow)
            buttonSave.clicked.connect(self.saveCloseWindow)
            layout.addWidget(buttonSave)

            self.buttonGroup = layout
        except Exception:
            module_logger.exception("message")

    def changed(self, *values):
        """Handle changed data."""
        self.__dataChanged = True

    def saveData(self):
        """Save the data to config."""
        if (self.__dataChanged):
            self.saveWebsocketdata()

            maps = list()
            for i in range(self.maplist.count()):
                maps.append(str(self.maplist.item(i).text()).strip())

            self.controller.mapstatsManager.setCustomMapPool(maps)
            self.controller.mapstatsManager.setMapPoolType(
                self.cb_mappool.currentIndex())

            scctool.settings.config.parser.set(
                "Mapstats", "autoset_next_map",
                str(self.cb_autoset_map.isChecked()))

            scctool.settings.config.parser.set(
                "Mapstats", "mark_played",
                str(self.cb_mark_played.isChecked()))

            scctool.settings.config.parser.set(
                "Mapstats", "mark_vetoed",
                str(self.cb_mark_vetoed.isChecked()))

            scctool.settings.config.parser.set(
                "Mapstats", "sort_maps", str(self.cb_sort_maps.isChecked()))

            scctool.settings.config.parser.set(
                "Intros", "hardcode_players",
                str(self.cb_hardcode_players.isChecked()))

            self.controller.mapstatsManager.sendMapPool()
            self.mainWindow.updateAllMapButtons()

            for idx in range(3):
                scctool.settings.config.parser.set(
                    "MapIcons", "scope_box_{}".format(idx + 1),
                    self.scope_box[idx].getScope())
                scctool.settings.config.parser.set(
                    "MapIcons", "scope_landscape_{}".format(idx + 1),
                    self.scope_landscape[idx].getScope())
            self.controller.matchMetaDataChanged()
            self.__dataChanged = False
            # self.controller.refreshButtonStatus()

    def saveWebsocketdata(self):
        """Save Websocket data."""
        for ident, key in self.hotkeys.items():
            string = scctool.settings.config.dumpHotkey(key.getKey())
            scctool.settings.config.parser.set("Intros", ident, string)
        scctool.settings.config.parser.set("Intros", "display_time",
                                           str(self.sb_displaytime.value()))
        scctool.settings.config.parser.set("Intros", "sound_volume",
                                           str(self.sl_sound.value()))
        scctool.settings.config.parser.set(
            "Intros", "animation",
            self.cb_animation.currentData().strip())
        scctool.settings.config.parser.set(
            "Intros", "tts_voice",
            '' if self.cb_tts_voice.currentData() is None else
            self.cb_tts_voice.currentData().strip())
        scctool.settings.config.parser.set(
            "Intros", "tts_scope",
            self.cb_tts_scope.currentData().strip())
        scctool.settings.config.parser.set("Intros", "tts_active",
                                           str(self.cb_tts_active.isChecked()))
        scctool.settings.config.parser.set("Intros", "tts_volume",
                                           str(self.sl_tts_sound.value()))
        scctool.settings.config.parser.set("Intros", "tts_pitch",
                                           str(self.sb_tts_pitch.value()))
        scctool.settings.config.parser.set("Intros", "tts_rate",
                                           str(self.sb_tts_rate.value()))

    def openHTML(self, file):
        """Open file in browser."""
        self.controller.openURL(scctool.settings.getAbsPath(file))

    def changePadding(self, scope, padding):
        """Change the padding."""
        if scope == 'vetoes':
            scctool.settings.config.parser.set("Vetoes", "padding",
                                               str(padding))
            self.controller.websocketThread.changePadding("vetoes", padding)
        else:
            scctool.settings.config.parser.set("MapIcons", f"padding_{scope}",
                                               str(padding))
            self.controller.websocketThread.changePadding(
                f"mapicons_{scope}", padding)

    def saveCloseWindow(self):
        """Save and close window."""
        self.saveData()
        self.closeWindow()

    def closeWindow(self):
        """Close window without save."""
        self.passEvent = True
        self.close()

    def closeEvent(self, event):
        """Handle close event."""
        try:
            if (not self.__dataChanged):
                self.controller.updateHotkeys()
                event.accept()
                return
            if (not self.passEvent):
                if (self.isMinimized()):
                    self.showNormal()
                buttonReply = QMessageBox.question(
                    self, _('Save data?'), _("Do you want to save the data?"),
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                if buttonReply == QMessageBox.Yes:
                    self.saveData()
            self.controller.updateHotkeys()
            event.accept()
        except Exception:
            module_logger.exception("message")
コード例 #58
0
ファイル: testgui.py プロジェクト: adriane0523/Bridge2Africa
class WidgetGallery(QDialog):
    def __init__(self, parent=None):
        super(WidgetGallery, self).__init__(parent)

        self.originalPalette = QApplication.palette()

        styleComboBox = QComboBox()
        styleComboBox.addItems(QStyleFactory.keys())

        styleLabel = QLabel("&Style:")
        styleLabel.setBuddy(styleComboBox)

        self.useStylePaletteCheckBox = QCheckBox(
            "&Use style's standard palette")
        self.useStylePaletteCheckBox.setChecked(True)

        disableWidgetsCheckBox = QCheckBox("&Disable widgets")

        self.createTopLeftGroupBox()
        self.createTopRightGroupBox()
        self.createBottomLeftTabWidget()
        self.createBottomRightGroupBox()

        mainLayout = QGridLayout()
        mainLayout.addWidget(self.topLeftGroupBox, 1, 0)
        mainLayout.addWidget(self.topRightGroupBox, 1, 1)
        mainLayout.addWidget(self.bottomLeftTabWidget, 2, 0)
        mainLayout.addWidget(self.bottomRightGroupBox, 2, 1)
        mainLayout.setRowStretch(1, 1)
        mainLayout.setRowStretch(2, 1)
        mainLayout.setColumnStretch(0, 1)
        mainLayout.setColumnStretch(1, 1)
        self.setLayout(mainLayout)

        self.setWindowTitle("Bridge2Africa")
        self.changeStyle('Windows')

    def changeStyle(self, styleName):
        QApplication.setStyle(QStyleFactory.create(styleName))
        self.changePalette()

    def changePalette(self):
        if (self.useStylePaletteCheckBox.isChecked()):
            QApplication.setPalette(QApplication.style().standardPalette())
        else:
            QApplication.setPalette(self.originalPalette)

    def createTopLeftGroupBox(self):
        self.topLeftGroupBox = QGroupBox("Select Mode")

        radioButton1 = QRadioButton("Tutorial Mode")
        radioButton2 = QRadioButton("Active Mode: Both audio and Braille")
        radioButton3 = QRadioButton("Passive Mode: Braille")
        radioButton1.setChecked(True)

        checkBox = QCheckBox("Include Assessibility Rating in Search Results")
        checkBox.setTristate(True)
        checkBox.setCheckState(Qt.PartiallyChecked)

        layout = QVBoxLayout()
        layout.addWidget(radioButton1)
        layout.addWidget(radioButton2)
        layout.addWidget(radioButton3)
        layout.addWidget(checkBox)
        layout.addStretch(1)
        self.topLeftGroupBox.setLayout(layout)

    def createTopRightGroupBox(self):
        self.topRightGroupBox = QGroupBox("Some sample buttons")

        nameLabel_1 = QLabel(self)
        nameLabel_1.setText('Read Braille:')
        line_1 = QLineEdit(self)
        line_1.setText("test")

        nameLabel_2 = QLabel(self)
        nameLabel_2.setText('Activate Arduino:')
        line_2 = QLineEdit(self)

        nameLabel_3 = QLabel(self)
        nameLabel_3.setText('Navgiation:')
        line_3 = QLineEdit(self)

        nameLabel_4 = QLabel(self)
        nameLabel_4.setText('Acccessibility:')
        line_4 = QLineEdit(self)

        nameLabel_5 = QLabel(self)
        nameLabel_5.setText('Hierarchy:')
        line_5 = QLineEdit(self)

        nameLabel_6 = QLabel(self)
        nameLabel_6.setText('Minus Index:')
        line_6 = QLineEdit(self)

        nameLabel_7 = QLabel(self)
        nameLabel_7.setText('Plus Index:')
        line_7 = QLineEdit(self)

        nameLabel_8 = QLabel(self)
        nameLabel_8.setText('Speak:')
        line_8 = QLineEdit(self)

        nameLabel_9 = QLabel(self)
        nameLabel_9.setText('Braille Read Quit:')
        line_9 = QLineEdit(self)

        nameLabel_10 = QLabel(self)
        nameLabel_10.setText('Braille Read Contiue:')
        line_10 = QLineEdit(self)

        layout = QVBoxLayout()
        layout.addWidget(nameLabel_1)
        layout.addWidget(line_1)
        layout.addWidget(nameLabel_2)
        layout.addWidget(line_2)
        layout.addWidget(nameLabel_3)
        layout.addWidget(line_3)
        layout.addWidget(nameLabel_4)
        layout.addWidget(line_4)
        layout.addWidget(nameLabel_5)
        layout.addWidget(line_5)
        layout.addWidget(nameLabel_6)
        layout.addWidget(line_6)
        layout.addWidget(nameLabel_7)
        layout.addWidget(line_7)
        layout.addWidget(nameLabel_8)
        layout.addWidget(line_8)
        layout.addWidget(nameLabel_9)
        layout.addWidget(line_9)
        layout.addWidget(nameLabel_10)
        layout.addWidget(line_10)
        layout.addStretch(1)
        self.topRightGroupBox.setLayout(layout)

    def createBottomLeftTabWidget(self):
        self.bottomLeftTabWidget = QTabWidget()
        self.bottomLeftTabWidget.setSizePolicy(QSizePolicy.Preferred,
                                               QSizePolicy.Ignored)

        tab1 = QWidget()
        tableWidget = QTableWidget(10, 10)

        tab1hbox = QHBoxLayout()
        tab1hbox.setContentsMargins(5, 5, 5, 5)
        tab1hbox.addWidget(tableWidget)
        tab1.setLayout(tab1hbox)

        tab2 = QWidget()
        textEdit = QTextEdit()

        textEdit.setPlainText(
            "Test your Braille display and audio output. \n Enter sample text here.\n"
        )

        tab2hbox = QHBoxLayout()
        tab2hbox.setContentsMargins(5, 5, 5, 5)
        tab2hbox.addWidget(textEdit)
        tab2.setLayout(tab2hbox)

        self.bottomLeftTabWidget.addTab(tab2, "Calibrate")

    def createBottomRightGroupBox(self):
        self.bottomRightGroupBox = QGroupBox("Audio Speed")

        lineEdit = QLineEdit('s3cRe7')
        lineEdit.setEchoMode(QLineEdit.Password)

        spinBox = QSpinBox(self.bottomRightGroupBox)
        spinBox.setValue(50)

        slider = QSlider(Qt.Horizontal, self.bottomRightGroupBox)
        slider.setValue(40)

        scrollBar = QScrollBar(Qt.Horizontal, self.bottomRightGroupBox)
        scrollBar.setValue(60)

        dial = QDial(self.bottomRightGroupBox)
        dial.setValue(30)
        dial.setNotchesVisible(True)

        layout = QGridLayout()
        layout.addWidget(spinBox, 1, 0, 1, 2)
        layout.addWidget(slider, 3, 0)
        layout.addWidget(scrollBar, 4, 0)
        layout.addWidget(dial, 3, 1, 2, 1)
        self.bottomRightGroupBox.setLayout(layout)
コード例 #59
0
class MainWindow(QMainWindow):
    """Main Window for the application"""
    def __init__(self):
        super().__init__()
        self.tabs = QTabWidget(self)
        self.tabs.setMovable(True)
        self.tabs.setTabsClosable(True)
        self.tabs.tabCloseRequested.connect(self.close_tab)
        self.setCentralWidget(self.tabs)

        self.last_open_directory = ''
        self.last_save_directory = ''

        self.setWindowTitle('Melee Dat Editor')
        self.setWindowIcon(QIcon('resources/icon-256.ico'))
        self.statusBar().showMessage('')  # enable status bar
        self.setup_menus()

        self.setAcceptDrops(True)

        self.resize(QSize(640, 480))
        self.show()

    def setup_menus(self):
        menubar = self.menuBar()
        style = self.style()
        file_menu = menubar.addMenu('File')
        open_action = file_menu.addAction(
            style.standardIcon(QStyle.SP_DialogOpenButton), 'Open PlXx.dat...')
        open_action.setShortcut(QKeySequence('Ctrl+O'))
        open_action.triggered.connect(self.open_file_dialog)
        #        open_action.setStatusTip('Open a dat file')

        save_action = file_menu.addAction(
            style.standardIcon(QStyle.SP_DialogSaveButton), 'Save')
        save_action.setShortcut(QKeySequence('Ctrl+S'))
        save_action.triggered.connect(self.save)

        saveas_action = file_menu.addAction(
            style.standardIcon(QStyle.SP_DialogSaveButton), 'Save As...')
        saveas_action.setShortcut(QKeySequence('Ctrl+Shift+S'))
        saveas_action.triggered.connect(self.saveas)
        file_menu.addSeparator()

        reload_action = file_menu.addAction(
            style.standardIcon(QStyle.SP_BrowserReload), 'Reload From Disk')
        reload_action.triggered.connect(self.reload)

        close_action = file_menu.addAction(
            style.standardIcon(QStyle.SP_DialogCloseButton), 'Close')
        close_action.triggered.connect(self.close_current)

        help_menu = menubar.addMenu('Help')
        about_action = help_menu.addAction(
            style.standardIcon(QStyle.SP_MessageBoxInformation), 'About...')
        about_action.triggered.connect(self.about)

    def open_file_dialog(self):
        """Spawn an open file dialog and open the selected dat file"""
        fname = QFileDialog.getOpenFileName(
            self, 'Open Moveset File', self.last_open_directory,
            'Moveset dat files (*.dat);;All Files (*.*)')[0]
        if fname:
            self.open_file(fname)

    def open_file(self, fname):
        # TODO: when DatEx is implemented, replace MoveSetDatFile
        # constructor with a factory that examines the file and returns
        # an instance of the correct class, standard vs ex (vs other?)
        # and probably also updates old ex versions to newer ones
        # if necessary
        try:
            e = MovesetDatEditor(fname, self.last_save_directory, self)
        except Exception:
            import traceback
            print(traceback.format_exc())
            mbox = QMessageBox(self)
            mbox.setWindowTitle(self.windowTitle())
            mbox.setText(f"Error opening {fname}.\n\n" +
                         traceback.format_exc())
            mbox.exec_()
            return
        self.last_open_directory = os.path.dirname(fname)
        self.tabs.addTab(e, os.path.basename(fname))
        self.tabs.setCurrentWidget(e)
        self.updateGeometry()
        self.resize(self.sizeHint())
        QApplication.instance().processEvents()

    def save(self):
        if self.current_editor():
            self.current_editor().save()

    def saveas(self):
        if self.current_editor():
            self.current_editor().saveas()

    def reload(self):
        if self.current_editor():
            self.current_editor().reload()

    def current_editor(self):
        return self.tabs.currentWidget()

    def close_tab(self, index):
        e = self.tabs.widget(index)
        self.tabs.removeTab(index)
        if e:
            e.close()

    def close_current(self):
        self.close_tab(self.tabs.currentIndex())

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

    def dropEvent(self, event):
        for url in event.mimeData().urls():
            fname = url.toLocalFile()
            if os.path.isfile(fname):
                self.open_file(fname)

    def about(self):
        mbox = QMessageBox(self)
        mbox.setText(ABOUT_TEXT)
        mbox.setWindowTitle(self.windowTitle())
        mbox.exec_()
コード例 #60
0
class pl_main(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.main_vbox = QVBoxLayout()

        self.setWindowIcon(icon_get("preferences-system"))

        self.setWindowTitle(
            _("Luminescence editor") + " (https://www.gpvdm.com)")

        toolbar = QToolBar()
        toolbar.setIconSize(QSize(48, 48))

        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        toolbar.addWidget(spacer)

        self.help = QAction(icon_get("help"), _("Help"), self)
        self.help.setStatusTip(_("Help"))
        self.help.triggered.connect(self.callback_help)
        toolbar.addAction(self.help)

        self.main_vbox.addWidget(toolbar)

        self.notebook = QTabWidget()

        css_apply(self, "tab_default.css")

        self.main_vbox.addWidget(self.notebook)
        self.setLayout(self.main_vbox)

        self.notebook.setTabsClosable(True)
        self.notebook.setMovable(True)
        bar = QHTabBar()
        bar.setStyleSheet("QTabBar::tab { height: 35px; width: 200px; }")
        self.notebook.setTabBar(bar)
        self.notebook.setTabPosition(QTabWidget.West)

        global_object_register("pl_update", self.update)

        self.update()

    def update(self):
        self.notebook.clear()

        files = epitaxy_get_dos_files()
        for i in range(0, epitaxy_get_layers()):
            pl_file = epitaxy_get_pl_file(i)
            if pl_file.startswith("pl") == True:
                widget = QWidget()

                name = _("Luminescence of ") + epitaxy_get_name(i)

                widget = tab_class(pl_file + ".inp")

                self.notebook.addTab(widget, name)

    def callback_help(self, widget):
        webbrowser.open('http://www.gpvdm.com/man/index.html')

    def help(self):
        help_window().help_set_help([
            "tab.png",
            _("<big><b>Luminescence</b></big>\nIf you set 'Turn on luminescence' to true, the simulation will assume recombination is a raditave process and intergrate it to produce Voltage-Light intensity curves (lv.dat).  Each number in the tab tells the model how efficient each recombination mechanism is at producing photons."
              )
        ])