示例#1
0
class Cart_Pay(QWidget):

    #Initialiaze the first page for class View_Menu_First_Page()
    def __init__(self,parent=None):
        super(Cart_Pay,self).__init__(parent)
        self.resize(800,600)
        self.stackedwidget = QStackedWidget(self)
        self.stackedwidget.setGeometry(QtCore.QRect(0,0 , 800, 600))
        self.stackedwidget.setObjectName("stackwidget")

        self.add_first_page()

    #function to show first page
    def add_first_page(self):
        self.first_page = Pay_First_Page()
        self.stackedwidget.addWidget(self.first_page)
        self.stackedwidget.setCurrentIndex(0)
        print(self.first_page.tableWidget.rowCount())
        self.first_page.BlueButton.clicked.connect(self.add_second_page) #only can use lambda: to make use of return value form functions

    #function to show second page
    def add_second_page(self):
        self.second_page = See_Waiting_Time()
        self.stackedwidget.addWidget(self.second_page)
        self.stackedwidget.setCurrentIndex(1)
示例#2
0
 def init_main_stacked_widget(self):
     """
     create and return the main stackedWidget object
     """
     stacked_widget = QStackedWidget(self)
     stacked_widget.setObjectName(u"stacked_widget")
     stacked_widget.setGeometry(QRect(0, 0, WINDOW_HEIGHT, WINDOW_WIDTH))
     return stacked_widget
示例#3
0
 def _initUI(self):
     self.toolbar = None
     w = QStackedWidget()
     w.setObjectName('block-principal')
     self.setCentralWidget(w)
     style = PARAMETERS["MAIN_STYLE"] + PARAMETERS["WIDGETS_STYLE"]
     self.setStyleSheet(style)
     self.setWindowTitle(self.WINDOW_TITLE)
     self.setWindowIcon(AppIcon())
     self.move(200, 200)
示例#4
0
class View_Menu(QWidget):

    #Initialiaze the first page for class View_Menu_First_Page()
    def __init__(self,parent=None):
        super(View_Menu,self).__init__(parent)
        self.resize(800,600)
        self.stackedwidget = QStackedWidget(self)
        self.stackedwidget.setGeometry(QtCore.QRect(0,0 , 800, 600))
        self.stackedwidget.setObjectName("stackwidget")
        self.add_first_page()

    #function to show first page
    def add_first_page(self):
        self.first_page = View_Menu_First_Page()
        self.stackedwidget.addWidget(self.first_page)
        self.stackedwidget.setCurrentIndex(0)
        self.first_page.label_malay.clicked.connect(lambda:self.add_second_page(self.first_page.MY_link_click())) #only can use lambda: to make use of return value form functions
        self.first_page.label_mcdonalds.clicked.connect(lambda:self.add_second_page(self.first_page.MC_link_click())) #only can use lambda: to make use of return value form functions
        self.first_page.label_kfc.clicked.connect(lambda:self.add_second_page(self.first_page.KFC_link_click())) #only can use lambda: to make use of return value form functions
        self.first_page.label_subway.clicked.connect(lambda:self.add_second_page(self.first_page.Subway_link_click())) #only can use lambda: to make use of return value form functions

    #function to show second page
    def add_second_page(self,store):
        self.second_page = View_Menu_Second_Page(store)
        self.stackedwidget.addWidget(self.second_page)
        self.stackedwidget.setCurrentIndex(1)
        if 'Subway' in self.second_page.Logo.text():
            print('Logo')
            self.second_page.BlueButton.clicked.connect(lambda:self.add_third_page(self.first_page.Subway_link_click(),self.second_page.SearchMenu()))
        elif 'Malay' in self.second_page.Logo.text():
            print('Malay logo')
            self.second_page.BlueButton.clicked.connect(lambda:self.add_third_page(self.first_page.MY_link_click(),self.second_page.SearchMenu()))
        elif 'Mcdonalds' in self.second_page.Logo.text():
            print('Mcdonalds Logo')
            self.second_page.BlueButton.clicked.connect(lambda:self.add_third_page(self.first_page.Mc_link_click(),self.second_page.SearchMenu()))
        elif 'KFC' in self.second_page.Logo.text():
            print('KFC Logo')
            self.second_page.BlueButton.clicked.connect(lambda:self.add_third_page(self.first_page.KFC_link_click(),self.second_page.SearchMenu()))
            
    #function to show third page
    def add_third_page(self,store,date_and_time):
        self.third_page = View_Menu_Third_Page(store,date_and_time)
        self.stackedwidget.addWidget(self.third_page)
        self.stackedwidget.setCurrentIndex(2)
        #kfcCombine.KFC_breakfast_window.BlueButton_2.clicked.connect(self.go_back)
        self.third_page.BlueButton_2.clicked.connect(self.go_back)

    def go_back(self):
        self.stackedwidget.setCurrentIndex(0)
        self.stackedwidget.removeWidget(self.second_page)
        self.stackedwidget.removeWidget(self.third_page)
示例#5
0
class salUI(object):
    def __init__(self):
        super(salUI).__init__()

    def setupUI(self, MainWindow):

        MainWindow.setWindowIcon(QIcon("icons/saldb_red"))
        MainWindow.setWindowTitle("Simple Anime Library   |   ヽ( ´ー`)ノ")

        # setup menubar

        menubar = MainWindow.menuBar()

        self.mb_file = menubar.addMenu("File")
        self.mb_edit = menubar.addMenu("Edit")
        self.mb_view = menubar.addMenu("View")
        self.mb_help = menubar.addMenu("Help")

        # menubar file menu

        self.mb_newAction = QAction("New Entry", MainWindow)
        self.mb_file.addAction(self.mb_newAction)

        # menubar edit menu

        self.mb_editEntryAction = QAction("Edit Entry", MainWindow)
        self.mb_edit.addAction(self.mb_editEntryAction)

        # menubar view menu

        # TODO

        # menubar help menu

        # TODO

        # Toolbar

        self.toolbar = QToolBar(MainWindow)
        self.toolbar.setIconSize(QSize(40, 40))

        MainWindow.addToolBar(self.toolbar)

        self.addnewAction = QAction(QIcon("icons/add_1.png"),
                                    "Create New Entry", MainWindow)
        self.addnewAction.setShortcut('Ctrl+N')

        self.toolbar.addAction(self.addnewAction)

        self.deleteAction = QAction(QIcon("icons/delete_1.png"),
                                    "Delete Entry", MainWindow)
        self.deleteAction.setShortcut("Ctrl+D")

        self.toolbar.addAction(self.deleteAction)

        self.editAction = QAction(QIcon("icons/edit.png"), "Edit Entry",
                                  MainWindow)
        self.editAction.setShortcut("Ctrl+E")

        self.toolbar.addAction(self.editAction)

        self.toolbar.addSeparator()

        self.findAction = QAction(QIcon("icons/find.png"), "Search",
                                  MainWindow)
        self.findAction.setShortcut("Ctrl+F")

        self.toolbar.addAction(self.findAction)

        self.queryAction = QAction(QIcon("icons/filter.png"), "Filter/Sort",
                                   MainWindow)
        self.queryAction.setShortcut("Ctrl+Alt+Q")

        self.toolbar.addAction(self.queryAction)

        self.toolbar.addSeparator()

        self.settingsAction = QAction(QIcon("icons/settings.png"),
                                      "App Settings", MainWindow)
        self.settingsAction.setShortcut("Ctrl+Shift+S")

        self.toolbar.addAction(self.settingsAction)

        self.infoAction = QAction(QIcon("icons/info.png"), "App Info",
                                  MainWindow)

        self.toolbar.addAction(self.infoAction)

        #############################################################################################################

        self.centralWidget = QWidget(MainWindow)
        self.centralWidget.setObjectName('central')

        self.splitter = QSplitter(self.centralWidget)
        self.splitter.setOrientation(Qt.Horizontal)
        self.splitter.setStretchFactor(0, 25)
        self.splitter.setStretchFactor(1, 75)

        # sidebar (QListWidget)

        self.sidebar = QListWidget(self.splitter)
        self.sidebar.setObjectName('sidebar')
        self.sidebar.addItem('Fin.')
        self.sidebar.addItem('Planned')
        self.sidebar.addItem('Ongoing')
        self.sidebar.addItem('Current')
        self.sidebar.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)

        # [nevermind lol] pretty sure i dont need this here, it should be created in the backend and added to the stack.
        self.watchListTable = QTableWidget()
        self.watchListTable.setObjectName('watchListTable')
        self.watchListTable.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.watchListTable.setSelectionMode(QAbstractItemView.SingleSelection)
        self.watchListTable.setContextMenuPolicy(Qt.CustomContextMenu)
        self.watchListTable.customContextMenuRequested.connect(
            self.tableContextMenu)
        self.watchListTable.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.watchListTable.setFont(QFont('Arial', 14))
        self.watchListTable.setWordWrap(False)
        #self.watchListTable.setTextAlignment(Qt.AlignCenter)
        self.watchListTable.setColumnCount(7)

        self.watchListTable.setHorizontalHeaderLabels([
            "Art", "Title", "English Title", "SUB/DUB", "Start Date",
            "Completion Date", "Series Type"
        ])
        self.watchListTable.verticalHeader().setDefaultSectionSize(140)
        self.watchListTable.horizontalHeader().setDefaultSectionSize(120)

        # stackwidget to switch contents of list catagories

        self.tableStack = QStackedWidget(self.splitter)
        self.tableStack.setObjectName('tablestack')

        self.tableStack.addWidget(self.watchListTable)

        # add widgets to splitter

        self.splitter.addWidget(self.sidebar)
        self.splitter.addWidget(self.tableStack)

        self.splitter.setSizes([50, 650])

        ########################################################################################################
        ########################################################################################################

        self.boxLayout = QHBoxLayout()
        self.centralWidget.setLayout(self.boxLayout)
        MainWindow.setCentralWidget(self.centralWidget)

        self.boxLayout.addWidget(self.splitter)

        MainWindow.show()
示例#6
0
class ExperimentActionsWidget(QtWidgets.QWidget):
    def __init__(self, parent=None, statusBar=None):
        logging.debug("ExperimentActionsWidget instantiated")
        QtWidgets.QWidget.__init__(self, parent=None)
        self.statusBar = statusBar
        self.experimentItemNames = {}
        self.experimentActionsBaseWidgets = {}
        self.eco = ExperimentConfigIO.getInstance()
        self.rolledoutjson = None

        self.setObjectName("ExperimentActionsWidget")

        self.windowWidget = QtWidgets.QWidget()
        self.windowWidget.setObjectName("windowWidget")
        self.windowBoxHLayout = QtWidgets.QHBoxLayout()
        #self.windowBoxHLayout.setContentsMargins(0, 0, 0, 0)
        self.windowBoxHLayout.setObjectName("windowBoxHLayout")
        self.windowWidget.setLayout(self.windowBoxHLayout)

        self.experimentTree = QtWidgets.QTreeWidget(parent)
        self.experimentTree.setObjectName("experimentTree")
        self.experimentTree.header().resizeSection(0, 150)
        self.experimentTree.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.experimentTree.customContextMenuRequested.connect(
            self.showContextMenu)
        self.experimentTree.itemSelectionChanged.connect(self.onItemSelected)
        self.experimentTree.setEnabled(True)
        self.experimentTree.setMinimumSize(200, 521)
        self.experimentTree.setMaximumWidth(350)
        self.experimentTree.setObjectName("experimentTree")
        self.experimentTree.headerItem().setText(0, "Experiments New")
        self.experimentTree.setSortingEnabled(False)
        self.windowBoxHLayout.addWidget(self.experimentTree)

        self.windowBoxVLayout = QtWidgets.QVBoxLayout()
        #self.windowBoxHLayout.setContentsMargins(0, 0, 0, 0)
        self.windowBoxVLayout.setObjectName("windowBoxVLayout")

        self.basedataStackedWidget = QStackedWidget()
        self.basedataStackedWidget.setObjectName("basedataStackedWidget")
        self.basedataStackedWidget.setEnabled(False)
        self.windowBoxVLayout.addWidget(self.basedataStackedWidget)

        self.refreshVMsButton = QtWidgets.QPushButton("Refresh Status")
        self.refreshVMsButton.clicked.connect(self.refreshVMStatus)
        self.refreshVMsButton.setEnabled(False)
        self.windowBoxVLayout.addWidget(self.refreshVMsButton)

        self.windowBoxHLayout.addLayout(self.windowBoxVLayout)

        # Context menus
        self.experimentMenu = QtWidgets.QMenu()
        self.startupContextMenu = QtWidgets.QMenu("Startup")
        self.shutdownContextMenu = QtWidgets.QMenu("Shutdown")
        self.stateContextMenu = QtWidgets.QMenu("State")
        self.experimentMenu.addMenu(self.startupContextMenu)
        self.experimentMenu.addMenu(self.shutdownContextMenu)
        self.experimentMenu.addMenu(self.stateContextMenu)

        self.cloneExperiment = self.startupContextMenu.addAction(
            "Signal - Create Clones")
        self.cloneExperiment.triggered.connect(self.menuItemSelected)

        self.startVMs = self.startupContextMenu.addAction(
            "Signal - Start VMs (headless)")
        self.startVMs.triggered.connect(self.menuItemSelected)

        self.restoreSnapshots = self.startupContextMenu.addAction(
            "Signal - Restore Snapshots")
        self.restoreSnapshots.triggered.connect(self.menuItemSelected)

        self.pauseVMs = self.shutdownContextMenu.addAction(
            "Signal - Pause VMs")
        self.pauseVMs.triggered.connect(self.menuItemSelected)

        self.suspendVMs = self.shutdownContextMenu.addAction(
            "Signal - Suspend & Save States")
        self.suspendVMs.triggered.connect(self.menuItemSelected)

        self.poweroffVMs = self.shutdownContextMenu.addAction(
            "Signal - Power Off VMs")
        self.poweroffVMs.triggered.connect(self.menuItemSelected)

        self.deleteClones = self.shutdownContextMenu.addAction(
            "Signal - Delete Clones")
        self.deleteClones.triggered.connect(self.menuItemSelected)
        self.shutdownContextMenu.addAction(self.deleteClones)

        self.snapshotVMs = self.stateContextMenu.addAction(
            "Signal - Snapshot VMs")
        self.snapshotVMs.triggered.connect(self.menuItemSelected)

        self.setLayout(self.windowBoxHLayout)
        self.retranslateUi()

    def retranslateUi(self):
        logging.debug("ExperimentActionsWidget: retranslateUi(): instantiated")
        self.setWindowTitle("ExperimentActionsWidget")
        self.experimentTree.headerItem().setText(0, "Experiments")
        self.experimentTree.setSortingEnabled(False)

    def onItemSelected(self):
        logging.debug("MainApp:onItemSelected instantiated")
        self.basedataStackedWidget.setEnabled(True)
        self.refreshVMsButton.setEnabled(True)
        # Get the selected item
        selectedItem = self.experimentTree.currentItem()
        if selectedItem == None:
            logging.debug("MainApp:onItemSelected no configurations left")
            self.statusBar.showMessage(
                "No configuration items selected or available.")
            return

        #Check if it's the case that an experiment name was selected
        parentparentSelectedItem = None
        parentSelectedItem = selectedItem.parent()
        if parentSelectedItem != None:
            parentparentSelectedItem = selectedItem.parent().parent()

        if parentSelectedItem == None:
            #A base widget was selected
            self.basedataStackedWidget.setCurrentWidget(
                self.experimentActionsBaseWidgets[selectedItem.text(
                    0)]["ExperimentActionsBaseWidget"])
            self.experimentTree.resizeColumnToContents(0)
        elif parentparentSelectedItem == None:
            #A base widget was selected
            self.basedataStackedWidget.setCurrentWidget(
                self.experimentActionsBaseWidgets[parentSelectedItem.text(
                    0)]["ExperimentActionsBaseWidget"])
            self.experimentTree.resizeColumnToContents(0)
        else:
            #Check if it's the case that a VM Name was selected
            if (selectedItem.text(0)[0] == "V"):
                logging.debug(
                    "Setting right widget: " +
                    str(self.experimentActionsBaseWidgets[
                        parentparentSelectedItem.text(0)]
                        ["ExperimentActionsVMWidgets"][selectedItem.text(0)]))
                self.basedataStackedWidget.setCurrentWidget(
                    self.experimentActionsBaseWidgets[
                        parentparentSelectedItem.text(0)]
                    ["ExperimentActionsVMWidgets"][selectedItem.text(0)])
            if (selectedItem.text(0)[0] == "S"):
                logging.debug(
                    "Setting right widget: " +
                    str(self.experimentActionsBaseWidgets[
                        parentparentSelectedItem.text(0)]
                        ["ExperimentActionsSetWidgets"][selectedItem.text(0)]))
                self.basedataStackedWidget.setCurrentWidget(
                    self.experimentActionsBaseWidgets[
                        parentparentSelectedItem.text(0)]
                    ["ExperimentActionsSetWidgets"][selectedItem.text(0)])
            if (selectedItem.text(0)[0] == "T"):
                logging.debug("Setting right widget: " +
                              str(self.experimentActionsBaseWidgets[
                                  parentparentSelectedItem.text(0)]
                                  ["ExperimentActionsTemplateWidgets"][
                                      selectedItem.text(0)]))
                self.basedataStackedWidget.setCurrentWidget(
                    self.experimentActionsBaseWidgets[
                        parentparentSelectedItem.text(0)]
                    ["ExperimentActionsTemplateWidgets"][selectedItem.text(0)])
            if (selectedItem.text(0)[0] == "U"):
                logging.debug("Setting right widget: " + str(
                    self.experimentActionsBaseWidgets[
                        parentparentSelectedItem.text(0)]
                    ["ExperimentActionsUserWidgets"][selectedItem.text(0)]))
                self.basedataStackedWidget.setCurrentWidget(
                    self.experimentActionsBaseWidgets[
                        parentparentSelectedItem.text(0)]
                    ["ExperimentActionsUserWidgets"][selectedItem.text(0)])

    def getExperimentVMRolledOut(self, configname, config_json):
        logging.debug(
            "ExperimentActionsWidget(): getExperimentVMRolledOut(): retranslateUi(): instantiated"
        )
        self.rolledoutjson = self.eco.getExperimentVMRolledOut(
            configname, config_json)

    def addExperimentItem(self, configname, config_jsondata=None):
        logging.debug("addExperimentItem(): retranslateUi(): instantiated")
        if configname in self.experimentItemNames:
            logging.error(
                "addExperimentItem(): Item already exists in tree: " +
                str(configname))
            return
        userpool = UserPool()
        ##Now add the item to the tree widget and create the baseWidget
        experimentTreeWidgetItem = QtWidgets.QTreeWidgetItem(
            self.experimentTree)
        experimentTreeWidgetItem.setText(0, configname)

        experimentSetTreeItem = QtWidgets.QTreeWidgetItem(
            experimentTreeWidgetItem)
        experimentSetTreeItem.setText(0, "Sets")

        experimentCloneTreeItem = QtWidgets.QTreeWidgetItem(
            experimentTreeWidgetItem)
        experimentCloneTreeItem.setText(0, "Templates")

        experimentVMTreeItem = QtWidgets.QTreeWidgetItem(
            experimentTreeWidgetItem)
        experimentVMTreeItem.setText(0, "VMs")

        experimentUserTreeItem = QtWidgets.QTreeWidgetItem(
            experimentTreeWidgetItem)
        experimentUserTreeItem.setText(0, "Users")

        self.experimentItemNames[configname] = experimentTreeWidgetItem
        #get all rolled out and then get them by VM
        funcs = []
        funcs.append(
            (self.getExperimentVMRolledOut, configname, config_jsondata))
        GUIFunctionExecutingDialog(None,
                                   "Processing VMs for " + str(configname),
                                   funcs).exec_()
        rolledoutjson = self.rolledoutjson
        if rolledoutjson != None:
            # if file was specified, but it doesn't exist, prepend usernames
            invalid_userfile = False
            users_filename = config_jsondata["xml"]["testbed-setup"]["vm-set"][
                "users-filename"]
            if users_filename != None and users_filename.strip() != "":
                if os.path.exists(users_filename) == False:
                    invalid_userfile = True
            #get the usersConn associations first:
            usersConns = userpool.generateUsersConns(
                configname,
                creds_file=users_filename,
                rolledout_json=rolledoutjson)
            vmuser_mapping = {}
            for (username, password) in usersConns:
                for conn in usersConns[(username, password)]:
                    cloneVMName = conn[0]
                    if invalid_userfile == False:
                        vmuser_mapping[cloneVMName] = (username, password)
                    else:
                        vmuser_mapping[cloneVMName] = "userfile_not_found"

            #create the status widgets (tables)
            self.experimentActionsBaseWidget = ExperimentActionsVMStatusWidget(
                self,
                configname,
                rolledoutjson=rolledoutjson,
                interest_vmnames=[],
                vmuser_mapping=vmuser_mapping,
                status_bar=self.statusBar)
            self.experimentActionsBaseWidgets[configname] = {
                "ExperimentActionsBaseWidget": {},
                "ExperimentActionsSetWidgets": {},
                "ExperimentActionsTemplateWidgets": {},
                "ExperimentActionsVMWidgets": {},
                "ExperimentActionsUserWidgets": {}
            }
            self.experimentActionsBaseWidgets[configname][
                "ExperimentActionsBaseWidget"] = self.experimentActionsBaseWidget
            self.basedataStackedWidget.addWidget(
                self.experimentActionsBaseWidget)
            #Set-based view
            (template_vms, num_clones) = rolledoutjson
            #First create the sets from the rolled out data
            sets = self.eco.getExperimentSetDictFromRolledOut(
                configname, rolledoutjson)
            for set in sets:
                set_item = QtWidgets.QTreeWidgetItem(experimentSetTreeItem)
                setlabel = "S: Set " + set
                set_item.setText(0, setlabel)
                # Set Widget
                experimentActionsSetStatusWidget = ExperimentActionsVMStatusWidget(
                    self,
                    configname,
                    rolledoutjson=rolledoutjson,
                    interest_vmnames=sets[set],
                    vmuser_mapping=vmuser_mapping,
                    status_bar=self.statusBar)
                self.experimentActionsBaseWidgets[configname][
                    "ExperimentActionsSetWidgets"][
                        setlabel] = experimentActionsSetStatusWidget
                self.basedataStackedWidget.addWidget(
                    experimentActionsSetStatusWidget)

            templates = self.eco.getExperimentVMNamesFromTemplateFromRolledOut(
                configname, rolledoutjson)
            for templatename in templates:
                template_item = QtWidgets.QTreeWidgetItem(
                    experimentCloneTreeItem)
                templatelabel = "T: " + templatename
                template_item.setText(0, templatelabel)
                # Set Widget
                experimentActionsTemplateStatusWidget = ExperimentActionsVMStatusWidget(
                    self,
                    configname,
                    rolledoutjson=rolledoutjson,
                    interest_vmnames=templates[templatename],
                    vmuser_mapping=vmuser_mapping,
                    status_bar=self.statusBar)
                self.experimentActionsBaseWidgets[configname][
                    "ExperimentActionsTemplateWidgets"][
                        templatelabel] = experimentActionsTemplateStatusWidget
                self.basedataStackedWidget.addWidget(
                    experimentActionsTemplateStatusWidget)

            #Individual VM-based view
            vms_list = self.eco.getExperimentVMListsFromRolledOut(
                configname, rolledoutjson)
            for vm in vms_list:
                vmname = vm["name"]
                vm_item = QtWidgets.QTreeWidgetItem(experimentVMTreeItem)
                vmlabel = "V: " + vmname
                vm_item.setText(0, vmlabel)
                # VM Config Widget
                experimentActionsVMStatusWidget = ExperimentActionsVMStatusWidget(
                    self,
                    configname,
                    rolledoutjson=rolledoutjson,
                    interest_vmnames=[vmname],
                    vmuser_mapping=vmuser_mapping,
                    status_bar=self.statusBar)
                self.experimentActionsBaseWidgets[configname][
                    "ExperimentActionsVMWidgets"][
                        vmlabel] = experimentActionsVMStatusWidget
                self.basedataStackedWidget.addWidget(
                    experimentActionsVMStatusWidget)

            #Individual Users-based view
            num = 1
            for (username, password) in usersConns:
                vmnames = [
                    tuple[0] for tuple in usersConns[(username, password)]
                ]
                user_item = QtWidgets.QTreeWidgetItem(experimentUserTreeItem)
                user_label = "U: " + username + " (Set " + str(num) + ")"
                num += 1
                user_item.setText(0, user_label)
                # VM Config Widget
                experimentActionsUserStatusWidget = ExperimentActionsVMStatusWidget(
                    self,
                    configname,
                    rolledoutjson=rolledoutjson,
                    interest_vmnames=vmnames,
                    vmuser_mapping=vmuser_mapping,
                    status_bar=self.statusBar)
                self.experimentActionsBaseWidgets[configname][
                    "ExperimentActionsUserWidgets"][
                        user_label] = experimentActionsUserStatusWidget
                self.basedataStackedWidget.addWidget(
                    experimentActionsUserStatusWidget)

        self.statusBar.showMessage("Added new experiment: " + str(configname))
        logging.debug("addExperimentItem(): retranslateUi(): Completed")

    def resetExperiment(self, configname, config_jsondata):
        logging.debug("updateExperimentItem(): retranslateUi(): instantiated")
        if configname not in self.experimentItemNames:
            logging.error(
                "removeExperimentItem(): Item does not exist in tree: " +
                str(configname))
            return
        self.removeExperimentItem(configname)
        self.addExperimentItem(configname, config_jsondata)

    def removeExperimentItem(self, configname):
        logging.debug("removeExperimentItem(): retranslateUi(): instantiated")
        if configname not in self.experimentItemNames:
            logging.error(
                "removeExperimentItem(): Item does not exist in tree: " +
                str(configname))
            return
        experimentTreeWidgetItem = self.experimentItemNames[configname]
        self.experimentTree.invisibleRootItem().removeChild(
            experimentTreeWidgetItem)
        del self.experimentItemNames[configname]
        logging.debug("removeExperimentItem(): Completed")

    def showContextMenu(self, position):
        logging.debug(
            "ExperimentActionsWidget(): showContextMenu(): instantiated")
        self.experimentMenu.popup(self.experimentTree.mapToGlobal(position))

    def getTypeNameFromSelection(self):
        configname = ""
        itype = ""
        name = ""
        #configname selected
        if self.experimentTree.currentItem().parent() == None:
            configname = self.experimentTree.currentItem().text(0)
            itype = "set"
            name = "all"
        #sets, clones, or VMs label selected
        elif self.experimentTree.currentItem().parent().parent() == None:
            configname = self.experimentTree.currentItem().parent().text(0)
            itype = "set"
            name = "all"
        #specific item selected
        elif self.experimentTree.currentItem().parent().parent().parent(
        ) == None:
            configname = self.experimentTree.currentItem().parent().parent(
            ).text(0)
            currItemText = self.experimentTree.currentItem().text(0)
            if currItemText.startswith("S: Set "):
                itype = "set"
                name = currItemText.split("S: Set ")[1:]
                name = " ".join(name)
            elif currItemText.startswith("V: "):
                itype = "vm"
                name = currItemText.split("V: ")[1:]
                name = "\"" + " ".join(name) + "\""
            elif currItemText.startswith("T: "):
                itype = "template"
                name = currItemText.split("T: ")[1:]
                name = "\"" + " ".join(name) + "\""
            elif currItemText.startswith("U: "):
                itype = "set"
                name = currItemText.split("(Set ")[1].split(")")[0:-1]
                name = " ".join(name)
        return configname, itype, name

    def menuItemSelected(self):
        logging.debug("menuItemSelected(): instantiated")
        actionlabelname = self.sender().text()
        configname, itype, name = self.getTypeNameFromSelection()
        ExperimentActions().experimentActionEvent(configname, actionlabelname,
                                                  itype, name)
        self.statusBar.showMessage("Executed " + str(actionlabelname) +
                                   " on " + configname)

    def refreshVMStatus(self):
        logging.debug("refreshVMStatus(): instantiated")

        #Get the configname based on selected item:
        selectedItem = self.experimentTree.currentItem()
        #Check if an experiment name is selected
        if selectedItem == None:
            logging.error("No experiment label was selected.")
            return

        #If so, get the configname associated with it
        while selectedItem.parent() != None:
            selectedItem = selectedItem.parent()
        configname = selectedItem.text(0)
        s = VMRetrievingDialog(self).exec_()
        self.vms = s["vmstatus"]

        #Update all vm status in the subtrees
        #First the "all" view
        for widget in self.experimentActionsBaseWidgets[configname].values():
            if isinstance(widget, ExperimentActionsVMStatusWidget):
                widget.updateVMStatus(self.vms)
        #The Sets:
        for widget in self.experimentActionsBaseWidgets[configname][
                "ExperimentActionsSetWidgets"].values():
            if isinstance(widget, ExperimentActionsVMStatusWidget):
                widget.updateVMStatus(self.vms)
        #The Templates:
        for widget in self.experimentActionsBaseWidgets[configname][
                "ExperimentActionsTemplateWidgets"].values():
            if isinstance(widget, ExperimentActionsVMStatusWidget):
                widget.updateVMStatus(self.vms)
        #The VMs
        for widget in self.experimentActionsBaseWidgets[configname][
                "ExperimentActionsVMWidgets"].values():
            if isinstance(widget, ExperimentActionsVMStatusWidget):
                widget.updateVMStatus(self.vms)
        #The Users
        for widget in self.experimentActionsBaseWidgets[configname][
                "ExperimentActionsUserWidgets"].values():
            if isinstance(widget, ExperimentActionsVMStatusWidget):
                widget.updateVMStatus(self.vms)
示例#7
0
class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.patient_id = ''
        self.result_list = []

        self.title_lb = QPushButton()
        self.exit_bt = QPushButton()
        self.logo_bt = QPushButton()

        self.main_widget = QWidget()
        self.main_layout = QVBoxLayout()
        self.left_widget = QWidget()
        self.left_layout = QGridLayout()
        self.right_widget = QStackedWidget()
        self.mid_widget = QWidget()
        self.mid_layout = QHBoxLayout()
        self.bottom_layout = QHBoxLayout()
        self.bottom_widget = QWidget()
        # self.status_bar = QPushButton()
        # self.status_bar.set
        # self.stack1 = QWidget()

        self.stack_system_intro = SystemIntro()
        self.stack_border_map_intro = BorderMapIntro()
        self.stack_datapreprocessUI = DataPreprocessUI()
        self.stack_clusterUI = ClusterUI()
        self.stack_load_electrode_picUI = LoadElectrodePic()
        self.stack_generate_border_mapUI = GenerateBorderMap()
        self.stack_property_map_intro = PropertyMapIntro()
        self.stack_load_cortex_pic = LoadCortexPic()
        self.stack_generate_property_map = GeneratePropertyMap()
        self.stack_function_map_intro = FunctionMapIntro()
        self.stack_generate_function_map = GenerateFunctionMap()

        self.left_close = QPushButton("")  # 关闭按钮
        self.left_visit = QPushButton("")  # 空白按钮
        self.left_mini = QPushButton("")  # 最小化按钮
        self.left_close.setFixedSize(15, 15)  # 设置关闭按钮的大小
        self.left_visit.setFixedSize(15, 15)  # 设置按钮大小
        self.left_mini.setFixedSize(15, 15)  # 设置最小化按钮大小
        self.left_close.setStyleSheet(
            '''QPushButton{background:#F76677;border-radius:5px;}QPushButton:hover{background:red;}'''
        )
        self.left_visit.setStyleSheet(
            '''QPushButton{background:#F7D674;border-radius:5px;}QPushButton:hover{background:yellow;}'''
        )
        self.left_mini.setStyleSheet(
            '''QPushButton{background:#6DDF6D;border-radius:5px;}QPushButton:hover{background:green;}'''
        )
        self.left_label_1 = QPushButton("功能区边界聚类算法")
        self.left_label_1.clicked.connect(self.show_click_meg)
        self.left_label_1.clicked.connect(self.on_border_map_bt_clicked)
        self.left_label_1.setObjectName('left_label')
        self.left_label_2 = QPushButton("功能区属性分类算法")
        self.left_label_2.clicked.connect(self.show_click_meg)
        self.left_label_2.clicked.connect(self.on_property_map_bt_clicked)
        self.left_label_2.setObjectName('left_label')
        self.left_label_3 = QPushButton("基于聚类和分类的定位算法")
        self.left_label_3.clicked.connect(self.show_click_meg)
        self.left_label_3.clicked.connect(self.on_function_map_bt_clicked)
        self.left_label_3.setObjectName('left_label')

        self.left_button_1 = QPushButton(
            qtawesome.icon('fa.music', color='white'), "导入数据")
        self.left_button_1.clicked.connect(self.on_load_data_bt_clicked)
        self.left_button_1.clicked.connect(self.show_click_meg)
        self.left_button_1.setObjectName('left_button')
        self.left_button_2 = QPushButton(
            qtawesome.icon('fa.sellsy', color='white'), "预处理及特征提取")
        self.left_button_2.clicked.connect(self.on_preprocessing_bt_clicked)
        self.left_button_2.setObjectName('left_button')
        self.left_button_2.clicked.connect(self.show_click_meg)
        self.left_button_3 = QPushButton(
            qtawesome.icon('fa.film', color='white'), "模型加载与识别")
        self.left_button_3.clicked.connect(self.on_load_model_bt_clicked)
        self.left_button_3.setObjectName('left_button')
        self.left_button_3.clicked.connect(self.show_click_meg)

        self.left_button_4 = QPushButton(
            qtawesome.icon('fa.home', color='white '), "导入电极分布图")
        self.left_button_4.clicked.connect(self.on_load_pic_bt_clicked)
        self.left_button_4.setObjectName('left_button')
        self.left_button_4.clicked.connect(self.show_click_meg)

        self.left_button_5 = QPushButton(
            qtawesome.icon('fa.download', color='white'), "边界定位图")
        self.left_button_5.clicked.connect(
            self.on_generate_border_map_bt_clicked)
        self.left_button_5.setObjectName('left_button')
        self.left_button_5.clicked.connect(self.show_click_meg)

        self.left_button_6 = QPushButton(
            qtawesome.icon('fa.heart', color='white'), "加载皮质图片")
        self.left_button_6.clicked.connect(self.on_load_cortex_bt_clicked)
        self.left_button_6.setObjectName('left_button')
        self.left_button_6.clicked.connect(self.show_click_meg)

        self.left_button_7 = QPushButton(
            qtawesome.icon('fa.comment', color='white'), "属性定位图")
        self.left_button_7.clicked.connect(
            self.on_generate_property_map_bt_clicked)
        self.left_button_7.setObjectName('left_button')
        self.left_button_7.clicked.connect(self.show_click_meg)

        self.left_button_8 = QPushButton(
            qtawesome.icon('fa.star', color='white'), "功能区地形图")
        self.left_button_8.clicked.connect(
            self.on_generate_function_map_bt_clicked)
        self.left_button_8.setObjectName('left_button')
        self.left_button_8.clicked.connect(self.show_click_meg)

        self.statusBar = QStatusBar()

        self.setupUI()
        self.raw_data = 0
        self.data_path = ''
        self.pic_path = ''
        self.border_pic_path = None
        self.feature_sample = None

    def setupUI(self):
        self.resize(1000, 800)
        self.setWindowTitle('基于静息态ECoG聚类和分类的术中脑功能定位系统')
        self.title_lb.setText('基于静息态ECoG聚类和分类的术中脑功能定位系统')
        # self.title_lb.setStyleSheet("QLabel{background-color:black; font-size:20px}")

        self.setStatusBar(self.statusBar)
        self.statusBar.setStyleSheet("QStatusBar{font-size:15px}")  # 调大状态栏的字体
        # self.statusBar.setStyleSheet("QStatusBar{background-color:gray; font-size:20px}")  # 改状态栏的颜色与背景颜色一致
        # self.statusBar.setVisible(True)  # 最下面额外增加一栏状态栏
        self.statusBar.showMessage('就绪!')
        self.title_lb.clicked.connect(self.on_title_bt_clicked)
        self.title_lb.clicked.connect(self.show_click_meg)

        self.title_lb.setFixedSize(750, 70)
        self.title_lb.setStyleSheet(
            'QPushButton{color:rgb(0, 0, 0, 255);border:none;font-size:30px;font-family: \
                "Helvetica Neue", Helvetica, Arial, sans-serif;}\
                QPushButton:hover{border-left:4px solid red;font-weight:700;}')
        self.exit_bt.setText('退出')
        self.exit_bt.setFixedSize(100, 50)
        self.exit_bt.setStyleSheet(
            'QPushButton{color:rgb(0, 0, 0, 255);border:none;font-size:25px;font-family: \
        "Helvetica Neue", Helvetica, Arial, sans-serif;}\
        QPushButton:hover{border-left:4px solid red;font-weight:700;}')
        self.exit_bt.clicked.connect(self.exit_bt_clicked)
        self.logo_bt.setText('copyright@SCUT-BME-504')
        self.logo_bt.setFixedSize(300, 30)
        self.logo_bt.clicked.connect(self.show_click_meg)
        self.logo_bt.setStyleSheet(
            'QPushButton{color:rgb(0, 0, 0, 255);border:none;font-size:15px;font-family: \
        "Helvetica Neue", Helvetica, Arial, sans-serif;}\
        QPushButton:hover{border-left:4px solid red;font-weight:700;}')

        # self.bottom_layout.addWidget(self.status_bar, alignment=Qt.AlignLeft)
        self.bottom_layout.addStretch(2)
        self.bottom_layout.addWidget(self.logo_bt, alignment=Qt.AlignLeft)
        self.bottom_layout.addStretch(1)
        self.bottom_layout.addWidget(self.exit_bt, alignment=Qt.AlignRight)

        self.bottom_widget.setLayout(self.bottom_layout)

        self.stack_datapreprocessUI.setStyleSheet(
            'QLabel{color:black;font-size:20px;font-family:Arial; \
         header:None}')

        self.main_widget.setLayout(self.main_layout)

        self.left_widget.setObjectName('left_widget')
        self.left_widget.setLayout(self.left_layout)
        self.right_widget.setObjectName('right_widget')

        self.left_layout.addWidget(self.left_mini, 0, 0, 1, 1)
        self.left_layout.addWidget(self.left_close, 0, 2, 1, 1)
        self.left_layout.addWidget(self.left_visit, 0, 1, 1, 1)
        self.left_layout.addWidget(self.left_label_1, 1, 0, 1, 3)
        self.left_layout.addWidget(self.left_button_1, 2, 0, 1, 3)
        self.left_layout.addWidget(self.left_button_2, 3, 0, 1, 3)
        self.left_layout.addWidget(self.left_button_3, 4, 0, 1, 3)
        self.left_layout.addWidget(self.left_button_4, 5, 0, 1, 3)
        self.left_layout.addWidget(self.left_button_5, 6, 0, 1, 3)
        self.left_layout.addWidget(self.left_label_2, 7, 0, 1, 3)
        self.left_layout.addWidget(self.left_button_6, 8, 0, 1, 3)
        self.left_layout.addWidget(self.left_button_7, 9, 0, 1, 3)
        self.left_layout.addWidget(self.left_label_3, 10, 0, 1, 3)
        self.left_layout.addWidget(self.left_button_8, 11, 0, 1, 3)

        # self.left_layout.setSpacing(0)
        # self.stack = QStackedWidget()
        self.right_widget.addWidget(self.stack_system_intro)
        self.right_widget.addWidget(self.stack_border_map_intro)
        self.right_widget.addWidget(self.stack_datapreprocessUI)
        self.right_widget.addWidget(self.stack_clusterUI)
        self.right_widget.addWidget(self.stack_load_electrode_picUI)
        self.right_widget.addWidget(self.stack_generate_border_mapUI)
        self.right_widget.addWidget(self.stack_property_map_intro)
        self.right_widget.addWidget(self.stack_load_cortex_pic)
        self.right_widget.addWidget(self.stack_generate_property_map)
        self.right_widget.addWidget(self.stack_function_map_intro)
        self.right_widget.addWidget(self.stack_generate_function_map)

        self.mid_layout.addWidget(self.left_widget, stretch=1)
        self.mid_layout.addWidget(self.right_widget, stretch=3)
        self.mid_widget.setFixedSize(1000, 650)
        self.mid_layout.setSpacing(0)
        self.mid_widget.setLayout(self.mid_layout)

        self.main_widget.setObjectName('main_widget')
        self.main_layout.addWidget(self.title_lb,
                                   alignment=Qt.AlignCenter,
                                   stretch=1)
        self.main_layout.addWidget(self.mid_widget, stretch=7)
        self.main_layout.addWidget(self.bottom_widget, stretch=1)
        self.main_layout.setSpacing(0)
        # 设置窗口的样式
        main_widget_stylesheet = '''
            QWidget#main_widget{
                background:gray;
            }
            QPushButton#left_button{border:none;color:white;}
            QPushButton#left_label{
                border:none;
                border-bottom:1px solid white;
                font-size:18px;
                font-weight:700;
                font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
            }
            QWidget#left_widget{
                background:grey;
                border-top:1px solid white;
                border-bottom:1px solid white;
                border-left:1px solid white;
                border-top-left-radius:10px;
                border-bottom-left-radius:10px;
            }
            QWidget#right_widget{
                color:#232C51;
                background:white;
                border-top:1px solid darkGray;
                border-bottom:1px solid darkGray;
                border-right:1px solid darkGray;
                border-top-right-radius:10px;
                border-bottom-right-radius:10px;
            }
            QPushButton#left_button:hover{border-left:4px solid red;font-weight:700;}
            QPushButton#left_label:hover{border-left:4px solid red;font-weight:700;}
        '''
        self.main_widget.setStyleSheet(main_widget_stylesheet)
        self.setCentralWidget(self.main_widget)  # 一定要有要句代码,要不然主窗口不显示
        self.setWindowOpacity(1)  # 设置窗口透明度

        # self.setAttribute(Qt.WA_TranslucentBackground)  # 设置窗口背景透明  加上的话状态栏不显示。

        self.right_widget.setCurrentWidget(self.stack_system_intro)
        # self.setWindowFlag(Qt.FramelessWindowHint)  # 隐藏边框

    def on_title_bt_clicked(self):
        self.right_widget.setCurrentWidget(self.stack_system_intro)

    def on_border_map_bt_clicked(self):
        self.right_widget.setCurrentWidget(self.stack_border_map_intro)

    def on_load_data_bt_clicked(self):
        self.stack_datapreprocessUI.status_signal.connect(
            self.show_process_msg)
        self.right_widget.setCurrentWidget(self.stack_datapreprocessUI)

    def on_preprocessing_bt_clicked(self):
        self.feature_sample = self.stack_datapreprocessUI.feature_extract()
        self.stack_datapreprocessUI.status_signal.connect(
            self.show_process_msg)
        if self.feature_sample:
            self.right_widget.setCurrentWidget(self.stack_datapreprocessUI)
        else:
            if not self.raw_data:
                QMessageBox.information(self, '消息', '请先加载数据', QMessageBox.Ok)
            else:
                self.feature_sample = self.stack_datapreprocessUI.feature_extract(
                )

    def on_load_model_bt_clicked(self):
        self.stack_clusterUI.get_feature_sample(self.feature_sample)
        self.stack_clusterUI.status_signal.connect(self.show_process_msg)

        self.right_widget.setCurrentWidget(self.stack_clusterUI)

    def on_load_pic_bt_clicked(self):
        self.pic_path = self.stack_datapreprocessUI.trans_pic_path()
        self.stack_load_electrode_picUI.get_pic_path(self.pic_path)
        self.right_widget.setCurrentWidget(self.stack_load_electrode_picUI)

    def on_generate_border_map_bt_clicked(self):
        self.stack_generate_border_mapUI.get_pic_path(self.pic_path)
        self.result_list = self.stack_clusterUI.trans_result_list()
        self.stack_generate_border_mapUI.get_result_list(self.result_list)

        self.stack_generate_border_mapUI.status_signal.connect(
            self.show_process_msg)

        self.right_widget.setCurrentWidget(self.stack_generate_border_mapUI)

    def on_property_map_bt_clicked(self):
        self.right_widget.setCurrentWidget(self.stack_property_map_intro)

    def on_load_cortex_bt_clicked(self):
        self.right_widget.setCurrentWidget(self.stack_load_cortex_pic)

    def on_generate_property_map_bt_clicked(self):
        self.right_widget.setCurrentWidget(self.stack_generate_property_map)

    def on_function_map_bt_clicked(self):
        self.right_widget.setCurrentWidget(self.stack_function_map_intro)

    def on_generate_function_map_bt_clicked(self):
        self.right_widget.setCurrentWidget(self.stack_generate_function_map)

    def exit_bt_clicked(self):
        # sender是发送信号的对象,这里获得的是按钮的名称
        sender = self.sender()
        # 以文本的形式输出按钮的名称
        print(sender.text() + ' 被按下了')
        # 获取QApplication类的对象
        q_app = QApplication.instance()
        # 退出
        q_app.quit()

    def show_click_meg(self):
        sender = self.sender()
        self.statusBar.showMessage(sender.text(), 3000)

    def show_process_msg(self, msg):
        self.statusBar.showMessage(msg)
class ConfigurationWidget(QWidget):
    """
    Class implementing a dialog for the configuration of eric6.
    
    @signal preferencesChanged() emitted after settings have been changed
    @signal masterPasswordChanged(str, str) emitted after the master
        password has been changed with the old and the new password
    @signal accepted() emitted to indicate acceptance of the changes
    @signal rejected() emitted to indicate rejection of the changes
    """
    preferencesChanged = pyqtSignal()
    masterPasswordChanged = pyqtSignal(str, str)
    accepted = pyqtSignal()
    rejected = pyqtSignal()

    DefaultMode = 0
    HelpBrowserMode = 1
    TrayStarterMode = 2

    def __init__(self, parent=None, fromEric=True, displayMode=DefaultMode):
        """
        Constructor
        
        @param parent The parent widget of this dialog. (QWidget)
        @keyparam fromEric flag indicating a dialog generation from within the
            eric6 ide (boolean)
        @keyparam displayMode mode of the configuration dialog
            (DefaultMode, HelpBrowserMode, TrayStarterMode)
        @exception RuntimeError raised to indicate an invalid dialog mode
        """
        assert displayMode in (ConfigurationWidget.DefaultMode,
                               ConfigurationWidget.HelpBrowserMode,
                               ConfigurationWidget.TrayStarterMode)

        super(ConfigurationWidget, self).__init__(parent)
        self.fromEric = fromEric
        self.displayMode = displayMode

        self.__setupUi()

        self.itmDict = {}

        if not fromEric:
            from PluginManager.PluginManager import PluginManager
            try:
                self.pluginManager = e5App().getObject("PluginManager")
            except KeyError:
                self.pluginManager = PluginManager(self)
                e5App().registerObject("PluginManager", self.pluginManager)

        if displayMode == ConfigurationWidget.DefaultMode:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function create to
                # create the configuration page. This must have the method
                # save to save the settings.
                "applicationPage": [
                    self.tr("Application"), "preferences-application.png",
                    "ApplicationPage", None, None
                ],
                "cooperationPage": [
                    self.tr("Cooperation"), "preferences-cooperation.png",
                    "CooperationPage", None, None
                ],
                "corbaPage": [
                    self.tr("CORBA"), "preferences-orbit.png", "CorbaPage",
                    None, None
                ],
                "emailPage": [
                    self.tr("Email"), "preferences-mail_generic.png",
                    "EmailPage", None, None
                ],
                "graphicsPage": [
                    self.tr("Graphics"), "preferences-graphics.png",
                    "GraphicsPage", None, None
                ],
                "iconsPage": [
                    self.tr("Icons"), "preferences-icons.png", "IconsPage",
                    None, None
                ],
                "ircPage": [self.tr("IRC"), "irc.png", "IrcPage", None, None],
                "networkPage": [
                    self.tr("Network"), "preferences-network.png",
                    "NetworkPage", None, None
                ],
                "notificationsPage": [
                    self.tr("Notifications"), "preferences-notifications.png",
                    "NotificationsPage", None, None
                ],
                "pluginManagerPage": [
                    self.tr("Plugin Manager"), "preferences-pluginmanager.png",
                    "PluginManagerPage", None, None
                ],
                "printerPage": [
                    self.tr("Printer"), "preferences-printer.png",
                    "PrinterPage", None, None
                ],
                "pythonPage": [
                    self.tr("Python"), "preferences-python.png", "PythonPage",
                    None, None
                ],
                "qtPage": [
                    self.tr("Qt"), "preferences-qtlogo.png", "QtPage", None,
                    None
                ],
                "securityPage": [
                    self.tr("Security"), "preferences-security.png",
                    "SecurityPage", None, None
                ],
                "shellPage": [
                    self.tr("Shell"), "preferences-shell.png", "ShellPage",
                    None, None
                ],
                "tasksPage":
                [self.tr("Tasks"), "task.png", "TasksPage", None, None],
                "templatesPage": [
                    self.tr("Templates"), "preferences-template.png",
                    "TemplatesPage", None, None
                ],
                "trayStarterPage": [
                    self.tr("Tray Starter"), "erict.png", "TrayStarterPage",
                    None, None
                ],
                "vcsPage": [
                    self.tr("Version Control Systems"), "preferences-vcs.png",
                    "VcsPage", None, None
                ],
                "0debuggerPage": [
                    self.tr("Debugger"), "preferences-debugger.png", None,
                    None, None
                ],
                "debuggerGeneralPage": [
                    self.tr("General"), "preferences-debugger.png",
                    "DebuggerGeneralPage", "0debuggerPage", None
                ],
                "debuggerPythonPage": [
                    self.tr("Python"), "preferences-pyDebugger.png",
                    "DebuggerPythonPage", "0debuggerPage", None
                ],
                "debuggerPython3Page": [
                    self.tr("Python3"), "preferences-pyDebugger.png",
                    "DebuggerPython3Page", "0debuggerPage", None
                ],
                "debuggerRubyPage": [
                    self.tr("Ruby"), "preferences-rbDebugger.png",
                    "DebuggerRubyPage", "0debuggerPage", None
                ],
                "0editorPage": [
                    self.tr("Editor"), "preferences-editor.png", None, None,
                    None
                ],
                "editorAPIsPage": [
                    self.tr("APIs"), "preferences-api.png", "EditorAPIsPage",
                    "0editorPage", None
                ],
                "editorAutocompletionPage": [
                    self.tr("Autocompletion"),
                    "preferences-autocompletion.png",
                    "EditorAutocompletionPage", "0editorPage", None
                ],
                "editorAutocompletionQScintillaPage": [
                    self.tr("QScintilla"), "qscintilla.png",
                    "EditorAutocompletionQScintillaPage",
                    "editorAutocompletionPage", None
                ],
                "editorCalltipsPage": [
                    self.tr("Calltips"), "preferences-calltips.png",
                    "EditorCalltipsPage", "0editorPage", None
                ],
                "editorCalltipsQScintillaPage": [
                    self.tr("QScintilla"), "qscintilla.png",
                    "EditorCalltipsQScintillaPage", "editorCalltipsPage", None
                ],
                "editorGeneralPage": [
                    self.tr("General"), "preferences-general.png",
                    "EditorGeneralPage", "0editorPage", None
                ],
                "editorFilePage": [
                    self.tr("Filehandling"), "preferences-filehandling.png",
                    "EditorFilePage", "0editorPage", None
                ],
                "editorSearchPage": [
                    self.tr("Searching"), "preferences-search.png",
                    "EditorSearchPage", "0editorPage", None
                ],
                "editorSpellCheckingPage": [
                    self.tr("Spell checking"), "preferences-spellchecking.png",
                    "EditorSpellCheckingPage", "0editorPage", None
                ],
                "editorStylesPage": [
                    self.tr("Style"), "preferences-styles.png",
                    "EditorStylesPage", "0editorPage", None
                ],
                "editorSyntaxPage": [
                    self.tr("Code Checkers"), "preferences-debugger.png",
                    "EditorSyntaxPage", "0editorPage", None
                ],
                "editorTypingPage": [
                    self.tr("Typing"), "preferences-typing.png",
                    "EditorTypingPage", "0editorPage", None
                ],
                "editorExportersPage": [
                    self.tr("Exporters"), "preferences-exporters.png",
                    "EditorExportersPage", "0editorPage", None
                ],
                "1editorLexerPage": [
                    self.tr("Highlighters"),
                    "preferences-highlighting-styles.png", None, "0editorPage",
                    None
                ],
                "editorHighlightersPage": [
                    self.tr("Filetype Associations"),
                    "preferences-highlighter-association.png",
                    "EditorHighlightersPage", "1editorLexerPage", None
                ],
                "editorHighlightingStylesPage": [
                    self.tr("Styles"), "preferences-highlighting-styles.png",
                    "EditorHighlightingStylesPage", "1editorLexerPage", None
                ],
                "editorKeywordsPage": [
                    self.tr("Keywords"), "preferences-keywords.png",
                    "EditorKeywordsPage", "1editorLexerPage", None
                ],
                "editorPropertiesPage": [
                    self.tr("Properties"), "preferences-properties.png",
                    "EditorPropertiesPage", "1editorLexerPage", None
                ],
                "0helpPage":
                [self.tr("Help"), "preferences-help.png", None, None, None],
                "helpAppearancePage": [
                    self.tr("Appearance"), "preferences-styles.png",
                    "HelpAppearancePage", "0helpPage", None
                ],
                "helpDocumentationPage": [
                    self.tr("Help Documentation"),
                    "preferences-helpdocumentation.png",
                    "HelpDocumentationPage", "0helpPage", None
                ],
                "helpViewersPage": [
                    self.tr("Help Viewers"), "preferences-helpviewers.png",
                    "HelpViewersPage", "0helpPage", None
                ],
                "helpWebBrowserPage": [
                    self.tr("eric6 Web Browser"), "ericWeb.png",
                    "HelpWebBrowserPage", "0helpPage", None
                ],
                "0projectPage": [
                    self.tr("Project"), "preferences-project.png", None, None,
                    None
                ],
                "projectBrowserPage": [
                    self.tr("Project Viewer"), "preferences-project.png",
                    "ProjectBrowserPage", "0projectPage", None
                ],
                "projectPage": [
                    self.tr("Project"), "preferences-project.png",
                    "ProjectPage", "0projectPage", None
                ],
                "multiProjectPage": [
                    self.tr("Multiproject"), "preferences-multiproject.png",
                    "MultiProjectPage", "0projectPage", None
                ],
                "0interfacePage": [
                    self.tr("Interface"), "preferences-interface.png", None,
                    None, None
                ],
                "interfacePage": [
                    self.tr("Interface"), "preferences-interface.png",
                    "InterfacePage", "0interfacePage", None
                ],
                "viewmanagerPage": [
                    self.tr("Viewmanager"), "preferences-viewmanager.png",
                    "ViewmanagerPage", "0interfacePage", None
                ],
            }

            self.configItems.update(
                e5App().getObject("PluginManager").getPluginConfigData())
        elif displayMode == ConfigurationWidget.HelpBrowserMode:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function create to
                # create the configuration page. This must have the method
                # save to save the settings.
                "interfacePage": [
                    self.tr("Interface"), "preferences-interface.png",
                    "HelpInterfacePage", None, None
                ],
                "networkPage": [
                    self.tr("Network"), "preferences-network.png",
                    "NetworkPage", None, None
                ],
                "printerPage": [
                    self.tr("Printer"), "preferences-printer.png",
                    "PrinterPage", None, None
                ],
                "securityPage": [
                    self.tr("Security"), "preferences-security.png",
                    "SecurityPage", None, None
                ],
                "0helpPage":
                [self.tr("Help"), "preferences-help.png", None, None, None],
                "helpAppearancePage": [
                    self.tr("Appearance"), "preferences-styles.png",
                    "HelpAppearancePage", "0helpPage", None
                ],
                "helpDocumentationPage": [
                    self.tr("Help Documentation"),
                    "preferences-helpdocumentation.png",
                    "HelpDocumentationPage", "0helpPage", None
                ],
                "helpWebBrowserPage": [
                    self.tr("eric6 Web Browser"), "ericWeb.png",
                    "HelpWebBrowserPage", "0helpPage", None
                ],
            }
        elif displayMode == ConfigurationWidget.TrayStarterMode:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function create to
                # create the configuration page. This must have the method
                # save to save the settings.
                "trayStarterPage": [
                    self.tr("Tray Starter"), "erict.png", "TrayStarterPage",
                    None, None
                ],
            }
        else:
            raise RuntimeError("Illegal mode value: {0}".format(displayMode))

        # generate the list entries
        for key in sorted(self.configItems.keys()):
            pageData = self.configItems[key]
            if pageData[3]:
                pitm = self.itmDict[pageData[3]]  # get the parent item
            else:
                pitm = self.configList
            self.itmDict[key] = ConfigurationPageItem(pitm, pageData[0], key,
                                                      pageData[1])
            self.itmDict[key].setData(0, Qt.UserRole, key)
            self.itmDict[key].setExpanded(True)
        self.configList.sortByColumn(0, Qt.AscendingOrder)

        # set the initial size of the splitter
        self.configSplitter.setSizes([200, 600])

        self.configList.itemActivated.connect(self.__showConfigurationPage)
        self.configList.itemClicked.connect(self.__showConfigurationPage)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.rejected)

        if displayMode != ConfigurationWidget.TrayStarterMode:
            self.__initLexers()

    def accept(self):
        """
        Public slot to accept the buttonBox accept signal.
        """
        if not isMacPlatform():
            wdg = self.focusWidget()
            if wdg == self.configList:
                return

        self.accepted.emit()

    def __setupUi(self):
        """
        Private method to perform the general setup of the configuration
        widget.
        """
        self.setObjectName("ConfigurationDialog")
        self.resize(900, 650)
        self.verticalLayout_2 = QVBoxLayout(self)
        self.verticalLayout_2.setSpacing(6)
        self.verticalLayout_2.setContentsMargins(6, 6, 6, 6)
        self.verticalLayout_2.setObjectName("verticalLayout_2")

        self.configSplitter = QSplitter(self)
        self.configSplitter.setOrientation(Qt.Horizontal)
        self.configSplitter.setObjectName("configSplitter")

        self.configListWidget = QWidget(self.configSplitter)
        self.leftVBoxLayout = QVBoxLayout(self.configListWidget)
        self.leftVBoxLayout.setContentsMargins(0, 0, 0, 0)
        self.leftVBoxLayout.setSpacing(0)
        self.leftVBoxLayout.setObjectName("leftVBoxLayout")
        self.configListFilter = E5ClearableLineEdit(
            self, self.tr("Enter filter text..."))
        self.configListFilter.setObjectName("configListFilter")
        self.leftVBoxLayout.addWidget(self.configListFilter)
        self.configList = QTreeWidget()
        self.configList.setObjectName("configList")
        self.leftVBoxLayout.addWidget(self.configList)
        self.configListFilter.textChanged.connect(self.__filterTextChanged)

        self.scrollArea = QScrollArea(self.configSplitter)
        self.scrollArea.setFrameShape(QFrame.NoFrame)
        self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.scrollArea.setWidgetResizable(False)
        self.scrollArea.setObjectName("scrollArea")

        self.configStack = QStackedWidget()
        self.configStack.setFrameShape(QFrame.Box)
        self.configStack.setFrameShadow(QFrame.Sunken)
        self.configStack.setObjectName("configStack")
        self.scrollArea.setWidget(self.configStack)

        self.emptyPage = QWidget()
        self.emptyPage.setGeometry(QRect(0, 0, 372, 591))
        self.emptyPage.setObjectName("emptyPage")
        self.vboxlayout = QVBoxLayout(self.emptyPage)
        self.vboxlayout.setSpacing(6)
        self.vboxlayout.setContentsMargins(6, 6, 6, 6)
        self.vboxlayout.setObjectName("vboxlayout")
        spacerItem = QSpacerItem(20, 20, QSizePolicy.Minimum,
                                 QSizePolicy.Expanding)
        self.vboxlayout.addItem(spacerItem)
        self.emptyPagePixmap = QLabel(self.emptyPage)
        self.emptyPagePixmap.setAlignment(Qt.AlignCenter)
        self.emptyPagePixmap.setObjectName("emptyPagePixmap")
        self.emptyPagePixmap.setPixmap(
            QPixmap(os.path.join(getConfig('ericPixDir'), 'eric.png')))
        self.vboxlayout.addWidget(self.emptyPagePixmap)
        self.textLabel1 = QLabel(self.emptyPage)
        self.textLabel1.setAlignment(Qt.AlignCenter)
        self.textLabel1.setObjectName("textLabel1")
        self.vboxlayout.addWidget(self.textLabel1)
        spacerItem1 = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                  QSizePolicy.Expanding)
        self.vboxlayout.addItem(spacerItem1)
        self.configStack.addWidget(self.emptyPage)

        self.verticalLayout_2.addWidget(self.configSplitter)

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Apply
                                          | QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok
                                          | QDialogButtonBox.Reset)
        self.buttonBox.setObjectName("buttonBox")
        if not self.fromEric and \
                self.displayMode == ConfigurationWidget.DefaultMode:
            self.buttonBox.button(QDialogButtonBox.Apply).hide()
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False)
        self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(False)
        self.verticalLayout_2.addWidget(self.buttonBox)

        self.setWindowTitle(self.tr("Preferences"))

        self.configList.header().hide()
        self.configList.header().setSortIndicator(0, Qt.AscendingOrder)
        self.configList.setSortingEnabled(True)
        self.textLabel1.setText(
            self.tr("Please select an entry of the list \n"
                    "to display the configuration page."))

        QMetaObject.connectSlotsByName(self)
        self.setTabOrder(self.configList, self.configStack)

        self.configStack.setCurrentWidget(self.emptyPage)

        self.configList.setFocus()

    def __filterTextChanged(self, filter):
        """
        Private slot to handle a change of the filter.
        
        @param filter text of the filter line edit (string)
        """
        self.__filterChildItems(self.configList.invisibleRootItem(), filter)

    def __filterChildItems(self, parent, filter):
        """
        Private method to filter child items based on a filter string.
        
        @param parent reference to the parent item (QTreeWidgetItem)
        @param filter filter string (string)
        @return flag indicating a visible child item (boolean)
        """
        childVisible = False
        filter = filter.lower()
        for index in range(parent.childCount()):
            itm = parent.child(index)
            if itm.childCount() > 0:
                visible = self.__filterChildItems(itm, filter) or \
                    filter == "" or filter in itm.text(0).lower()
            else:
                visible = filter == "" or filter in itm.text(0).lower()
            if visible:
                childVisible = True
            itm.setHidden(not visible)

        return childVisible

    def __initLexers(self):
        """
        Private method to initialize the dictionary of preferences lexers.
        """
        import QScintilla.Lexers
        from .PreferencesLexer import PreferencesLexer, \
            PreferencesLexerLanguageError

        self.lexers = {}
        for language in QScintilla.Lexers.getSupportedLanguages():
            if language not in self.lexers:
                try:
                    self.lexers[language] = PreferencesLexer(language, self)
                except PreferencesLexerLanguageError:
                    pass

    def __importConfigurationPage(self, name):
        """
        Private method to import a configuration page module.
        
        @param name name of the configuration page module (string)
        @return reference to the configuration page module
        """
        modName = "Preferences.ConfigurationPages.{0}".format(name)
        try:
            mod = __import__(modName)
            components = modName.split('.')
            for comp in components[1:]:
                mod = getattr(mod, comp)
            return mod
        except ImportError:
            E5MessageBox.critical(
                self, self.tr("Configuration Page Error"),
                self.tr("""<p>The configuration page <b>{0}</b>"""
                        """ could not be loaded.</p>""").format(name))
            return None

    def __showConfigurationPage(self, itm, column):
        """
        Private slot to show a selected configuration page.
        
        @param itm reference to the selected item (QTreeWidgetItem)
        @param column column that was selected (integer) (ignored)
        """
        pageName = itm.getPageName()
        self.showConfigurationPageByName(pageName, setCurrent=False)

    def __initPage(self, pageData):
        """
        Private method to initialize a configuration page.
        
        @param pageData data structure for the page to initialize
        @return reference to the initialized page
        """
        page = None
        if isinstance(pageData[2], types.FunctionType):
            page = pageData[2](self)
        else:
            mod = self.__importConfigurationPage(pageData[2])
            if mod:
                page = mod.create(self)
        if page is not None:
            self.configStack.addWidget(page)
            pageData[-1] = page
            try:
                page.setMode(self.displayMode)
            except AttributeError:
                pass
        return page

    def showConfigurationPageByName(self, pageName, setCurrent=True):
        """
        Public slot to show a named configuration page.
        
        @param pageName name of the configuration page to show (string)
        @param setCurrent flag indicating to set the current item (boolean)
        """
        if pageName == "empty" or pageName not in self.configItems:
            page = self.emptyPage
        else:
            pageData = self.configItems[pageName]
            if pageData[-1] is None and pageData[2] is not None:
                # the page was not loaded yet, create it
                page = self.__initPage(pageData)
            else:
                page = pageData[-1]
            if page is None:
                page = self.emptyPage
            elif setCurrent:
                items = self.configList.findItems(
                    pageData[0], Qt.MatchFixedString | Qt.MatchRecursive)
                for item in items:
                    if item.data(0, Qt.UserRole) == pageName:
                        self.configList.setCurrentItem(item)
        self.configStack.setCurrentWidget(page)
        ssize = self.scrollArea.size()
        if self.scrollArea.horizontalScrollBar():
            ssize.setHeight(ssize.height() -
                            self.scrollArea.horizontalScrollBar().height() - 2)
        if self.scrollArea.verticalScrollBar():
            ssize.setWidth(ssize.width() -
                           self.scrollArea.verticalScrollBar().width() - 2)
        psize = page.minimumSizeHint()
        self.configStack.resize(max(ssize.width(), psize.width()),
                                max(ssize.height(), psize.height()))

        if page != self.emptyPage:
            page.polishPage()
            self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)
            self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(True)
        else:
            self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False)
            self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(False)

        # reset scrollbars
        for sb in [
                self.scrollArea.horizontalScrollBar(),
                self.scrollArea.verticalScrollBar()
        ]:
            if sb:
                sb.setValue(0)

        self.__currentConfigurationPageName = pageName

    def getConfigurationPageName(self):
        """
        Public method to get the page name of the current page.
        
        @return page name of the current page (string)
        """
        return self.__currentConfigurationPageName

    def calledFromEric(self):
        """
        Public method to check, if invoked from within eric.
        
        @return flag indicating invocation from within eric (boolean)
        """
        return self.fromEric

    def getPage(self, pageName):
        """
        Public method to get a reference to the named page.
        
        @param pageName name of the configuration page (string)
        @return reference to the page or None, indicating page was
            not loaded yet
        """
        return self.configItems[pageName][-1]

    def getLexers(self):
        """
        Public method to get a reference to the lexers dictionary.
        
        @return reference to the lexers dictionary
        """
        return self.lexers

    def setPreferences(self):
        """
        Public method called to store the selected values into the preferences
        storage.
        """
        for key, pageData in list(self.configItems.items()):
            if pageData[-1]:
                pageData[-1].save()
                # page was loaded (and possibly modified)
                QApplication.processEvents()  # ensure HMI is responsive

    def on_buttonBox_clicked(self, button):
        """
        Private slot called by a button of the button box clicked.
        
        @param button button that was clicked (QAbstractButton)
        """
        if button == self.buttonBox.button(QDialogButtonBox.Apply):
            self.on_applyButton_clicked()
        elif button == self.buttonBox.button(QDialogButtonBox.Reset):
            self.on_resetButton_clicked()

    @pyqtSlot()
    def on_applyButton_clicked(self):
        """
        Private slot called to apply the settings of the current page.
        """
        if self.configStack.currentWidget() != self.emptyPage:
            page = self.configStack.currentWidget()
            savedState = page.saveState()
            page.save()
            self.preferencesChanged.emit()
            if savedState is not None:
                page.setState(savedState)

    @pyqtSlot()
    def on_resetButton_clicked(self):
        """
        Private slot called to reset the settings of the current page.
        """
        if self.configStack.currentWidget() != self.emptyPage:
            currentPage = self.configStack.currentWidget()
            savedState = currentPage.saveState()
            pageName = self.configList.currentItem().getPageName()
            self.configStack.removeWidget(currentPage)
            if pageName == "editorHighlightingStylesPage":
                self.__initLexers()
            self.configItems[pageName][-1] = None

            self.showConfigurationPageByName(pageName)
            if savedState is not None:
                self.configStack.currentWidget().setState(savedState)
示例#9
0
class AppManager(metaclass=Singleton):
    APP_NAME = 'Lang tutor'
    WIDGETS = [
        main_widget,
        scenario_widget,
        editor_widget
    ]

    MSB_TYPE = {
        MsgType.INFO: QMessageBox.information,
        MsgType.WARN: QMessageBox.warning,
    }

    def __init__(self):
        init_locale()
        self.translator = Translator.get_translator('main')
        self.__init_main_window()
        self.__init_widgets()
        self.__init_event_handlers()

    def __init_main_window(self):
        self.main_window = QMainWindow()
        self.main_window.resize(1024, 768)
        self.main_window.setWindowTitle(self.APP_NAME)

        font = QFont()
        font.setFamily("Calibri")
        font.setPointSize(12)
        font.setBold(False)
        font.setWeight(50)
        self.main_window.setFont(font)

        self.centralwidget = QWidget(self.main_window)
        self.centralwidget.setMinimumSize(QSize(1024, 768))
        grid = QGridLayout(self.centralwidget)
        self.mainStackWidget = QStackedWidget(self.centralwidget)
        self.mainStackWidget.setObjectName("mainStackWidget")

        grid.addWidget(self.mainStackWidget, 0, 0, 1, 1)
        grid.setColumnMinimumWidth(0, 200)
        self.main_window.setCentralWidget(self.centralwidget)

    def __init_widgets(self):
        for wid in self.WIDGETS:
            self.mainStackWidget.addWidget(wid.init())

    def __init_event_handlers(self):
        CrossWidgetEvents.change_screen_event += self.select_active_widget
        CrossWidgetEvents.show_message_event += self.show_info_msb
        CrossWidgetEvents.show_question_event += self.show_question_msb
        CrossWidgetEvents.clsoe_main_window_event += self.main_window.close

    def get_main_window(self):
        return self.main_window

    def select_active_widget(self, wid_id):
        self.mainStackWidget.setCurrentIndex(wid_id)

    def show_info_msb(self, t, title, message):
        if t not in self.MSB_TYPE.keys():
            t = MsgType.INFO
        self.MSB_TYPE[t](self.main_window, title, message)

    def __init_quest_msb(self):
        quest_msb = QMessageBox()
        quest_msb.setIcon(QMessageBox.Question)
        quest_msb.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        yes_btn = quest_msb.button(QMessageBox.Yes)
        yes_btn.setText(self.translator.translate('YES_ANSWER'))
        no_btn = quest_msb.button(QMessageBox.No)
        no_btn.setText(self.translator.translate('NO_ANSWER'))
        return quest_msb

    def show_question_msb(self, title, message, yes_action):
        quest_msb = self.__init_quest_msb()
        quest_msb.setWindowTitle(title)
        quest_msb.setText(message)
        answer = quest_msb.exec()
        if answer == QMessageBox.Yes:
            yes_action()
示例#10
0
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        # window = QMainWindow()
        # window.resize(800, 600)

        # self.centralwidget = QtWidgets.QWidget(MainWindow)
        # self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.stack = QStackedWidget(parent=MainWindow)
        self.centralwidget = QStackedWidget(parent=MainWindow)

        self.centralwidget.setObjectName("centralwidget")

        # self.matplotlibwidget_static = MatplotlibWidget(self.centralwidget)
        matplotlibwidget_static = MatplotlibWidget()
        matplotlibwidget_static.setGeometry(QtCore.QRect(10, 0, 611, 271))
        matplotlibwidget_static.setObjectName("matplotlibwidget_static")

        self.stack.addWidget(matplotlibwidget_static)

        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(670, 80, 75, 23))
        self.pushButton.setObjectName("pushButton")

        # self.matplotlibwidget_dynamic = MatplotlibWidget()
        # self.matplotlibwidget_dynamic.setEnabled(True)
        # self.matplotlibwidget_dynamic.setGeometry(QtCore.QRect(10, 270, 611, 291))
        # self.matplotlibwidget_dynamic.setObjectName("matplotlibwidget_dynamic")
        matplotlibwidget_dynamic = MatplotlibWidget()
        matplotlibwidget_dynamic.setEnabled(True)
        matplotlibwidget_dynamic.setGeometry(QtCore.QRect(10, 0, 611, 271))
        matplotlibwidget_dynamic.setObjectName("matplotlibwidget_dynamic")

        self.stack.addWidget(matplotlibwidget_dynamic)

        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(670, 370, 75, 23))
        self.pushButton_2.setObjectName("pushButton_2")
        MainWindow.setCentralWidget(self.centralwidget)

        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        self.stack.show()
        # window.show()

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "显示静态图"))
        self.pushButton_2.setText(_translate("MainWindow", "显示动态图"))

    def next(self):
        self.stack.setCurrentIndex(self.stack.currentIndex() + 1)
        print('current', self.stack.currentIndex())
示例#11
0
文件: main.py 项目: 437730201/PyQt5-
class FraudFrame(QDialog):
    version = 'Fraud Detect Tool 1.0.0'

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

        self.contentsWidget = QListWidget()
        self.contentsWidget.setViewMode(QListView.IconMode)
        self.contentsWidget.setIconSize(QSize(120, 110))
        self.contentsWidget.setMovement(QListView.Static)
        self.contentsWidget.setMaximumWidth(130)
        self.contentsWidget.setSpacing(10)
        self.contentsWidget.setObjectName('left_widget')

        self.pagesWidget = QStackedWidget()
        self.pagesWidget.addWidget(NPoPage())
        self.pagesWidget.addWidget(NPoPage())
        self.pagesWidget.addWidget(NPoPage())
        self.pagesWidget.addWidget(SettingPage())
        self.pagesWidget.addWidget(InformationPage())
        self.pagesWidget.setObjectName('left_widget')

        self.logoLabel()

        vLayout = QVBoxLayout()
        vWidget = QWidget()
        vWidget.setObjectName('vWidget')
        vLayout.addWidget(self.left_label_1)
        vLayout.addWidget(self.contentsWidget)
        vWidget.setLayout(vLayout)

        horizontalLayout = QHBoxLayout()
        horizontalLayout.addWidget(vWidget)
        horizontalLayout.addWidget(self.pagesWidget, 1)

        mainLayout = QVBoxLayout()
        mainLayout.addLayout(horizontalLayout)
        mainLayout.addStretch(1)
        mainLayout.addSpacing(1)

        self.setStyleBetter()
        self.setLayout(mainLayout)
        self.createIcons()
        self.setWindowTitle(self.version)
        self.setWindowFlags(Qt.WindowMinimizeButtonHint)

    def changePage(self, current, previous):
        if not current:
            current = previous

        self.pagesWidget.setCurrentIndex(self.contentsWidget.row(current))

    def logoLabel(self):
        # # LOGO
        logo_jpg = QPixmap("logo.png")
        self.left_label_1 = QLabel(self)
        self.left_label_1.setObjectName('logo')
        self.left_label_1.setPixmap(logo_jpg)
        self.left_label_1.setAlignment(Qt.AlignCenter)

    def createIcons(self):

        poButton = QListWidgetItem(self.contentsWidget)
        # poButton.setIcon(QIcon('PO.jpg'))
        poButton.setIcon(QIcon('PO.png'))
        poButton.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)

        nPoButton = QListWidgetItem(self.contentsWidget)
        nPoButton.setIcon(QIcon('NPO.png'))
        nPoButton.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)

        moreButton = QListWidgetItem(self.contentsWidget)
        moreButton.setIcon(QIcon('MORE.png'))
        moreButton.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
        moreButton.setToolTip('这是MORE按钮')

        settingButton = QListWidgetItem(self.contentsWidget)
        settingButton.setIcon(QIcon('Setting.png'))
        settingButton.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
        settingButton.setToolTip('这是设定按钮')

        informationButton = QListWidgetItem(self.contentsWidget)
        informationButton.setIcon(QIcon('information.png'))
        informationButton.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
        informationButton.setToolTip('这是工具信息按钮')
        # 为contentsWidget界面切换添加changePage响应
        self.contentsWidget.currentItemChanged.connect(self.changePage)

    def setStyleBetter(self):
        """
            @todo  border: 2px outset red
        :return:
        """

        # set style
        self.setStyleSheet(""" 
            QWidget{
            background:#15191C;
            }
                """)
示例#12
0
class MainApp(QWidget):
    def __init__(self, parent=None):
        logging.debug("MainApp:init() instantiated")
        super().__init__()
        self.baseWidgets = {}
        self.vmWidgets = {}
        self.materialWidgets = {}
        self.cf = SystemConfigIO()
        self.ec = ExperimentConfigIO.getInstance()
        self.statusBar = QStatusBar()

        self.setMinimumSize(670, 565)
        quit = QAction("Quit", self)
        quit.triggered.connect(self.closeEvent)
        self.setWindowTitle("ARL South RES v0.1")

        self.tabWidget = QtWidgets.QTabWidget()
        self.tabWidget.setGeometry(QtCore.QRect(0, 15, 668, 565))
        self.tabWidget.setObjectName("tabWidget")

        # Configuration Window (windowBox) contains:
        ## windowBoxHLayout contains:
        ###experimentTree (Left)
        ###basedataStackedWidget (Right)
        self.windowWidget = QtWidgets.QWidget()
        self.windowWidget.setObjectName("windowWidget")
        self.windowBoxHLayout = QtWidgets.QHBoxLayout()
        #self.windowBoxHLayout.setContentsMargins(0, 0, 0, 0)
        self.windowBoxHLayout.setObjectName("windowBoxHLayout")
        self.windowWidget.setLayout(self.windowBoxHLayout)

        self.experimentTree = QtWidgets.QTreeWidget()
        self.experimentTree.itemSelectionChanged.connect(self.onItemSelected)
        self.experimentTree.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.experimentTree.customContextMenuRequested.connect(
            self.showContextMenu)
        self.experimentTree.setEnabled(True)
        self.experimentTree.setMinimumSize(200, 521)
        self.experimentTree.setMaximumWidth(350)
        self.experimentTree.setObjectName("experimentTree")
        self.experimentTree.headerItem().setText(0, "Experiments")
        self.experimentTree.setSortingEnabled(False)
        self.windowBoxHLayout.addWidget(self.experimentTree)

        self.basedataStackedWidget = QStackedWidget()
        self.basedataStackedWidget.setObjectName("basedataStackedWidget")
        self.basedataStackedWidget.setEnabled(False)
        self.windowBoxHLayout.addWidget(self.basedataStackedWidget)
        self.tabWidget.addTab(self.windowWidget, "Configuration")

        # VBox Actions Tab
        self.experimentActionsWidget = ExperimentActionsWidget(
            statusBar=self.statusBar)
        self.experimentActionsWidget.setObjectName("experimentActionsWidget")
        self.tabWidget.addTab(self.experimentActionsWidget,
                              "Experiment Actions")

        # Remote Connections Tab
        self.connectionWidget = ConnectionWidget(statusBar=self.statusBar)
        self.connectionWidget.setObjectName("connectionsWidget")
        self.tabWidget.addTab(self.connectionWidget, "Remote Connections")

        #Create the bottom layout so that we can access the status bar
        self.bottomLayout = QHBoxLayout()
        self.statusBar.showMessage("Loading GUI...")
        self.bottomLayout.addWidget(self.statusBar)
        self.saveButton = QtWidgets.QPushButton("Save Current")
        self.saveButton.clicked.connect(self.saveExperimentButton)
        self.saveButton.setEnabled(False)
        self.bottomLayout.addWidget(self.saveButton)

        self.populateUi()
        self.setupContextMenus()

        self.initMenu()
        self.mainLayout = QVBoxLayout()
        self.mainLayout.addWidget(self.mainMenu)
        self.mainLayout.addWidget(self.tabWidget)
        self.mainLayout.addLayout(self.bottomLayout)

        self.setLayout(self.mainLayout)
        #self.setCentralWidget(self.outerBox)
        self.tabWidget.setCurrentIndex(0)

        #self.statusBar.showMessage("Finished Loading GUI Components")

        # Plugin Section
        self.tabWidget.addTab(CTFi2GUI(), "CTFi2")

    def readSystemConfig(self):
        logging.debug("MainApp:readSystemConfig() instantiated")
        self.vboxPath = self.cf.getConfig()['VBOX']['VMANAGE_PATH']
        self.experimentPath = self.cf.getConfig(
        )['EXPERIMENTS']['EXPERIMENTS_PATH']
        self.statusBar.showMessage("Finished reading system config")

    def setupContextMenus(self):
        logging.debug("MainApp:setupContextMenus() instantiated")
        # Context menu for blank space
        self.blankTreeContextMenu = QtWidgets.QMenu()
        self.addExperiment = self.blankTreeContextMenu.addAction(
            "New Experiment")
        self.addExperiment.triggered.connect(self.addExperimentActionEvent)
        self.importExperiment = self.blankTreeContextMenu.addAction(
            "Import Experiment from RES archive")
        self.importExperiment.triggered.connect(self.importActionEvent)

        # Experiment context menu
        self.experimentContextMenu = QtWidgets.QMenu()
        self.addVMContextSubMenu = QtWidgets.QMenu()
        self.experimentContextMenu.addMenu(self.addVMContextSubMenu)
        self.addVMContextSubMenu.setTitle("Add")
        self.addVM = self.addVMContextSubMenu.addAction("Virtual Machines")
        self.addVM.triggered.connect(self.addVMActionEvent)
        self.addMaterial = self.addVMContextSubMenu.addAction("Material Files")
        self.addMaterial.triggered.connect(self.addMaterialActionEvent)

        # Add line separator here
        self.removeExperiment = self.experimentContextMenu.addAction(
            "Remove Experiment")
        self.removeExperiment.triggered.connect(
            self.removeExperimentItemActionEvent)
        self.exportExperiment = self.experimentContextMenu.addAction(
            "Export Experiment")
        self.exportExperiment.triggered.connect(self.exportActionEvent)

        # VM/Material context menu
        self.itemContextMenu = QtWidgets.QMenu()
        self.removeItem = self.itemContextMenu.addAction(
            "Remove Experiment Item")
        self.removeItem.triggered.connect(self.removeExperimentItemActionEvent)

    def populateUi(self):
        logging.debug("MainApp:populateUi() instantiated")
        self.statusBar.showMessage("Populating UI")
        self.readSystemConfig()
        #####Create the following based on the config file
        result = self.ec.getExperimentXMLFilenames()
        if result == None:
            return
        [xmlExperimentFilenames, xmlExperimentNames] = result
        if xmlExperimentFilenames == [] or xmlExperimentNames == []:
            self.statusBar.showMessage("No configs found")
            return

        #For all experiment files found
        for configname in xmlExperimentNames:
            ####Read Experiment Config Data and Populate Tree
            self.loadConfigname(configname)
        self.statusBar.showMessage(
            "Completed populating the User Interface from " +
            str(len(xmlExperimentNames)) + " config files read", 6000)

    ###############################

    def loadConfigname(self, configname):
        logging.debug("MainApp(): loadConfigname instantiated")
        logging.info("Reading XML data for " + str(configname))
        jsondata = self.ec.getExperimentXMLFileData(configname)
        self.statusBar.showMessage("Finished reading experiment config")

        ##########testbed-setup data######
        if jsondata == None:
            jsondata = {}
        if "xml" not in jsondata or jsondata["xml"] == None or str(
                jsondata["xml"]).strip() == "":
            jsondata["xml"] = {}
        if "testbed-setup" not in jsondata["xml"]:
            jsondata["xml"]["testbed-setup"] = {}
        if "vm-set" not in jsondata["xml"]["testbed-setup"]:
            jsondata["xml"]["testbed-setup"]["vm-set"] = {}
        #Temporary fix for older xml/json files.
        if "users-filename" not in jsondata["xml"]["testbed-setup"]["vm-set"]:
            jsondata["xml"]["testbed-setup"]["vm-set"]["users-filename"] = ""
        if "rdp-broker-ip" not in jsondata["xml"]["testbed-setup"]["vm-set"]:
            jsondata["xml"]["testbed-setup"]["vm-set"]["rdp-broker-ip"] = ""
        if "chat-server-ip" not in jsondata["xml"]["testbed-setup"]["vm-set"]:
            jsondata["xml"]["testbed-setup"]["vm-set"]["chat-server-ip"] = ""

        configTreeWidgetItem = QtWidgets.QTreeWidgetItem(self.experimentTree)
        configTreeWidgetItem.setText(0, configname)
        self.experimentActionsWidget.addExperimentItem(
            configname, config_jsondata=jsondata)
        self.connectionWidget.addExperimentItem(configname,
                                                config_jsondata=jsondata)
        basejsondata = jsondata["xml"]
        # Base Config Widget
        self.baseWidget = BaseWidget(self, configname, configname,
                                     basejsondata)
        self.baseWidgets[configname] = {
            "BaseWidget": {},
            "VMWidgets": {},
            "MaterialWidgets": {}
        }
        self.baseWidgets[configname]["BaseWidget"] = self.baseWidget
        self.basedataStackedWidget.addWidget(self.baseWidget)

        ##########vm data######
        if "vm" in jsondata["xml"]["testbed-setup"]["vm-set"]:
            vmsjsondata = jsondata["xml"]["testbed-setup"]["vm-set"]["vm"]
            if isinstance(vmsjsondata, list):
                for vm in vmsjsondata:
                    vm_item = QtWidgets.QTreeWidgetItem(configTreeWidgetItem)
                    vmlabel = "V: " + vm["name"]
                    vm_item.setText(0, vmlabel)
                    # VM Config Widget
                    vmWidget = VMWidget(None, configname, vm["name"], vm)
                    self.baseWidgets[configname]["VMWidgets"][
                        vmlabel] = vmWidget
                    self.basedataStackedWidget.addWidget(vmWidget)
            else:
                vm_item = QtWidgets.QTreeWidgetItem(configTreeWidgetItem)
                vmlabel = "V: " + vmsjsondata["name"]
                vm_item.setText(0, vmlabel)
                # VM Config Widget
                vmWidget = VMWidget(None, configname, vmsjsondata["name"],
                                    vmsjsondata)
                self.baseWidgets[configname]["VMWidgets"][vmlabel] = vmWidget
                self.basedataStackedWidget.addWidget(vmWidget)

    ##########material data######
        if "material" in jsondata["xml"]["testbed-setup"]["vm-set"]:
            materialsjsondata = jsondata["xml"]["testbed-setup"]["vm-set"][
                "material"]
            if isinstance(materialsjsondata, list):
                for material in materialsjsondata:
                    material_item = QtWidgets.QTreeWidgetItem(
                        configTreeWidgetItem)
                    materiallabel = "M: " + material["name"]
                    material_item.setText(0, materiallabel)
                    # Material Config Widget
                    materialWidget = MaterialWidget(None, configname,
                                                    material["name"], material)
                    self.baseWidgets[configname]["MaterialWidgets"][
                        materiallabel] = materialWidget
                    self.basedataStackedWidget.addWidget(materialWidget)
            else:
                material_item = QtWidgets.QTreeWidgetItem(configTreeWidgetItem)
                materiallabel = "M: " + materialsjsondata["name"]
                material_item.setText(0, materiallabel)
                # Material Config Widget
                materialWidget = MaterialWidget(None, configname,
                                                materialsjsondata["name"],
                                                materialsjsondata)
                self.baseWidgets[configname]["MaterialWidgets"][
                    materiallabel] = materialWidget
                self.basedataStackedWidget.addWidget(materialWidget)
        logging.debug("MainApp(): Finished loading configname: " +
                      str(configname))

    def onItemSelected(self):
        logging.debug("MainApp:onItemSelected instantiated")
        # Get the selected item
        selectedItem = self.experimentTree.currentItem()
        if selectedItem == None:
            logging.debug("MainApp:onItemSelected no configurations left")
            self.statusBar.showMessage(
                "No configuration items selected or available.")
            return
        self.basedataStackedWidget.setEnabled(True)
        # Now enable the save button
        self.saveButton.setEnabled(True)
        self.saveExperimentMenuButton.setEnabled(True)
        #Check if it's the case that an experiment name was selected
        parentSelectedItem = selectedItem.parent()
        if (parentSelectedItem == None):
            #A base widget was selected
            self.basedataStackedWidget.setCurrentWidget(
                self.baseWidgets[selectedItem.text(0)]["BaseWidget"])
        else:
            #Check if it's the case that a VM Name was selected
            if (selectedItem.text(0)[0] == "V"):
                logging.debug("Setting right widget: " +
                              str(self.baseWidgets[parentSelectedItem.text(0)]
                                  ["VMWidgets"][selectedItem.text(0)]))
                self.basedataStackedWidget.setCurrentWidget(
                    self.baseWidgets[parentSelectedItem.text(0)]["VMWidgets"][
                        selectedItem.text(0)])
            #Check if it's the case that a Material Name was selected
            elif (selectedItem.text(0)[0] == "M"):
                logging.debug("Setting right widget: " +
                              str(self.baseWidgets[parentSelectedItem.text(0)]
                                  ["MaterialWidgets"][selectedItem.text(0)]))
                self.basedataStackedWidget.setCurrentWidget(
                    self.baseWidgets[parentSelectedItem.text(
                        0)]["MaterialWidgets"][selectedItem.text(0)])

    def showContextMenu(self, position):
        logging.debug("MainApp:showContextMenu() instantiated: " +
                      str(position))
        if (self.experimentTree.itemAt(position) == None):
            self.blankTreeContextMenu.popup(
                self.experimentTree.mapToGlobal(position))
        elif (self.experimentTree.itemAt(position).parent() == None):
            self.experimentContextMenu.popup(
                self.experimentTree.mapToGlobal(position))
        else:
            self.itemContextMenu.popup(
                self.experimentTree.mapToGlobal(position))

    def addExperimentActionEvent(self):
        logging.debug("MainApp:addExperimentActionEvent() instantiated")
        configname = ExperimentAddDialog().experimentAddDialog(
            self, self.baseWidgets.keys())

        if configname != None:
            logging.debug(
                "configureVM(): OK pressed and valid configname entered: " +
                str(configname))
        else:
            logging.debug("configureVM(): Cancel pressed or no VM selected")
            return

        ##Now add the item to the tree widget and create the baseWidget
        configTreeWidgetItem = QtWidgets.QTreeWidgetItem(self.experimentTree)
        configTreeWidgetItem.setText(0, configname)
        self.experimentActionsWidget.addExperimentItem(configname)
        self.connectionWidget.addExperimentItem(configname)
        # Base Config Widget
        self.baseWidget = BaseWidget(self, configname, configname)
        self.baseWidgets[configname] = {
            "BaseWidget": {},
            "VMWidgets": {},
            "MaterialWidgets": {}
        }
        self.baseWidgets[configname]["BaseWidget"] = self.baseWidget
        self.basedataStackedWidget.addWidget(self.baseWidget)
        self.statusBar.showMessage("Added new experiment: " + str(configname))

    def importActionEvent(self):
        logging.debug("MainApp:importActionEvent() instantiated")
        #Check if it's the case that an experiment name was selected
        confignamesChosen = PackageImportDialog().packageImportDialog(
            self, self.baseWidgets.keys())
        if confignamesChosen == []:
            logging.debug(
                "importActionEvent(): Canceled or a file could not be imported. make sure file exists."
            )
            return
        #for fileChosen in filesChosen:
        logging.debug(
            "MainApp: importActionEvent(): Files choosen (getting only first): "
            + confignamesChosen)
        firstConfignameChosen = confignamesChosen
        self.loadConfigname(firstConfignameChosen)
        #Add the items to the tree
        self.statusBar.showMessage("Imported " + firstConfignameChosen)

    def addVMActionEvent(self):
        logging.debug("MainApp:addVMActionEvent() instantiated")
        selectedItem = self.experimentTree.currentItem()
        if selectedItem == None:
            logging.debug("MainApp:addVMActionEvent no configurations left")
            self.statusBar.showMessage(
                "Could not add VM. No configuration items selected or available."
            )
            return
        selectedItemName = selectedItem.text(0)
        #Now allow the user to choose the VM:
        (response, vmsChosen) = VMRetrieveDialog(self).exec_()

        if response == QMessageBox.Ok and vmsChosen != None:
            logging.debug("configureVM(): OK pressed and VMs selected " +
                          str(vmsChosen))
        else:
            logging.debug("configureVM(): Cancel pressed or no VM selected")
            return

        if vmsChosen == []:
            logging.debug(
                "configureVM(): Canceled or a file could not be added. Try again later or check permissions"
            )
            return

        for vmChosen in vmsChosen:
            logging.debug("MainApp: addVMActionEvent(): File choosen: " +
                          str(vmChosen))
            #Add the item to the tree
            vmItem = QtWidgets.QTreeWidgetItem(selectedItem)
            vmlabel = "V: " + vmChosen
            vmItem.setText(0, vmlabel)
            # VM Config Widget
            #Now add the item to the stack and list of baseWidgets
            vmjsondata = {"name": vmChosen}
            vmWidget = VMWidget(self, selectedItemName, vmChosen, vmjsondata)
            self.baseWidgets[selectedItemName]["VMWidgets"][vmlabel] = vmWidget
            self.basedataStackedWidget.addWidget(vmWidget)
        #Now add data to the experimentActionWidget associated with the current config
        #Check if it's the case that an experiment name was selected
        parentSelectedItem = selectedItem.parent()
        if parentSelectedItem != None:
            selectedItem = parentSelectedItem
        configname = selectedItem.text(0)
        config_jsondata = self.getWritableData(configname)
        self.experimentActionsWidget.resetExperiment(
            configname, config_jsondata=config_jsondata)
        self.connectionWidget.resetExperiment(configname,
                                              config_jsondata=config_jsondata)
        self.statusBar.showMessage("Added " + str(len(vmsChosen)) +
                                   " VM files to experiment: " +
                                   str(selectedItemName))

    def startHypervisorActionEvent(self):
        logging.debug("MainApp:startHypervisorActionEvent() instantiated")
        logging.debug(
            "MainApp:startHypervisorActionEvent no configurations left")

        # Try to open the hypervisor and check if it worked or not
        result = HypervisorOpenDialog().hypervisorOpenDialog(self)
        if result != "success":
            logging.debug(
                "startHypervisorActionEvent(): Could not start the hypervisor")
            self.statusBar.showMessage("Hypervisor could not be started.")
            return

        self.statusBar.showMessage("Started hypervisor.")

    def addMaterialActionEvent(self):
        logging.debug("MainApp:addMaterialActionEvent() instantiated")
        selectedItem = self.experimentTree.currentItem()
        if selectedItem == None:
            logging.debug(
                "MainApp:addMaterialActionEvent no configurations left")
            self.statusBar.showMessage(
                "Could not add item. No configuration items selected or available."
            )
            return

        selectedItemName = selectedItem.text(0)
        #Check if it's the case that an experiment name was selected
        filesChosen = MaterialAddFileDialog().materialAddFileDialog(
            selectedItemName)
        if filesChosen == []:
            logging.debug(
                "addMaterialActionEvent(): Canceled or a file could not be added. Try again later or check permissions"
            )
            return
        for fileChosen in filesChosen:
            fileChosen = os.path.basename(fileChosen)
            logging.debug("MainApp: addMaterialActionEvent(): File choosen: " +
                          fileChosen)
            #Add the item to the tree
            material_item = QtWidgets.QTreeWidgetItem(selectedItem)
            materiallabel = "M: " + fileChosen
            material_item.setText(0, materiallabel)
            # Material Config Widget
            #Now add the item to the stack and list of baseWidgets
            materialsjsondata = {"name": fileChosen}
            materialWidget = MaterialWidget(self, selectedItemName, fileChosen,
                                            materialsjsondata)
            self.baseWidgets[selectedItem.text(
                0)]["MaterialWidgets"][materiallabel] = materialWidget
            self.basedataStackedWidget.addWidget(materialWidget)
        self.statusBar.showMessage("Added " + str(len(filesChosen)) +
                                   " material files to experiment: " +
                                   str(selectedItemName))

    def removeExperimentItemActionEvent(self):
        logging.debug("MainApp:removeExperimentItemActionEvent() instantiated")
        selectedItem = self.experimentTree.currentItem()
        if selectedItem == None:
            logging.debug("MainApp:onItemSelected no configurations left")
            self.statusBar.showMessage(
                "Could not remove. No configuration items selected or available."
            )
            return

        selectedItemName = selectedItem.text(0)
        #Check if it's the case that an experiment name was selected
        parentSelectedItem = selectedItem.parent()
        if (parentSelectedItem == None):
            #A base widget was selected
            successfilenames = ExperimentRemoveFileDialog(
            ).experimentRemoveFileDialog(selectedItemName)
            if successfilenames == [] or successfilenames == "":
                logging.debug(
                    "removeExperimentItemActionEvent(): Canceled or a file could not be removed. Try again later or check permissions"
                )
                return

            self.experimentTree.invisibleRootItem().removeChild(selectedItem)
            self.basedataStackedWidget.removeWidget(
                self.baseWidgets[selectedItemName]["BaseWidget"])
            del self.baseWidgets[selectedItemName]
            self.experimentActionsWidget.removeExperimentItem(selectedItemName)
            self.experimentActionsWidget.removeExperimentItem(selectedItemName)
            self.statusBar.showMessage("Removed experiment: " +
                                       str(selectedItemName))
        else:
            #Check if it's the case that a VM Name was selected
            if (selectedItem.text(0)[0] == "V"):
                parentSelectedItem.removeChild(selectedItem)
                configname = parentSelectedItem.text(0)
                self.basedataStackedWidget.removeWidget(
                    self.baseWidgets[configname]["VMWidgets"][
                        selectedItem.text(0)])
                del self.baseWidgets[configname]["VMWidgets"][
                    selectedItem.text(0)]
                self.statusBar.showMessage("Removed VM: " +
                                           str(selectedItemName) +
                                           " from experiment: " +
                                           str(parentSelectedItem.text(0)))
                #Also remove from the experiment action widget:
                config_jsondata = self.getWritableData(configname)
                self.experimentActionsWidget.resetExperiment(
                    configname, config_jsondata=config_jsondata)
                self.connectionWidget.resetExperiment(
                    configname, config_jsondata=config_jsondata)

            #Check if it's the case that a Material Name was selected
            elif (selectedItem.text(0)[0] == "M"):
                materialName = selectedItemName.split("M: ")[1]
                successfilenames = MaterialRemoveFileDialog(
                ).materialRemoveFileDialog(parentSelectedItem.text(0),
                                           materialName)
                if successfilenames == []:
                    logging.debug(
                        "Canceled or a file could not be removed. Try again later or check permissions"
                    )
                    return
                parentSelectedItem.removeChild(selectedItem)
                self.basedataStackedWidget.removeWidget(
                    self.baseWidgets[parentSelectedItem.text(
                        0)]["MaterialWidgets"][selectedItem.text(0)])
                del self.baseWidgets[parentSelectedItem.text(
                    0)]["MaterialWidgets"][selectedItem.text(0)]
                self.statusBar.showMessage("Removed Material: " +
                                           str(materialName) +
                                           " from experiment: " +
                                           str(parentSelectedItem.text(0)))

    def exportActionEvent(self):
        logging.debug("MainApp:exportActionEvent() instantiated")
        #Check if it's the case that an experiment name was selected
        selectedItem = self.experimentTree.currentItem()
        if selectedItem == None:
            logging.debug("MainApp:exportActionEvent no configurations left")
            self.statusBar.showMessage(
                "Could not export experiment. No configuration items selected or available."
            )
            return
        selectedItemName = selectedItem.text(0)

        folderChosen = PackageExportDialog().packageExportDialog(
            self, selectedItemName)
        if folderChosen == []:
            logging.debug(
                "exportActionEvent(): Canceled or the experiment could not be exported. Check folder permissions."
            )
            return
        folderChosen = os.path.basename(folderChosen[0])

        logging.debug("MainApp: exportActionEvent(): File choosen: " +
                      folderChosen)
        #Add the items to the tree

        self.statusBar.showMessage("Exported to " + folderChosen)

    def editPathActionEvent(self):
        logging.debug("MainApp:editPathActionEvent() instantiated")
        result = ConfigurationDialog(self).exec_()

    def closeEvent(self, event):
        logging.debug("MainApp:closeEvent(): instantiated")
        logging.debug("closeEvent(): returning accept")
        event.accept()
        qApp.quit()
        return

    def initMenu(self):

        self.mainMenu = QMenuBar()
        self.fileMenu = self.mainMenu.addMenu("File")
        self.editMenu = self.mainMenu.addMenu("Edit")
        self.hypervisorMenu = self.mainMenu.addMenu("Hypervisor")

        self.newExperimentMenuButton = QAction(QIcon(), "New Experiment", self)
        self.newExperimentMenuButton.setShortcut("Ctrl+N")
        self.newExperimentMenuButton.setStatusTip("Create New Experiment")
        self.newExperimentMenuButton.triggered.connect(
            self.addExperimentActionEvent)
        self.fileMenu.addAction(self.newExperimentMenuButton)

        self.importExperimentMenuButton = QAction(QIcon(), "Import Experiment",
                                                  self)
        self.importExperimentMenuButton.setShortcut("Ctrl+I")
        self.importExperimentMenuButton.setStatusTip(
            "Import Experiment from RES File")
        self.importExperimentMenuButton.triggered.connect(
            self.importActionEvent)
        self.fileMenu.addAction(self.importExperimentMenuButton)

        self.saveExperimentMenuButton = QAction(QIcon(), "Save Experiment",
                                                self)
        self.saveExperimentMenuButton.setShortcut("Ctrl+I")
        self.saveExperimentMenuButton.setStatusTip(
            "Save currently selected experiment")
        self.saveExperimentMenuButton.triggered.connect(
            self.saveExperimentButton)
        self.saveExperimentMenuButton.setEnabled(False)
        self.fileMenu.addAction(self.saveExperimentMenuButton)

        self.exitMenuButton = QAction(QIcon("exit24.png"), "Exit", self)
        self.exitMenuButton.setShortcut("Ctrl+Q")
        self.exitMenuButton.setStatusTip("Exit application")
        self.exitMenuButton.triggered.connect(self.close)
        self.fileMenu.addAction(self.exitMenuButton)

        self.pathMenuButton = QAction(QIcon(), "Edit Paths", self)
        self.pathMenuButton.setShortcut("Ctrl+E")
        self.pathMenuButton.setStatusTip("Edit Paths")
        self.pathMenuButton.triggered.connect(self.editPathActionEvent)
        self.editMenu.addAction(self.pathMenuButton)

        self.startHypervisorMenuButton = QAction(QIcon(),
                                                 "Instantiate Hypervisor",
                                                 self)
        self.startHypervisorMenuButton.setShortcut("Ctrl+O")
        self.startHypervisorMenuButton.setStatusTip(
            "Start the hypervisor that is currently configured")
        self.startHypervisorMenuButton.triggered.connect(
            self.startHypervisorActionEvent)
        self.hypervisorMenu.addAction(self.startHypervisorMenuButton)

    def getWritableData(self, configname):
        logging.debug("MainApp: getWritableData() instantiated")
        jsondata = {}
        jsondata["xml"] = {}
        #get baseWidget data
        baseWidget = self.baseWidgets[configname]["BaseWidget"]
        ###TODO: make this work for multiple experiments (current testing assumes only one)
        if isinstance(baseWidget, BaseWidget):
            jsondata["xml"] = baseWidget.getWritableData()
        ###Setup the dictionary
        if "testbed-setup" not in jsondata["xml"]:
            jsondata["xml"]["testbed-setup"] = {}
        if "vm-set" not in jsondata["xml"]["testbed-setup"]:
            jsondata["xml"]["testbed-setup"]["vm-set"] = {}
        if "vm" not in jsondata["xml"]["testbed-setup"]["vm-set"]:
            jsondata["xml"]["testbed-setup"]["vm-set"]["vm"] = []
        if "material" not in jsondata["xml"]["testbed-setup"]["vm-set"]:
            jsondata["xml"]["testbed-setup"]["vm-set"]["material"] = []

        for vmData in self.baseWidgets[configname]["VMWidgets"].values():
            jsondata["xml"]["testbed-setup"]["vm-set"]["vm"].append(
                vmData.getWritableData())
        for materialData in self.baseWidgets[configname][
                "MaterialWidgets"].values():
            jsondata["xml"]["testbed-setup"]["vm-set"]["material"].append(
                materialData.getWritableData())
        return jsondata

    def saveExperimentButton(self):
        logging.debug("MainApp: saveExperiment() instantiated")
        self.saveExperiment()

    def saveExperiment(self, configname=None):
        logging.debug("MainApp: saveExperiment() instantiated")
        selectedItem = self.experimentTree.currentItem()
        if selectedItem == None:
            logging.debug("MainApp:onItemSelected no configurations left")
            self.statusBar.showMessage(
                "Could not save. No configuration items selected or available."
            )
            return
        #Check if it's the case that an experiment name was selected
        parentSelectedItem = selectedItem.parent()
        if parentSelectedItem != None:
            selectedItem = parentSelectedItem
        configname = selectedItem.text(0)
        jsondata = self.getWritableData(configname)

        self.ec.writeExperimentXMLFileData(jsondata, configname)
        self.ec.writeExperimentJSONFileData(jsondata, configname)
        self.ec.getExperimentVMRolledOut(configname,
                                         jsondata,
                                         force_refresh=True)
        res = self.ec.getExperimentServerInfo(configname)
        #Now reset the experimentActions view
        self.experimentActionsWidget.resetExperiment(configname, jsondata)
        self.connectionWidget.resetExperiment(configname, jsondata)
        self.statusBar.showMessage(
            "Succesfully saved experiment file for " + str(configname), 2000)
示例#13
0
class MainWindow(QMainWindow):
    """
    主窗口界面
    """

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

        # 初始化
        self.init()
        # ui设计
        self.setup_ui()
        # 创建右键菜单
        self.create_context_menu()
        # 主框体设计
        self.set_main_form()
        # 加载qss样式
        self.load_qss()

    def init(self):
        self.setGeometry(Const.WIN_X, Const.WIN_Y, Const.WIN_WIDTH, Const.WIN_HEIGHT)
        self.setObjectName('mainWindow')
        self.setWindowIcon(QIcon("./image/Logo/logo.png"))
        self.setWindowTitle('IFR智能公式识别系统')

        # 加载图片缩放公共类
        self.imageScale = ImageScale()

    def setup_ui(self):
        """
        创建状态栏、菜单栏、工具栏
        """

        # 状态栏
        self.statusBar = QStatusBar()
        self.setStatusBar(self.statusBar)
        self.statusBar.showMessage('准备就绪', 5000)
        # self.statusBar().setStyleSheet('background-color:lightGray;')

        # 菜单栏
        self.menubar = QMenuBar()
        self.setMenuBar(self.menubar)
        # self.menuBar().setStyleSheet('background-color:lightGray;')

        # 文件
        self.fileMenu = self.menubar.addMenu('&文件(F)')

        # 调用自定义action
        self.openPimax = Action.action_b_2(self, 'openPimax', '&打开图片文件', 'Ctrl+P', '打开图片文件')
        self.openPimax.setIcon(QIcon('./image/openQpixmap.jpg'))
        self.openText = Action.action_b_2(self, 'openText', '&打开文本文件', 'Ctrl+T', '打开文本文件')
        self.openText.setIcon(QIcon('./image/openText.ico'))
        self.openFile = Action.action_b_3(self, 'openFile', '打开文件', '打开文件', self.fileMenu)
        self.openFile.addAction(self.openPimax)
        self.openFile.addAction(self.openText)

        self.openPimax.triggered.connect(lambda: self.get_image())
        self.openText.triggered.connect(lambda: self.get_text())
        self.openRecentFile = Action.action_a_2(self, 'openRecentFile', '&最近打开的文件', 'Ctrl+O', '最近打开的文件', self.fileMenu)
        # self.openRecentFile.triggered.connect(self.)
        self.save = Action.action_a_2(self, 'save', '&保存分析结果', 'Ctrl+S', '保存数据分析结果', self.fileMenu)
        # self.save.triggered.connect(self.)
        self.saveAs = Action.action_a_2(self, 'saveAs', '&另保存分析结果', 'Ctrl+Shift+S', '另保存数据分析结果', self.fileMenu)
        # self.saveAs.triggered.connect(self.)
        self.printf = Action.action_a_2(self, 'printef', '&打印分析结果', 'Ctrl+P', '打印数据分析结果', self.fileMenu)
        # self.printf.triggered.connect(self.)
        self.exitAction = Action.action_a_1(self, 'exitAction', './image/mainWindowIcon/toolBarIcon/exit.png', '&退出',
                                            'Ctrl+Q', '退出应用程序',
                                            self.fileMenu)
        self.exitAction.triggered.connect(self.close)

        # 编辑
        self.exitMenu = self.menubar.addMenu('&编辑(E)')
        #
        # ####################查找与替换####################开始
        self.search = Action.action_b_2(self, 'search', '&快速查找', 'Ctrl+F', '快速查找')
        self.replace = Action.action_b_2(self, 'replace', '&快速替换', 'Ctrl+H', '快速替换')

        # 新增二级菜单
        self.searchAndReplaceMenu = Action.action_b_3(self, 'searchAndReplaceMenu', '查找与替换', '查找与替换', self.exitMenu)
        self.searchAndReplaceMenu.addAction(self.search)
        self.searchAndReplaceMenu.addAction(self.replace)

        # self.search.triggered.connect(self.)
        # self.replace.triggered.connect(self.)

        # ####################查找与替换####################结束

        self.cut = Action.action_a_2(self, 'cut', '&剪切', 'Ctrl+X', '剪切', self.exitMenu)
        # self.cut.triggered.connect(self.)
        self.copy = Action.action_a_2(self, 'copy', '&复制', 'Ctrl+C', '复制', self.exitMenu)
        # self.copy.triggered.connect(self.)
        self.paste = Action.action_a_2(self, 'paste', '&粘贴', 'Ctrl+V', '粘贴', self.exitMenu)
        # self.paste.triggered.connect(self.)
        self.delete = Action.action_a_2(self, 'delect', '&删除', 'Del', '删除', self.exitMenu)
        # self.delect.triggered.connect(self.)
        self.selectAll = Action.action_a_2(self, 'selectAll', '&全选', 'Ctrl+Alt', '全选', self.exitMenu)
        # self.selectAll.triggered.connect(self.)

        # 视图
        self.viewMenu = self.menubar.addMenu('&视图(V)')

        self.notice = Action.action_a_2(self, 'notice', '&通知', 'Ctrl+Alt+X', '信息通知提醒', self.viewMenu)
        # self.notice.triggered.connect(self.)

        # ####################窗口管理####################开始
        self.window = Action.action_b_3(self, 'window', '&窗口', '展示一些基本窗口', self.viewMenu)

        # ####################窗口管理####################结束
        #
        #
        #
        # ####################工具栏####################开始
        self.tool = Action.action_b_3(self, 'tool', '&工具栏', '基本工具', self.viewMenu)

        self.calculator = Action.action_a_1(self, 'calculator', './image/calculator.jpg', '&计算器',
                                            'C', '计算器', self.viewMenu)
        self.calculator.triggered.connect(lambda: self.calculator_win())

        # ####################工具####################结束
        self.fullScreen = Action.action_a_2(self, 'fullScreen', '&全屏幕', 'Shift+Alt+Enter', '全屏', self.viewMenu)
        # self.fullScreen.triggered.connect(self.)
        self.propertyWindow = Action.action_a_2(self, 'propertyWindow', '&属性窗口', 'F4', '属性窗口', self.viewMenu)
        # self.propertyWindow.triggered.connect(self.)
        #

        # 分析
        self.navigateMenu = self.menubar.addMenu('&分析(N)')
        #

        # 工具
        self.toolMenu = self.menubar.addMenu('&工具(T)')
        #

        # 扩展
        self.extendMenu = self.menubar.addMenu('&扩展(X)')
        #

        # 窗口
        self.windowMenu = self.menubar.addMenu('&窗口(W)')
        #

        # 帮助
        self.helpMenu = self.menubar.addMenu('&帮助(H)')

        self.help = Action.action_a_2(self, 'help ', '&查看帮助', 'Ctrl+F1', '查看帮助', self.helpMenu)
        # self.help.triggered.connect(self.)
        # ####################菜单####################结束

        ################################################################################################################

        # ####################工具栏####################开始
        # 工具

        self.pixmapToolbar = self.addToolBar('打开图形文件')
        self.textToolbar = self.addToolBar('打开文本文件')
        self.pixmapToolbar.addAction(self.openPimax)
        self.textToolbar.addAction(self.openText)

        self.exitToolbar = self.addToolBar('退出')
        self.exitToolbar.addAction(self.exitAction)

        self.calculatorTooolbar = self.addToolBar('计算器')
        self.calculatorTooolbar.addAction(self.calculator)

        # ####################工具栏####################结束

        #  槽函数线程

    # 创建右键菜单
    def create_context_menu(self):
        """
        创建右键菜单
        :return:
        """
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.show_context_menu)

        # 创建QMenu
        self.contextMenu = QMenu(self)

        # ####################工具栏管理####################开始
        self.toolBarManagementMenu = Action.action_b_4(self, 'toolBarManagementMenu', '&工具栏管理', self.contextMenu)
        # 未完成
        # ####################工具栏管理####################结束

        self.minAtion = Action.action_a_1(self, 'minAction', './image/min.png', '&最小化', 'Ctrl+M', '最小化窗口',
                                          self.contextMenu)

        self.contextMenu.addSeparator()  # 添加分隔线

        self.cutAction = Action.action_a_2(self, 'cutAction', '&剪切', 'Ctrl+X', '剪切', self.contextMenu)
        self.copyAction = Action.action_a_2(self, 'copyAction', '&复制', 'Ctrl+C', '复制', self.contextMenu)
        self.pasteAction = Action.action_a_2(self, 'pasteAction', '&粘贴', 'Ctrl+V', '粘贴', self.contextMenu)
        self.deleteAction = Action.action_a_2(self, 'delectAction', '&删除', 'Del', '删除', self.contextMenu)
        self.selectAllAction = Action.action_a_2(self, 'selectAllAction', '&全选', 'Ctrl+Alt', '全选', self.contextMenu)

        self.contextMenu.addSeparator()  # 添加分隔线

        self.closeAction = Action.action_a_1(self, 'closeAction', './image/Exit.png', '&退出', 'Ctrl+W', '退出',
                                             self.contextMenu)

        self.minAtion.triggered.connect(self.show_mininized_window)

        self.closeAction.triggered.connect(self.quit_window)
        # self.selectAllAction.triggered.connect(self.)
        # self.cutAction.triggered.connect(self.)
        # self.copyAction.triggered.connect(self.)
        # self.pasteAction.triggered.connect(self.)
        # self.delectAction.triggered.connect(self.)

    # ****************************** 业务逻辑 *********************************
    def load_qss(self):
        """
         加载Qss样式表
        :return:
        """
        style_file = './Window/mainWindow/Qss/mainWindow.qss'
        qss_style = CommonhelperQss.read_qss(style_file)
        self.setStyleSheet(qss_style)

    def set_action_connect(self):
        """
        菜单栏、工具栏槽函数连接
        :return:
        """
        pass

    def calculator_win(self):
        """
        加载计算器窗口
        :return:
        """
        self.calculator_Win = Calculatormainwindow()
        self.calculator_Win.show()

    def set_main_form(self):
        """
        窗体布局以及主框体设计
        :return:
        """
        # 主框体
        self.mainSpiltter = QSplitter(Qt.Vertical)
        self.mainSpiltter.setObjectName('mainSpiltter')

        self.mainSpiltterLayout = QVBoxLayout()

        # 设置主窗口中心窗体
        self.setCentralWidget(self.mainSpiltter)

        # *******工作区间*******
        self.workWidget = QSplitter()
        self.workWidget.setObjectName('workWidget')
        self.mainSpiltter.addWidget(self.workWidget)

        self.workWidgetLayout = QHBoxLayout()
        self.workWidget.setLayout(self.workWidgetLayout)

        self.leftWidget = QFrame()
        self.leftWidget.setObjectName('leftWidget')
        self.leftWidget.setFrameShape(QFrame.StyledPanel)
        self.leftWidget.setMaximumWidth(230)

        self.leftWidgetLayout = QVBoxLayout()
        self.leftWidgetLayout.setContentsMargins(0, 0, 0, 0)
        self.leftWidget.setLayout(self.leftWidgetLayout)

        # self.hideBtn = QLabel()
        # self.hideBtn.setObjectName('hideBtn')
        # self.hideBtn.setPixmap(QPixmap('./image/mainWindowIcon/showAndHideIcon/hide0.ico'))
        #
        # self.showBtn = QLabel()
        # self.showBtn.setObjectName('showBtn')
        # self.showBtn.setPixmap(QPixmap('./image/mainWindowIcon/showAndHideIcon/show0.ico'))

        # 存放按钮
        self.widget = QWidget()
        self.widget.setObjectName('widget')
        self.leftWidgetLayout.addWidget(self.widget)

        pixmap = self.imageScale.pixmap_scale('./image/Logo/logo0.png', 204, 80)

        self.logoIamgeLabel = QLabel(self.widget)
        self.logoIamgeLabel.setObjectName('logoImageLabel')
        self.logoIamgeLabel.setPixmap(pixmap)

        self.widgetLayout = QGridLayout()
        self.widget.setLayout(self.widgetLayout)

        self.widgetLayout.addWidget(self.logoIamgeLabel, 0, 1)

        # 多界面
        # QListWidget + QStackedWidget实现
        self.leftListWidget = QListWidget()  # 左侧选项列表
        self.leftListWidget.setObjectName('leftListWidget')
        self.rightWidget = QStackedWidget()  # 右侧框体
        self.rightWidget.setObjectName('rightWidget')

        self.leftWidgetLayout.addWidget(self.leftListWidget)

        self.workWidgetLayout.addWidget(self.leftWidget)
        self.workWidgetLayout.addWidget(self.rightWidget)

        # ********左侧选项列表布局以及设置******************************
        # 设置左侧选项列表大小
        self.leftListWidget.setMinimumWidth(Const.LEFTWIDGET_WIDTH)
        # 左侧选项列表与右侧框体的index对应绑定
        self.leftListWidget.currentRowChanged.connect(self.rightWidget.setCurrentIndex)
        # 去掉边框
        self.leftListWidget.setFrameShape(QListWidget.NoFrame)
        # 隐藏滚动条
        self.leftListWidget.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.leftListWidget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        list_str = ['智能识别', '公式生成器', '学习资源区', '设置', '关于']

        # 左侧选项添加
        for i in range(5):
            self.item = QListWidgetItem(list_str[i], self.leftListWidget)
            self.item.setSizeHint(QSize(Const.ITEM_WIDTH, Const.ITEM_HEIGHT))
            # 居中显示
            self.item.setTextAlignment(Qt.AlignCenter)

        # 设置默认选中item[1]
        self.leftListWidget.setCurrentRow(0)

        # ********右侧主框体布局以及设置**********************************
        self.rightForm1 = RightForm1()
        self.rightForm2 = RightForm2()
        self.rightForm3 = RightForm3()
        self.rightForm4 = RightForm4()
        self.rightForm5 = RightForm5()
        self.rightWidget.addWidget(self.rightForm1)
        self.rightWidget.addWidget(self.rightForm2)
        self.rightWidget.addWidget(self.rightForm3)
        self.rightWidget.addWidget(self.rightForm4)
        self.rightWidget.addWidget(self.rightForm5)

        # #############################################################
        # 消息通知框
        self.messageInform = MesageFrame()
        self.messageInform.setObjectName('messageInform')
        # 消息通知框默认隐藏
        self.messageInform.hide()

        self.mainSpiltter.addWidget(self.messageInform)

        # *****侧边栏*****
        # 右侧边栏
        self.rightBar = QFrame()
        self.rightBar.setObjectName('rightBar')
        self.rightBar.setFixedWidth(35)
        self.rightBar.setFrameShape(QFrame.StyledPanel)

        self.rightBarLayout = QVBoxLayout()
        self.rightBar.setLayout(self.rightBarLayout)

        self.workWidgetLayout.addWidget(self.rightBar)

        # 右侧边栏控件

        # 右侧边栏添加控件

        # 下侧边栏
        self.bottomBar = QFrame()
        self.bottomBar.setObjectName('bottomBar')
        self.bottomBar.setMaximumHeight(35)
        self.bottomBar.setFrameShape(QFrame.StyledPanel)

        self.bottomBarLayout = QHBoxLayout()
        self.bottomBarLayout.setAlignment(Qt.AlignRight)  # 右对齐
        self.bottomBar.setLayout(self.bottomBarLayout)

        self.mainSpiltter.addWidget(self.bottomBar)

        # 下侧边栏控件
        # 留白控件
        blank = QLabel(self.bottomBar)
        blank.setObjectName('blank')

        self.informText = QLabel(self.bottomBar)
        self.informText.setObjectName('informText')
        self.informText.setText('通知')

        self.informBtn = QPushButton(self.bottomBar)
        self.informBtn.setObjectName('informBtn')
        self.informBtn.resize(QSize(35, 35))
        self.informBtn.setIcon(QIcon('./image/mainWindowIcon/messageBarBtnIcon/inform0.png'))
        self.informBtn.clicked.connect(lambda: self.open_inform_frame())

        # 下侧边栏添加控件

        self.bottomBarLayout.addWidget(self.informBtn)
        self.bottomBarLayout.addWidget(self.informText)
        self.bottomBarLayout.addWidget(blank)

    # ****************************业务逻辑******************************
    # 右键菜单
    def show_context_menu(self):
        """
        右键点击时调用的函数
        :return:
        """
        # 显示菜单前,将它移动到鼠标点击的位置
        self.contextMenu.exec_(QCursor.pos())

    # 最小化窗口
    def show_mininized_window(self):
        """
        :return:
        """
        self.showMinimized()

    # 最大化窗口
    def show_maximized_window(self):
        """

        :return:
        """
        self.showMaximized()

    # 复原窗口
    def show_restore_window(self):
        """

        :return:
        """
        if self.isMaximized():
            self.showNormal()
        else:
            self.showMaximized()

    # 关闭窗口
    def quit_window(self):
        """

        :return:
        """
        self.close()

    # 打开文件
    def get_image(self):

        """
            getOpenFileName():返回用户所选择文件的名称,并打开该文件
            第一个参数用于指定父组件
            第二个参数指定对话框标题
            第三个参数指定目录
            第四个参数是文件扩展名过滤器
        """
        pass
        # fname, _ = QFileDialog.getOpenFileName(self, '选择图形文件', 'C:\\', "*.jpg *.gif *.png")
        # self.pixmapLabel.setPixmap(QPixmap(fname))

    def get_text(self):
        """

        :return:
        """
        pass
        # # 初始化实例,并设置一些参数
        # # textDialog = QFileDialog()
        # # textDialog.setFileMode(QFileDialog.AnyFile)
        # # textDialog.setFilter(QDir.Files)
        # textDialog = QFileDialog.getOpenFileName(self, '选择文本文件', 'C:\\', "*.txt *.doc *.docx")
        # # 当选择器关闭的时候
        # if textDialog.exec_():
        #     # 拿到所选择的文本
        #     filenames = textDialog.selectedFiles()
        #     # 读取文本内容设置到textEdit中
        #     f = open(filenames[0], 'r')
        #     with f:
        #         data = f.read()
        #         self.textEdit.setText(data)

    def open_inform_frame(self):
        self.messageInform.show()
示例#14
0
class SettingsDialog(QDialog):
    '''
    Dialog object for application settings.
    '''
    def __init__(self):
        super().__init__()

        self.settings = QSettings()
        self.modified_settings = []
        self.initUi()

    def initUi(self):
        self.setObjectName('dialogSettings')
        self.resize(725, 475)

        self.horizontalLayout = QHBoxLayout(self)
        self.horizontalLayout.setObjectName('horizontalLayoutSettings')

        self.listWidget = QListWidget(self)
        self.listWidget.setObjectName('listWidgetSettings')
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(1)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.listWidget.sizePolicy().hasHeightForWidth())
        self.listWidget.setSizePolicy(sizePolicy)
        font = QFont()
        font.setPointSize(12)
        self.listWidget.setFont(font)
        self.listWidget.setSortingEnabled(False)
        self.horizontalLayout.addWidget(self.listWidget)

        self.verticalWidget = QWidget(self)
        self.verticalWidget.setObjectName('verticalWidgetSettings')
        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(2)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.verticalWidget.sizePolicy().hasHeightForWidth())
        self.verticalWidget.setSizePolicy(sizePolicy)
        self.horizontalLayout.addWidget(self.verticalWidget)

        self.verticalLayout = QVBoxLayout(self.verticalWidget)
        self.verticalLayout.setObjectName('verticalLayoutSettings')

        self.stackedWidget = QStackedWidget(self.verticalWidget)
        self.stackedWidget.setObjectName('stackedWidgetSettings')
        self.verticalLayout.addWidget(self.stackedWidget)

        self.buttonBox = QDialogButtonBox(self.verticalWidget)
        self.buttonBox.setObjectName('buttonBoxSettings')
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.buttonBox.sizePolicy().hasHeightForWidth())
        self.buttonBox.setSizePolicy(sizePolicy)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Apply
                                          | QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        apply = self.buttonBox.button(QDialogButtonBox.Apply)
        apply.clicked.connect(self.saveSettings)
        apply.setEnabled(False)
        self.verticalLayout.addWidget(self.buttonBox)

        self.initSettingGroups()

        self.retranslateUi()
        self.listWidget.setCurrentRow(0)
        self.stackedWidget.setCurrentIndex(0)

    def initSettingGroups(self):
        '''
        Adds setting groups as ListItems and connects them to their specific
        widgets.
        '''
        # Server settings - Index 0
        item = QListWidgetItem()
        icon = QIcon()
        icon.addPixmap(QPixmap(':/icons/network.svg'), QIcon.Normal, QIcon.On)
        item.setIcon(icon)
        self.listWidget.addItem(item)

        self.widgetServerSettings = ServerSettingsWidget(self)
        self.stackedWidget.addWidget(self.widgetServerSettings)

    def saveSettings(self):
        for setting in self.modified_settings:
            widget = self.findChild(QObject, setting)
            if setting == 'lineEditApiUrl':
                self.settings.setValue('server/api_base_url', widget.text())
            if setting == 'lineEditApiToken':
                if widget.text().strip() == '':
                    keyring.delete_password(qApp.applicationName(), 'Token')
                else:
                    keyring.set_password(qApp.applicationName(), 'Token',
                                         widget.text())
        self.settings.sync()
        self.modified_settings = []
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False)

    def accept(self):
        self.saveSettings()
        self.done(QDialog.Accepted)

    def reject(self):
        self.done(QDialog.Rejected)

    def retranslateUi(self):
        '''Translate labels into native language and assign them to widgets.'''
        _ = QCoreApplication.translate

        # Dialog title
        self.setWindowTitle(_('Client', 'Settings'))

        # Server settings
        item = self.listWidget.item(0)
        item.setText(_('Client', ' Server'))
        self.widgetServerSettings.labelApiUrl.setText(
            _('Client', 'API Base URL:'))
        self.widgetServerSettings.labelApiToken.setText(
            _('Client', 'API Token:'))
示例#15
0
文件: main.py 项目: wangbo0316/new_ro
class QUnFrameWindow(QWidget):
    """
    无边框窗口类
    """
    def __init__(self):
        super(QUnFrameWindow, self).__init__(None, Qt.FramelessWindowHint)  # 设置为顶级窗口,无边框
        self._padding = 5  # 设置边界宽度为5
        self.initTitleLabel()  # 安放标题栏标签
        self.setWindowTitle = self._setTitleText(self.setWindowTitle)  # 用装饰器将设置WindowTitle名字函数共享到标题栏标签上
        self.setWindowTitle("        The LC. Technology Refined Operation Console")
        self.initLayout()  # 设置框架布局
        self.setMinimumWidth(250)
        self.setMouseTracking(True)  # 设置widget鼠标跟踪
        self.initDrag()  # 设置鼠标跟踪判断默认值
        #--------------------------------------------------------
        with open(setting.STATIC_PATH+'\\main.qss', 'r',encoding='UTF-8') as f:  # 导入QListWidget的qss样式
            self.list_style = f.read()

        self.main_layout = QHBoxLayout(self, spacing=0)  # 窗口的整体布局
        self.addLayout(self.main_layout)
        self.main_layout.setContentsMargins(0, 50, 0, 0)

        self.left_widget = QListWidget()  # 左侧选项列表
        self.left_widget.setStyleSheet(self.list_style)
        self.main_layout.addWidget(self.left_widget)

        self.right_widget = QStackedWidget()
        self.main_layout.addWidget(self.right_widget)

        self._setup_ui()
        #------------------------------------------------------------------------------------------------------

    def _setup_ui(self):
        '''加载界面ui'''
        self.left_widget.currentRowChanged.connect(self.right_widget.setCurrentIndex)   #list和右侧窗口的index对应绑定
        self.left_widget.setFrameShape(QListWidget.NoFrame)    #去掉边框
        self.left_widget.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)  #隐藏滚动条
        self.left_widget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        for item in router.ROUTER:
            self.item = QListWidgetItem(item, self.left_widget)
            self.item.setSizeHint(QSize(20, 60))
            self.item.setTextAlignment(Qt.AlignCenter)
            self.right_widget.addWidget(router.ROUTER[item]())
            self.right_widget.setObjectName('content')

    def initDrag(self):
        # 设置鼠标跟踪判断扳机默认值
        self._move_drag = False
        self._corner_drag = False
        self._bottom_drag = False
        self._right_drag = False

    def initTitleLabel(self):
        # 安放标题栏标签
        self._TitleLabel = QTitleLabel(self)
        self._TitleLabel.setMouseTracking(True)  # 设置标题栏标签鼠标跟踪(如不设,则标题栏内在widget上层,无法实现跟踪)
        self._TitleLabel.setIndent(10)  # 设置标题栏文本缩进
        self._TitleLabel.move(0, 0)  # 标题栏安放到左上角

        self._Ico = QLabel(self._TitleLabel)
        self.setObjectName('title_ico')
        png = QPixmap(setting.STATIC_PATH+'\\main_ico.png')
        self._Ico.setPixmap(png)
        self._Ico.move(10,7)

    def initLayout(self):
        # 设置框架布局
        self._MainLayout = QVBoxLayout()
        self._MainLayout.setSpacing(0)
        # self._MainLayout.addWidget(QLabel(), Qt.AlignLeft)  # 顶一个QLabel在竖放框架第一行,以免正常内容挤占到标题范围里
        # self._MainLayout.addStretch()
        self.setLayout(self._MainLayout)

    def addLayout(self, QLayout):
        # 给widget定义一个addLayout函数,以实现往竖放框架的正确内容区内嵌套Layout框架
        self._MainLayout.addLayout(QLayout)

    def _setTitleText(self, func):
        # 设置标题栏标签的装饰器函数
        def wrapper(*args):
            self._TitleLabel.setText(*args)
            return func(*args)

        return wrapper

    def setTitleAlignment(self, alignment):
        # 给widget定义一个setTitleAlignment函数,以实现标题栏标签的对齐方式设定
        self._TitleLabel.setAlignment(alignment | Qt.AlignVCenter)

    def setCloseButton(self, bool):
        # 给widget定义一个setCloseButton函数,为True时设置一个关闭按钮
        if bool == True:
            self._CloseButton = QTitleButton(b'x'.decode("utf-8"), self)
            self._CloseButton.setObjectName("CloseButton")  # 设置按钮的ObjectName以在qss样式表内定义不同的按钮样式
            self._CloseButton.setMouseTracking(True)  # 设置按钮鼠标跟踪(如不设,则按钮在widget上层,无法实现跟踪)
            self._CloseButton.setFixedHeight(self._TitleLabel.height())  # 设置按钮高度为标题栏高度
            self._CloseButton.clicked.connect(self.close)  # 按钮信号连接到关闭窗口的槽函数

    def setMinMaxButtons(self, bool):
        # 给widget定义一个setMinMaxButtons函数,为True时设置一组最小化最大化按钮
        if bool == True:
            self._MinimumButton = QTitleButton(b'-'.decode("utf-8"), self)
            self._MinimumButton.setObjectName("MinMaxButton")  # 设置按钮的ObjectName以在qss样式表内定义不同的按钮样式
            self._MinimumButton.setMouseTracking(True)  # 设置按钮鼠标跟踪(如不设,则按钮在widget上层,无法实现跟踪)
            self._MinimumButton.setFixedHeight(self._TitleLabel.height())  # 设置按钮高度为标题栏高度
            self._MinimumButton.clicked.connect(self.showMinimized)  # 按钮信号连接到最小化窗口的槽函数

    def resizeEvent(self, QResizeEvent):
        # 自定义窗口调整大小事件
        self._TitleLabel.setFixedWidth(self.width())  # 将标题标签始终设为窗口宽度
        # 分别移动三个按钮到正确的位置
        try:
            self._CloseButton.move(self.width() - self._CloseButton.width(), 0)
        except:
            pass
        try:
            self._MinimumButton.move(self.width() - (self._CloseButton.width() + 1) * 2 + 1, 0)
        except:
            pass
        # 重新调整边界范围以备实现鼠标拖放缩放窗口大小,采用三个列表生成式生成三个列表
        self._right_rect = [QPoint(x, y) for x in range(self.width() - self._padding, self.width() + 1)
                            for y in range(1, self.height() - self._padding)]
        self._bottom_rect = [QPoint(x, y) for x in range(1, self.width() - self._padding)
                             for y in range(self.height() - self._padding, self.height() + 1)]
        self._corner_rect = [QPoint(x, y) for x in range(self.width() - self._padding, self.width() + 1)
                             for y in range(self.height() - self._padding, self.height() + 1)]

    def mousePressEvent(self, event):
        # 重写鼠标点击的事件
        if (event.button() == Qt.LeftButton) and (event.pos() in self._corner_rect):
            # 鼠标左键点击右下角边界区域
            self._corner_drag = True
            event.accept()
        elif (event.button() == Qt.LeftButton) and (event.pos() in self._right_rect):
            # 鼠标左键点击右侧边界区域
            self._right_drag = True
            event.accept()
        elif (event.button() == Qt.LeftButton) and (event.pos() in self._bottom_rect):
            # 鼠标左键点击下侧边界区域
            self._bottom_drag = True
            event.accept()
        elif (event.button() == Qt.LeftButton) and (event.y() < self._TitleLabel.height()):
            # 鼠标左键点击标题栏区域
            self._move_drag = True
            self.move_DragPosition = event.globalPos() - self.pos()
            event.accept()

    def mouseMoveEvent(self, QMouseEvent):
        # 判断鼠标位置切换鼠标手势
        if QMouseEvent.pos() in self._corner_rect:
            self.setCursor(Qt.SizeFDiagCursor)
        elif QMouseEvent.pos() in self._bottom_rect:
            self.setCursor(Qt.SizeVerCursor)
        elif QMouseEvent.pos() in self._right_rect:
            self.setCursor(Qt.SizeHorCursor)
        else:
            self.setCursor(Qt.ArrowCursor)
        # 当鼠标左键点击不放及满足点击区域的要求后,分别实现不同的窗口调整
        # 没有定义左方和上方相关的5个方向,主要是因为实现起来不难,但是效果很差,拖放的时候窗口闪烁,再研究研究是否有更好的实现
        if Qt.LeftButton and self._right_drag:
            # 右侧调整窗口宽度
            self.resize(QMouseEvent.pos().x(), self.height())
            QMouseEvent.accept()
        elif Qt.LeftButton and self._bottom_drag:
            # 下侧调整窗口高度
            self.resize(self.width(), QMouseEvent.pos().y())
            QMouseEvent.accept()
        elif Qt.LeftButton and self._corner_drag:
            # 右下角同时调整高度和宽度
            self.resize(QMouseEvent.pos().x(), QMouseEvent.pos().y())
            QMouseEvent.accept()
        elif Qt.LeftButton and self._move_drag:
            # 标题栏拖放窗口位置
            self.move(QMouseEvent.globalPos() - self.move_DragPosition)
            QMouseEvent.accept()

    def mouseReleaseEvent(self, QMouseEvent):
        # 鼠标释放后,各扳机复位
        self._move_drag = False
        self._corner_drag = False
        self._bottom_drag = False
        self._right_drag = False
示例#16
0
class DnmrGui(QMainWindow):
    """
    Create the GUI for the application.

    Currently the app features a single simulation model (two uncoupled
    spins), and so a single main window. TODO: as views are added, create a
    toggle between GUI windows tailored to each simulation (e.g. appropriate
    widgets for data entry)
    """

    def __init__(self, parent=None):

        print('ititializing gui class')

        super(DnmrGui, self).__init__(parent)

        print('creating views list')
        self.views = []
        self.models = [dnmrplot_2spin, dnmrplot_AB]
        self.setObjectName('toplevel')
        self.setupUi()

    class MainView(QWidget):
        """A QWidget that has the following properties:
        - A top row of labeled QDoubleSpinBox es for data entry
        - Beneath them, a pqtgraph PlotWidget for the simulated plot
        - the ability to detect changes to the data entries, store their 
        current values, call the appropriate model and pass the simulation 
        results to the pyqtgraph widget
        """
        def __init__(self, name, *args):
            super().__init__()
            self.setObjectName(name + 'widget')
            self.setAutoFillBackground(True)
            self.setStyleSheet("background-color: rgb(60, 63, 65);")

            self.simulation_vars = {}

            layout = QGridLayout()
            layout.setObjectName(name + 'layout')

            for i, widget in enumerate(args):
                # make a label for the widget
                wlabel = QLabel(widget.string)
                wlabel.setObjectName(widget.key + '_label')
                wlabel.setStyleSheet('color: white')
                wlabel.setAlignment(Qt.AlignCenter)

                # Make a QDoubleSpinBox widget
                wbox = QDoubleSpinBox()
                wbox.setObjectName(widget.key)
                wbox.setStyleSheet('color: white')
                wbox.setRange(*widget.range)  # SET RANGE BEFORE VALUE
                wbox.setValue(widget.value)
                wbox.setAlignment(Qt.AlignCenter)
                wbox.setAccelerated(True)

                # Add label (above) and spinbox (below) to layout
                layout.addWidget(wlabel, 0, i)
                layout.addWidget(wbox, 1, i)

                # Store the default simulation value
                self.simulation_vars[widget.key] = widget.value

                # update the view if this widget's value is changed
                # Using the lambda expression below allows extra information to
                # be passed to the self.update slot, allowing the delegator to
                # see who sent the signal, update the dictionary of model
                # inputs, call the model for a simulation result, and plot
                # it. See:
                # https://mfitzp.io/article/transmit-extra-data-with-signals-in-pyqt/
                wbox.valueChanged.connect(
                    lambda val, key=widget.key:
                    self.parent().parent().updateView(key, val))

            # Add pyqtgraph widget
            setConfigOption('background', (43, 43, 43))
            setConfigOption('foreground', (187, 187, 187))
            graphicsView = PlotWidget()

            layout.addWidget(graphicsView, 2, 0, 1, len(twosinglets_vars))
            plots.append(graphicsView.plot())
            # lets the graph span the entire width of the window, no matter how
            # many input widgets appear above

            self.setLayout(layout)

    def setupUi(self):
        """
        Set up the GUI with the default moded, default variables,
        and simulated lineshape.
        """

        self.setupCentral()
        self.setupModelBar()
        self.initializeGui()

    def setupCentral(self):

        self.stackedWidget = QStackedWidget()
        self.stackedWidget.setObjectName('stackedwidget')
        self.stackedWidget.setStyleSheet("background-color: rgb(60, 63, 65);")

        for view in mainviews:
            widget = self.MainView(view[0], *view[1])
            self.stackedWidget.addWidget(widget)
        self.setCentralWidget(self.stackedWidget)

    def setupModelBar(self):
        """
        Add a tool bar to the GUI for selecting which model to display 
        """

        leftToolBar = QToolBar()
        leftToolBar.setStyleSheet("background-color: rgb(60, 63, 65);")
        leftToolBar.setObjectName('lefttoolbar')

        leftToolBar.addWidget(self.modelButtonGroup())
        self.addToolBar(Qt.LeftToolBarArea, leftToolBar)

    def modelButtonGroup(self):
        """
        A widget of radio buttons that will determine which QStackedWidget is
        displayed.
        """

        # It seems that in order for the buttonClicked signal to work,
        # self.ButtonGroup and not ButtonGroup is necessary. Does not work
        # with out 'self.' prefix!!!

        modelsWidget = QWidget()
        modelsWidget.setObjectName('modelswidget')
        modelsLayout = QVBoxLayout()
        modelsLayout.setObjectName('modelslayout')
        self.ButtonGroup = QButtonGroup()

        selectModelLabel = QLabel('Select Model:')
        selectModelLabel.setAlignment(Qt.AlignCenter)
        selectModelLabel.setStyleSheet('color: white')

        twosingletbutton = QRadioButton('Two uncoupled spin-1/2 nuclei')
        twosingletbutton.setObjectName('twosingletbutton')
        twosingletbutton.setStyleSheet('color: white')
        twosingletbutton.setChecked(True)
        self.ButtonGroup.addButton(twosingletbutton, 0)

        abbutton = QRadioButton('Two coupled spin-1/2 nuclei\n ("AB quartet)')
        abbutton.setObjectName('abbutton')
        abbutton.setStyleSheet('color: white')
        self.ButtonGroup.addButton(abbutton, 1)

        self.ButtonGroup.buttonClicked[int].connect(self.switchView)

        modelsLayout.addStretch()
        modelsLayout.addWidget(selectModelLabel)
        modelsLayout.addWidget(twosingletbutton)
        modelsLayout.addWidget(abbutton)
        modelsLayout.addStretch()
        modelsWidget.setLayout(modelsLayout)
        modelsWidget.setStyleSheet("background-color: rgb(60, 63, 65);")

        return modelsWidget

    def switchView(self, index):
        self.stackedWidget.setCurrentIndex(index)
        self.call_model()

    def initializeGui(self):

        # Note order of models in stackedWidget and plots must be same
        for i in range(len(plots)):
            self.stackedWidget.setCurrentIndex(i)
            plot = plots[i]
            plot.getViewBox().invertX(True)  # Reverse x axis "NMR style"
            plot.setData(*self.call_model())

        self.stackedWidget.setCurrentIndex(0)
        self.setGeometry(50, 50, 800, 600)
        self.setWindowTitle('pyDNMR')
        self.statusBar().showMessage('Ready')

    def call_model(self):
        """
        Send the dictionary as **kwargs to the model
        :return: a spectrum, consisting of a tuple of x and y coordinate arrays
        """
        model = self.models[self.stackedWidget.currentIndex()]
        x, y = model(
            **self.stackedWidget.currentWidget().simulation_vars)
        return x, y

    def updateView(self, key, val):
        """
        Detect a change in numerical input; record the change in
        the dictionary of widget values; call the model to get an updated
        spectrum; and plot the spectrum.
        :param key: the dictionary key for the variable associated with the
        signalling widget
        :param val: the current value of the signalling widget
        """
        self.stackedWidget.currentWidget().simulation_vars[key] = val
        self.plot_graph()

    def plot_graph(self):
        activePlot = plots[self.stackedWidget.currentIndex()]
        activePlot.setData(*self.call_model())
示例#17
0
class Notes(object):
    def __init__(self):
        super(Notes).__init__()

    def setupUi(self, MainWindow):

        menubar = MainWindow.menuBar()

        self.menu_file = menubar.addMenu("File")
        self.menu_edit = menubar.addMenu("Edit")
        self.menu_format = menubar.addMenu("Format")
        self.menu_help = menubar.addMenu("Help")
        #self.menu_view = menubar.addMenu("Export")

        # menubar file menu

        self.menu_file_action = QAction("New File", MainWindow)
        self.menu_file.addAction(self.menu_file_action)

        self.new_notebook_action = QAction("New Notebook", MainWindow)
        self.menu_file.addAction(self.new_notebook_action)

        self.open_file_action = QAction("Open an existing file", MainWindow)
        self.menu_file.addAction(self.open_file_action)

        self.save_file_action = QAction("Save File", MainWindow)
        self.menu_file.addAction(self.save_file_action)

        # menubar edit menu

        self.undo_edit_action = QAction("Undo", MainWindow)
        self.menu_edit.addAction(self.undo_edit_action)

        self.redo_edit_action = QAction("Redo", MainWindow)
        self.menu_edit.addAction(self.redo_edit_action)

        self.copy_edit_action = QAction("Copy", MainWindow)
        self.menu_edit.addAction(self.copy_edit_action)

        self.cut_edit_action = QAction("Cut", MainWindow)
        self.menu_edit.addAction(self.cut_edit_action)

        self.paste_edit_action = QAction("Paste", MainWindow)
        self.menu_edit.addAction(self.paste_edit_action)

        self.image_edit_action = QAction("Insert an Image", MainWindow)
        self.menu_edit.addAction(self.image_edit_action)

        self.table_edit_action = QAction("Insert a Table", MainWindow)
        self.menu_edit.addAction(self.table_edit_action)

        self.time_edit_action = QAction("Insert the current Time", MainWindow)
        self.menu_edit.addAction(self.time_edit_action)

        self.date_edit_action = QAction("Insert the current Date", MainWindow)
        self.menu_edit.addAction(self.date_edit_action)

        # menubar format menu

        self.fontcolor_format_action = QAction("Choose font color", MainWindow)
        self.menu_format.addAction(self.fontcolor_format_action)

        self.fontbgcolor_format_action = QAction(
            "Choose font Background Color", MainWindow)
        self.menu_format.addAction(self.fontbgcolor_format_action)

        self.font_format_action = QAction("Choose font", MainWindow)
        self.menu_format.addAction(self.font_format_action)

        self.leftalign_format_action = QAction("Align Text Left", MainWindow)
        self.menu_format.addAction(self.leftalign_format_action)

        self.centeralign_format_action = QAction("Align Text Center",
                                                 MainWindow)
        self.menu_format.addAction(self.centeralign_format_action)

        self.rightalign_format_action = QAction("Align Text Right", MainWindow)
        self.menu_format.addAction(self.rightalign_format_action)

        self.alignjustify_format_action = QAction("Align Text Justify",
                                                  MainWindow)
        self.menu_format.addAction(self.alignjustify_format_action)

        # menubar export menu

        self.toolbar = QToolBar(MainWindow)
        MainWindow.addToolBar(self.toolbar)

        self.addnew = QAction(QIcon("icons/notebookgrey.png"),
                              "Add New Nobebook", MainWindow)

        self.addnew.setShortcut('Ctrl+N')

        self.toolbar.addAction(self.addnew)

        self.addtab = QAction(QIcon("icons/tabtest"), "Add New Tab",
                              MainWindow)

        self.addtab.setShortcut('Ctrl+T')

        self.toolbar.addAction(self.addtab)

        self.toolbar.addSeparator()

        self.saveAction = QAction(QIcon("icons/save.png"),
                                  "Save Current Note File", MainWindow)

        self.saveAction.setShortcut('Ctrl+S')

        self.toolbar.addAction(self.saveAction)

        self.newFile = QAction(QIcon("icons/new.png"), "Create New Note File",
                               MainWindow)

        self.newFile.setShortcut('Ctrl+Shift+N')

        self.toolbar.addAction(self.newFile)

        self.openAction = QAction(QIcon("icons/open.png"), "open notes file",
                                  MainWindow)

        self.openAction.setShortcut('Ctrl+O')

        self.toolbar.addAction(self.openAction)

        self.toolbar.addSeparator()

        self.undoAction = QAction(QIcon("icons/undo.png"), "undo", MainWindow)

        self.undoAction.setShortcut('Ctrl+Z')

        self.toolbar.addAction(self.undoAction)

        self.redoAction = QAction(QIcon("icons/redo.png"), "redo", MainWindow)

        self.redoAction.setShortcut('Ctrl+Alt+Z')

        self.toolbar.addAction(self.redoAction)

        self.printcfg = QAction(QIcon("icons/pdf.png"), "print", MainWindow)

        self.toolbar.addAction(self.printcfg)

        self.toolbar.addSeparator()

        self.copyAction = QAction(QIcon("icons/copy.png"), "copy text",
                                  MainWindow)

        self.copyAction.setShortcut('Ctrl+C')

        self.toolbar.addAction(self.copyAction)

        self.pasteAction = QAction(QIcon("icons/paste.png"), "paste text",
                                   MainWindow)

        self.pasteAction.setShortcut('Ctrl+V')

        self.toolbar.addAction(self.pasteAction)

        self.cutAction = QAction(QIcon("icons/cut.png"), "cut text",
                                 MainWindow)

        self.cutAction.setShortcut('Ctrl+X')

        self.toolbar.addAction(self.cutAction)

        self.toolbar.addSeparator()

        self.leftAlign = QAction(QIcon("icons/alignleft.png"), "align left",
                                 MainWindow)

        self.toolbar.addAction(self.leftAlign)

        self.rightAlign = QAction(QIcon("icons/alignright.png"), "align right",
                                  MainWindow)

        self.toolbar.addAction(self.rightAlign)

        self.centerAlign = QAction(QIcon("icons/center.png"), "align center",
                                   MainWindow)

        self.toolbar.addAction(self.centerAlign)

        self.justifyAlign = QAction(QIcon("icons/justify.png"),
                                    "align justify", MainWindow)

        self.toolbar.addAction(self.justifyAlign)

        self.toolbar.addSeparator()

        self.dateAction = QAction(QIcon("icons/calendar.png"), "insert date",
                                  MainWindow)

        self.dateAction.setShortcut('Ctrl+Alt+D')

        self.toolbar.addAction(self.dateAction)

        self.timeAction = QAction(QIcon("icons/clock.png"), "insert time",
                                  MainWindow)

        self.timeAction.setShortcut('Ctrl+Alt+T')

        self.toolbar.addAction(self.timeAction)

        self.toolbar.addSeparator()

        self.bulletAction = QAction(QIcon("icons/bullets.png"),
                                    "insert bulleted list", MainWindow)

        self.bulletAction.setShortcut('Ctrl+B')

        self.toolbar.addAction(self.bulletAction)

        self.numberAction = QAction(QIcon("icons/numbers.png"),
                                    "insert numbered list", MainWindow)

        self.numberAction.setShortcut('Alt+N')

        self.toolbar.addAction(self.numberAction)

        self.toolbar.addSeparator()

        self.tableAction = QAction(QIcon("icons/table.png"), "insert table",
                                   MainWindow)

        self.tableAction.setShortcut('Ctrl+Shift+T')

        self.toolbar.addAction(self.tableAction)

        self.imageAction = QAction(QIcon("icons/image.png"), "insert image",
                                   MainWindow)

        self.imageAction.setShortcut('Ctrl+Alt+I')

        self.toolbar.addAction(self.imageAction)

        self.toolbar.addSeparator()

        self.fontcolorAction = QAction(QIcon("icons/fontcolor.png"),
                                       "Select font color", MainWindow)

        self.fontcolorAction.setShortcut('Ctrl+Shift+C')

        self.toolbar.addAction(self.fontcolorAction)

        self.fontBackgroundAction = QAction(QIcon("icons/highlight.png"),
                                            "Select font background color",
                                            MainWindow)

        self.fontBackgroundAction.setShortcut('Ctrl+Alt+C')

        self.toolbar.addAction(self.fontBackgroundAction)

        self.fontAction = QAction(QIcon("icons/text.png"), "Choose Font",
                                  MainWindow)

        self.fontAction.setShortcut('Ctrl+F')

        self.toolbar.addAction(self.fontAction)

        self.HRAction = QAction(QIcon("icons/hr.png"),
                                "Insert Horizontal Rule", MainWindow)

        self.HRAction.setShortcut('Ctrl+L')

        self.toolbar.addAction(self.HRAction)

        self.central_widget = QWidget(MainWindow)
        self.central_widget.setObjectName('central')

        self.splitter = QSplitter(self.central_widget)
        self.splitter.setOrientation(Qt.Horizontal)
        self.splitter.setStretchFactor(0, 25)
        self.splitter.setStretchFactor(1, 75)

        self.list = QListWidget(self.splitter)
        self.list.setObjectName("List")
        self.list.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        #self.list.setAlternatingRowColors(True)

        self.list.setAcceptDrops(True)
        self.list.setDragDropMode(QAbstractItemView.InternalMove)
        self.list.setDragEnabled(True)

        self.stack = QStackedWidget(self.splitter)
        self.stack.setObjectName("Stack")
        self.stack.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)

        self.listFrame = QFrame()
        self.stackFrame = QFrame()  #maybe delete this

        self.splitter.addWidget(self.list)
        self.splitter.addWidget(self.stack)

        self.splitter.setSizes([50, 650])

        ####################################################################################################################

        self.boxlayout = QHBoxLayout()
        self.central_widget.setLayout(self.boxlayout)
        MainWindow.setCentralWidget(self.central_widget)

        self.boxlayout.addWidget(self.splitter)
        MainWindow.show()
示例#18
0
文件: gui.py 项目: ARL-UTEP-OC/ndct
class MainGUI(QMainWindow):
    def __init__(self, logman, comment_mgr, val):
        logging.debug("MainGUI(): Instantiated")
        super(MainGUI, self).__init__()
        self.setWindowTitle('Traffic Annotation Workflow')
        self.setFixedSize(670,565)

        self.logman = logman
        self.comment_mgr = comment_mgr
        self.val = val

        self.project_sessions = ProjectSessions()
        self.cm = ConfigurationManager.get_instance()

        #shared data between widgets
        self.existingconfignames = {}
        self.logEnabled = ''
        self.closeConfirmed = ''
        self.newProject_pressed = False
        self.newPro = None

        #get project folder
        self.project_data_folder = self.cm.read_config_value("PROJECTS", "PROJECTS_BASE_PATH")
        self.createRequiredSubDirectories()

        self.at_start = True

        self.mainWidget = QWidget()
        self.setCentralWidget(self.mainWidget)
        mainlayout = QVBoxLayout()
        self.baseWidget = QWidget() #BaseWidget()
        self.annotateWidget = QWidget()
        self.resultsWidget = QWidget()
        self.projectTree = QtWidgets.QTreeWidget()
        self.baseWidgets = {}
        self.blankTreeContextMenu = {}
        
        quit = QAction("Quit", self)
        quit.triggered.connect(self.closeEvent)

        #Add tab widget - RES
        tabWidget = QtWidgets.QTabWidget()
        tabWidget.setGeometry(QtCore.QRect(0, 15, 668, 565))
        tabWidget.setObjectName("tabWidget")

        #BaseWidget
        self.baseWidget.setWindowTitle("BaseWidget")
        self.baseWidget.setObjectName("BaseWidget")
        baseLayoutWidget = QtWidgets.QWidget()
        baseLayoutWidget.setObjectName("layoutWidget")
        self.baseOuterVertBox = QtWidgets.QVBoxLayout()
        self.baseOuterVertBox.setObjectName("outerVertBox")
        baseLayoutWidget.setLayout(self.baseOuterVertBox)

        self.baseWidget.setLayout(self.baseOuterVertBox)

        #Configuration window - RES
        ## windowBoxHLayout contains:
        ###projectTree (Left)
        ###basedataStackedWidget (Right)
        windowWidget = QtWidgets.QWidget()
        windowWidget.setObjectName("windowWidget")
        windowBoxHLayout = QtWidgets.QHBoxLayout()
        windowBoxHLayout.setObjectName("windowBoxHLayout")
        windowWidget.setLayout(windowBoxHLayout)

        self.projectTree.itemSelectionChanged.connect(self.onItemSelected)
        self.projectTree.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.projectTree.customContextMenuRequested.connect(self.showContextMenu)
        self.projectTree.setEnabled(True)
        self.projectTree.setMaximumSize(200,521)
        self.projectTree.setObjectName("projectTree")
        self.projectTree.headerItem().setText(0, "Projects")
        self.projectTree.setSortingEnabled(False)
        windowBoxHLayout.addWidget(self.projectTree)

        self.basedataStackedWidget = QStackedWidget()
        self.basedataStackedWidget.setObjectName("basedataStackedWidget")
        windowBoxHLayout.addWidget(self.basedataStackedWidget)
        tabWidget.addTab(windowWidget, "Configuration")

        #ADD TAB WIDGET - RES
        self.initMenu()
        mainlayout = QVBoxLayout()
        mainlayout.addWidget(self.mainMenu)
        mainlayout.addWidget(tabWidget)
        self.mainWidget.setLayout(mainlayout)

        #load any saved projects
        self.load_saved()
        self.load_sessions()
        self.at_start = False

        logging.debug("MainWindow(): Complete")

    def createRequiredSubDirectories(self):
        logging.debug("MainApp:createRequiredSubDirectories() instantiated")
        if os.path.exists(self.project_data_folder) == False:
            try:
                os.makedirs(self.project_data_folder)
            except:
                logging.error("MainApp:createRequiredSubDirectories(): An error occured when trying to create project directories: ")
                exc_type, exc_value, exc_traceback = sys.exc_info()
                traceback.print_exception(exc_type, exc_value, exc_traceback)
                QMessageBox.error(self,
                                        "Create Error",
                                        "Could not create project subdirectories, quitting...",
                                        QMessageBox.Ok) 
                exit()

    #RES Method
    def onItemSelected(self):
        logging.debug("MainApp:onItemSelected instantiated")
    	# Get the selected item
        self.selectedItem = self.projectTree.currentItem()
        if self.selectedItem == None:
            logging.debug("MainApp:onItemSelected no configurations left")
            self.statusBar.showMessage("No configuration items selected or available.")
            return
        #Check if it's the case that an project name was selected
        parentSelectedItem = self.selectedItem.parent()

        if(parentSelectedItem == None):
            #A base widget was selected
            #logging.debug"PROJECT_WIDGET: " + str((self.baseWidgets[self.selectedItem.text(0)]["ProjectWidget"])))
            self.basedataStackedWidget.setCurrentWidget(self.baseWidgets[self.selectedItem.text(0)]["ProjectWidget"])
        else:
            #for children
            parentOfParent = parentSelectedItem.parent()

            #Check if it's the case that a Session Name was selected
            if(self.selectedItem.text(0)[0] == "S"):
                #logging.debug"SESSION_WIDGET: " + str(self.baseWidgets[parentSelectedItem.text(0)][self.selectedItem.text(0)]["SessionWidget"]))
                logging.debug("Setting right widget: " + str(self.baseWidgets[parentSelectedItem.text(0)][self.selectedItem.text(0)]["SessionWidget"]))
                self.basedataStackedWidget.setCurrentWidget(self.baseWidgets[parentSelectedItem.text(0)][self.selectedItem.text(0)]["SessionWidget"])
                #Check if it's the case that a Annotate was selected
            elif(self.selectedItem.text(0)[0] == "A"):
                #logging.debug"ANNOTATE " + str(self.baseWidgets[parentOfParent.text(0)][parentSelectedItem.text(0)]["AnnotateWidget"]))
                logging.debug("Setting right widget: " + str(self.baseWidgets[parentOfParent.text(0)][parentSelectedItem.text(0)]["AnnotateWidget"]))
                self.basedataStackedWidget.setCurrentWidget(self.baseWidgets[parentOfParent.text(0)][parentSelectedItem.text(0)]["AnnotateWidget"])
            #Check if it's the case that a Rules was selected
            elif(self.selectedItem.text(0)[0] == "R"):
                #logging.debug"RULES " + str(self.baseWidgets[parentOfParent.text(0)][parentSelectedItem.text(0)]["RulesWidget"]))
                logging.debug("Setting right widget: " + str(self.baseWidgets[parentOfParent.text(0)][parentSelectedItem.text(0)]["RulesWidget"]))
                self.basedataStackedWidget.setCurrentWidget(self.baseWidgets[parentOfParent.text(0)][parentSelectedItem.text(0)]["RulesWidget"])
            #Check if it's the case that a Results was selected
            elif(self.selectedItem.text(0)[0] == "X"):
                #logging.debug"RESULTS " + str(self.baseWidgets[parentOfParent.text(0)][parentSelectedItem.text(0)]["ResultsWidget"]))
                logging.debug("Setting right widget: " + str(self.baseWidgets[parentOfParent.text(0)][parentSelectedItem.text(0)]["ResultsWidget"]))
                self.basedataStackedWidget.setCurrentWidget(self.baseWidgets[parentOfParent.text(0)][parentSelectedItem.text(0)]["ResultsWidget"])


    def on_add_curation_clicked(self):
        logging.debug("on_add_curation_clicked(): Instantiated")
        selectedItem = self.projectTree.currentItem()

        self.nsd = NewSessionDialog(selectedItem.text(0))
        projectSessions = []
        for pot_session in self.baseWidgets[selectedItem.text(0)]:
            if pot_session.startswith("S:"):
                projectSessions.append(pot_session)
        if len(projectSessions) > 0:
            self.nsd.templateNameComboBox.addItems(projectSessions)
            self.nsd.templateNameComboBox.setEnabled(True)
        self.nsd.created.connect(self.session_created)
        self.nsd.setWindowModality(QtCore.Qt.ApplicationModal)
        self.nsd.show()

    def addSession(self, projectItem, sessionName):
        logging.debug("addSession(): Instantiated")

        projectName = projectItem.text(0)
        add_session_result = self.add_session_list(projectName, sessionName)

        if add_session_result == False:
            logging.error("An error occured when trying to add session to GUI: " + str(sessionName))
            return
        else:
            sessionLabel = "S: " + sessionName
            #create tree widget item
            sessionItem = QtWidgets.QTreeWidgetItem(projectItem)
            sessionItem.setText(0,sessionLabel)   
            sessionWidget = SessionWidget(sessionName)

            self.baseWidgets[projectName][sessionLabel] = {} #project name (Parent of Parent) + session name (parent of children)
            self.baseWidgets[projectName][sessionLabel]["SessionWidget"] = sessionWidget
            self.basedataStackedWidget.addWidget(sessionWidget)

            #create other widget items
            ##ANNOTATE
            annItem = QtWidgets.QTreeWidgetItem()
            annLabel = "A: " + "Annotate"
            annItem.setText(0, annLabel)
            sessionItem.addChild(annItem)
            self.annotateWidget = AnnotateWidget(self.project_data_folder, projectName, os.path.basename(self.existingconfignames[projectName]), sessionName, self.comment_mgr) #send project name for the corresponding directory

            self.baseWidgets[projectName][sessionLabel]["AnnotateWidget"] = self.annotateWidget #child
            self.basedataStackedWidget.addWidget(self.annotateWidget)

            ##RULES
            rulesItem = QtWidgets.QTreeWidgetItem()
            rulesLabel = "R: " + "Rules"
            rulesItem.setText(0, rulesLabel)
            sessionItem.addChild(rulesItem)
            #add the corresponding directory -- if it is already created, skip
            rulesDir = os.path.join(self.project_data_folder, projectName)
            rulesDir = os.path.join(rulesDir, ConfigurationManager.STRUCTURE_RULES_GEN_PATH)

            if os.path.exists(rulesDir) == False:
                os.mkdir(rulesDir)

            rulesWidget = RulesWidget(self.project_data_folder, projectName, os.path.basename(self.existingconfignames[projectName]), sessionName, rulesDir, self.comment_mgr, self.val)

            self.baseWidgets[projectName][sessionLabel]["RulesWidget"] = rulesWidget
            self.basedataStackedWidget.addWidget(rulesWidget)

            ##RESULTS
            resultsItem = QtWidgets.QTreeWidgetItem()
            resultsLabel = "X: " + "Results"
            resultsItem.setText(0, resultsLabel)
            sessionItem.addChild(resultsItem)

            #add the corresponding directory -- if it is already created, skip
            resultsDir = os.path.join(self.project_data_folder, projectName)
            resultsDir = os.path.join(resultsDir, "IDS-ALERTS")

            if os.path.exists(resultsDir) == False:
                os.mkdir(resultsDir)
        
            self.resultsWidget = ResultsWidget(self.project_data_folder, projectName, sessionName, resultsDir, self.val)
        
            self.baseWidgets[projectName][sessionLabel]["ResultsWidget"] = self.resultsWidget
            self.basedataStackedWidget.addWidget(self.resultsWidget)

        logging.debug("on_add_curation_clicked(): Completed")

    def on_export_clicked(self):
        #get project dir
        selectedItem = self.projectTree.currentItem()
        selectedItemName = selectedItem.text(0)

        project_folder = os.path.join(self.project_data_folder, selectedItemName)
        project_folder = os.path.abspath(project_folder)

        self.exportPro = ExportDialog(self, selectedItemName, project_folder).exec_()
        #self.exportPro.setWindowModality(QtCore.Qt.ApplicationModal)
        #self.exportPro.show()

    #RES METHOD
    def showContextMenu(self, position):
    	logging.debug("MainApp:showContextMenu() instantiated: " + str(position))
    	if(self.projectTree.itemAt(position) == None):
    		self.blankTreeContextMenu.popup(self.projectTree.mapToGlobal(position))
    	elif(self.projectTree.itemAt(position).parent() == None):
    		self.projectContextMenu.popup(self.projectTree.mapToGlobal(position))

    #RES METHOD
    def initMenu(self):               
        logging.debug("MainApp:initMenu() instantiated")
        self.mainMenu = QMenuBar()
        self.fileMenu = self.mainMenu.addMenu("File")

        self.blankTreeContextMenu = QtWidgets.QMenu()
       	self.newProjectContextMenu = QtWidgets.QMenu("New Project")
        self.blankTreeContextMenu.addMenu(self.newProjectContextMenu)

        self.fromCapture = self.newProjectContextMenu.addAction("Create Capture")
        self.fromCapture.triggered.connect(self.newFromCapture)

        self.fromPCAP = self.newProjectContextMenu.addAction("From PCAP")
        self.fromPCAP.triggered.connect(self.newFromPCAP)

        # Experiment context menu
        self.importContextMenu =  QtWidgets.QMenu("Import Project")
        self.blankTreeContextMenu.addMenu(self.importContextMenu)
        
        self.fromFolderContextSubMenu = self.importContextMenu.addAction("From Folder")
        self.fromFolderContextSubMenu.triggered.connect(self.importFromFolder)

        self.fromZipContextSubMenu = self.importContextMenu.addAction("From Zip")
        self.fromZipContextSubMenu.triggered.connect(self.importFromZip)

        #Context menu project 
        self.projectContextMenu = QtWidgets.QMenu()
        self.addCuration = self.projectContextMenu.addAction("Create curation session")
        self.addCuration.triggered.connect(self.on_add_curation_clicked)

        self.exportProject = self.projectContextMenu.addAction("Export project")
        self.exportProject.triggered.connect(self.on_export_clicked)

        self.quitAppMenuButton = QAction(QIcon(), "Quit", self)
        self.quitAppMenuButton.setShortcut("Ctrl+Q")
        self.quitAppMenuButton.setStatusTip("Quit App")
        self.quitAppMenuButton.triggered.connect(self.closeEvent)
        self.fileMenu.addAction(self.quitAppMenuButton)
    
    #Used to create a new project, this is where the prompt to write a name for the project is taken.
    def newFromCapture(self):
        logging.debug("MainApp:newFromCapture() instantiated")
        #Creating a custom widget to display what is needed for creating a new project:
        self.newPro = NewFromCollectDataDialog(self.logman, self.existingconfignames)
        #slots to receive data from the custom widget
        self.newPro.logEnabled.connect(self.log_enabled)
        self.newPro.created.connect(self.project_created)
        self.newPro.closeConfirmed.connect(self.close_confirmed)
        self.newProject_pressed = True
        self.newPro.setWindowModality(QtCore.Qt.ApplicationModal)
        self.newPro.show()

    def newFromPCAP(self):
        logging.debug("MainApp:newFromPCAP() instantiated")
        #Creating a custom widget to display what is needed for creating a new project:
        self.newCap = NewFromPCAPDialog(self.existingconfignames)
        #slot to receive data from the custom widget
        self.newCap.created.connect(self.project_created)
        self.newProject_pressed = True
        self.newCap.setWindowModality(QtCore.Qt.ApplicationModal)
        self.newCap.show()

    #Slot for when the user created the new project, path and configname
    @QtCore.pyqtSlot(str, dict, str)
    def project_created(self, configname, existingconfignames, path):
        #update project info with new info selected from widget     
        self.existingconfignames = existingconfignames
        #create the new project with the updated information
        self.addProject(configname, self.existingconfignames[configname], path)
    
    @QtCore.pyqtSlot(str)
    def session_created(self, newsessionname):
        #call the function to add session to gui
        selectedProject =  self.projectTree.currentItem()
        self.addSession(selectedProject, newsessionname)

    #Slot to let us know if the logging has started
    @QtCore.pyqtSlot(str)
    def log_enabled(self, status):
        self.logEnabled = status

    #Slot to let us know if the close has been confirmed or canceled
    @QtCore.pyqtSlot(str)
    def close_confirmed(self, status):
        self.closeConfirmed = status

    #Used to create a new project, and this is where the project will actually be populated
    def addProject(self, configname, projectPCAP, path):
        if configname in self.baseWidgets:
            logging.debug("Project already in tree: " + str(configname + "; skipping"))
            return
        #create the folders and files for new project if it's not already there:
        self.projectWidget  = ProjectWidget(configname, projectPCAP, path)
        configTreeWidgetItem = QtWidgets.QTreeWidgetItem(self.projectTree)
        configTreeWidgetItem.setText(0,configname)
        self.projectWidget.addProjectItem(configname)

        #Add base info
        self.baseWidgets[configname] = {"BaseWidget": {}, "ProjectWidget": {}, "SessionWidget": {}, "AnnotateWidget": {}, "RulesWidget": {}, "ResultsWidget": {}}
        self.baseWidgets[configname]["BaseWidget"] = self.baseWidget
        self.basedataStackedWidget.addWidget(self.baseWidget)
        
        self.baseWidgets[configname]["ProjectWidget"] = self.projectWidget

        self.basedataStackedWidget.addWidget(self.projectWidget)
        self.basedataStackedWidget.addWidget(self.baseWidget)

        #add to list
        self.project_sessions.add_project(configname)

    def importFromZip(self):
        logging.debug("MainApp:importFromZip() instantiated") 
        zip_file = QFileDialog()
        zip_file.setWindowTitle("Select File")
        zip_file.setFileMode(QtWidgets.QFileDialog.ExistingFile)
        zip_file.setNameFilter("Zip Files (*.zip)")

        filenames = zip_file.getOpenFileName()
        filename = filenames[0]
        if filename == "":
            logging.debug("File choose cancelled")
            return
        else:

            configname = os.path.basename(filename)
            configname = os.path.splitext(configname)[0]

            if configname in self.existingconfignames:
                QMessageBox.warning(self,
                                    "Name Exists",
                                    "A project with the same name already exists.",
                                    QMessageBox.Ok)            
                return None
            else:
                #instance of package manage
                pack_mgr = PackageManager()
                self.populate_import(pack_mgr, configname, os.path.abspath(filename))

    def importFromFolder(self, configname):
        logging.debug("MainApp:importFromFolder() instantiated") 

        folder_chosen = str(QFileDialog.getExistingDirectory(self, "Select Directory to Store Data"))
        if folder_chosen == "":
            logging.debug("File choose cancelled")
            return

        if len(folder_chosen) > 0:
            baseNoExt = os.path.basename(folder_chosen)
            baseNoExt = os.path.splitext(baseNoExt)[0]
            configname = ''.join(e for e in baseNoExt if e.isalnum)
            if configname in self.existingconfignames:
                QMessageBox.warning(self,
                                    "Name Exists",
                                    "A project with the same name already exists.",
                                    QMessageBox.Ok)            
                return None
    
            else:
                self.populate_import("dir", configname, folder_chosen)

                
    def populate_import(self, function, configname, from_file):
        importedProjectPath = os.path.join(self.project_data_folder, configname)
        #copy selected dir to new dir
        self.batch_thread = BatchThread()
        self.batch_thread.progress_signal.connect(self.update_progress_bar)
        self.batch_thread.completion_signal.connect(self.copy_dir_complete)
        if function == "dir":
            self.batch_thread.add_function(self.copy_dir, from_file, importedProjectPath)
        else:
            self.batch_thread.add_function(function.unzip, from_file, configname, self.project_data_folder)

        self.progress_dialog_overall = ProgressBarDialog(self, self.batch_thread.get_load_count())
        self.batch_thread.start()
        self.progress_dialog_overall.show()

    def load_project_widgets(self):
        logging.debug("load_project_widgets(): instantiated")
        for name in self.existingconfignames:
            path = os.path.join(self.project_data_folder, name)
            projectPCAP = os.path.join(path, self.existingconfignames[name])
            configname = name
            self.addProject(configname, projectPCAP, path)
        logging.debug("load_project_widgets(): Complete")

    def copy_dir(self, from_dir, to_dir):
        logging.debug("copy_dir(): copying selected directory")
        copy_tree(from_dir, to_dir)
        logging.debug("copy_dir(): copying complete")

    def copy_dir_complete(self):
        logging.debug("copy_dir_complete(): Instantiated")
        self.progress_dialog_overall.update_progress()
        self.progress_dialog_overall.hide()
        #Need to load projects (add to existing...)
        ##GET Project PCAP Name Here and also add to existingprojectnames
        self.load_saved()
        self.load_sessions()
        logging.debug("copy_dir_complete(): Complete")

    def load_saved(self):
        i = 0

        #for each subdir, import the saved projects
        for (dirName, subdirlist, filelist) in os.walk(self.project_data_folder):
            for projectFolder in subdirlist:
                pcapSubdir = os.path.join(self.project_data_folder, projectFolder, ConfigurationManager.STRUCTURE_PCAP_SUBDIR)
                abspcapSubdir = os.path.abspath(pcapSubdir)
                if os.path.exists(abspcapSubdir):
                    #go one level down
                    #if this is the pcap directory, then check if a pcap exists
                    #if so, this is a good project; create an entry in existingconfignames
                    for (subdirName, subsubdirlist, subfilelist) in os.walk(abspcapSubdir):
                        if len(subfilelist) == 1:
                            filename = subfilelist[0]
                            spt = os.path.splitext(filename)
                            if spt[1] == ".pcap" or spt[1] == ".pcapng":
                                self.existingconfignames[projectFolder] = filename
                                break
        #once everything has been added, populate widget
        self.load_project_widgets()

    def load_sessions(self):
        for name in self.existingconfignames:
            #for already saved project
            project_path = os.path.join(self.project_data_folder, name)
            project_pcap_session = os.path.join(project_path, ConfigurationManager.STRUCTURE_PCAP_SUBDIR)
            if os.path.exists(project_pcap_session):
                paths, dirs, files = next(os.walk(project_pcap_session))
                if len(dirs) > 0:
                    self.traverse_sessions(name, project_pcap_session)

    def traverse_sessions(self, project_name, path):
        #if RULES dir exists in project folder, then sessions exists
        i = 0

        for (dirName, subdirlist, filelist) in os.walk(path):
            for sessionName in subdirlist:
                if os.path.isfile(sessionName):
                    #skip
                    break
                
                elif self.add_session_list(project_name, sessionName) == True:
                    self.add_session_widgets(project_name, self.existingconfignames[project_name], sessionName)

    def add_session_widgets(self, project_name, project_pcap_filename, sessionName):
        sessionLabel = "S: " + sessionName
        #create tree widget item
        selectedItem = self.projectTree.findItems(project_name, Qt.Qt.MatchContains)
        sessionItem = QtWidgets.QTreeWidgetItem(selectedItem[0])
        sessionItem.setText(0,sessionLabel)   
        sessionWidget = SessionWidget(sessionName)
        
        self.baseWidgets[project_name][sessionLabel] = {} #project name (Parent of Parent) + session name (parent of children)
        self.baseWidgets[project_name][sessionLabel]["SessionWidget"] = sessionWidget
        self.basedataStackedWidget.addWidget(sessionWidget)

        #create other widget items
        ##ANNOTATE
        annItem = QtWidgets.QTreeWidgetItem()
        annLabel = "A: " + "Annotate"
        annItem.setText(0, annLabel)
        sessionItem.addChild(annItem)
        self.annotateWidget = AnnotateWidget(self.project_data_folder, project_name, project_pcap_filename, sessionName, self.comment_mgr) #send project name for the corresponding directory

        self.baseWidgets[project_name][sessionLabel]["AnnotateWidget"] = self.annotateWidget #child
        self.basedataStackedWidget.addWidget(self.annotateWidget)

        ##RULES
        rulesItem = QtWidgets.QTreeWidgetItem()
        rulesLabel = "R: " + "Rules"
        rulesItem.setText(0, rulesLabel)
        sessionItem.addChild(rulesItem)
        #add the corresponding directory -- if it is already created, skip
        rulesDir = os.path.join(self.project_data_folder, project_name)
        rulesDir = os.path.join(rulesDir, ConfigurationManager.STRUCTURE_RULES_GEN_PATH)

        if os.path.exists(rulesDir) == False:
            os.mkdir(rulesDir)
    
        self.rulesWidget = RulesWidget(self.project_data_folder, project_name, project_pcap_filename, sessionName, rulesDir, self.comment_mgr, self.val)

        self.baseWidgets[project_name][sessionLabel]["RulesWidget"] = self.rulesWidget
        self.basedataStackedWidget.addWidget(self.rulesWidget)

        ##RESULTS
        resultsItem = QtWidgets.QTreeWidgetItem()
        resultsLabel = "X: " + "Results"
        resultsItem.setText(0, resultsLabel)
        sessionItem.addChild(resultsItem)
        #add the corresponding directory -- if it is already created, skip
        resultsDir = os.path.join(self.project_data_folder, project_name)
        resultsDir = os.path.join(resultsDir, "IDS-ALERTS")

        if os.path.exists(resultsDir) == False:
            os.mkdir(resultsDir)
                
        self.resultsWidget = ResultsWidget(self.project_data_folder, project_name, sessionName, resultsDir, self.val)
               
        self.baseWidgets[project_name][sessionLabel]["ResultsWidget"] = self.resultsWidget
        self.basedataStackedWidget.addWidget(self.resultsWidget)
            
    def add_session_list(self, project_name, project_session):
        #method returns true if session was successfully added
        success = self.project_sessions.add_project_session(project_name, project_session)

        if success == False:
            #self.project_sessions.print_d()
            return False
        else:
            #self.project_sessions.print_d()
            return True

    def update_progress_bar(self):
        logging.debug('update_progress_bar(): Instantiated')
        self.progress_dialog_overall.update_progress()
        logging.debug('update_progress_bar(): Complete')


    def closeEvent(self, event):
        logging.debug("closeEvent(): instantiated")

        self.quit_event = event

        if self.logEnabled == "TRUE":
            #This means that the new project widget is still running so call the close event
            #for that widget first to stop logger
            self.newPro.closeEvent(event)

            #Check if the close was confirmed or not
            if self.closeConfirmed == "TRUE":
                #after that's done, make sure to quit the app
                self.quit_event.accept()
                #self.close()
                qApp.quit()
            else: 
                return
        else:
            close = QMessageBox.question(self, 
                                "QUIT",
                                "Are you sure you want to quit?",
                                QMessageBox.Yes | QMessageBox.No)

            if close == QMessageBox.Yes:
                #call the delete data function from new project, just to make sure
                #everything has been cleared out
                if self.newProject_pressed == True:
                    if self.newPro != None:
                        self.newPro.delete_data()
                qApp.quit()
                return
            elif close == QMessageBox.No and not type(self.quit_event) == bool:
                    self.quit_event.ignore()
            pass
        return

    def quit_app(self):
        self.quit_event.accept()
        qApp.quit()
        return
示例#19
0
class SettingsWindow(QDialog):

    def __init__(self):
        super().__init__()
        self.setWindowTitle('nParse Settings')

        layout = QVBoxLayout()

        top_layout = QHBoxLayout()
        self._list_widget = QListWidget()
        self._list_widget.setObjectName('SettingsList')
        self._list_widget.setSelectionMode(QListWidget.SingleSelection)
        self._list_widget.currentItemChanged.connect(self._switch_stack)
        self._widget_stack = QStackedWidget()
        self._widget_stack.setObjectName('SettingsStack')
        top_layout.addWidget(self._list_widget, 0)
        top_layout.addWidget(self._widget_stack, 1)

        settings = self._create_settings()
        if settings:
            for setting_name, stacked_widget in settings:
                self._list_widget.addItem(QListWidgetItem(setting_name))
                self._widget_stack.addWidget(stacked_widget)

            self._list_widget.setCurrentRow(0)
        self._list_widget.setMaximumWidth(
            self._list_widget.minimumSizeHint().width())

        self._list_widget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        buttons = QWidget()
        buttons.setObjectName('SettingsButtons')
        buttons_layout = QHBoxLayout()
        buttons_layout.setContentsMargins(0, 0, 0, 0)
        save_button = QPushButton('Save')
        save_button.setAutoDefault(False)
        save_button.clicked.connect(self._save)
        buttons_layout.addWidget(save_button)
        cancel_button = QPushButton('Cancel')
        cancel_button.setAutoDefault(False)
        cancel_button.clicked.connect(self._cancelled)
        buttons_layout.addWidget(cancel_button)
        buttons_layout.insertStretch(0)
        buttons.setLayout(buttons_layout)
        layout.addLayout(top_layout, 1)
        layout.addWidget(buttons, 0)

        self.setLayout(layout)

        self._set_values()

    def _save(self):
        for stacked_widget in self._widget_stack.findChildren(QFrame):
            for widget in stacked_widget.children():
                wt = type(widget)
                if wt == QCheckBox:
                    key1, key2 = widget.objectName().split(':')
                    config.data[key1][key2] = widget.isChecked()
                elif wt == QSpinBox:
                    key1, key2 = widget.objectName().split(':')
                    config.data[key1][key2] = widget.value()
                elif wt == QLineEdit:
                    key1, key2 = widget.objectName().split(':')
                    config.data[key1][key2] = widget.text()
        config.save()
        self.accept()

    def _cancelled(self):
        self._set_values()
        self.reject()

    def showEvent(self, _):
        self._set_values()

    def closeEvent(self, _):
        self._set_values()
        self.reject()

    def _switch_stack(self):
        if self._list_widget.selectedIndexes():
            self._widget_stack.setCurrentIndex(self._list_widget.currentRow())

    def _set_values(self):
        for stacked_widget in self._widget_stack.findChildren(QFrame):
            for widget in stacked_widget.children():
                wt = type(widget)
                if wt == QCheckBox:
                    key1, key2 = widget.objectName().split(':')
                    widget.setChecked(config.data[key1][key2])
                elif wt == QSpinBox:
                    key1, key2 = widget.objectName().split(':')
                    widget.setValue(config.data[key1][key2])
                elif wt == QLineEdit:
                    key1, key2 = widget.objectName().split(':')
                    widget.setText(config.data[key1][key2])

    def _create_settings(self):
        stacked_widgets = []

        # General Settings
        general_settings = QFrame()
        gsl = QFormLayout()
        gsl.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow)
        gsl.addRow(SettingsHeader('general'))
        gsl_update_check = QCheckBox()
        gsl_update_check.setObjectName('general:update_check')
        gsl.addRow('Check for Updates', gsl_update_check)
        gsl.addRow(SettingsHeader('parsers'))
        gsl_opacity = QSpinBox()
        gsl_opacity.setRange(1, 100)
        gsl_opacity.setSingleStep(5)
        gsl_opacity.setSuffix('%')
        gsl_opacity.setObjectName('general:parser_opacity')
        gsl.addRow('Parser Window Opacity (% 1-100)', gsl_opacity)
        gsl_scaling = QSpinBox()
        gsl_scaling.setRange(100, 300)
        gsl_scaling.setSingleStep(5)
        gsl_scaling.setSuffix('%')
        gsl_scaling.setObjectName('general:qt_scale_factor')
        gsl.addRow('Window Scaling Factor', gsl_scaling)
        gsl.addRow(SettingsHeader('experimental'))
        gsl_enable_plugins = QCheckBox()
        gsl_enable_plugins.setObjectName('general:enable_plugins')
        gsl.addRow('Enable Plugins', gsl_enable_plugins)
        gsl_safe_mode = QCheckBox()
        gsl_safe_mode.setObjectName('general:safe_mode')
        gsl.addRow('Safe Mode', gsl_safe_mode)
        general_settings.setLayout(gsl)

        stacked_widgets.append(('General', general_settings))

        # Spell Settings
        spells_settings = QFrame()
        ssl = QFormLayout()
        ssl.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow)
        ssl.addRow(SettingsHeader('general'))
        ssl_casting_window = QCheckBox()
        ssl_casting_window.setWhatsThis(WHATS_THIS_CASTING_WINDOW)
        ssl_casting_window.setObjectName('spells:use_casting_window')
        ssl.addRow('Use Casting Window', ssl_casting_window)
        ssl_casting_window_buffer = QSpinBox()
        ssl_casting_window_buffer.setWhatsThis(WHATS_THIS_CASTING_BUFFER)
        ssl_casting_window_buffer.setRange(1, 4000)
        ssl_casting_window_buffer.setSingleStep(100)
        ssl_casting_window_buffer.setObjectName('spells:casting_window_buffer')

        ssl.addRow(
            'Casting Window Buffer (msec 1-4000)',
            ssl_casting_window_buffer
            )
        ssl_open_custom = QPushButton("Edit")
        ssl_open_custom.clicked.connect(self._get_custom_timers)
        row = ssl.addRow('Custom Timers', ssl_open_custom)

        ssl.addRow(SettingsHeader('experimental'))
        ssl_secondary_duration = QCheckBox()
        ssl_secondary_duration.setWhatsThis(WHATS_THIS_PVP_DURATION)
        ssl_secondary_duration.setObjectName('spells:use_secondary_all')
        ssl.addRow('Use PvP Durations', ssl_secondary_duration)
        ssl_save_spells = QCheckBox()
        ssl_save_spells.setObjectName('spells:save_spells')
        ssl.addRow('Save Spells Between Sessions', ssl_save_spells)
        spells_settings.setLayout(ssl)
        stacked_widgets.append(('Spells', spells_settings))

        # caoilainn fork
        # log streaming
        push_settings = QFrame()
        push = QFormLayout()
        push.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow)
        push.addRow(SettingsHeader('push notifications (experimental)'))

        push_enable = QCheckBox()
        push_enable.setWhatsThis(WHATS_THIS_PUSH_NOTIFICATIONS)
        push_enable.setObjectName('push:push_enabled')
        push.addRow('Use Push Notifications', push_enable)

        push_timer_expiry = QCheckBox()
        push_timer_expiry.setObjectName('push:timer_expiry')
        push.addRow('Push When Timer Expires', push_timer_expiry)

        push_afk_only = QCheckBox()
        push_afk_only.setObjectName('push:afk_only')
        push.addRow('Triggers Only When AFK', push_afk_only)

        push_timer_afk_only = QCheckBox()
        push_timer_afk_only.setObjectName('push:timer_expiry_afk_only')
        push.addRow('Timers Only When AFK', push_timer_afk_only)

        push_afk_idle_time = QSpinBox()
        push_afk_idle_time.setRange(0, 600)
        push_afk_idle_time.setSingleStep(1)
        push_afk_idle_time.setSuffix('s')
        push_afk_idle_time.setObjectName('push:idle_time_to_afk')
        push.addRow('Idle time to be AFK', push_afk_idle_time)
        push.addWidget(QLabel("You are always afk when using /afk.\n(0 to disable idle timer)"))

        push_api_key = QLineEdit()
        push_api_key.setMaxLength(512)
        push_api_key.setObjectName('push:prowl_api_key')
        push.addRow('Prowl API Key', push_api_key)

        push_edit_triggers = QPushButton("Edit")
        push_edit_triggers.clicked.connect(self._get_push_triggers)
        push.addRow('Push Triggers', push_edit_triggers)

        push_settings.setLayout(push)
        stacked_widgets.append(('Push', push_settings))

        # Map Settings
        map_settings = QFrame()
        msl = QFormLayout()
        msl.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow)
        msl.addRow(SettingsHeader('general'))
        msl_line_width = QSpinBox()
        msl_line_width.setObjectName('maps:line_width')
        msl_line_width.setRange(1, 10)
        msl_line_width.setSingleStep(1)
        msl.addRow('Map Line Width', msl_line_width)

        msl_grid_line_width = QSpinBox()
        msl_grid_line_width.setObjectName('maps:grid_line_width')
        msl_grid_line_width.setRange(1, 10)
        msl_grid_line_width.setSingleStep(1)
        msl.addRow('Grid Line Width', msl_grid_line_width)

        msl.addRow(SettingsHeader('z levels'))

        msl_current_z_alpha = QSpinBox()
        msl_current_z_alpha.setRange(1, 100)
        msl_current_z_alpha.setSingleStep(1)
        msl_current_z_alpha.setSuffix('%')
        msl_current_z_alpha.setObjectName('maps:current_z_alpha')
        msl.addRow('Current Z Opacity', msl_current_z_alpha)

        msl_closest_z_alpha = QSpinBox()
        msl_closest_z_alpha.setRange(1, 100)
        msl_closest_z_alpha.setSingleStep(1)
        msl_closest_z_alpha.setSuffix('%')
        msl_closest_z_alpha.setObjectName('maps:closest_z_alpha')
        msl.addRow('Closest Z Opacity', msl_closest_z_alpha)

        msl_other_z_alpha = QSpinBox()
        msl_other_z_alpha.setRange(1, 100)
        msl_other_z_alpha.setSingleStep(1)
        msl_other_z_alpha.setSuffix('%')
        msl_other_z_alpha.setObjectName('maps:other_z_alpha')
        msl.addRow('Other Z Opacity', msl_other_z_alpha)

        map_settings.setLayout(msl)
        stacked_widgets.append(('Maps', map_settings))

        return stacked_widgets

    def _get_custom_timers(self):
        dialog = CustomTriggerSettings()
        dialog.exec()

    def _get_push_triggers(self):
        dialog = PushTriggerSettings()
        dialog.exec()
示例#20
0
class MinWindow(Winform):
    def __init__(self, parent=None):
        super(MinWindow, self).__init__(parent)

        self.setWindowTitle('主窗口')
        self.resize(900, 600)
        self.center()

        # 创建主窗口
        self.create_main_frame()
        self.add_button()
        # 创建菜单
        self.create_menu()
        # 画出图像
        self.on_draw()

        # 绑定所有事件
        self.events_all_siganl_connect()

    def save_plot(self):
        # 保存当前matplotlib图像
        file_choices = "PNG (*.png)|*.png"

        # path = QFileDialog.getSaveFileName(self,
        #                                    'Save file', '',
        #                                    file_choices)
        # path = self.get_current_path()
        self.stack_tabWidget.currentWidget().mpl_nav_toolbar.save_figure()

        # if path:
        #     print('保存啊')
        #     # self.stack_tabWidget.currentWidget()
        #     self.stack_tabWidget.currentWidget().mpl_nav_toolbar.save_figure()
        #     print('保存了啊')
        #     self.statusBar().showMessage('Saved to %s' % path, 2000)

        pass

    def create_menu(self):
        # 添加菜单栏

        self.setCentralWidget(self.centralwidget)

        # 添加菜单栏
        self.main_menubar = QtWidgets.QMenuBar()
        self.main_menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))
        self.main_menubar.setObjectName("main_menubar")

        self.menu = QtWidgets.QMenu(self.main_menubar)
        self.menu.setObjectName("menu")
        self.file_menu = QtWidgets.QMenu(self.main_menubar)
        self.file_menu.setObjectName("file_menu")

        self.save_menu = QtWidgets.QMenu(self.main_menubar)
        self.save_menu.setObjectName("save_menu")

        self.setMenuBar(self.main_menubar)

        self.statusbar = QtWidgets.QStatusBar()
        self.statusbar.setObjectName("statusbar")

        self.setStatusBar(self.statusbar)

        # 添加状态栏
        self.show_status_bar()
        # self.statusbar.showMessage("这是状态栏")

        self.plot_save_action = QAction(self)
        self.plot_save_action.setObjectName("plot_save_action")

        _translate = QtCore.QCoreApplication.translate
        self.menu.setTitle(_translate("MainWindow", "菜单"))
        self.file_menu.setTitle(_translate("MainWindow", "保存"))
        self.save_menu.setTitle(_translate("MainWindow", "保存图片"))
        self.plot_save_action.setText(_translate("MainWindow", "保存图片"))

        self.file_menu.addAction(self.plot_save_action)
        self.main_menubar.addAction(self.menu.menuAction())
        self.main_menubar.addAction(self.file_menu.menuAction())
        self.main_menubar.addAction(self.save_menu.menuAction())

        self.retranslateUi()

        # 给菜单按钮添加绑定事件
        # QtCore.QMetaObject.connectSlotsByName(self)
        save_file_action = self.create_action("&保存图像",
                                              shortcut="Ctrl+S",
                                              slot=self.save_plot,
                                              tip="Save the plot")
        quit_action = self.create_action("&Quit",
                                         slot=self.close,
                                         shortcut="Ctrl+Q",
                                         tip="Close the application")

        self.add_actions(self.file_menu, (save_file_action, None, quit_action))
        pass

    def create_main_frame(self):
        # 窗口布局
        # 添加主窗口
        self.setObjectName("MainWindow")
        # self.layout =
        self.layout = QVBoxLayout(self)
        self.centralwidget = QtWidgets.QWidget()
        self.centralwidget.setObjectName("centralwidget")
        self.setCentralWidget(self.centralwidget)

        self.main_widget = QtWidgets.QWidget(self.centralwidget)
        self.main_widget.setGeometry(QtCore.QRect(10, 20, 761, 481))
        self.main_widget.setObjectName("main_widget")

        # 此区域存放图像
        self.stack_tabWidget = QtWidgets.QTabWidget(self.main_widget)
        self.stack_tabWidget.setGeometry(QtCore.QRect(30, 60, 721, 401))
        self.stack_tabWidget.setObjectName("stack_tabWidget")

        # 此区域存放图像的工具栏
        self.toolbar_stackedWidget = QStackedWidget(self.main_widget)
        self.toolbar_stackedWidget.setGeometry(QtCore.QRect(20, 0, 791, 71))
        self.toolbar_stackedWidget.setObjectName("toolbar_stackedWidget")
        self.layout.addWidget(self.centralwidget)

    def on_draw(self):
        # 添加图像
        self.draw_all_stack_tab()
        # 添加工具栏
        self.set_all_stack_tab_toolbar()
        pass

    def create_status_bar(self):

        pass

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

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

    def add_button(self):
        self.save_pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.save_pushButton.setGeometry(QtCore.QRect(800, 160, 75, 23))
        self.save_pushButton.setObjectName("save_pushButton")
        pass

    def on_about(self):
        # 弹出关于此软件的信息
        msg = """ A demo of using PyQt with matplotlib:

         * Use the matplotlib navigation bar
         * Add values to the text box and press Enter (or click "Draw")
         * Show or hide the grid
         * Drag the slider to modify the width of the bars
         * Save the plot to a file using the File menu
         * Click on a bar to receive an informative message
        """
        QMessageBox.about(self, "About the demo", msg.strip())

    def retranslateUi(self):
        # 设置各个菜单的名字
        _translate = QtCore.QCoreApplication.translate

        self.setWindowTitle(_translate("MainWindow", "曲线翻页"))

        # self.stack_tabWidget.setTabText(self.stack_tabWidget.indexOf(self.tab), _translate("MainWindow", "Tab 1"))
        # self.stack_tabWidget.setTabText(self.stack_tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Tab 2"))

        self.menu.setTitle(_translate("MainWindow", "菜单"))
        self.file_menu.setTitle(_translate("MainWindow", "保存"))
        self.save_menu.setTitle(_translate("MainWindow", "状态"))
        self.plot_save_action.setText(_translate("MainWindow", "保存图片"))
        self.save_pushButton.setText(_translate("MainWindow", "点击保存"))

    def draw_all_stack_tab(self):
        # 绘制所有图像
        # 添加到stack_tabWidget上

        # 创建matplot画布
        self.tab1 = PlotCanvas(self, width=9, height=6, dpi=100)
        self.tab2 = PlotCanvas(self, width=9, height=6, dpi=100)
        self.tab3 = PlotCanvas(self, width=9, height=6, dpi=100)
        # mpl.draw_one_line()

        # 加载数据
        # 在不同的画布上画出来
        # 将所有f分页加入到tabWidget上
        lines = load_all_lines()

        self.tab1.draw_one_line(lines[0])
        self.tab2.draw_one_line(lines[1])
        self.tab3.draw_one_line(lines[2])

        # 将所有的tab添加到stack_tabWidget上
        self.stack_tabWidget.addTab(self.tab1, 'td=0.12')
        self.stack_tabWidget.addTab(self.tab2, 'td=0.144')
        self.stack_tabWidget.addTab(self.tab3, 'td=0.176')
        pass

    def set_all_stack_tab_toolbar(self):
        # 添加图像的工具栏 所有的工具栏用容器toolbar_stackedWidget保存
        self.add_stack_toolbar()
        self.tab1_ntb = NavigationToolbar(self.tab1,
                                          self.toolbar_page1)  # 添加完整的 toolbar
        self.tab2_ntb = NavigationToolbar(self.tab2,
                                          self.toolbar_page2)  # 添加完整的 toolbar
        self.tab3_ntb = NavigationToolbar(self.tab3,
                                          self.toolbar_page3)  # 添加完整的 toolbar

        self.tab1.mpl_nav_toolbar = self.tab1_ntb
        self.tab2.mpl_nav_toolbar = self.tab2_ntb
        self.tab3.mpl_nav_toolbar = self.tab3_ntb
        # log('设置了的')
        pass

    def show_status_bar(self):
        # 添加状态栏
        self.status_text = QLabel(" demo 状态栏")
        self.statusbar.addWidget(self.status_text, 1)

    def add_stack_toolbar(self):
        # 添加matplotlib的工具栏
        # toolbar_stackedWidget

        # 创建QStackedWidget容器 将matplotlib所有图像的工具栏叠加放在一起
        # self.toolbar_stackedWidget = QStackedWidget()

        # 创建不同的 QWidget保存单个matplotlib图像的工具栏
        self.toolbar_page1 = QtWidgets.QWidget()
        self.toolbar_page1.setObjectName("toolbar_page1")

        self.toolbar_page2 = QtWidgets.QWidget()
        self.toolbar_page2.setObjectName("toolbar_page2")

        self.toolbar_page3 = QtWidgets.QWidget()
        self.toolbar_page3.setObjectName("toolbar_page3")

        # 初始化空白toolbar区域
        # 添加三个空页
        self.toolbar_stackedWidget.addWidget(self.toolbar_page1)
        self.toolbar_stackedWidget.addWidget(self.toolbar_page2)
        self.toolbar_stackedWidget.addWidget(self.toolbar_page3)

        pass

    def events_all_siganl_connect(self):
        # 连接所有的事件

        # 切换tabWidget图像 显示 当前图像的toolbar
        self.stack_tabWidget.currentChanged.connect(
            self.event_change_toolbar_page)

        # 点击按钮 保存当前图像
        self.save_pushButton.clicked.connect(self.save_plot)

        pass

    def event_change_toolbar_page(self):
        # 切换当前td图像触发
        # 在toolbar_stackedWidget区域显示当前图像的matplotlib工具栏

        # 获取当前的tab
        # log('点击了当前的widget')
        c = self.stack_tabWidget.currentIndex()
        # 设置当前stackWidget的当前
        self.toolbar_stackedWidget.setCurrentIndex(c)
        # log("toolbar_stackedWidget 当前页面是({})".format(c))
        # 设置当前的tool stackWidget的page
        pass

    def get_current_path(self):
        # 获取当前文件目录
        paths = sys.path
        current_file = os.path.basename(__file__)
        for path in paths:
            try:
                if current_file in os.listdir(path):
                    self.current_path = path
                    break
            except (FileExistsError, FileNotFoundError) as e:
                print(e)
示例#21
0
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        self.MainWindow = MainWindow

        self.setupMainWindow()
        self.setupMenuBar()
        self.setupAjdustmentOptionBar()
        self.setupMainStack()

        self.shiftUi = Ui_ShiftWindow(self.shift_page)
        self.shiftUi.setupUi()

        self.perpetualUi = Ui_PerpetualWindow(self.perpetual_page)
        self.perpetualUi.setupUi()

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def setupMainWindow(self):
        self.MainWindow.setObjectName("MainWindow")
        self.MainWindow.resize(1500, 800)
        sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding,
                                 QSizePolicy.MinimumExpanding)
        sizePolicy.setHorizontalStretch(1)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(
            self.MainWindow.sizePolicy().hasHeightForWidth())
        self.MainWindow.setSizePolicy(sizePolicy)
        self.MainWindow.setMinimumSize(QtCore.QSize(1500, 800))

        self.centralWidget = QWidget(self.MainWindow)
        sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding,
                                 QSizePolicy.MinimumExpanding)
        sizePolicy.setHorizontalStretch(1)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(
            self.centralWidget.sizePolicy().hasHeightForWidth())
        self.centralWidget.setSizePolicy(sizePolicy)
        self.centralWidget.setMinimumSize(QtCore.QSize(1500, 800))
        self.centralWidget.setSizeIncrement(QtCore.QSize(5, 5))
        self.centralWidget.setBaseSize(QtCore.QSize(5, 5))
        self.centralWidget.setObjectName("centralWidget")
        self.MainWindow.setCentralWidget(self.centralWidget)

        self.statusBar = QStatusBar(self.MainWindow)
        self.statusBar.setObjectName("statusBar")
        self.MainWindow.setStatusBar(self.statusBar)

        self.toolBar = QToolBar(self.MainWindow)
        self.toolBar.setObjectName("toolBar")
        self.MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)

        self.outer_gridLayout = QGridLayout(self.centralWidget)
        self.outer_gridLayout.setSizeConstraint(QLayout.SetMinimumSize)
        self.outer_gridLayout.setContentsMargins(11, 6, 11, 0)
        self.outer_gridLayout.setSpacing(6)
        self.outer_gridLayout.setObjectName("outer_gridLayout")

    def setupMenuBar(self):
        self.menuBar = QMenuBar(self.MainWindow)
        self.menuBar.setGeometry(QtCore.QRect(0, 0, 942, 21))
        self.menuBar.setObjectName("menuBar")

        self.MainWindow.setMenuBar(self.menuBar)

        self.menuLog = QMenu(self.menuBar)
        self.menuLog.setObjectName("menuLog")
        self.actionLog = QAction(self.MainWindow)
        self.actionLog.setObjectName("actionLog")
        self.menuLog.addAction(self.actionLog)
        self.menuBar.addAction(self.menuLog.menuAction())

        _translate = QtCore.QCoreApplication.translate
        self.menuLog.setTitle(_translate("MainWindow", "Log"))
        self.actionLog.setText(_translate("MainWindow", "Show Log"))

        self.menuAbout = QMenu(self.menuBar)
        self.menuAbout.setObjectName("menuAbout")
        self.actionHelp = QAction(self.MainWindow)
        self.actionHelp.setObjectName("actionHelp")
        self.menuAbout.addAction(self.actionHelp)
        self.menuBar.addAction(self.menuAbout.menuAction())

        _translate = QtCore.QCoreApplication.translate
        self.menuAbout.setTitle(_translate("MainWindow", "About"))
        self.actionHelp.setText(_translate("MainWindow", "Help"))

    def setupAjdustmentOptionBar(self):
        self.verticalWidget = QWidget(self.centralWidget)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed,
                                 QSizePolicy.MinimumExpanding)
        sizePolicy.setHorizontalStretch(1)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(
            self.verticalWidget.sizePolicy().hasHeightForWidth())
        self.verticalWidget.setSizePolicy(sizePolicy)
        self.verticalWidget.setMinimumSize(QtCore.QSize(120, 0))
        self.verticalWidget.setMaximumSize(QtCore.QSize(120, 16777215))
        self.verticalWidget.setStyleSheet("background-color:darkgray")
        self.verticalWidget.setObjectName("verticalWidget")

        self.verticalLayout = QVBoxLayout(self.verticalWidget)
        self.verticalLayout.setContentsMargins(5, 65, 5, 11)
        self.verticalLayout.setSpacing(20)
        self.verticalLayout.setObjectName("verticalLayout")

        self.shift_button = QPushButton(self.verticalWidget)
        self.shift_button.setMinimumSize(QtCore.QSize(0, 100))
        font = QtGui.QFont()
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)
        self.shift_button.setFont(font)
        self.shift_button.setObjectName("shift_button")
        self.shift_button.setCheckable(True)

        self.perpetual_button = QPushButton(self.verticalWidget)
        self.perpetual_button.setMinimumSize(QtCore.QSize(0, 100))
        font = QtGui.QFont()
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)
        self.perpetual_button.setFont(font)
        self.perpetual_button.setCheckable(True)
        self.perpetual_button.setObjectName("perpetual_button")

        self.verticalLayout.addWidget(self.shift_button)
        self.verticalLayout.addWidget(self.perpetual_button)

        self.buttonGroup = QButtonGroup(self.verticalWidget)
        self.buttonGroup.addButton(self.shift_button)
        self.buttonGroup.addButton(self.perpetual_button)
        self.buttonGroup.setExclusive(True)

        spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                 QSizePolicy.MinimumExpanding)
        self.verticalLayout.addItem(spacerItem)
        self.outer_gridLayout.addWidget(self.verticalWidget, 0, 0, 1, 1)

    def setupMainStack(self):

        self.shift_main_stacked = QStackedWidget(self.centralWidget)
        sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding,
                                 QSizePolicy.MinimumExpanding)
        sizePolicy.setHorizontalStretch(1)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(
            self.shift_main_stacked.sizePolicy().hasHeightForWidth())
        self.shift_main_stacked.setSizePolicy(sizePolicy)
        self.shift_main_stacked.setObjectName("shift_main_stacked")

        self.shift_page = QWidget()
        sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding,
                                 QSizePolicy.MinimumExpanding)
        sizePolicy.setHorizontalStretch(1)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(
            self.shift_page.sizePolicy().hasHeightForWidth())
        self.shift_page.setSizePolicy(sizePolicy)
        self.shift_page.setObjectName("shift_page")
        self.shift_main_stacked.addWidget(self.shift_page)

        self.perpetual_page = QWidget()
        sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding,
                                 QSizePolicy.MinimumExpanding)
        sizePolicy.setHorizontalStretch(1)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(
            self.perpetual_page.sizePolicy().hasHeightForWidth())
        self.perpetual_page.setSizePolicy(sizePolicy)
        self.perpetual_page.setObjectName("perpetual_page")
        self.shift_main_stacked.addWidget(self.perpetual_page)

        self.outer_gridLayout.addWidget(self.shift_main_stacked, 0, 1, 1, 1)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        self.MainWindow.setWindowTitle(
            _translate("MainWindow", "Continuous Contract Maker"))
        self.shift_button.setText(
            _translate("MainWindow", "Forward\n"
                       "Backward"))
        self.perpetual_button.setText(
            _translate("MainWindow", "Perputual\n"
                       " Series"))

        self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
示例#22
-1
class ConfigurationWidget(QWidget):
    """
    Class implementing a dialog for the configuration of eric6.
    
    @signal preferencesChanged() emitted after settings have been changed
    @signal masterPasswordChanged(str, str) emitted after the master
        password has been changed with the old and the new password
    @signal accepted() emitted to indicate acceptance of the changes
    @signal rejected() emitted to indicate rejection of the changes
    """
    preferencesChanged = pyqtSignal()
    masterPasswordChanged = pyqtSignal(str, str)
    accepted = pyqtSignal()
    rejected = pyqtSignal()
    
    DefaultMode = 0
    HelpBrowserMode = 1
    TrayStarterMode = 2
    HexEditorMode = 3
    
    def __init__(self, parent=None, fromEric=True, displayMode=DefaultMode,
                 expandedEntries=[]):
        """
        Constructor
        
        @param parent The parent widget of this dialog. (QWidget)
        @keyparam fromEric flag indicating a dialog generation from within the
            eric6 ide (boolean)
        @keyparam displayMode mode of the configuration dialog
            (DefaultMode, HelpBrowserMode, TrayStarterMode, HexEditorMode)
        @exception RuntimeError raised to indicate an invalid dialog mode
        @keyparam expandedEntries list of entries to be shown expanded
            (list of strings)
        """
        assert displayMode in (
            ConfigurationWidget.DefaultMode,
            ConfigurationWidget.HelpBrowserMode,
            ConfigurationWidget.TrayStarterMode,
            ConfigurationWidget.HexEditorMode,
        )
        
        super(ConfigurationWidget, self).__init__(parent)
        self.fromEric = fromEric
        self.displayMode = displayMode
        
        self.__setupUi()
        
        self.itmDict = {}
        
        if not fromEric:
            from PluginManager.PluginManager import PluginManager
            try:
                self.pluginManager = e5App().getObject("PluginManager")
            except KeyError:
                self.pluginManager = PluginManager(self)
                e5App().registerObject("PluginManager", self.pluginManager)
        
        if displayMode == ConfigurationWidget.DefaultMode:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "applicationPage":
                [self.tr("Application"), "preferences-application.png",
                 "ApplicationPage", None, None],
                "cooperationPage":
                [self.tr("Cooperation"), "preferences-cooperation.png",
                 "CooperationPage", None, None],
                "corbaPage":
                [self.tr("CORBA"), "preferences-orbit.png",
                 "CorbaPage", None, None],
                "emailPage":
                [self.tr("Email"), "preferences-mail_generic.png",
                 "EmailPage", None, None],
                "graphicsPage":
                [self.tr("Graphics"), "preferences-graphics.png",
                 "GraphicsPage", None, None],
                "hexEditorPage":
                [self.tr("Hex Editor"), "hexEditor.png",
                 "HexEditorPage", None, None],
                "iconsPage":
                [self.tr("Icons"), "preferences-icons.png",
                 "IconsPage", None, None],
                "ircPage":
                [self.tr("IRC"), "irc.png",
                 "IrcPage", None, None],
                "logViewerPage":
                [self.tr("Log-Viewer"), "preferences-logviewer.png",
                 "LogViewerPage", None, None],
                "mimeTypesPage":
                [self.tr("Mimetypes"), "preferences-mimetypes.png",
                 "MimeTypesPage", None, None],
                "networkPage":
                [self.tr("Network"), "preferences-network.png",
                 "NetworkPage", None, None],
                "notificationsPage":
                [self.tr("Notifications"),
                 "preferences-notifications.png",
                 "NotificationsPage", None, None],
                "pluginManagerPage":
                [self.tr("Plugin Manager"),
                 "preferences-pluginmanager.png",
                 "PluginManagerPage", None, None],
                "printerPage":
                [self.tr("Printer"), "preferences-printer.png",
                 "PrinterPage", None, None],
                "pythonPage":
                [self.tr("Python"), "preferences-python.png",
                 "PythonPage", None, None],
                "qtPage":
                [self.tr("Qt"), "preferences-qtlogo.png",
                 "QtPage", None, None],
                "securityPage":
                [self.tr("Security"), "preferences-security.png",
                 "SecurityPage", None, None],
                "shellPage":
                [self.tr("Shell"), "preferences-shell.png",
                 "ShellPage", None, None],
                "tasksPage":
                [self.tr("Tasks"), "task.png",
                 "TasksPage", None, None],
                "templatesPage":
                [self.tr("Templates"), "preferences-template.png",
                 "TemplatesPage", None, None],
                "trayStarterPage":
                [self.tr("Tray Starter"), "erict.png",
                 "TrayStarterPage", None, None],
                "vcsPage":
                [self.tr("Version Control Systems"),
                 "preferences-vcs.png",
                 "VcsPage", None, None],
                
                "0debuggerPage":
                [self.tr("Debugger"), "preferences-debugger.png",
                 None, None, None],
                "debuggerGeneralPage":
                [self.tr("General"), "preferences-debugger.png",
                 "DebuggerGeneralPage", "0debuggerPage", None],
                "debuggerPythonPage":
                [self.tr("Python"), "preferences-pyDebugger.png",
                 "DebuggerPythonPage", "0debuggerPage", None],
                "debuggerPython3Page":
                [self.tr("Python3"), "preferences-pyDebugger.png",
                 "DebuggerPython3Page", "0debuggerPage", None],
                
                "0editorPage":
                [self.tr("Editor"), "preferences-editor.png",
                 None, None, None],
                "editorAPIsPage":
                [self.tr("APIs"), "preferences-api.png",
                 "EditorAPIsPage", "0editorPage", None],
                "editorAutocompletionPage":
                [self.tr("Autocompletion"),
                 "preferences-autocompletion.png",
                 "EditorAutocompletionPage", "0editorPage", None],
                "editorAutocompletionQScintillaPage":
                [self.tr("QScintilla"), "qscintilla.png",
                 "EditorAutocompletionQScintillaPage",
                 "editorAutocompletionPage", None],
                "editorCalltipsPage":
                [self.tr("Calltips"), "preferences-calltips.png",
                 "EditorCalltipsPage", "0editorPage", None],
                "editorCalltipsQScintillaPage":
                [self.tr("QScintilla"), "qscintilla.png",
                 "EditorCalltipsQScintillaPage", "editorCalltipsPage", None],
                "editorGeneralPage":
                [self.tr("General"), "preferences-general.png",
                 "EditorGeneralPage", "0editorPage", None],
                "editorFilePage":
                [self.tr("Filehandling"),
                 "preferences-filehandling.png",
                 "EditorFilePage", "0editorPage", None],
                "editorSearchPage":
                [self.tr("Searching"), "preferences-search.png",
                 "EditorSearchPage", "0editorPage", None],
                "editorSpellCheckingPage":
                [self.tr("Spell checking"),
                 "preferences-spellchecking.png",
                 "EditorSpellCheckingPage", "0editorPage", None],
                "editorStylesPage":
                [self.tr("Style"), "preferences-styles.png",
                 "EditorStylesPage", "0editorPage", None],
                "editorSyntaxPage":
                [self.tr("Code Checkers"), "preferences-debugger.png",
                 "EditorSyntaxPage", "0editorPage", None],
                "editorTypingPage":
                [self.tr("Typing"), "preferences-typing.png",
                 "EditorTypingPage", "0editorPage", None],
                "editorExportersPage":
                [self.tr("Exporters"), "preferences-exporters.png",
                 "EditorExportersPage", "0editorPage", None],
                
                "1editorLexerPage":
                [self.tr("Highlighters"),
                 "preferences-highlighting-styles.png",
                 None, "0editorPage", None],
                "editorHighlightersPage":
                [self.tr("Filetype Associations"),
                 "preferences-highlighter-association.png",
                 "EditorHighlightersPage", "1editorLexerPage", None],
                "editorHighlightingStylesPage":
                [self.tr("Styles"),
                 "preferences-highlighting-styles.png",
                 "EditorHighlightingStylesPage", "1editorLexerPage", None],
                "editorKeywordsPage":
                [self.tr("Keywords"), "preferences-keywords.png",
                 "EditorKeywordsPage", "1editorLexerPage", None],
                "editorPropertiesPage":
                [self.tr("Properties"), "preferences-properties.png",
                 "EditorPropertiesPage", "1editorLexerPage", None],
                
                "1editorMouseClickHandlers":
                [self.tr("Mouse Click Handlers"),
                 "preferences-mouse-click-handler.png",
                 "EditorMouseClickHandlerPage", "0editorPage", None],
                
                "0helpPage":
                [self.tr("Help"), "preferences-help.png",
                 None, None, None],
                "helpDocumentationPage":
                [self.tr("Help Documentation"),
                 "preferences-helpdocumentation.png",
                 "HelpDocumentationPage", "0helpPage", None],
                "helpViewersPage":
                [self.tr("Help Viewers"),
                 "preferences-helpviewers.png",
                 "HelpViewersPage", "0helpPage", None],
                
                "0projectPage":
                [self.tr("Project"), "preferences-project.png",
                 None, None, None],
                "projectBrowserPage":
                [self.tr("Project Viewer"), "preferences-project.png",
                 "ProjectBrowserPage", "0projectPage", None],
                "projectPage":
                [self.tr("Project"), "preferences-project.png",
                 "ProjectPage", "0projectPage", None],
                "multiProjectPage":
                [self.tr("Multiproject"),
                 "preferences-multiproject.png",
                 "MultiProjectPage", "0projectPage", None],
                
                "0interfacePage":
                [self.tr("Interface"), "preferences-interface.png",
                 None, None, None],
                "interfacePage":
                [self.tr("Interface"), "preferences-interface.png",
                 "InterfacePage", "0interfacePage", None],
                "viewmanagerPage":
                [self.tr("Viewmanager"), "preferences-viewmanager.png",
                 "ViewmanagerPage", "0interfacePage", None],
            }
            try:
                from PyQt5 import QtWebKit      # __IGNORE_WARNING__
                self.configItems.update({
                    "helpAppearancePage":
                    [self.tr("Appearance"), "preferences-styles.png",
                     "HelpAppearancePage", "0helpPage", None],
                    "helpFlashCookieManagerPage":
                    [self.tr("Flash Cookie Manager"),
                     "flashCookie16.png",
                     "HelpFlashCookieManagerPage", "0helpPage", None],
                    "helpVirusTotalPage":
                    [self.tr("VirusTotal Interface"), "virustotal.png",
                     "HelpVirusTotalPage", "0helpPage", None],
                    "helpWebBrowserPage":
                    [self.tr("eric6 Web Browser"), "ericWeb.png",
                     "HelpWebBrowserPage", "0helpPage", None],
                })
            except ImportError:
                pass
            
            self.configItems.update(
                e5App().getObject("PluginManager").getPluginConfigData())
        
        elif displayMode == ConfigurationWidget.HelpBrowserMode:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "interfacePage":
                [self.tr("Interface"), "preferences-interface.png",
                 "HelpInterfacePage", None, None],
                "networkPage":
                [self.tr("Network"), "preferences-network.png",
                 "NetworkPage", None, None],
                "printerPage":
                [self.tr("Printer"), "preferences-printer.png",
                 "PrinterPage", None, None],
                "securityPage":
                [self.tr("Security"), "preferences-security.png",
                 "SecurityPage", None, None],
                
                "0helpPage":
                [self.tr("Help"), "preferences-help.png",
                 None, None, None],
                "helpDocumentationPage":
                [self.tr("Help Documentation"),
                 "preferences-helpdocumentation.png",
                 "HelpDocumentationPage", "0helpPage", None],
            }
            try:
                from PyQt5 import QtWebKit      # __IGNORE_WARNING__
                self.configItems.update({
                    "helpAppearancePage":
                    [self.tr("Appearance"), "preferences-styles.png",
                     "HelpAppearancePage", "0helpPage", None],
                    "helpFlashCookieManagerPage":
                    [self.tr("Flash Cookie Manager"),
                     "flashCookie16.png",
                     "HelpFlashCookieManagerPage", "0helpPage", None],
                    "helpVirusTotalPage":
                    [self.tr("VirusTotal Interface"), "virustotal.png",
                     "HelpVirusTotalPage", "0helpPage", None],
                    "helpWebBrowserPage":
                    [self.tr("eric6 Web Browser"), "ericWeb.png",
                     "HelpWebBrowserPage", "0helpPage", None],
                })
            except ImportError:
                pass
        
        elif displayMode == ConfigurationWidget.TrayStarterMode:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "trayStarterPage":
                [self.tr("Tray Starter"), "erict.png",
                 "TrayStarterPage", None, None],
            }
        
        elif displayMode == ConfigurationWidget.HexEditorMode:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "hexEditorPage":
                [self.tr("Hex Editor"), "hexEditor.png",
                 "HexEditorPage", None, None],
            }
        
        else:
            raise RuntimeError("Illegal mode value: {0}".format(displayMode))
        
        # generate the list entries
        self.__expandedEntries = []
        for key in sorted(self.configItems.keys()):
            pageData = self.configItems[key]
            if pageData[3]:
                if pageData[3] in self.itmDict:
                    pitm = self.itmDict[pageData[3]]  # get the parent item
                else:
                    continue
            else:
                pitm = self.configList
            self.itmDict[key] = ConfigurationPageItem(pitm, pageData[0], key,
                                                      pageData[1])
            self.itmDict[key].setData(0, Qt.UserRole, key)
            if (not self.fromEric or
                displayMode != ConfigurationWidget.DefaultMode or
                    key in expandedEntries):
                self.itmDict[key].setExpanded(True)
        self.configList.sortByColumn(0, Qt.AscendingOrder)
        
        # set the initial size of the splitter
        self.configSplitter.setSizes([200, 600])
        
        self.configList.itemActivated.connect(self.__showConfigurationPage)
        self.configList.itemClicked.connect(self.__showConfigurationPage)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.rejected)
        
        if displayMode in [ConfigurationWidget.HelpBrowserMode,
                           ConfigurationWidget.TrayStarterMode,
                           ConfigurationWidget.HexEditorMode]:
            self.configListSearch.hide()
        
        if displayMode not in [ConfigurationWidget.TrayStarterMode,
                               ConfigurationWidget.HexEditorMode]:
            self.__initLexers()
        
    def accept(self):
        """
        Public slot to accept the buttonBox accept signal.
        """
        if not isMacPlatform():
            wdg = self.focusWidget()
            if wdg == self.configList:
                return
        
        self.accepted.emit()
        
    def __setupUi(self):
        """
        Private method to perform the general setup of the configuration
        widget.
        """
        self.setObjectName("ConfigurationDialog")
        self.resize(900, 650)
        self.verticalLayout_2 = QVBoxLayout(self)
        self.verticalLayout_2.setSpacing(6)
        self.verticalLayout_2.setContentsMargins(6, 6, 6, 6)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        
        self.configSplitter = QSplitter(self)
        self.configSplitter.setOrientation(Qt.Horizontal)
        self.configSplitter.setObjectName("configSplitter")
        
        self.configListWidget = QWidget(self.configSplitter)
        self.leftVBoxLayout = QVBoxLayout(self.configListWidget)
        self.leftVBoxLayout.setContentsMargins(0, 0, 0, 0)
        self.leftVBoxLayout.setSpacing(0)
        self.leftVBoxLayout.setObjectName("leftVBoxLayout")
        self.configListSearch = E5ClearableLineEdit(
            self, self.tr("Enter search text..."))
        self.configListSearch.setObjectName("configListSearch")
        self.leftVBoxLayout.addWidget(self.configListSearch)
        self.configList = QTreeWidget()
        self.configList.setObjectName("configList")
        self.leftVBoxLayout.addWidget(self.configList)
        self.configListSearch.textChanged.connect(self.__searchTextChanged)
        
        self.scrollArea = QScrollArea(self.configSplitter)
        self.scrollArea.setFrameShape(QFrame.NoFrame)
        self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.scrollArea.setWidgetResizable(False)
        self.scrollArea.setObjectName("scrollArea")
        
        self.configStack = QStackedWidget()
        self.configStack.setFrameShape(QFrame.Box)
        self.configStack.setFrameShadow(QFrame.Sunken)
        self.configStack.setObjectName("configStack")
        self.scrollArea.setWidget(self.configStack)
        
        self.emptyPage = QWidget()
        self.emptyPage.setGeometry(QRect(0, 0, 372, 591))
        self.emptyPage.setObjectName("emptyPage")
        self.vboxlayout = QVBoxLayout(self.emptyPage)
        self.vboxlayout.setSpacing(6)
        self.vboxlayout.setContentsMargins(6, 6, 6, 6)
        self.vboxlayout.setObjectName("vboxlayout")
        spacerItem = QSpacerItem(
            20, 20, QSizePolicy.Minimum, QSizePolicy.Expanding)
        self.vboxlayout.addItem(spacerItem)
        self.emptyPagePixmap = QLabel(self.emptyPage)
        self.emptyPagePixmap.setAlignment(Qt.AlignCenter)
        self.emptyPagePixmap.setObjectName("emptyPagePixmap")
        self.emptyPagePixmap.setPixmap(
            QPixmap(os.path.join(getConfig('ericPixDir'), 'eric.png')))
        self.vboxlayout.addWidget(self.emptyPagePixmap)
        self.textLabel1 = QLabel(self.emptyPage)
        self.textLabel1.setAlignment(Qt.AlignCenter)
        self.textLabel1.setObjectName("textLabel1")
        self.vboxlayout.addWidget(self.textLabel1)
        spacerItem1 = QSpacerItem(
            20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
        self.vboxlayout.addItem(spacerItem1)
        self.configStack.addWidget(self.emptyPage)
        
        self.verticalLayout_2.addWidget(self.configSplitter)
        
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(
            QDialogButtonBox.Apply | QDialogButtonBox.Cancel |
            QDialogButtonBox.Ok | QDialogButtonBox.Reset)
        self.buttonBox.setObjectName("buttonBox")
        if not self.fromEric and \
                self.displayMode == ConfigurationWidget.DefaultMode:
            self.buttonBox.button(QDialogButtonBox.Apply).hide()
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False)
        self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(False)
        self.verticalLayout_2.addWidget(self.buttonBox)

        self.setWindowTitle(self.tr("Preferences"))
        
        self.configList.header().hide()
        self.configList.header().setSortIndicator(0, Qt.AscendingOrder)
        self.configList.setSortingEnabled(True)
        self.textLabel1.setText(
            self.tr("Please select an entry of the list \n"
                    "to display the configuration page."))
        
        QMetaObject.connectSlotsByName(self)
        self.setTabOrder(self.configList, self.configStack)
        
        self.configStack.setCurrentWidget(self.emptyPage)
        
        self.configList.setFocus()
    
    def __searchTextChanged(self, text):
        """
        Private slot to handle a change of the search text.
        
        @param text text to search for (string)
        """
        self.__searchChildItems(self.configList.invisibleRootItem(), text)
    
    def __searchChildItems(self, parent, text):
        """
        Private method to enable child items based on a search string.
        
        @param parent reference to the parent item (QTreeWidgetItem)
        @param text text to search for (string)
        @return flag indicating an enabled child item (boolean)
        """
        childEnabled = False
        text = text.lower()
        for index in range(parent.childCount()):
            itm = parent.child(index)
            if itm.childCount() > 0:
                enable = self.__searchChildItems(itm, text) or \
                    text == "" or text in itm.text(0).lower()
            else:
                enable = text == "" or text in itm.text(0).lower()
            if enable:
                childEnabled = True
            itm.setDisabled(not enable)
        
        return childEnabled
    
    def __initLexers(self):
        """
        Private method to initialize the dictionary of preferences lexers.
        """
        import QScintilla.Lexers
        from .PreferencesLexer import PreferencesLexer, \
            PreferencesLexerLanguageError
        
        self.lexers = {}
        for language in QScintilla.Lexers.getSupportedLanguages():
            if language not in self.lexers:
                try:
                    self.lexers[language] = PreferencesLexer(language, self)
                except PreferencesLexerLanguageError:
                    pass
        
    def __importConfigurationPage(self, name):
        """
        Private method to import a configuration page module.
        
        @param name name of the configuration page module (string)
        @return reference to the configuration page module
        """
        modName = "Preferences.ConfigurationPages.{0}".format(name)
        try:
            mod = __import__(modName)
            components = modName.split('.')
            for comp in components[1:]:
                mod = getattr(mod, comp)
            return mod
        except ImportError:
            E5MessageBox.critical(
                self,
                self.tr("Configuration Page Error"),
                self.tr("""<p>The configuration page <b>{0}</b>"""
                        """ could not be loaded.</p>""").format(name))
            return None
        
    def __showConfigurationPage(self, itm, column):
        """
        Private slot to show a selected configuration page.
        
        @param itm reference to the selected item (QTreeWidgetItem)
        @param column column that was selected (integer) (ignored)
        """
        pageName = itm.getPageName()
        self.showConfigurationPageByName(pageName, setCurrent=False)
        
    def __initPage(self, pageData):
        """
        Private method to initialize a configuration page.
        
        @param pageData data structure for the page to initialize
        @return reference to the initialized page
        """
        page = None
        if isinstance(pageData[2], types.FunctionType):
            page = pageData[2](self)
        else:
            mod = self.__importConfigurationPage(pageData[2])
            if mod:
                page = mod.create(self)
        if page is not None:
            self.configStack.addWidget(page)
            pageData[-1] = page
            try:
                page.setMode(self.displayMode)
            except AttributeError:
                pass
        return page
        
    def showConfigurationPageByName(self, pageName, setCurrent=True):
        """
        Public slot to show a named configuration page.
        
        @param pageName name of the configuration page to show (string)
        @param setCurrent flag indicating to set the current item (boolean)
        """
        if pageName == "empty" or pageName not in self.configItems:
            page = self.emptyPage
        else:
            pageData = self.configItems[pageName]
            if pageData[-1] is None and pageData[2] is not None:
                # the page was not loaded yet, create it
                page = self.__initPage(pageData)
            else:
                page = pageData[-1]
            if page is None:
                page = self.emptyPage
            elif setCurrent:
                items = self.configList.findItems(
                    pageData[0],
                    Qt.MatchFixedString | Qt.MatchRecursive)
                for item in items:
                    if item.data(0, Qt.UserRole) == pageName:
                        self.configList.setCurrentItem(item)
        self.configStack.setCurrentWidget(page)
        ssize = self.scrollArea.size()
        if self.scrollArea.horizontalScrollBar():
            ssize.setHeight(
                ssize.height() -
                self.scrollArea.horizontalScrollBar().height() - 2)
        if self.scrollArea.verticalScrollBar():
            ssize.setWidth(
                ssize.width() -
                self.scrollArea.verticalScrollBar().width() - 2)
        psize = page.minimumSizeHint()
        self.configStack.resize(max(ssize.width(), psize.width()),
                                max(ssize.height(), psize.height()))
        
        if page != self.emptyPage:
            page.polishPage()
            self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)
            self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(True)
        else:
            self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False)
            self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(False)
        
        # reset scrollbars
        for sb in [self.scrollArea.horizontalScrollBar(),
                   self.scrollArea.verticalScrollBar()]:
            if sb:
                sb.setValue(0)
        
        self.__currentConfigurationPageName = pageName
        
    def getConfigurationPageName(self):
        """
        Public method to get the page name of the current page.
        
        @return page name of the current page (string)
        """
        return self.__currentConfigurationPageName
        
    def calledFromEric(self):
        """
        Public method to check, if invoked from within eric.
        
        @return flag indicating invocation from within eric (boolean)
        """
        return self.fromEric
        
    def getPage(self, pageName):
        """
        Public method to get a reference to the named page.
        
        @param pageName name of the configuration page (string)
        @return reference to the page or None, indicating page was
            not loaded yet
        """
        return self.configItems[pageName][-1]
        
    def getLexers(self):
        """
        Public method to get a reference to the lexers dictionary.
        
        @return reference to the lexers dictionary
        """
        return self.lexers
        
    def setPreferences(self):
        """
        Public method called to store the selected values into the preferences
        storage.
        """
        for key, pageData in list(self.configItems.items()):
            if pageData[-1]:
                pageData[-1].save()
                # page was loaded (and possibly modified)
                QApplication.processEvents()    # ensure HMI is responsive
        
    def on_buttonBox_clicked(self, button):
        """
        Private slot called by a button of the button box clicked.
        
        @param button button that was clicked (QAbstractButton)
        """
        if button == self.buttonBox.button(QDialogButtonBox.Apply):
            self.on_applyButton_clicked()
        elif button == self.buttonBox.button(QDialogButtonBox.Reset):
            self.on_resetButton_clicked()
        
    @pyqtSlot()
    def on_applyButton_clicked(self):
        """
        Private slot called to apply the settings of the current page.
        """
        if self.configStack.currentWidget() != self.emptyPage:
            page = self.configStack.currentWidget()
            savedState = page.saveState()
            page.save()
            self.preferencesChanged.emit()
            if savedState is not None:
                page.setState(savedState)
            page.polishPage()
        
    @pyqtSlot()
    def on_resetButton_clicked(self):
        """
        Private slot called to reset the settings of the current page.
        """
        if self.configStack.currentWidget() != self.emptyPage:
            currentPage = self.configStack.currentWidget()
            savedState = currentPage.saveState()
            pageName = self.configList.currentItem().getPageName()
            self.configStack.removeWidget(currentPage)
            if pageName == "editorHighlightingStylesPage":
                self.__initLexers()
            self.configItems[pageName][-1] = None
            
            self.showConfigurationPageByName(pageName)
            if savedState is not None:
                self.configStack.currentWidget().setState(savedState)
        
    def getExpandedEntries(self):
        """
        Public method to get a list of expanded entries.
        
        @return list of expanded entries (list of string)
        """
        return self.__expandedEntries
    
    @pyqtSlot(QTreeWidgetItem)
    def on_configList_itemCollapsed(self, item):
        """
        Private slot handling a list entry being collapsed.
        
        @param item reference to the collapsed item (QTreeWidgetItem)
        """
        pageName = item.data(0, Qt.UserRole)
        if pageName in self.__expandedEntries:
            self.__expandedEntries.remove(pageName)
    
    @pyqtSlot(QTreeWidgetItem)
    def on_configList_itemExpanded(self, item):
        """
        Private slot handling a list entry being expanded.
        
        @param item reference to the expanded item (QTreeWidgetItem)
        """
        pageName = item.data(0, Qt.UserRole)
        if pageName not in self.__expandedEntries:
            self.__expandedEntries.append(pageName)