示例#1
0
    def __init__(self, app, ui):
        QWidget.__init__(self)
        center_layout = QVBoxLayout()
        self.fwidg = QWidget()
        self.paramfunc = 0
        self.c = Communicate()
        self.c.exec_operation_signal[Myc.FuncCommand].connect(app.exec_command)
        self.application = app
        self.setLayout(center_layout)

        print('ddd')
        self.ui = ui
        self.ui.setupUi(self.fwidg)


        splitter = QSplitter(Qt.Vertical)
        splitter.addWidget(self.fwidg)

        buttonExec = QPushButton()
        buttonExec.setText("Выполнить")
        center_layout.addWidget(buttonExec)
        buttonExec.clicked.connect(self.execOperation)

        splitter.addWidget(buttonExec)
        center_layout.addWidget(splitter)
    def __init__(self):
        super().__init__()

        # information widget
        self.plotWidget = VariantPlotWidget()
        self.infoWidget = VariantInfoWidget()

        # splitter settings
        splitter = QSplitter(Qt.Horizontal)
        splitter.addWidget(self.plotWidget)
        splitter.addWidget(self.infoWidget)
        splitter.setStretchFactor(0, 3)
        splitter.setStretchFactor(1, 1)

        # layout
        layout = QBoxLayout(QBoxLayout.TopToBottom)
        layout.addWidget(splitter)
        self.setLayout(layout)

        # connect signals
        self.plotWidget.curvePlotted.connect(self.infoWidget.updateResults)
        self.plotWidget.plotReady.connect(self.infoWidget.showResults)
        self.plotWidget.cleared.connect(self.infoWidget.clear)
        self.infoWidget.legendChanged.connect(self.plotWidget.paintCalculation)

        # translate the graphical user interface
        self.retranslateUi()
示例#3
0
    def initUI(self):
        """Create User Interface.
        """
        sourcePath = self.widgetSourcePath()
        parameters = self.widgetParameters()
        scroll = self.widgetImage()
        debug = self.widgetDebug()

        vbox1 = QVBoxLayout()
        vbox1.addLayout(sourcePath)
        hbox = QHBoxLayout()
        hbox.addLayout(parameters, 1)
        hbox.addLayout(scroll, 10)
        vbox1.addLayout(hbox)
        upSide = QWidget()
        upSide.setLayout(vbox1)

        vbox2 = QVBoxLayout()
        vbox2.addLayout(debug)
        downSide = QWidget()
        downSide.setLayout(vbox2)

        splitter = QSplitter(QtCore.Qt.Vertical)
        splitter.addWidget(upSide)
        splitter.addWidget(downSide)
        splitter.splitterMoved.connect(self.splitterMoved)

        mainLayout = QHBoxLayout()
        mainLayout.addWidget(splitter)

        self.setLayout(mainLayout)

        self.setGeometry(300, 300, 300, 150)
        self.show()
示例#4
0
	def __init__(self):
		QWidget.__init__(self)
		self.sun=1
		hbox=QHBoxLayout(self)
		mainLayout = QSplitter(Qt.Horizontal)
       # splitter1 = QtGui.QSplitter(QtCore.Qt.Horizontal)
		self.three_d=display_widget()
		self.three_d.show()

		self.frame=layer_widget()

		self.frame.changed.connect(self.three_d.recalculate)
		
		mainLayout.addWidget(self.frame)
		mainLayout.addWidget(self.three_d)
		hbox.addWidget(mainLayout)
		
		self.setLayout(hbox)

		if enable_webupdates()==True:
			print("Looking for updates")
			self.web_update=update_thread()
			self.web_update.got_data.connect(self.got_help)
			self.web_update.start()
		self.frame.tab.itemSelectionChanged.connect(self.layer_selection_changed)
    def __init__(self, parent=None):
        super(QMainWindow,self).__init__()
 #---------------------------------------------------------------       
        statusWin = QLabel(self)
        #statusWin = QPlainTextEdit(self)  # status window
        #statusWin.appendHtml("<b>hallo<br>hallo2<br>hallo3</b>")
        tabWin    = TabWidgets(self) # tabbed window
        print('hint status win: {0}'.format(statusWin.sizeHint()))
        print('hint_tab win: {0}'.format(tabWin.sizeHint()))
        print('hint main win: {0}'.format(self.sizeHint()))
        mSize = QFontMetrics(statusWin.font())
        rowHt = mSize.lineSpacing()
        # fixed height for statusWin needed as the sizeHint of tabWin is very small
        #statusWin.setFixedHeight(4*rowHt+4)
        # add status window underneath plot Tab Widgets:
        spltVMain = QSplitter(QtCore.Qt.Vertical)
        spltVMain.addWidget(tabWin)
        spltVMain.addWidget(statusWin)
        # relative initial sizes of subwidgets, this doesn't work here
#        spltVMain.setStretchFactor(4,1)
        spltVMain.setSizes([statusWin.sizeHint().height()*2, statusWin.sizeHint().height()*0.05])

        spltVMain.setFocus()
        # make spltVMain occupy the main area of QMainWindow and set inheritance
        self.setCentralWidget(spltVMain)   
        print('size tabs: {0}'.format(tabWin.size()))
        print('size status: {0}'.format(statusWin.size()))
        print('size self: {0}'.format(self.size()))
示例#6
0
    def init_ui(self):
        """Initialize all GUI elements and show window."""

        self.set_status('Welcome')
        self.create_menus()

        canvas_box = self.create_canvas()
        sequence_form = self.create_sequence_form()

        # let's have the sequence form over the canvas.
        vbox = QVBoxLayout()
        vbox.addLayout(sequence_form, stretch=0)
        vbox.setAlignment(Qt.AlignTop)

        vbox.addLayout(canvas_box, stretch=1)

        splitter = QSplitter(Qt.Horizontal)

        options = OptionPanel(self.args)

        for layout in [vbox, options]:
            widget = QWidget()
            widget.setLayout(layout)
            splitter.addWidget(widget)

        self.setCentralWidget(splitter)

        self.resize(600, 600)
        self.setWindowTitle('Dotplot')
        self.show()
示例#7
0
class Ui:
    def __init__(self, app):
        self._app = app
        self._layout = QVBoxLayout(app)
        self._bottom_layout = QHBoxLayout()
        self._top_separator = Separator(parent=app)
        self._splitter = QSplitter(app)
        if use_mac_theme():
            self._splitter.setHandleWidth(0)

        # NOTE: 以位置命名的部件应该只用来组织界面布局,不要
        # 给其添加任何功能性的函数
        self.top_panel = TopPanel(app, app)
        self._left_panel_container = QScrollArea(self._app)
        self._left_panel_container.setWidgetResizable(True)
        self.left_panel = LeftPanel(self._app, self._splitter)
        self._left_panel_container.setWidget(self.left_panel)
        self.right_panel = RightPanel(self._app, self._splitter)

        # alias
        self.pc_panel = self.top_panel.pc_panel
        self.table_container = self.right_panel.table_container
        self.magicbox = MagicBox(self._app)

        # 对部件进行一些 UI 层面的初始化
        self._splitter.addWidget(self._left_panel_container)
        self._splitter.addWidget(self.right_panel)

        self.right_panel.setMinimumWidth(780)
        self._left_panel_container.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding)
        self.right_panel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        if use_mac_theme():
            self._layout.addWidget(self.magicbox)
            self._layout.addWidget(self._splitter)
            self._layout.addWidget(self._top_separator)
            self._layout.addWidget(self.top_panel)
        else:
            self._layout.addWidget(self.top_panel)
            self._layout.addWidget(self._top_separator)
            self._layout.addWidget(self._splitter)
            self._layout.addWidget(self.magicbox)

        # self._layout.addLayout(self._bottom_layout)
        # self._bottom_layout.addWidget(self.magicbox)
        self._layout.setSpacing(0)
        self._layout.setContentsMargins(0, 0, 0, 0)
        self.top_panel.layout().setSpacing(0)
        self.top_panel.layout().setContentsMargins(0, 0, 0, 0)

        self.pc_panel.playlist_btn.clicked.connect(self.show_player_playlist)

        self._app.hotkey_manager.registe(
            [QKeySequence('Ctrl+F'), QKeySequence(':'), QKeySequence('Alt+x')],
            self.magicbox.setFocus
        )

    def show_player_playlist(self):
        songs = self._app.playlist.list()
        self.table_container.show_player_playlist(songs)
示例#8
0
    def __init__(self, signalNames):
        super(MainWindow, self).__init__()

        widget = QWidget()
        self.setCentralWidget(widget)

        self.consoleView = ConsoleView()
        self.signalView = SignalView()
        buttonsWidget = QWidget()

        scroll = QScrollArea()
        scroll.setWidget(self.signalView)
        scroll.setWidgetResizable(True)

        hboxSignalButtons = QHBoxLayout()
        self.signalButtons = self.createSignalButtons(signalNames,
                                                      hboxSignalButtons)
        buttonsWidget.setLayout(hboxSignalButtons)

        splitter = QSplitter(self)
        splitter.setOrientation(Qt.Vertical)
        splitter.addWidget(scroll)
        splitter.addWidget(self.consoleView)
        vbox = QVBoxLayout()
        vbox.addWidget(buttonsWidget)
        vbox.addWidget(splitter)
        

        self.createActions()
        self.createMenu()

        widget.setLayout(vbox)
        self.setWindowTitle("kit")
示例#9
0
    def __init__(self, parent=None):
        super().__init__(parent)

        self.editor = PythonEditor(self)
        self.resize(650, 500)

        fileMenu = QMenu(self.tr("&File"), self)
        fileMenu.addAction(self.tr("&New…"), self.newFile, QKeySequence.New)
        fileMenu.addAction(self.tr("&Open…"), self.openFile, QKeySequence.Open)
        fileMenu.addAction(self.tr("&Save"), self.saveFile, QKeySequence.Save)
        fileMenu.addAction(self.tr("Save &As…"), self.saveFileAs, QKeySequence.SaveAs)
        fileMenu.addSeparator()
        fileMenu.addAction(self.tr("&Run…"), self.runScript, "Ctrl+R")
        fileMenu.addSeparator()
        fileMenu.addAction(self.tr("&Close"), self.close, platformSpecific.closeKeySequence())
        self.menuBar().addMenu(fileMenu)

        self.fileChooser = FileChooser(self)
        self.fileChooser.fileOpened.connect(self.openFile)
        splitter = QSplitter(self)
        splitter.addWidget(self.fileChooser)
        splitter.addWidget(self.editor)
        splitter.setStretchFactor(0, 2)
        splitter.setStretchFactor(1, 5)
        splitter.setSizes([0, 1])
        self.setCentralWidget(splitter)
        self.newFile()
        self.editor.modificationChanged.connect(self.setWindowModified)
示例#10
0
class DualFrame(QFrame):

    def __init__(self, plot_title, finish_creating_plot_gui, is_top_level):
        QFrame.__init__(self)

        self.setWindowTitle(plot_title)

        self.main_layout = QVBoxLayout(self)

        self.splitter = QSplitter()
        self.dnd_frame_1 = DndFrame('Output Graphs')
        self.dnd_frame_2 = DndFrame('Graphs to Display')

        self.splitter.addWidget(self.dnd_frame_1)
        self.splitter.addWidget(self.dnd_frame_2)

        self.main_layout.addWidget(self.splitter)

        self.button_layout = QHBoxLayout()

        self.dnd_close_button = PyQtExtras.CommandButton('Close')
        self.dnd_close_button.set_handler(self.on_close)

        self.dnd_accept_button = PyQtExtras.CommandButton('Accept')
        self.dnd_accept_button.set_handler(self.on_accept)

        self.button_layout.addWidget(self.dnd_close_button)
        self.button_layout.addWidget(self.dnd_accept_button)

        self.button_layout.setAlignment(Qt.AlignRight)

        self.main_layout.addLayout(self.button_layout)

        self.finish_creating_plot_gui = finish_creating_plot_gui

        self.is_top_level = is_top_level

        self.setMinimumSize(QSize(800, 640))

    def add_to_first(self, text):
        self.dnd_frame_1.add_label(text)

    def add_to_second(self, text):
        self.dnd_frame_2.add_label(text)

    def on_accept(self):
        plots_to_output = self.dnd_frame_1.get_output_plot_filenames()

        if self.finish_creating_plot_gui != None:
            self.finish_creating_plot_gui(plots_to_output)

        self.close()

    def on_close(self):

        self.hide()

        if self.is_top_level:
            QApplication.exit(0)
示例#11
0
    def sig_to_stems_clicked(self, row):
        signature = self.sig_to_stems_major_table.item(row, 0).text()
        print(signature)
        signature = tuple(signature.split(SEP_SIG))

        stems = sorted(self.lexicon.signatures_to_stems()[signature])
        number_of_stems_per_column = 5

        # create a master list of sublists, where each sublist contains k stems
        # k = number_of_stems_per_column
        stem_rows = list()
        stem_row = list()

        for i, stem in enumerate(stems, 1):
            stem_row.append(stem)
            if not i % number_of_stems_per_column:
                stem_rows.append(stem_row)
                stem_row = list()
        if stem_row:
            stem_rows.append(stem_row)

        # set up the minor table as table widget
        sig_to_stems_minor_table = QTableWidget()
        sig_to_stems_minor_table.horizontalHeader().hide()
        sig_to_stems_minor_table.verticalHeader().hide()
        sig_to_stems_minor_table.clear()
        sig_to_stems_minor_table.setRowCount(len(stem_rows))
        sig_to_stems_minor_table.setColumnCount(number_of_stems_per_column)

        # fill in the minor table
        for row, stem_row in enumerate(stem_rows):
            for col, stem in enumerate(stem_row):
                item = QTableWidgetItem(stem)
                sig_to_stems_minor_table.setItem(row, col, item)

        sig_to_stems_minor_table.resizeColumnsToContents()

        minor_table_title = QLabel('{} (number of stems: {})'
                                   .format(SEP_SIG.join(signature), len(stems)))

        minor_table_widget_with_title = QWidget()
        layout = QVBoxLayout()
        layout.addWidget(minor_table_title)
        layout.addWidget(sig_to_stems_minor_table)
        minor_table_widget_with_title.setLayout(layout)

        new_display = QSplitter(Qt.Horizontal)
        new_display.setHandleWidth(10)
        new_display.setChildrenCollapsible(False)

        new_display.addWidget(self.sig_to_stems_major_table)
        new_display.addWidget(minor_table_widget_with_title)
        new_display_width = self.majorDisplay.width() / 2
        new_display.setSizes(
            [new_display_width * 0.4, new_display_width * 0.6])

        self.load_main_window(major_display=new_display)
        self.status.clearMessage()
        self.status.showMessage('{} selected'.format(signature))
示例#12
0
文件: tab.py 项目: modulexcite/retext
	def getSplitter(self):
		splitter = QSplitter(Qt.Horizontal)
		# Give both boxes a minimum size so the minimumSizeHint will be
		# ignored when splitter.setSizes is called below
		for widget in self.editBox, self.previewBox:
			widget.setMinimumWidth(125)
			splitter.addWidget(widget)
		splitter.setSizes((50, 50))
		splitter.setChildrenCollapsible(False)
		return splitter
    def __init__(self, parent=None):
        super().__init__(parent)

        # initialize class attributes
        self._INPUTS_FIXED_WIDTH = 180
        self._BUTTON_MIN_WIDTH = 80
        self._OXYGEN_PATH_32 = os.path.join("resources", "icons", "oxygen", "32")

        # locale and language settings
        self.language = self.locale().name()[:2]
        self.qtTl = QTranslator()
        self.appTl = QTranslator()
        self.switchTranslator(self.qtTl, "qtbase", self.language)
        self.switchTranslator(self.appTl, "wuchshuellenrechner", self.language)

        # TODO(th)
        self.model = TreeModel()

        # setup gui
        self.setMinimumSize(1200, 760)

        self.createActions()
        self.createMainMenu()

        # plot widget
        self.plotWidget = VariantPlotView()
        self.plotWidget.setModel(self.model)

        # create vertical splitter
        splitter = QSplitter(Qt.Vertical)
        splitter.setContentsMargins(11, 11, 11, 11)
        splitter.addWidget(self.createEditBox())
        splitter.addWidget(self.plotWidget)

        self.setCentralWidget(splitter)

        self.dataWidget.setModel(self.model)

        selectionModel = QItemSelectionModel(self.model)
        self.dataWidget.setSelectionModel(selectionModel)
        self.plotWidget.setSelectionModel(selectionModel)

        self.retranslateUi()


        self.model.dataChanged.connect(self.updateInputs)
        self.model.itemsInserted.connect(self.taxInput.setDisabled)
        self.model.allItemsRemoved.connect(self.taxInput.setEnabled)
        self.operationInput.textChanged.connect(self.updateOperation)
        self.districtInput.textChanged.connect(self.updateDistrict)
        self.managerInput.textChanged.connect(self.updateManager)
        self.locationInput.textChanged.connect(self.updateLocation)
        self.taxInput.stateChanged.connect(self.updateTax)
示例#14
0
    def create_mid_group(self):
        self.ddi_tree = QTreeWidget()
        self.ddi_tree.itemSelectionChanged.connect(self.show_ddi_details)

        ddi_details = QGroupBox()
        ddi_details_layout = QGridLayout()
        ddi_details_layout.setContentsMargins(0,0,0,0)
        ddi_details_layout.addWidget(self.create_common_ddi_details(), 0, 0, 1, 1)
        ddi_details_layout.addWidget(self.create_specific_ddi_details(), 1, 0, 3, 1)
        ddi_details.setLayout(ddi_details_layout)

        self.step_tree = QTreeWidget()
        self.step_tree.itemSelectionChanged.connect(self.show_step_details)
        step_details = QGroupBox()
        step_details_layout = QGridLayout()
        step_details_layout.setContentsMargins(0,0,0,0)
        step_details_layout.addWidget(self.create_common_step_details(), 0, 0, 1, 1)
        # step_details_layout.addWidget(self.create_specific_step_details(), 1, 0, 3, 1)
        step_details.setLayout(step_details_layout)

        splitter = QSplitter(self)
        splitter.addWidget(self.ddi_tree)
        splitter.addWidget(ddi_details)
        splitter.addWidget(self.step_tree)
        splitter.addWidget(step_details)

        hbox = QHBoxLayout()
        hbox.setContentsMargins(0,0,0,0)
        # self.__mix_to_layout(hbox, self.ddi_tree, ddi_details, self.step_tree, step_details)
        hbox.addWidget(splitter)
        # group_box.setLayout(hbox)
        return hbox
示例#15
0
    def setup_layout(self):
        main_widget = QWidget()
        main_layout = QHBoxLayout()
        main_layout_splitter = QSplitter(Qt.Horizontal, self)
        main_widget.setLayout(main_layout)

        main_layout.addWidget(main_layout_splitter)

        main_layout_splitter.addWidget(self.selection_list)
        main_layout_splitter.addWidget(self.view_tabs)
        main_layout_splitter.setStretchFactor(0, 1)
        main_layout_splitter.setStretchFactor(1, 10)

        self.setCentralWidget(main_widget)
示例#16
0
    def initUI(self):      

        hbox = QHBoxLayout(self)

        topleft = QFrame(self)
        topleft.setFrameShape(QFrame.StyledPanel)
 
        topright = QFrame(self)
        topright.setFrameShape(QFrame.StyledPanel)

        bottom = QFrame(self)
        bottom.setFrameShape(QFrame.StyledPanel)

        splitter1 = QSplitter(Qt.Horizontal)
        splitter1.addWidget(topleft)
        splitter1.addWidget(topright)

        splitter2 = QSplitter(Qt.Vertical)
        splitter2.addWidget(splitter1)
        splitter2.addWidget(bottom)

        hbox.addWidget(splitter2)
        self.setLayout(hbox)
        
        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('QSplitter')
        self.show()
示例#17
0
文件: main.py 项目: dormouse/test
    def __init__(self):
        super(MainWindow, self).__init__()
        self.createActions()
        self.createMenus()
        # self.createToolBars()
        self.createStatusBar()

        treeLeft = FileTree()
        treeRight = FileTree()
        sp = QSplitter(Qt.Horizontal)
        sp.addWidget(treeLeft)
        sp.addWidget(treeRight)

        self.setCentralWidget(sp)
        self.resize(640, 480)
示例#18
0
class MainWindow(QMainWindow):


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

		self.container = QSplitter(self)
		self.setCentralWidget(self.container)

		#mon = DMX_Monitor(self)
		mon = None

		self.container.addWidget(ControlPanel(self, mon))
		if mon: 
			self.container.addWidget(mon)

		self.createActions()
		self.createMenus()
		self.createStatusBar()


	def about(self):
		QMessageBox.about(self, "About Application", __main__.__doc__)


	def createActions(self):
		self.exitAct = QAction("E&xit", self, shortcut="Ctrl+Q",
				statusTip="Exit the application", triggered=self.close)

		self.aboutAct = QAction("&About", self,
				statusTip="Show the application's About box",
				triggered=self.about)

		self.aboutQtAct = QAction("About &Qt", self,
				statusTip="Show the Qt library's About box",
				triggered=QApplication.instance().aboutQt)


	def createMenus(self):
		self.fileMenu = self.menuBar().addMenu("&File")
		self.fileMenu.addAction(self.exitAct)
		self.helpMenu = self.menuBar().addMenu("&About")
		self.helpMenu.addAction(self.aboutAct)
		self.helpMenu.addAction(self.aboutQtAct)


	def createStatusBar(self):
		self.statusBar().showMessage("Ready")
示例#19
0
    def __init__(self, chat_window, nick, parent=None):
        QWidget.__init__(self, parent)

        self.chat_window = chat_window
        self.nick = nick

        self.disabled = False
        self.cleared = False

        self.url_regex = re.compile(URL_REGEX)

        self.chat_log = QTextBrowser()
        self.chat_log.setOpenExternalLinks(True)

        self.chat_input = QTextEdit()
        self.chat_input.textChanged.connect(self.chatInputTextChanged)

        self.send_button = QPushButton("Send")
        self.send_button.clicked.connect(self.sendMessage)

        # Set the min height for the chatlog and a matching fixed height for the send button
        chat_input_font_metrics = QFontMetrics(self.chat_input.font())
        self.chat_input.setMinimumHeight(chat_input_font_metrics.lineSpacing() * 3)
        self.send_button.setFixedHeight(chat_input_font_metrics.lineSpacing() * 3)

        hbox = QHBoxLayout()
        hbox.addWidget(self.chat_input)
        hbox.addWidget(self.send_button)

        # Put the chatinput and send button in a wrapper widget so they may be added to the splitter
        chat_input_wrapper = QWidget()
        chat_input_wrapper.setLayout(hbox)
        chat_input_wrapper.setMinimumHeight(chat_input_font_metrics.lineSpacing() * 3.7)

        # Put the chat log and chat input into a splitter so the user can resize them at will
        splitter = QSplitter(Qt.Vertical)
        splitter.addWidget(self.chat_log)
        splitter.addWidget(chat_input_wrapper)
        splitter.setSizes([int(parent.height()), 1])

        hbox = QHBoxLayout()
        hbox.addWidget(splitter)
        self.setLayout(hbox)

        self.typing_timer = QTimer()
        self.typing_timer.setSingleShot(True)
        self.typing_timer.timeout.connect(self.stoppedTyping)
示例#20
0
    def create_settings(self):
        """Create the widget, organized in two parts.

        Notes
        -----
        When you add widgets in config, remember to update show_settings too
        """
        bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply |
                                QDialogButtonBox.Cancel)
        self.idx_ok = bbox.button(QDialogButtonBox.Ok)
        self.idx_apply = bbox.button(QDialogButtonBox.Apply)
        self.idx_cancel = bbox.button(QDialogButtonBox.Cancel)
        bbox.clicked.connect(self.button_clicked)

        page_list = QListWidget()
        page_list.setSpacing(1)
        page_list.currentRowChanged.connect(self.change_widget)

        pages = ['General', 'Overview', 'Signals', 'Channels', 'Spectrum',
                 'Notes', 'Video']
        for one_page in pages:
            page_list.addItem(one_page)

        self.stacked = QStackedWidget()
        self.stacked.addWidget(self.config)
        self.stacked.addWidget(self.parent.overview.config)
        self.stacked.addWidget(self.parent.traces.config)
        self.stacked.addWidget(self.parent.channels.config)
        self.stacked.addWidget(self.parent.spectrum.config)
        self.stacked.addWidget(self.parent.notes.config)
        self.stacked.addWidget(self.parent.video.config)

        hsplitter = QSplitter()
        hsplitter.addWidget(page_list)
        hsplitter.addWidget(self.stacked)

        btnlayout = QHBoxLayout()
        btnlayout.addStretch(1)
        btnlayout.addWidget(bbox)

        vlayout = QVBoxLayout()
        vlayout.addWidget(hsplitter)
        vlayout.addLayout(btnlayout)

        self.setLayout(vlayout)
示例#21
0
    def setupViews(self):
        splitter = QSplitter()
        table = QTableView()
        self.pieChart = PieView()
        splitter.addWidget(table)
        splitter.addWidget(self.pieChart)
        splitter.setStretchFactor(0, 0)
        splitter.setStretchFactor(1, 1)

        table.setModel(self.model)
        self.pieChart.setModel(self.model)

        self.selectionModel = QItemSelectionModel(self.model)
        table.setSelectionModel(self.selectionModel)
        self.pieChart.setSelectionModel(self.selectionModel)

        table.horizontalHeader().setStretchLastSection(True)

        self.setCentralWidget(splitter)
示例#22
0
    def __init_ui__(self):

        vbox = QVBoxLayout()

        splitter = QSplitter()

        splitter.addWidget(self.file_view)
        splitter.addWidget(self.overview)

        vbox.addWidget(splitter, 1)
        vbox.addWidget(self.lb_path)

        button_box = QHBoxLayout()
        button_box.addWidget(self.pb_select)
        button_box.addStretch(1)
        button_box.addWidget(self.pb_publish)
        button_box.addWidget(self.pb_zip)
        vbox.addLayout(button_box)

        self.setLayout(vbox)
示例#23
0
    def setupViews(self):
        splitter = QSplitter()
        splitter.setHandleWidth(5)

        browsers = QTabWidget()

        label = QLabel('Placeholder')
        label.setAlignment(Qt.AlignCenter|Qt.AlignHCenter|Qt.AlignVCenter)

        layout = QHBoxLayout()
        layout.addWidget(label)

        rightPane = QWidget()
        rightPane.setLayout(layout)

        splitter.addWidget(browsers)
        splitter.addWidget(rightPane)
        splitter.setStretchFactor(0, 1)
        splitter.setStretchFactor(1, 1)

        self.setCentralWidget(splitter)
示例#24
0
def main(args):
    app = QApplication(args)
    page = QSplitter()
    data = Model(1000, 10, page)
    selections = QItemSelectionModel(data)
    table = QTableView()
    table.setModel(data)
    table.setSelectionModel(selections)
    table.horizontalHeader().setSectionsMovable(True)
    table.verticalHeader().setSectionsMovable(True)
    # Set StaticContents to enable minimal repaints on resizes.
    table.viewport().setAttribute(Qt.WA_StaticContents)
    page.addWidget(table)
    tree = QTreeView()
    tree.setModel(data)
    tree.setSelectionModel(selections)
    tree.setUniformRowHeights(True)
    tree.header().setStretchLastSection(False)
    tree.viewport().setAttribute(Qt.WA_StaticContents)
    # Disable the focus rect to get minimal repaints when scrolling on Mac.
    tree.setAttribute(Qt.WA_MacShowFocusRect, False)
    page.addWidget(tree)
    list = QListView()
    list.setModel(data)
    list.setSelectionModel(selections)
    list.setViewMode(QListView.IconMode)
    list.setSelectionMode(QAbstractItemView.ExtendedSelection)
    list.setAlternatingRowColors(False)
    list.viewport().setAttribute(Qt.WA_StaticContents)
    list.setAttribute(Qt.WA_MacShowFocusRect, False)
    page.addWidget(list)
    page.setWindowIcon(QIcon(images_dir + '/interview.png'))
    page.setWindowTitle("Interview")
    page.show()
    return app.exec_()
示例#25
0
class TestWindow(QWidget):
    TMPDIR = "tmp"
    TMPHTMLFILE = os.path.join(TMPDIR,'tmptext.html')
    def __init__(self,parent = None):
        QWidget.__init__(self,parent)
        
        if os.path.isdir(TestWindow.TMPDIR) == False:
            os.mkdir(TestWindow.TMPDIR)
        
        self.textEditor = TextEditor(self)
        self.webViewer = QWebView(self)
        self.setupUI()
        self.textEditor.textChangeSignal.connect(self.reloadText)
    
    def reloadText(self,dataDict):
        if self.webViewer.isVisible() == False:
            self.webViewer.show()
        with codecs.open( ResourceManager.getResourceAbsPath('template.html'),'r','utf-8' ) as templateFileObj:
            templateStr = templateFileObj.read()
        with open( TestWindow.TMPHTMLFILE,'wb' ) as tempFileObj:
            tempFileObj.write( (templateStr % dataDict[TextEditor.KEY_ORIGINALTXET]).encode('utf-8') )
        self.webViewer.load(QUrl( "file:///%s" % os.path.abspath( TestWindow.TMPHTMLFILE ) ))


    def setupUI(self):
        self.webViewer.hide()
        
        layout = QHBoxLayout(self)
        self.splitter = QSplitter(self)
        self.splitter.addWidget(self.textEditor)
        self.splitter.addWidget(self.webViewer)
        layout.addWidget(self.splitter)

        self.textEditor.resize(400,600)
        self.webViewer.resize(400,600)
        self.resize(800,600)
        
        self.splitter.setStyleSheet("background-color:green;")
        self.textEditor.setStyleSheet("background-color:white;border:none;")
        self.webViewer.setStyleSheet("background-color:white;")
示例#26
0
    def setupViews(self):
        splitter = QSplitter()
        self.table = QTableView()
        self.pieChart = PieView()


        splitter.addWidget(self.pieChart)
        splitter.addWidget(self.table)
        splitter.setStretchFactor(0, 0)
        splitter.setStretchFactor(1, 0)

        self.table.setModel(self.model)
        self.pieChart.setModel(self.model2)

        self.selectionModel = QItemSelectionModel(self.model2)
        self.table.setSelectionModel(self.selectionModel)

        #self.pieChart.setSelectionModel(self.selectionModel)

        #table.setColumnWidth(0,100)
        self.setCentralWidget(splitter)
        self.table.doubleClicked.connect(self.ClickAction_table)
示例#27
0
    def initUI(self):
        '''
        Example
            hbox
                splitter2
                    splitter1
                        topleft
                            vbox
                                self.lbl
                                combo
                        topright
                    bottom
        '''
        # splitter
        hbox = QHBoxLayout(self)
        topleft = QFrame(self)
        topleft.setFrameShape(QFrame.StyledPanel)
        topright = QFrame(self)
        topright.setFrameShape(QFrame.StyledPanel)
        bottom = QFrame(self)
        bottom.setFrameShape(QFrame.StyledPanel)
        splitter1 = QSplitter(Qt.Horizontal)
        splitter1.addWidget(topleft)
        splitter1.addWidget(topright)
        splitter2 = QSplitter(Qt.Vertical)
        splitter2.addWidget(splitter1)
        splitter2.addWidget(bottom)
        hbox.addWidget(splitter2)
        self.setLayout(hbox)

        # combo
        self.lbl = QLabel("Ubuntu", self)
        combo = QComboBox(self)
        combo.addItem("Ubuntu")
        combo.addItem("Mandriva")
        combo.addItem("Fedora")
        combo.addItem("Arch")
        combo.addItem("Gentoo")
        combo.activated[str].connect(self.onActivated)

        # put combo and label into layout into frame
        vbox = QVBoxLayout(topleft)
        vbox.addWidget(self.lbl)
        vbox.addWidget(combo)

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('QSplitter')
        self.show()
示例#28
0
    def __init__(self, parent=None):
        super().__init__(parent)

        self.editor = PythonEditor(self)
        self.fileChooser = FileChooser(self)
        self.fileChooser.fileOpened.connect(self.openFile)
        self.outputEdit = OutputEdit(self)

        splitter = QSplitter(self)
        self.vSplitter = QSplitter(Qt.Vertical, splitter)
        self.vSplitter.addWidget(self.editor)
        self.vSplitter.addWidget(self.outputEdit)
        self.vSplitter.setStretchFactor(0, 1)
        self.vSplitter.setStretchFactor(1, 0)
        splitter.addWidget(self.fileChooser)
        splitter.addWidget(self.vSplitter)
        splitter.setStretchFactor(0, 0)
        splitter.setStretchFactor(1, 1)
        statusBar = ScriptingStatusBar(self)
        self.setCentralWidget(splitter)
        self.setStatusBar(statusBar)
        self.newFile()
        self.editor.modificationChanged.connect(self.setWindowModified)
        statusBar.setPosition(self.editor.textCursor())
        self.editor.cursorPositionChanged.connect(
            lambda: statusBar.setPosition(self.sender().textCursor()))
        statusBar.setIndent(self.editor.indent())
        self.editor.indentChanged.connect(statusBar.setIndent)
        statusBar.indentModified.connect(self.editor.setIndent)
        statusBar.positionClicked.connect(self.gotoLine)
        statusBar.clearButtonClicked.connect(self.outputEdit.clear)
        statusBar.runButtonClicked.connect(self.runScript)
        gotoLineShortcut = QShortcut(QKeySequence("Ctrl+G"), self)
        gotoLineShortcut.activated.connect(self.gotoLine)

        self.readSettings()
        splitter.splitterMoved.connect(self.writeSettings)
        self.vSplitter.splitterMoved.connect(self.writeSettings)
示例#29
0
class WindowUI(object):

    def widgetTraining(self):
        return TrainingWidget(self.classes_tree_view)

    def widgetRecognition(self):
        return RecognitionWidget(self.classes_tree_view)

    def widgetDataset(self):
        return DatasetWidget(self.classes_tree_view)

    def setupUI(self):
        """Create User Interface.
        """
        mainWidget = QWidget()
        mainLayout = QHBoxLayout()

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

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

        mainLayout.addWidget(self.hsplitter)
        mainWidget.setLayout(mainLayout)
        self.setCentralWidget(mainWidget)
示例#30
0
    def splitViewSpace(self, viewspace, orientation):
        """Split the given view.

        If orientation == Qt.Horizontal, adds a new view to the right.
        If orientation == Qt.Vertical, adds a new view to the bottom.

        """
        active = viewspace is self.activeViewSpace()
        splitter = viewspace.parentWidget()
        newspace = ViewSpace(self)

        if splitter.count() == 1:
            splitter.setOrientation(orientation)
            size = splitter.sizes()[0]
            splitter.addWidget(newspace)
            splitter.setSizes([size / 2, size / 2])
        elif splitter.orientation() == orientation:
            index = splitter.indexOf(viewspace)
            splitter.insertWidget(index + 1, newspace)
        else:
            index = splitter.indexOf(viewspace)
            newsplitter = QSplitter()
            newsplitter.setOrientation(orientation)
            sizes = splitter.sizes()
            splitter.insertWidget(index, newsplitter)
            newsplitter.addWidget(viewspace)
            splitter.setSizes(sizes)
            size = newsplitter.sizes()[0]
            newsplitter.addWidget(newspace)
            newsplitter.setSizes([size / 2, size / 2])
        self._viewSpaces.insert(0, newspace)
        newspace.showDocument(viewspace.document())
        if active:
            newspace.activeView().setFocus()
        self.actionCollection.window_close_view.setEnabled(self.canCloseViewSpace())
        self.actionCollection.window_close_others.setEnabled(self.canCloseViewSpace())
示例#31
0
class GuiMain(QMainWindow):

    def __init__(self):
        QMainWindow.__init__(self)

        logger.debug("Initialising GUI ...")
        self.setObjectName("GuiMain")
        self.mainConf = nw.CONFIG
        self.threadPool = QThreadPool()

        # System Info
        # ===========

        logger.info("OS: %s" % self.mainConf.osType)
        logger.info("Kernel: %s" % self.mainConf.kernelVer)
        logger.info("Host: %s" % self.mainConf.hostName)
        logger.info("Qt5 Version: %s (%d)" % (
            self.mainConf.verQtString, self.mainConf.verQtValue)
        )
        logger.info("PyQt5 Version: %s (%d)" % (
            self.mainConf.verPyQtString, self.mainConf.verPyQtValue)
        )
        logger.info("Python Version: %s (0x%x)" % (
            self.mainConf.verPyString, self.mainConf.verPyHexVal)
        )

        # Core Classes
        # ============

        # Core Classes and Settings
        self.theTheme    = GuiTheme(self)
        self.theProject  = NWProject(self)
        self.theIndex    = NWIndex(self.theProject, self)
        self.hasProject  = False
        self.isFocusMode = False

        # Prepare Main Window
        self.resize(*self.mainConf.getWinSize())
        self._updateWindowTitle()
        self.setWindowIcon(QIcon(self.mainConf.appIcon))

        # Build the GUI
        # =============

        # Main GUI Elements
        self.statusBar = GuiMainStatus(self)
        self.treeView  = GuiProjectTree(self)
        self.docEditor = GuiDocEditor(self)
        self.viewMeta  = GuiDocViewDetails(self)
        self.docViewer = GuiDocViewer(self)
        self.treeMeta  = GuiItemDetails(self)
        self.projView  = GuiOutline(self)
        self.projMeta  = GuiOutlineDetails(self)
        self.mainMenu  = GuiMainMenu(self)

        # Minor Gui Elements
        self.statusIcons = []
        self.importIcons = []

        # Project Tree View
        self.treePane = QWidget()
        self.treeBox = QVBoxLayout()
        self.treeBox.setContentsMargins(0, 0, 0, 0)
        self.treeBox.addWidget(self.treeView)
        self.treeBox.addWidget(self.treeMeta)
        self.treePane.setLayout(self.treeBox)

        # Splitter : Document Viewer / Document Meta
        self.splitView = QSplitter(Qt.Vertical)
        self.splitView.addWidget(self.docViewer)
        self.splitView.addWidget(self.viewMeta)
        self.splitView.setSizes(self.mainConf.getViewPanePos())

        # Splitter : Document Editor / Document Viewer
        self.splitDocs = QSplitter(Qt.Horizontal)
        self.splitDocs.addWidget(self.docEditor)
        self.splitDocs.addWidget(self.splitView)

        # Splitter : Project Outlie / Outline Details
        self.splitOutline = QSplitter(Qt.Vertical)
        self.splitOutline.addWidget(self.projView)
        self.splitOutline.addWidget(self.projMeta)
        self.splitOutline.setSizes(self.mainConf.getOutlinePanePos())

        # Main Tabs : Edirot / Outline
        self.tabWidget = QTabWidget()
        self.tabWidget.setTabPosition(QTabWidget.East)
        self.tabWidget.setStyleSheet("QTabWidget::pane {border: 0;}")
        self.tabWidget.addTab(self.splitDocs, "Editor")
        self.tabWidget.addTab(self.splitOutline, "Outline")
        self.tabWidget.currentChanged.connect(self._mainTabChanged)

        # Splitter : Project Tree / Main Tabs
        xCM = self.mainConf.pxInt(4)
        self.splitMain = QSplitter(Qt.Horizontal)
        self.splitMain.setContentsMargins(xCM, xCM, xCM, xCM)
        self.splitMain.addWidget(self.treePane)
        self.splitMain.addWidget(self.tabWidget)
        self.splitMain.setSizes(self.mainConf.getMainPanePos())

        # Indices of All Splitter Widgets
        self.idxTree     = self.splitMain.indexOf(self.treePane)
        self.idxMain     = self.splitMain.indexOf(self.tabWidget)
        self.idxEditor   = self.splitDocs.indexOf(self.docEditor)
        self.idxViewer   = self.splitDocs.indexOf(self.splitView)
        self.idxViewDoc  = self.splitView.indexOf(self.docViewer)
        self.idxViewMeta = self.splitView.indexOf(self.viewMeta)
        self.idxTabEdit  = self.tabWidget.indexOf(self.splitDocs)
        self.idxTabProj  = self.tabWidget.indexOf(self.splitOutline)

        # Splitter Behaviour
        self.splitMain.setCollapsible(self.idxTree, False)
        self.splitMain.setCollapsible(self.idxMain, False)
        self.splitDocs.setCollapsible(self.idxEditor, False)
        self.splitDocs.setCollapsible(self.idxViewer, True)
        self.splitView.setCollapsible(self.idxViewDoc, False)
        self.splitView.setCollapsible(self.idxViewMeta, False)

        # Editor / Viewer Default State
        self.splitView.setVisible(False)
        self.docEditor.closeSearch()

        # Initialise the Project Tree
        self.treeView.itemSelectionChanged.connect(self._treeSingleClick)
        self.treeView.itemDoubleClicked.connect(self._treeDoubleClick)
        self.rebuildTree()

        # Set Main Window Elements
        self.setMenuBar(self.mainMenu)
        self.setCentralWidget(self.splitMain)
        self.setStatusBar(self.statusBar)

        # Finalise Initialisation
        # =======================

        # Set Up Auto-Save Project Timer
        self.asProjTimer = QTimer()
        self.asProjTimer.timeout.connect(self._autoSaveProject)

        # Set Up Auto-Save Document Timer
        self.asDocTimer = QTimer()
        self.asDocTimer.timeout.connect(self._autoSaveDocument)

        # Shortcuts and Actions
        self._connectMenuActions()

        keyReturn = QShortcut(self.treeView)
        keyReturn.setKey(QKeySequence(Qt.Key_Return))
        keyReturn.activated.connect(self._treeKeyPressReturn)

        keyEscape = QShortcut(self)
        keyEscape.setKey(QKeySequence(Qt.Key_Escape))
        keyEscape.activated.connect(self._keyPressEscape)

        # Forward Functions
        self.setStatus = self.statusBar.setStatus
        self.setProjectStatus = self.statusBar.setProjectStatus

        # Force a show of the GUI
        self.show()

        # Check that config loaded fine
        self.reportConfErr()

        # Initialise Main GUI
        self.initMain()
        self.asProjTimer.start()
        self.asDocTimer.start()
        self.statusBar.clearStatus()

        # Handle Windows Mode
        self.showNormal()
        if self.mainConf.isFullScreen:
            self.toggleFullScreenMode()

        logger.debug("GUI initialisation complete")

        # Check if a project path was provided at command line, and if
        # not, open the project manager instead.
        if self.mainConf.cmdOpen is not None:
            logger.debug("Opening project from additional command line option")
            self.openProject(self.mainConf.cmdOpen)
        else:
            if self.mainConf.showGUI:
                self.showProjectLoadDialog()

        # Show the latest release notes, if they haven't been shown before
        if hexToInt(self.mainConf.lastNotes) < hexToInt(nw.__hexversion__):
            if self.mainConf.showGUI:
                self.showAboutNWDialog(showNotes=True)
            self.mainConf.lastNotes = nw.__hexversion__

        logger.debug("novelWriter is ready ...")
        self.setStatus("novelWriter is ready ...")

        return

    def clearGUI(self):
        """Wrapper function to clear all sub-elements of the main GUI.
        """
        # Project Area
        self.treeView.clearTree()
        self.treeMeta.clearDetails()

        # Work Area
        self.docEditor.clearEditor()
        self.docEditor.setDictionaries()
        self.closeDocViewer()
        self.projMeta.clearDetails()

        # General
        self.statusBar.clearStatus()
        self._updateWindowTitle()

        return True

    def initMain(self):
        """Initialise elements that depend on user settings.
        """
        self.asProjTimer.setInterval(int(self.mainConf.autoSaveProj*1000))
        self.asDocTimer.setInterval(int(self.mainConf.autoSaveDoc*1000))
        return True

    ##
    #  Project Actions
    ##

    def newProject(self, projData=None):
        """Create new project via the new project wizard.
        """
        if self.hasProject:
            if not self.closeProject():
                self.makeAlert(
                    "Cannot create new project when another project is open.",
                    nwAlert.ERROR
                )
                return False

        if projData is None:
            projData = self.showNewProjectDialog()

        if projData is None:
            return False

        projPath = projData.get("projPath", None)
        if projPath is None or projData is None:
            logger.error("No projData or projPath set")
            return False

        if os.path.isfile(os.path.join(projPath, self.theProject.projFile)):
            self.makeAlert(
                "A project already exists in that location. Please choose another folder.",
                nwAlert.ERROR
            )
            return False

        logger.info("Creating new project")
        if self.theProject.newProject(projData):
            self.rebuildTree()
            self.saveProject()
            self.hasProject = True
            self.docEditor.setDictionaries()
            self.rebuildIndex(beQuiet=True)
            self.statusBar.setRefTime(self.theProject.projOpened)
            self.statusBar.setProjectStatus(True)
            self.statusBar.setDocumentStatus(None)
            self.statusBar.setStatus("New project created ...")
            self._updateWindowTitle(self.theProject.projName)
        else:
            self.theProject.clearProject()
            return False

        return True

    def closeProject(self, isYes=False):
        """Closes the project if one is open. isYes is passed on from
        the close application event so the user doesn't get prompted
        twice to confirm.
        """
        if not self.hasProject:
            # There is no project loaded, everything OK
            return True

        if not isYes:
            msgYes = self.askQuestion(
                "Close Project",
                "Close the current project?<br>Changes are saved automatically."
            )
            if not msgYes:
                return False

        if self.docEditor.docChanged:
            self.saveDocument()

        if self.theProject.projAltered:
            saveOK   = self.saveProject()
            doBackup = False
            if self.theProject.doBackup and self.mainConf.backupOnClose:
                doBackup = True
                if self.mainConf.askBeforeBackup:
                    msgYes = self.askQuestion(
                        "Backup Project", "Backup the current project?"
                    )
                    if not msgYes:
                        doBackup = False
            if doBackup:
                self.theProject.zipIt(False)
        else:
            saveOK = True

        if saveOK:
            self.closeDocument()
            self.docViewer.clearNavHistory()
            self.projView.closeOutline()
            self.theProject.closeProject()
            self.theIndex.clearIndex()
            self.clearGUI()
            self.hasProject = False
            self.tabWidget.setCurrentWidget(self.splitDocs)

        return saveOK

    def openProject(self, projFile):
        """Open a project from a projFile path.
        """
        if projFile is None:
            return False

        # Make sure any open project is cleared out first before we load
        # another one
        if not self.closeProject():
            return False

        # Switch main tab to editor view
        self.tabWidget.setCurrentWidget(self.splitDocs)

        # Try to open the project
        if not self.theProject.openProject(projFile):
            # The project open failed.

            if self.theProject.lockedBy is None:
                # The project is not locked, so failed for some other
                # reason handled by the project class.
                return False

            try:
                lockDetails = (
                    "<br><br>The project was locked by the computer "
                    "'%s' (%s %s), last active on %s"
                ) % (
                    self.theProject.lockedBy[0],
                    self.theProject.lockedBy[1],
                    self.theProject.lockedBy[2],
                    datetime.fromtimestamp(
                        int(self.theProject.lockedBy[3])
                    ).strftime("%x %X")
                )
            except Exception:
                lockDetails = ""

            msgBox = QMessageBox()
            msgRes = msgBox.warning(
                self, "Project Locked", (
                    "The project is already open by another instance of novelWriter, and "
                    "is therefore locked. Override lock and continue anyway?<br><br>"
                    "Note: If the program or the computer previously crashed, the lock "
                    "can safely be overridden. If, however, another instance of "
                    "novelWriter has the project open, overriding the lock may corrupt "
                    "the project, and is not recommended.%s"
                ) % lockDetails,
                QMessageBox.Yes | QMessageBox.No, QMessageBox.No
            )
            if msgRes == QMessageBox.Yes:
                if not self.theProject.openProject(projFile, overrideLock=True):
                    return False
            else:
                return False

        # Project is loaded
        self.hasProject = True

        # Load the tag index
        self.theIndex.loadIndex()

        # Update GUI
        self._updateWindowTitle(self.theProject.projName)
        self.rebuildTree()
        self.docEditor.setDictionaries()
        self.docEditor.setSpellCheck(self.theProject.spellCheck)
        self.mainMenu.setAutoOutline(self.theProject.autoOutline)
        self.statusBar.setRefTime(self.theProject.projOpened)
        self.statusBar.setStats(self.theProject.currWCount, 0)

        # Restore previously open documents, if any
        if self.theProject.lastEdited is not None:
            self.openDocument(self.theProject.lastEdited, doScroll=True)

        if self.theProject.lastViewed is not None:
            self.viewDocument(self.theProject.lastViewed)

        # Check if we need to rebuild the index
        if self.theIndex.indexBroken:
            self.rebuildIndex()

        # Make sure the changed status is set to false on all that was
        # just opened
        qApp.processEvents()
        self.docEditor.setDocumentChanged(False)
        self.theProject.setProjectChanged(False)

        logger.debug("Project load complete")

        return True

    def saveProject(self, autoSave=False):
        """Save the current project.
        """
        if not self.hasProject:
            logger.error("No project open")
            return False

        # If the project is new, it may not have a path, so we need one
        if self.theProject.projPath is None:
            projPath = self.selectProjectPath()
            self.theProject.setProjectPath(projPath)

        if self.theProject.projPath is None:
            return False

        self.treeView.saveTreeOrder()
        self.theProject.saveProject(autoSave=autoSave)
        self.theIndex.saveIndex()

        return True

    ##
    #  Document Actions
    ##

    def closeDocument(self):
        """Close the document and clear the editor and title field.
        """
        if not self.hasProject:
            logger.error("No project open")
            return False

        self.docEditor.saveCursorPosition()
        if self.docEditor.docChanged:
            self.saveDocument()
        self.docEditor.clearEditor()

        return True

    def openDocument(self, tHandle, tLine=None, changeFocus=True, doScroll=False):
        """Open a specific document, optionally at a given line.
        """
        if not self.hasProject:
            logger.error("No project open")
            return False

        self.closeDocument()
        self.tabWidget.setCurrentWidget(self.splitDocs)
        if self.docEditor.loadText(tHandle, tLine):
            if changeFocus:
                self.docEditor.setFocus()
            self.theProject.setLastEdited(tHandle)
            self.treeView.setSelectedHandle(tHandle, doScroll=doScroll)
        else:
            return False

        return True

    def openNextDocument(self, tHandle, wrapAround=False):
        """Opens the next document in the project tree, following the
        document with the given handle. Stops when reaching the end.
        """
        if not self.hasProject:
            logger.error("No project open")
            return False

        self.treeView.flushTreeOrder()
        nHandle = None  # The next handle after tHandle
        fHandle = None  # The first file handle we encounter
        foundIt = False # We've found tHandle, pick the next we see
        for tItem in self.theProject.projTree:
            if tItem is None:
                continue
            if tItem.itemType != nwItemType.FILE:
                continue
            if fHandle is None:
                fHandle = tItem.itemHandle
            if tItem.itemHandle == tHandle:
                foundIt = True
            elif foundIt:
                nHandle = tItem.itemHandle
                break

        if nHandle is not None:
            self.openDocument(nHandle, tLine=0, doScroll=True)
            return True
        elif wrapAround:
            self.openDocument(fHandle, tLine=0, doScroll=True)
            return False

        return False

    def saveDocument(self):
        """Save the current documents.
        """
        if not self.hasProject:
            logger.error("No project open")
            return False

        self.docEditor.saveText()

        return True

    def viewDocument(self, tHandle=None, tAnchor=None):
        """Load a document for viewing in the view panel.
        """
        if not self.hasProject:
            logger.error("No project open")
            return False

        if tHandle is None:
            logger.debug("Viewing document, but no handle provided")

            if self.docEditor.hasFocus():
                logger.verbose("Trying editor document")
                tHandle = self.docEditor.theHandle

            if tHandle is not None:
                self.saveDocument()
            else:
                logger.verbose("Trying selected document")
                tHandle = self.treeView.getSelectedHandle()

            if tHandle is None:
                logger.verbose("Trying last viewed document")
                tHandle = self.theProject.lastViewed

            if tHandle is None:
                logger.verbose("No document to view, giving up")
                return False

        # Make sure main tab is in Editor view
        self.tabWidget.setCurrentWidget(self.splitDocs)

        logger.debug("Viewing document with handle %s" % tHandle)
        if self.docViewer.loadText(tHandle):
            if not self.splitView.isVisible():
                bPos = self.splitMain.sizes()
                self.splitView.setVisible(True)
                vPos = [0, 0]
                vPos[0] = int(bPos[1]/2)
                vPos[1] = bPos[1] - vPos[0]
                self.splitDocs.setSizes(vPos)
                self.viewMeta.setVisible(self.mainConf.showRefPanel)

            self.docViewer.navigateTo(tAnchor)

        return True

    def importDocument(self):
        """Import the text contained in an out-of-project text file, and
        insert the text into the currently open document.
        """
        if not self.hasProject:
            logger.error("No project open")
            return False

        lastPath = self.mainConf.lastPath
        extFilter = [
            "Text files (*.txt)",
            "Markdown files (*.md)",
            "novelWriter files (*.nwd)",
            "All files (*.*)",
        ]
        dlgOpt  = QFileDialog.Options()
        dlgOpt |= QFileDialog.DontUseNativeDialog
        loadFile, _ = QFileDialog.getOpenFileName(
            self, "Import File", lastPath, options=dlgOpt, filter=";;".join(extFilter)
        )
        if not loadFile:
            return False

        if loadFile.strip() == "":
            return False

        theText = None
        try:
            with open(loadFile, mode="rt", encoding="utf8") as inFile:
                theText = inFile.read()
            self.mainConf.setLastPath(loadFile)
        except Exception as e:
            self.makeAlert(
                ["Could not read file. The file must be an existing text file.", str(e)],
                nwAlert.ERROR
            )
            return False

        if self.docEditor.theHandle is None:
            self.makeAlert(
                "Please open a document to import the text file into.",
                nwAlert.ERROR
            )
            return False

        if not self.docEditor.isEmpty():
            msgYes = self.askQuestion("Import Document", (
                "Importing the file will overwrite the current content of the document. "
                "Do you want to proceed?"
            ))
            if not msgYes:
                return False

        self.docEditor.replaceText(theText)

        return True

    def mergeDocuments(self):
        """Merge multiple documents to one single new document.
        """
        if not self.hasProject:
            logger.error("No project open")
            return False

        dlgMerge = GuiDocMerge(self, self.theProject)
        dlgMerge.exec_()

        return True

    def splitDocument(self):
        """Split a single document into multiple documents.
        """
        if not self.hasProject:
            logger.error("No project open")
            return False

        dlgSplit = GuiDocSplit(self, self.theProject)
        dlgSplit.exec_()

        return True

    def passDocumentAction(self, theAction):
        """Pass on document action theAction to the document viewer if
        it has focus, otherwise pass it to the document editor.
        """
        if self.docViewer.hasFocus():
            self.docViewer.docAction(theAction)
        else:
            self.docEditor.docAction(theAction)
        return True

    ##
    #  Tree Item Actions
    ##

    def openSelectedItem(self):
        """Open the selected documents.
        """
        if not self.hasProject:
            logger.error("No project open")
            return False

        tHandle = self.treeView.getSelectedHandle()
        if tHandle is None:
            logger.warning("No item selected")
            return False

        logger.verbose("Opening item %s" % tHandle)
        nwItem = self.theProject.projTree[tHandle]
        if nwItem.itemType == nwItemType.FILE:
            logger.verbose("Requested item %s is a file" % tHandle)
            self.openDocument(tHandle, doScroll=False)
        else:
            logger.verbose("Requested item %s is not a file" % tHandle)

        return True

    def editItem(self, tHandle=None):
        """Open the edit item dialog.
        """
        if not self.hasProject:
            logger.error("No project open")
            return False

        if tHandle is None:
            tHandle = self.treeView.getSelectedHandle()
        if tHandle is None:
            logger.warning("No item selected")
            return

        tItem = self.theProject.projTree[tHandle]
        if tItem is None:
            return
        if tItem.itemType not in nwLists.REG_TYPES:
            return

        logger.verbose("Requesting change to item %s" % tHandle)
        dlgProj = GuiItemEditor(self, self.theProject, tHandle)
        dlgProj.exec_()
        if dlgProj.result() == QDialog.Accepted:
            self.treeView.setTreeItemValues(tHandle)
            self.treeMeta.updateViewBox(tHandle)
            self.docEditor.updateDocInfo(tHandle)
            self.docViewer.updateDocInfo(tHandle)

        return

    def rebuildTree(self):
        """Rebuild the project tree.
        """
        self._makeStatusIcons()
        self._makeImportIcons()
        self.treeView.clearTree()
        self.treeView.buildTree()
        return

    def rebuildIndex(self, beQuiet=False):
        """Rebuild the entire index.
        """
        if not self.hasProject:
            logger.error("No project open")
            return False

        logger.debug("Rebuilding index ...")
        qApp.setOverrideCursor(QCursor(Qt.WaitCursor))
        tStart = time()

        self.treeView.saveTreeOrder()
        self.theIndex.clearIndex()

        theDoc = NWDoc(self.theProject, self)
        for nDone, tItem in enumerate(self.theProject.projTree):

            if tItem is not None:
                self.setStatus("Indexing: '%s'" % tItem.itemName)
            else:
                self.setStatus("Indexing: Unknown item")

            if tItem is not None and tItem.itemType == nwItemType.FILE:
                logger.verbose("Scanning: %s" % tItem.itemName)
                theText = theDoc.openDocument(tItem.itemHandle, showStatus=False)

                # Build tag index
                self.theIndex.scanText(tItem.itemHandle, theText)

                # Get Word Counts
                cC, wC, pC = self.theIndex.getCounts(tItem.itemHandle)
                tItem.setCharCount(cC)
                tItem.setWordCount(wC)
                tItem.setParaCount(pC)
                self.treeView.propagateCount(tItem.itemHandle, wC)
                self.treeView.projectWordCount()

        tEnd = time()
        self.setStatus("Indexing completed in %.1f ms" % ((tEnd - tStart)*1000.0))
        self.docEditor.updateTagHighLighting()
        qApp.restoreOverrideCursor()

        if not beQuiet:
            self.makeAlert("The project index has been successfully rebuilt.", nwAlert.INFO)

        return True

    def rebuildOutline(self):
        """Force a rebuild of the Outline view.
        """
        if not self.hasProject:
            logger.error("No project open")
            return False

        logger.verbose("Forcing a rebuild of the Project Outline")
        self.tabWidget.setCurrentWidget(self.splitOutline)
        self.projView.refreshTree(overRide=True)

        return True

    ##
    #  Main Dialogs
    ##

    def selectProjectPath(self):
        """Select where to save project.
        """
        dlgOpt  = QFileDialog.Options()
        dlgOpt |= QFileDialog.ShowDirsOnly
        dlgOpt |= QFileDialog.DontUseNativeDialog
        projPath = QFileDialog.getExistingDirectory(
            self, "Save novelWriter Project", "", options=dlgOpt
        )
        if projPath:
            return projPath
        return None

    def showProjectLoadDialog(self):
        """Opens the projects dialog for selecting either existing
        projects from a cache of recently opened projects, or provide a
        browse button for projects not yet cached. Selecting to create a
        new project is forwarded to the new project wizard.
        """
        dlgProj = GuiProjectLoad(self)
        dlgProj.exec_()
        if dlgProj.result() == QDialog.Accepted:
            if dlgProj.openState == GuiProjectLoad.OPEN_STATE:
                self.openProject(dlgProj.openPath)
            elif dlgProj.openState == GuiProjectLoad.NEW_STATE:
                self.newProject()

        return True

    def showNewProjectDialog(self):
        """Open the wizard and assemble a project options dict.
        """
        newProj = GuiProjectWizard(self)
        newProj.exec_()

        if newProj.result() == QDialog.Accepted:
            return self._assembleProjectWizardData(newProj)

        return None

    def showPreferencesDialog(self):
        """Open the preferences dialog.
        """
        dlgConf = GuiPreferences(self, self.theProject)
        dlgConf.exec_()

        if dlgConf.result() == QDialog.Accepted:
            logger.debug("Applying new preferences")
            self.initMain()
            self.theTheme.updateTheme()
            self.saveDocument()
            self.docEditor.initEditor()
            self.docViewer.initViewer()
            self.treeView.initTree()
            self.projView.initOutline()
            self.projMeta.initDetails()

        return

    def showProjectSettingsDialog(self):
        """Open the project settings dialog.
        """
        if not self.hasProject:
            logger.error("No project open")
            return

        dlgProj = GuiProjectSettings(self, self.theProject)
        dlgProj.exec_()

        if dlgProj.result() == QDialog.Accepted:
            logger.debug("Applying new project settings")
            self.docEditor.setDictionaries()
            self._updateWindowTitle(self.theProject.projName)

        return

    def showBuildProjectDialog(self):
        """Open the build project dialog.
        """
        if not self.hasProject:
            logger.error("No project open")
            return

        dlgBuild = getGuiItem("GuiBuildNovel")
        if dlgBuild is None:
            dlgBuild = GuiBuildNovel(self, self.theProject)

        dlgBuild.setModal(False)
        dlgBuild.show()
        qApp.processEvents()
        dlgBuild.viewCachedDoc()

        return

    def showWritingStatsDialog(self):
        """Open the session log dialog.
        """
        if not self.hasProject:
            logger.error("No project open")
            return

        dlgStats = getGuiItem("GuiWritingStats")
        if dlgStats is None:
            dlgStats = GuiWritingStats(self, self.theProject)

        dlgStats.setModal(False)
        dlgStats.show()
        qApp.processEvents()
        dlgStats.populateGUI()

        return

    def showAboutNWDialog(self, showNotes=False):
        """Show the about dialog for novelWriter.
        """
        dlgAbout = GuiAbout(self)
        dlgAbout.setModal(True)
        dlgAbout.show()
        qApp.processEvents()
        dlgAbout.populateGUI()

        if showNotes:
            dlgAbout.showReleaseNotes()

        return

    def showAboutQtDialog(self):
        """Show the about dialog for Qt.
        """
        msgBox = QMessageBox()
        msgBox.aboutQt(self, "About Qt")
        return

    def makeAlert(self, theMessage, theLevel=nwAlert.INFO):
        """Alert both the user and the logger at the same time. Message
        can be either a string or an array of strings.
        """
        if isinstance(theMessage, list):
            popMsg = "<br>".join(theMessage)
            logMsg = theMessage
        else:
            popMsg = theMessage
            logMsg = [theMessage]

        # Write to Log
        if theLevel == nwAlert.INFO:
            for msgLine in logMsg:
                logger.info(msgLine)
        elif theLevel == nwAlert.WARN:
            for msgLine in logMsg:
                logger.warning(msgLine)
        elif theLevel == nwAlert.ERROR:
            for msgLine in logMsg:
                logger.error(msgLine)
        elif theLevel == nwAlert.BUG:
            for msgLine in logMsg:
                logger.error(msgLine)

        # Popup
        msgBox = QMessageBox()
        if theLevel == nwAlert.INFO:
            msgBox.information(self, "Information", popMsg)
        elif theLevel == nwAlert.WARN:
            msgBox.warning(self, "Warning", popMsg)
        elif theLevel == nwAlert.ERROR:
            msgBox.critical(self, "Error", popMsg)
        elif theLevel == nwAlert.BUG:
            popMsg += "<br>This is a bug!"
            msgBox.critical(self, "Internal Error", popMsg)

        return

    def askQuestion(self, theTitle, theQuestion):
        """Ask the user a Yes/No question.
        """
        msgBox = QMessageBox()
        msgRes = msgBox.question(self, theTitle, theQuestion)
        return msgRes == QMessageBox.Yes

    def reportConfErr(self):
        """Checks if the Config module has any errors to report, and let
        the user know if this is the case. The Config module caches
        errors since it is initialised before the GUI itself.
        """
        if self.mainConf.hasError:
            self.makeAlert(self.mainConf.getErrData(), nwAlert.ERROR)
            return True
        return False

    ##
    #  Main Window Actions
    ##

    def closeMain(self):
        """Save everything, and close novelWriter.
        """
        if self.hasProject:
            msgYes = self.askQuestion(
                "Exit",
                "Do you want to exit novelWriter?<br>Changes are saved automatically."
            )
            if not msgYes:
                return False

        logger.info("Exiting novelWriter")

        if not self.isFocusMode:
            self.mainConf.setMainPanePos(self.splitMain.sizes())
            self.mainConf.setDocPanePos(self.splitDocs.sizes())
            self.mainConf.setOutlinePanePos(self.splitOutline.sizes())
            if self.viewMeta.isVisible():
                self.mainConf.setViewPanePos(self.splitView.sizes())

        self.mainConf.setShowRefPanel(self.viewMeta.isVisible())
        self.mainConf.setTreeColWidths(self.treeView.getColumnSizes())
        if not self.mainConf.isFullScreen:
            self.mainConf.setWinSize(self.width(), self.height())

        if self.hasProject:
            self.closeProject(True)

        self.mainConf.saveConfig()
        self.reportConfErr()
        self.mainMenu.closeHelp()

        qApp.quit()

        return True

    def setFocus(self, paneNo):
        """Switch focus to one of the three main GUI panes.
        """
        if paneNo == 1:
            self.treeView.setFocus()
        elif paneNo == 2:
            self.docEditor.setFocus()
        elif paneNo == 3:
            self.docViewer.setFocus()
        return

    def closeDocEditor(self):
        """Close the document edit panel. This does not hide the editor.
        """
        self.closeDocument()
        self.theProject.setLastEdited(None)
        return

    def closeDocViewer(self):
        """Close the document view panel.
        """
        self.docViewer.clearViewer()
        self.theProject.setLastViewed(None)
        bPos = self.splitMain.sizes()
        self.splitView.setVisible(False)
        vPos = [bPos[1], 0]
        self.splitDocs.setSizes(vPos)
        return not self.splitView.isVisible()

    def toggleFocusMode(self):
        """Main GUI Focus Mode hides tree, view pane and optionally also
        statusbar and menu.
        """
        if self.docEditor.theHandle is None:
            logger.error("No document open, so not activating Focus Mode")
            self.mainMenu.aFocusMode.setChecked(self.isFocusMode)
            return False

        self.isFocusMode = not self.isFocusMode
        self.mainMenu.aFocusMode.setChecked(self.isFocusMode)
        if self.isFocusMode:
            logger.debug("Activating Focus Mode")
            self.tabWidget.setCurrentWidget(self.splitDocs)
        else:
            logger.debug("Deactivating Focus Mode")

        isVisible = not self.isFocusMode
        self.treePane.setVisible(isVisible)
        self.statusBar.setVisible(isVisible)
        self.mainMenu.setVisible(isVisible)
        self.tabWidget.tabBar().setVisible(isVisible)

        hideDocFooter = self.isFocusMode and self.mainConf.hideFocusFooter
        self.docEditor.docFooter.setVisible(not hideDocFooter)

        if self.splitView.isVisible():
            self.splitView.setVisible(False)
        elif self.docViewer.theHandle is not None:
            self.splitView.setVisible(True)

        return True

    def toggleFullScreenMode(self):
        """Main GUI full screen mode. The mode is tracked by the flag
        in config. This only tracks whether the window has been
        maximised using the internal commands, and may not be correct
        if the user uses the system window manager. Currently, Qt
        doesn't have access to the exact state of the window.
        """
        self.setWindowState(self.windowState() ^ Qt.WindowFullScreen)

        winState = self.windowState() & Qt.WindowFullScreen == Qt.WindowFullScreen
        if winState:
            logger.debug("Activated full screen mode")
        else:
            logger.debug("Deactivated full screen mode")

        self.mainConf.isFullScreen = winState

        return

    ##
    #  Internal Functions
    ##

    def _connectMenuActions(self):
        """Connect to the main window all menu actions that need to be
        available also when the main menu is hidden.
        """
        # Project
        self.addAction(self.mainMenu.aSaveProject)
        self.addAction(self.mainMenu.aExitNW)

        # Document
        self.addAction(self.mainMenu.aSaveDoc)
        self.addAction(self.mainMenu.aFileDetails)

        # Edit
        self.addAction(self.mainMenu.aEditUndo)
        self.addAction(self.mainMenu.aEditRedo)
        self.addAction(self.mainMenu.aEditCut)
        self.addAction(self.mainMenu.aEditCopy)
        self.addAction(self.mainMenu.aEditPaste)
        self.addAction(self.mainMenu.aSelectAll)
        self.addAction(self.mainMenu.aSelectPar)

        # View
        self.addAction(self.mainMenu.aFocusMode)
        self.addAction(self.mainMenu.aFullScreen)

        # Insert
        self.addAction(self.mainMenu.aInsENDash)
        self.addAction(self.mainMenu.aInsEMDash)
        self.addAction(self.mainMenu.aInsEllipsis)
        self.addAction(self.mainMenu.aInsQuoteLS)
        self.addAction(self.mainMenu.aInsQuoteRS)
        self.addAction(self.mainMenu.aInsQuoteLD)
        self.addAction(self.mainMenu.aInsQuoteRD)
        self.addAction(self.mainMenu.aInsMSApos)
        self.addAction(self.mainMenu.aInsHardBreak)
        self.addAction(self.mainMenu.aInsNBSpace)
        self.addAction(self.mainMenu.aInsThinSpace)
        self.addAction(self.mainMenu.aInsThinNBSpace)

        for mAction, _ in self.mainMenu.mInsKWItems.values():
            self.addAction(mAction)

        # Format
        self.addAction(self.mainMenu.aFmtEmph)
        self.addAction(self.mainMenu.aFmtStrong)
        self.addAction(self.mainMenu.aFmtStrike)
        self.addAction(self.mainMenu.aFmtDQuote)
        self.addAction(self.mainMenu.aFmtSQuote)
        self.addAction(self.mainMenu.aFmtHead1)
        self.addAction(self.mainMenu.aFmtHead2)
        self.addAction(self.mainMenu.aFmtHead3)
        self.addAction(self.mainMenu.aFmtHead4)
        self.addAction(self.mainMenu.aFmtComment)
        self.addAction(self.mainMenu.aFmtNoFormat)

        # Tools
        self.addAction(self.mainMenu.aSpellCheck)
        self.addAction(self.mainMenu.aReRunSpell)
        self.addAction(self.mainMenu.aPreferences)

        # Help
        if self.mainConf.hasHelp and self.mainConf.hasAssistant:
            self.addAction(self.mainMenu.aHelpLoc)
        self.addAction(self.mainMenu.aHelpWeb)

        return True

    def _updateWindowTitle(self, projName=None):
        """Set the window title and add the project's working title.
        """
        winTitle = self.mainConf.appName
        if projName is not None:
            winTitle += " - %s" % projName
        self.setWindowTitle(winTitle)
        return True

    def _autoSaveProject(self):
        """Triggered by the auto-save project timer to save the project.
        """
        doSave  = self.hasProject
        doSave &= self.theProject.projChanged
        doSave &= self.theProject.projPath is not None

        if doSave:
            logger.debug("Autosaving project")
            self.saveProject(autoSave=True)

        return

    def _autoSaveDocument(self):
        """Triggered by the auto-save document timer to save the
        document.
        """
        if self.hasProject and self.docEditor.docChanged:
            logger.debug("Autosaving document")
            self.saveDocument()
        return

    def _makeStatusIcons(self):
        """Generate all the item status icons based on project settings.
        """
        self.statusIcons = {}
        iPx = self.mainConf.pxInt(32)
        for sLabel, sCol, _ in self.theProject.statusItems:
            theIcon = QPixmap(iPx, iPx)
            theIcon.fill(QColor(*sCol))
            self.statusIcons[sLabel] = QIcon(theIcon)
        return

    def _makeImportIcons(self):
        """Generate all the item importance icons based on project
        settings.
        """
        self.importIcons = {}
        iPx = self.mainConf.pxInt(32)
        for sLabel, sCol, _ in self.theProject.importItems:
            theIcon = QPixmap(iPx, iPx)
            theIcon.fill(QColor(*sCol))
            self.importIcons[sLabel] = QIcon(theIcon)
        return

    def _assembleProjectWizardData(self, newProj):
        """Extract the user choices from the New Project Wizard and
        store them in a dictionary.
        """
        projData = {
            "projName": newProj.field("projName"),
            "projTitle": newProj.field("projTitle"),
            "projAuthors": newProj.field("projAuthors"),
            "projPath": newProj.field("projPath"),
            "popSample": newProj.field("popSample"),
            "popMinimal": newProj.field("popMinimal"),
            "popCustom": newProj.field("popCustom"),
            "addRoots": [],
            "numChapters": 0,
            "numScenes": 0,
            "chFolders": False,
        }
        if newProj.field("popCustom"):
            addRoots = []
            if newProj.field("addPlot"):
                addRoots.append(nwItemClass.PLOT)
            if newProj.field("addChar"):
                addRoots.append(nwItemClass.CHARACTER)
            if newProj.field("addWorld"):
                addRoots.append(nwItemClass.WORLD)
            if newProj.field("addTime"):
                addRoots.append(nwItemClass.TIMELINE)
            if newProj.field("addObject"):
                addRoots.append(nwItemClass.OBJECT)
            if newProj.field("addEntity"):
                addRoots.append(nwItemClass.ENTITY)
            projData["addRoots"] = addRoots
            projData["numChapters"] = newProj.field("numChapters")
            projData["numScenes"] = newProj.field("numScenes")
            projData["chFolders"] = newProj.field("chFolders")

        return projData

    ##
    #  Events
    ##

    def closeEvent(self, theEvent):
        """Capture the closing event of the GUI and call the close
        function to handle all the close process steps.
        """
        if self.closeMain():
            theEvent.accept()
        else:
            theEvent.ignore()
        return

    ##
    #  Signal Handlers
    ##

    def _treeSingleClick(self):
        """Single click on a project tree item just updates the details
        panel below the tree.
        """
        sHandle = self.treeView.getSelectedHandle()
        if sHandle is not None:
            self.treeMeta.updateViewBox(sHandle)
        return

    def _treeDoubleClick(self, tItem, colNo):
        """The user double-clicked an item in the tree. If it is a file,
        we open it. Otherwise, we do nothing.
        """
        tHandle = tItem.data(self.treeView.C_NAME, Qt.UserRole)
        logger.verbose("User double clicked tree item with handle %s" % tHandle)
        nwItem = self.theProject.projTree[tHandle]
        if nwItem is not None:
            if nwItem.itemType == nwItemType.FILE:
                logger.verbose("Requested item %s is a file" % tHandle)
                self.openDocument(tHandle, changeFocus=False, doScroll=False)
            else:
                logger.verbose("Requested item %s is a folder" % tHandle)

        return

    def _treeKeyPressReturn(self):
        """The user pressed return on an item in the tree. If it is a
        file, we open it. Otherwise, we do nothing. Pressing return does
        not change focus to the editor as double click does.
        """
        tHandle = self.treeView.getSelectedHandle()
        logger.verbose("User pressed return on tree item with handle %s" % tHandle)
        nwItem = self.theProject.projTree[tHandle]
        if nwItem is not None:
            if nwItem.itemType == nwItemType.FILE:
                logger.verbose("Requested item %s is a file" % tHandle)
                self.openDocument(tHandle, changeFocus=False, doScroll=False)
            else:
                logger.verbose("Requested item %s is a folder" % tHandle)
        return

    def _keyPressEscape(self):
        """When the escape key is pressed somewhere in the main window,
        do the following, in order:
        """
        if self.docEditor.docSearch.isVisible():
            self.docEditor.closeSearch()
        elif self.isFocusMode:
            self.toggleFocusMode()
        return

    def _mainTabChanged(self, tabIndex):
        """Activated when the main window tab is changed.
        """
        if tabIndex == self.idxTabEdit:
            logger.verbose("Editor tab activated")
        elif tabIndex == self.idxTabProj:
            logger.verbose("Project outline tab activated")
            if self.hasProject:
                self.projView.refreshTree()
        return
class UploadWindowUI(object):

    title = "DERIVA File Uploader"

    def __init__(self, MainWin):

        # Main Window
        MainWin.setObjectName("UploadWindow")
        MainWin.setWindowTitle(MainWin.tr(self.title))
        MainWin.resize(1024, 768)
        self.centralWidget = QWidget(MainWin)
        self.centralWidget.setObjectName("centralWidget")
        MainWin.setCentralWidget(self.centralWidget)
        self.verticalLayout = QVBoxLayout(self.centralWidget)
        self.verticalLayout.setContentsMargins(11, 11, 11, 11)
        self.verticalLayout.setSpacing(6)
        self.verticalLayout.setObjectName("verticalLayout")

        self.horizontalLayout = QHBoxLayout()
        self.pathLabel = QLabel("Directory:")
        self.horizontalLayout.addWidget(self.pathLabel)
        self.pathTextBox = QLineEdit()
        self.pathTextBox.setReadOnly(True)
        self.horizontalLayout.addWidget(self.pathTextBox)
        self.browseButton = QPushButton("Browse", self.centralWidget)
        self.browseButton.clicked.connect(MainWin.on_actionBrowse_triggered)
        self.horizontalLayout.addWidget(self.browseButton)
        self.verticalLayout.addLayout(self.horizontalLayout)

        # Splitter for Upload list/Log
        self.splitter = QSplitter(Qt.Vertical)

        # Table View (Upload list)
        self.uploadList = TableWidget(self.centralWidget)
        self.uploadList.setObjectName("uploadList")
        self.uploadList.setStyleSheet(
            """
            QTableWidget {
                    border: 2px solid grey;
                    border-radius: 5px;
            }
            """)
        self.uploadList.setEditTriggers(QAbstractItemView.NoEditTriggers)  # use NoEditTriggers to disable editing
        self.uploadList.setAlternatingRowColors(True)
        self.uploadList.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.uploadList.setSelectionMode(QAbstractItemView.NoSelection)
        self.uploadList.verticalHeader().setDefaultSectionSize(18)  # tighten up the row size
        self.uploadList.horizontalHeader().setStretchLastSection(True)
        self.uploadList.setSortingEnabled(True)  # allow sorting
        self.splitter.addWidget(self.uploadList)

        # Log Widget
        self.logTextBrowser = QPlainTextEditLogger(self.centralWidget)
        self.logTextBrowser.widget.setObjectName("logTextBrowser")
        self.logTextBrowser.widget.setStyleSheet(
            """
            QPlainTextEdit {
                    border: 2px solid grey;
                    border-radius: 5px;
                    background-color: lightgray;
            }
            """)
        self.splitter.addWidget(self.logTextBrowser.widget)

        # add splitter
        self.splitter.setSizes([400, 200])
        self.verticalLayout.addWidget(self.splitter)

    # Actions

        # Browse
        self.actionBrowse = QAction(MainWin)
        self.actionBrowse.setObjectName("actionBrowse")
        self.actionBrowse.setText(MainWin.tr("Browse"))
        self.actionBrowse.setToolTip(MainWin.tr("Set the upload directory"))
        self.actionBrowse.setShortcut(MainWin.tr("Ctrl+B"))

        # Upload
        self.actionUpload = QAction(MainWin)
        self.actionUpload.setObjectName("actionUpload")
        self.actionUpload.setText(MainWin.tr("Upload"))
        self.actionUpload.setToolTip(MainWin.tr("Upload files"))
        self.actionUpload.setShortcut(MainWin.tr("Ctrl+L"))
        self.actionUpload.setEnabled(False)

        # Rescan
        self.actionRescan = QAction(MainWin)
        self.actionRescan.setObjectName("actionRescan")
        self.actionRescan.setText(MainWin.tr("Rescan"))
        self.actionRescan.setToolTip(MainWin.tr("Rescan the upload directory"))
        self.actionRescan.setShortcut(MainWin.tr("Ctrl+R"))
        self.actionRescan.setEnabled(False)

        # Cancel
        self.actionCancel = QAction(MainWin)
        self.actionCancel.setObjectName("actionCancel")
        self.actionCancel.setText(MainWin.tr("Cancel"))
        self.actionCancel.setToolTip(MainWin.tr("Cancel any upload(s) in-progress"))
        self.actionCancel.setShortcut(MainWin.tr("Ctrl+C"))

        # Options
        self.actionOptions = QAction(MainWin)
        self.actionOptions.setObjectName("actionOptions")
        self.actionOptions.setText(MainWin.tr("Options"))
        self.actionOptions.setToolTip(MainWin.tr("Configuration Options"))
        self.actionOptions.setShortcut(MainWin.tr("Ctrl+P"))

        # Login
        self.actionLogin = QAction(MainWin)
        self.actionLogin.setObjectName("actionLogin")
        self.actionLogin.setText(MainWin.tr("Login"))
        self.actionLogin.setToolTip(MainWin.tr("Login to the server"))
        self.actionLogin.setShortcut(MainWin.tr("Ctrl+G"))
        self.actionLogin.setEnabled(False)

        # Logout
        self.actionLogout = QAction(MainWin)
        self.actionLogout.setObjectName("actionLogout")
        self.actionLogout.setText(MainWin.tr("Logout"))
        self.actionLogout.setToolTip(MainWin.tr("Logout of the server"))
        self.actionLogout.setShortcut(MainWin.tr("Ctrl+O"))
        self.actionLogout.setEnabled(False)

        # Exit
        self.actionExit = QAction(MainWin)
        self.actionExit.setObjectName("actionExit")
        self.actionExit.setText(MainWin.tr("Exit"))
        self.actionExit.setToolTip(MainWin.tr("Exit the application"))
        self.actionExit.setShortcut(MainWin.tr("Ctrl+Z"))

        # Help
        self.actionHelp = QAction(MainWin)
        self.actionHelp.setObjectName("actionHelp")
        self.actionHelp.setText(MainWin.tr("Help"))
        self.actionHelp.setToolTip(MainWin.tr("Help"))
        self.actionHelp.setShortcut(MainWin.tr("Ctrl+H"))

    # Menu Bar

        """
        self.menuBar = QMenuBar(MainWin)
        self.menuBar.setObjectName("menuBar")
        MainWin.setMenuBar(self.menuBar)
        self.menuBar.setStyleSheet(
            "QMenuBar{font-family: Arial;font-style: normal;font-size: 10pt;font-weight: bold;};")
        """

    # Tool Bar

        self.mainToolBar = QToolBar(MainWin)
        self.mainToolBar.setObjectName("mainToolBar")
        self.mainToolBar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        self.mainToolBar.setContextMenuPolicy(Qt.PreventContextMenu)
        MainWin.addToolBar(Qt.TopToolBarArea, self.mainToolBar)

        # Upload
        self.mainToolBar.addAction(self.actionUpload)
        self.actionUpload.setIcon(qApp.style().standardIcon(QStyle.SP_FileDialogToParent))

        # Rescan
        self.mainToolBar.addAction(self.actionRescan)
        self.actionRescan.setIcon(qApp.style().standardIcon(QStyle.SP_BrowserReload))

        # Cancel
        self.mainToolBar.addAction(self.actionCancel)
        self.actionCancel.setIcon(qApp.style().standardIcon(QStyle.SP_BrowserStop))
        self.actionCancel.setEnabled(False)

        # Options
        self.mainToolBar.addAction(self.actionOptions)
        self.actionOptions.setIcon(qApp.style().standardIcon(QStyle.SP_FileDialogDetailedView))

        # this spacer right justifies everything that comes after it
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.mainToolBar.addWidget(spacer)

        # Login
        self.mainToolBar.addAction(self.actionLogin)
        self.actionLogin.setIcon(qApp.style().standardIcon(QStyle.SP_DialogApplyButton))

        # Logout
        self.mainToolBar.addAction(self.actionLogout)
        self.actionLogout.setIcon(qApp.style().standardIcon(QStyle.SP_DialogOkButton))

        # Help
        #self.mainToolBar.addAction(self.actionHelp)
        self.actionHelp.setIcon(qApp.style().standardIcon(QStyle.SP_MessageBoxQuestion))

        # Exit
        self.mainToolBar.addAction(self.actionExit)
        self.actionExit.setIcon(qApp.style().standardIcon(QStyle.SP_DialogCancelButton))

    # Status Bar

        self.statusBar = QStatusBar(MainWin)
        self.statusBar.setToolTip("")
        self.statusBar.setStatusTip("")
        self.statusBar.setObjectName("statusBar")
        MainWin.setStatusBar(self.statusBar)

    # configure logging
        self.logTextBrowser.widget.log_update_signal.connect(MainWin.updateLog)
        self.logTextBrowser.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
        logging.getLogger().addHandler(self.logTextBrowser)

    # finalize UI setup
        QMetaObject.connectSlotsByName(MainWin)
示例#33
0
class App(QWidget):
    def __init__(self):
        super().__init__()
        self.title = 'ARXML Explorer'
        self.left = 10
        self.top = 10
        self.width = 800
        self.height = 700
        self.model_cache = NamespaceCache()
        self.deploy_cache = NamespaceCache()
        self.cache = NodeCache()
        self.views = []
        self.initUI()
        self.help = arxmlHelp()
        path = './models/demo7'
        files = [f for f in os.listdir(path) if os.path.isfile(path + '/' + f)]
        for f in files:
            if f.endswith('.arxml'):
                self.parseXML(path + '/' + f)

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.model_tree = ModelTreeView(self)
        self.detail = MethodArgumentsTreeView("Details", self)
        self.errorlist = MethodErrorListWidget()
        self.combo = MethodArgumentEditor()
        #self.tabs = QTabWidget()
        self.plaintext_xml = QPlainTextEdit()
        #self.plaintext_xml.resize(400,150)
        self.plaintext_help = QPlainTextEdit()
        #self.plaintext_help.resize(400,150)
        self.splitter1 = QSplitter(Qt.Vertical)

        self.splitter1.addWidget(self.model_tree.groupDataTypes)
        self.splitter1.addWidget(self.detail.groupDataTypes)

        self.splitter2 = QSplitter(Qt.Horizontal)
        self.splitter2.addWidget(self.plaintext_xml)
        self.splitter2.addWidget(self.plaintext_help)
        self.splitter1.addWidget(self.splitter2)
        self.splitter2.setStretchFactor(0, 1)
        self.splitter2.setStretchFactor(1, 0)
        #self.splitter2.setSizes([0, 1])

        #self.splitter1.addWidget(self.tabs)

        mainLayout = QVBoxLayout()
        #self.tabs.addTab(self.plaintext_xml,"XML")
        #self.tabs.addTab(self.plaintext_help,"Help")
        #self.tabs.addTab(self.errorlist.groupDataTypes, "Possible Errors")

        self.model_tree.treeView.selectionModel().selectionChanged.connect(
            self.on_model_tree_selection_changed)
        #self.detail.treeView.selectionModel().selectionChanged.connect(self.on_detail_tree_selection_changed)

        self.setLayout(mainLayout)
        mainLayout.addWidget(self.splitter1)
        self.show()
        """
        self.view_error = self.add_view(ViewError(self.model_tree.root_node_model, self.model_cache))
        self.view_datatype = self.add_view(ViewDataType(self.model_tree.root_node_model))
        self.view_method = self.add_view(ViewMethod(self.model_tree.root_node_model, self.model_cache))
        self.view_event = self.add_view(ViewEvent(self.model_tree.root_node_model, self.model_cache))
        self.view_field = self.add_view(ViewField(self.model_tree.root_node_model, self.model_cache))
        self.view_deployment = self.add_view(ViewDeployment(self.model_tree.root_node_deployment, self.deploy_cache))

        """

        self.view_executable = self.add_view(
            ViewExecutable(self.model_tree.root_node_application_design,
                           self.cache))

        self.view_ethernet = self.add_view(
            ViewEthernet(self.model_tree.root_node_communication_connector,
                         self.cache))
        self.view_machine = self.add_view(
            ViewMachine(self.model_tree.root_node_machine_manifest,
                        self.cache))

        self.view_adaptive_sw_component = self.add_view(
            ViewAdaptiveSwComponent(
                self.model_tree.root_node_application_design, self.cache))
        self.view_application = self.add_view(
            ViewApplication(self.model_tree.root_node_application_design,
                            self.cache))
        self.view_mode_declaration = self.add_view(
            ViewModeDeclaration(self.model_tree.root_node_machine_manifest,
                                self.cache))
        self.view_startup_config = self.add_view(
            ViewStartupConfig(self.model_tree.root_node_startup_config_set,
                              self.cache))
        self.view_process = self.add_view(
            ViewProcess(self.model_tree.root_node_execution_manifest,
                        self.cache))

    def get_cache_for(self, name):
        for view in self.views:
            if view.xml_tag_name == name:
                return view.cache
        return None

    def add_view(self, view):
        self.views.append(view)
        return view

    def handle_selected_main_item(self, index):
        self.show_help_row(index)

        xml_node = index.data(Qt.UserRole + 1)
        self.show_help(index.data(Qt.DisplayRole))
        self.detail.clear()
        if xml_node != None:
            self.show_xml(xml_node)
            for item in self.views:
                if item.show_detail(self.detail.model, xml_node):
                    self.detail.treeView.expandAll()
                    return
            return
        self.plaintext_xml.setPlainText('')
        pass

    def on_model_tree_selection_changed(self, selected, deselected):
        a = self.model_tree.treeView.selectedIndexes()[0]
        self.handle_selected_main_item(a)

    def show_xml(self, node):
        str = node.toprettyxml(indent=' ', newl='')
        self.plaintext_xml.setPlainText(str)

    def show_help_row(self, index):
        self.show_help(index.data(RoleHelp))
        self.show_xml(index.data(RoleXmlNode))
        pass

    def show_help(self, item):
        self.set_help_text(self.help.get(item))

    def set_help_text(self, str):
        self.plaintext_help.setPlainText(str)

    def parseXML(self, file):
        self.xmldoc = minidom.parse(file)
        for item in self.views:
            item.parse(self.xmldoc, file)
示例#34
0
文件: tab.py 项目: AlexArcPy/GDBee
    def __init__(self):
        """Initialize Tab with layout and behavior."""
        super(Tab, self).__init__()

        # regex pattern for SQL query block comments
        self.block_comment_re = re.compile(
            r'(^)?[^\S\n]*/(?:\*(.*?)\*/[^\S\n]*|/[^\n]*)($)?',
            re.DOTALL | re.MULTILINE)

        main_layout = QVBoxLayout(self)

        # define gdb props
        self.gdb = None
        self.gdb_items = None
        self.gdb_columns_names = None
        self.gdb_schemas = None

        # connected geodatabase path toolbar
        self.connected_gdb_path_label = QLabel('')
        self.connected_gdb_path_label.setTextInteractionFlags(
            Qt.TextSelectableByMouse)
        self.connected_gdb_path_label.setToolTip(
            'Connected geodatabase that queries will be run against')
        self.connected_gdb_path_label.setText(not_connected_to_gdb_message)

        self.browse_to_gdb = QPushButton('Browse')
        self.browse_to_gdb.setShortcut(QKeySequence('Ctrl+B'))
        self.browse_to_gdb.clicked.connect(
            lambda evt, arg=True: self.connect_to_geodatabase(
                evt, triggered_with_browse=True))

        self.gdb_sql_dialect_combobox = QComboBox()
        for dialect in sql_dialects_names:
            self.gdb_sql_dialect_combobox.addItem(dialect)

        self.gdb_browse_toolbar = QToolBar()
        self.gdb_browse_toolbar.setMaximumHeight(50)
        self.gdb_browse_toolbar.addWidget(self.browse_to_gdb)
        self.gdb_browse_toolbar.addWidget(self.connected_gdb_path_label)
        self.gdb_browse_toolbar.addSeparator()
        self.gdb_browse_toolbar.addWidget(self.gdb_sql_dialect_combobox)

        # table with results
        self.table = ResultTable()

        # execute SQL query
        self.execute = QAction('Execute', self)
        self.execute.setShortcuts(
            [QKeySequence('F5'),
             QKeySequence('Ctrl+Return')])
        self.execute.triggered.connect(self.run_query)
        self.addAction(self.execute)

        # enter a SQL query
        self.query = TextEditor()
        self.query.setPlainText('')
        font = self.query.font()
        font.setFamily('Consolas')
        font.setStyleHint(QFont.Monospace)

        # TODO: add line numbers to the text editor
        font.setPointSize(14)
        self.query.setFont(font)
        self.query.setTabStopWidth(20)
        self.highlighter = Highlighter(self.query.document())

        # TODO select block of text - Ctrl+/ and they become comments
        self.completer = Completer()
        self.query.set_completer(self.completer.completer)

        # errors panel to show if query fails to execute properly
        self.errors_panel = QPlainTextEdit()
        font = self.query.font()
        font.setPointSize(12)
        self.errors_panel.setStyleSheet('color:red')
        self.errors_panel.setFont(font)
        self.errors_panel.hide()

        # splitter between the toolbar, query window, and the result set table
        splitter = QSplitter(Qt.Vertical)
        splitter.addWidget(self.gdb_browse_toolbar)
        splitter.addWidget(self.query)
        splitter.addWidget(self.table)
        splitter.addWidget(self.errors_panel)

        # add the settings after the widget have been added
        splitter.setCollapsible(0, True)
        splitter.setCollapsible(1, False)
        splitter.setCollapsible(2, False)
        splitter.setCollapsible(3, False)
        splitter.setStretchFactor(0, 3)
        splitter.setStretchFactor(1, 7)
        splitter.setSizes((100, 200, 300))
        self.table.hide()

        # TOC
        self.toc = QTreeWidget()
        self.toc.setHeaderHidden(True)

        # second splitter between the TOC to the left and the query/table to the
        # right
        toc_splitter = QSplitter(Qt.Horizontal)
        toc_splitter.addWidget(self.toc)
        toc_splitter.addWidget(splitter)
        toc_splitter.setCollapsible(0, True)
        toc_splitter.setSizes((200, 800))  # set the TOC vs data panel

        main_layout.addWidget(toc_splitter)

        margins = QMargins()
        margins.setBottom(10)
        margins.setLeft(10)
        margins.setRight(10)
        margins.setTop(10)
        main_layout.setContentsMargins(margins)

        self.setLayout(main_layout)
        QApplication.setStyle(QStyleFactory.create('Cleanlooks'))
        self.show()

        return
示例#35
0
    def create_top_group_box(self):
        top_splitter = QSplitter()
        top_splitter.setSizePolicy(QSizePolicy.Expanding,
                                   QSizePolicy.Expanding)

        # 좌
        top_left_group_box = QGroupBox("레이드 함수 목록")
        top_left_group_box.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Expanding)

        names = list(map(lambda i: i.get_name(), self._methods))
        model = QStringListModel(names)
        view = QListView()
        view.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        view.setModel(model)
        view.clicked.connect(self.on_show_method)

        add_function = QPushButton("함수 추가")

        layout = QVBoxLayout()
        layout.addWidget(add_function)
        layout.addWidget(view)

        top_left_group_box.setLayout(layout)

        # 우
        top_right_group_box = QGroupBox("레이드 함수")

        # 우 - 텍스트
        tab_method_body = QTabWidget()

        tab_block = QWidget()

        tab_plain = QWidget()
        self._edit_method_body_plain = QTextEdit()
        tab_hbox_plain = QHBoxLayout()
        tab_hbox_plain.setContentsMargins(5, 5, 5, 5)
        tab_hbox_plain.addWidget(self._edit_method_body_plain)

        self._edit_method_body_block = PyJavaCode()
        self._edit_method_body_block.set_plain_view(
            self._edit_method_body_plain)
        tab_hbox_block = QHBoxLayout()
        tab_hbox_block.setContentsMargins(5, 5, 5, 5)
        tab_hbox_block.addWidget(self._edit_method_body_block)

        tab_block.setLayout(tab_hbox_block)
        tab_plain.setLayout(tab_hbox_plain)

        tab_method_body.addTab(tab_block, "&Block")
        tab_method_body.addTab(tab_plain, "&Plain")

        # 배치
        label_method_name = QLabel("name")
        self._edit_method_name = QLineEdit()
        label_method_body = QLabel("body")
        self._edit_method_body = tab_method_body

        #
        layout = QVBoxLayout()
        layout.addWidget(label_method_name)
        layout.addWidget(self._edit_method_name)
        layout.addWidget(label_method_body)
        layout.addWidget(self._edit_method_body)

        top_right_group_box.setLayout(layout)

        # test
        # top_left_group_box.setStyleSheet("color: blue;"
        #                       "background-color: #87CEFA;"
        #                       "border-style: dashed;"
        #                       "border-width: 3px;"
        #                       "border-color: #1E90FF")
        #
        # top_right_group_box.setStyleSheet("color: blue;"
        #                       "background-color: #87CEFA;"
        #                       "border-style: dashed;"
        #                       "border-width: 3px;"
        #                       "border-color: #1E90FF")

        # spliter
        top_splitter.addWidget(top_left_group_box)
        top_splitter.addWidget(top_right_group_box)

        return top_splitter
示例#36
0
    def initUI(self):
        # TODO: initCanvas()?
        self.canvas = PlotCanvas(self)
        self.canvas.setFocusPolicy(Qt.ClickFocus)
        self.canvas.setFocus()

        # self.canvas.mpl_connect('button_press_event', self.on_press)
        # self.canvas.mpl_connect('button_release_event', self.on_release)
        # self.canvas.mpl_connect('motion_notify_event', self.on_motion)
        # self.canvas.mpl_connect('scroll_event', self.on_scroll)
        # self.canvas.mpl_connect('key_release_event', self.on_key_release)

        menuBar = self.menuBar()
        openMenu = menuBar.addMenu('Open')
        showMenu = menuBar.addMenu('Show')

        allAct = QAction("All", self)
        allAct.setCheckable(True)
        allAct.setChecked(True)
        allAct.triggered.connect(lambda: self.showPts(0))

        missAct = QAction("Miss Clf", self)
        missAct.setCheckable(True)
        missAct.setChecked(False)
        missAct.triggered.connect(lambda: self.showPts(1))

        noneAct = QAction("None", self)
        noneAct.setCheckable(True)
        noneAct.setChecked(False)
        noneAct.triggered.connect(lambda: self.showPts(2))

        showMenu.addAction(allAct)
        showMenu.addAction(missAct)
        showMenu.addAction(noneAct)

        showMenuGroup = QActionGroup(self)
        showMenuGroup.addAction(allAct)
        showMenuGroup.addAction(missAct)
        showMenuGroup.addAction(noneAct)
        showMenuGroup.setExclusive(True)

        showMenu.addSeparator()

        # highlight action
        hlAct = QAction('Highlight Neighbors', self)
        hlAct.setShortcut("Ctrl+H")
        hlAct.setCheckable(True)
        hlAct.setChecked(False)
        hlAct.triggered.connect(self.setHLNeighbors)
        showMenu.addAction(hlAct)

        freezeAct = QAction('Freeze', self)
        freezeAct.setShortcut("Ctrl+F")
        freezeAct.setCheckable(True)
        freezeAct.setChecked(False)
        freezeAct.triggered.connect(self.freeze_act)
        showMenu.addAction(freezeAct)

        boundaryMapAct = QAction('Show boundary map')
        boundaryMapAct.setShortcut("Ctrl+B")
        boundaryMapAct.setCheckable(True)
        boundaryMapAct.setChecked(True)
        boundaryMapAct.triggered.connect(lambda: self.show_map(self.BMAP))
        showMenu.addAction(boundaryMapAct)

        distMapAct = QAction('Show dist map', self)
        distMapAct.setShortcut("Ctrl+D")
        distMapAct.setCheckable(True)
        distMapAct.setChecked(False)
        distMapAct.triggered.connect(lambda: self.show_map(self.DMAP2D))
        showMenu.addAction(distMapAct)

        distMapNDAct = QAction('Show dist map nD', self)
        distMapNDAct.setCheckable(True)
        distMapNDAct.setChecked(False)
        distMapNDAct.triggered.connect(lambda: self.show_map(self.DMAPND))
        showMenu.addAction(distMapNDAct)

        distMapND2Act = QAction('Show dist map nD2', self)
        distMapND2Act.setCheckable(True)
        distMapND2Act.setChecked(False)
        distMapND2Act.triggered.connect(lambda: self.show_map(self.DMAPND2))
        showMenu.addAction(distMapND2Act)

        distMapND3Act = QAction('Show dist map nD3', self)
        distMapND3Act.setCheckable(True)
        distMapND3Act.setChecked(False)
        distMapND3Act.triggered.connect(lambda: self.show_map(self.DMAPND3))
        showMenu.addAction(distMapND3Act)

        distMenuGroup = QActionGroup(self)
        distMenuGroup.addAction(boundaryMapAct)
        distMenuGroup.addAction(distMapAct)
        distMenuGroup.addAction(distMapNDAct)
        distMenuGroup.addAction(distMapND2Act)
        distMenuGroup.addAction(distMapND3Act)

        openProjAct = QAction("Projection", self)
        openProjAct.setShortcut("Ctrl+O")
        openProjAct.triggered.connect(self.openProjection)

        saveAct = QAction('Save', self)
        saveAct.setShortcut("Ctrl+S")
        saveAct.triggered.connect(self.save_new_samples)

        openMenu.addAction(openProjAct)
        openMenu.addAction(saveAct)

        self.errUI = ErrUI()

        splitter = QSplitter(self)
        splitter.addWidget(self.errUI)
        splitter.addWidget(self.canvas)
        splitter.addWidget(self.newsamplesUI)
        self.setCentralWidget(splitter)
示例#37
0
 def make_splitter(orientation, *widgets):
     spl = QSplitter(orientation, self)
     for w in widgets:
         spl.addWidget(w)
     return spl
示例#38
0
    def __init__(self, parent=None):
        super(Main, self).__init__(parent)

        self.dirList = QListWidget()
        self.fileList = QListWidget()

        self.setDirList()
        self.fileName = ""
        self.dirName = self.dirList.item(0).text()
        self.path = "/" + self.dirName + "/"
        self.dirList.itemSelectionChanged.connect(self.selectDir)
        self.fileList.itemSelectionChanged.connect(self.selectFile)

        latLabel = QLabel("lat(緯度): ")
        self.latEdit = QLineEdit()

        lonLabel = QLabel("lon(経度): ")
        self.lonEdit = QLineEdit()

        editLayout = QGridLayout()
        editLayout.addWidget(latLabel, 0, 0)
        editLayout.addWidget(self.latEdit, 0, 1)
        editLayout.addWidget(lonLabel, 1, 0)
        editLayout.addWidget(self.lonEdit, 1, 1)

        startButton = QPushButton("Start")
        startButton.clicked.connect(self.clickedStart)

        exitButton = QPushButton("Exit")
        exitButton.clicked.connect(self.clickedExit)

        buttonLayout = QHBoxLayout()
        buttonLayout.addWidget(startButton)
        buttonLayout.addWidget(exitButton)

        inputLayout = QVBoxLayout()
        inputLayout.addWidget(self.dirList)
        inputLayout.addLayout(editLayout)
        inputLayout.addLayout(buttonLayout)

        inputWidget = QWidget()
        inputWidget.setLayout(inputLayout)

        self.canvas = QLabel(u" ここに地形図が表示されます ")
        self.canvas.setScaledContents(True)

        saveButton = QPushButton("Save Figure")
        saveButton.clicked.connect(self.clickedSave)

        figureLayout = QVBoxLayout()
        figureLayout.addWidget(self.canvas)
        figureLayout.addWidget(saveButton)

        figureWidget = QWidget()
        figureWidget.setLayout(figureLayout)

        splitter = QSplitter(Qt.Horizontal)
        splitter.addWidget(inputWidget)
        splitter.addWidget(figureWidget)
        splitter.setStretchFactor(1, 1)

        entireLayout = QHBoxLayout()
        entireLayout.addWidget(splitter)
        entireLayout.addWidget(self.fileList)

        self.setLayout(entireLayout)
class MainWindow(QMainWindow, mainwindow.Ui_MainWindow):

    waterfall_data_signal = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.setupUi(self)
        self.setup_window()

    def setup_window(self):
        #Dialogs
        self.Waterfall_Plot = WaterfallPlotter(self)
        self.Waterfall = Waterfall(self)
        self.Waterfall_Widget = QWidget()
        self.Waterfall_Box = QVBoxLayout()
        self.Waterfall_Splitter = QSplitter(QtCore.Qt.Horizontal)
        self.Waterfall_Splitter.addWidget(self.Waterfall)
        self.Waterfall_Splitter.addWidget(self.Waterfall_Plot)
        self.Waterfall_Box.addWidget(self.Waterfall_Splitter)
        self.Waterfall_Widget.setLayout(self.Waterfall_Box)

        self.Spider_Widget = QWidget()
        self.Spider_Box = QVBoxLayout()
        self.Spider_Splitter = QSplitter(QtCore.Qt.Horizontal)
        self.Spider_Plot = SpiderPlotter(self)
        self.Spider = Spider(self)
        self.Spider_Splitter.addWidget(self.Spider)
        self.Spider_Splitter.addWidget(self.Spider_Plot)
        self.Spider_Box.addWidget(self.Spider_Splitter)
        self.Spider_Widget.setLayout(self.Spider_Box)

        self.Swimmer_Widget = QWidget()
        self.Swimmer_Box = QVBoxLayout()
        self.Swimmer_Splitter = QSplitter(QtCore.Qt.Horizontal)
        self.Swimmer_Plot = SwimmerPlotter(self)
        self.Swimmer = Swimmer(self)
        self.Swimmer_Splitter.addWidget(self.Swimmer)
        self.Swimmer_Splitter.addWidget(self.Swimmer_Plot)
        self.Swimmer_Box.addWidget(self.Swimmer_Splitter)
        self.Swimmer_Widget.setLayout(self.Swimmer_Box)

        self.stackedWidget.addWidget(self.Waterfall_Widget)  #0
        self.stackedWidget.addWidget(self.Spider_Widget)  #1
        self.stackedWidget.addWidget(self.Swimmer_Widget)  #2
        self.stackedWidget.hide()

        #Set up toolBar
        self.toolBar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)

        importAction = QAction(
            QtGui.QIcon(os.path.join(image_dir, 'images\Download.png')),
            'Import date template', self)
        importAction.triggered.connect(self.import_data)
        importAction.setIconText("Import")
        self.toolBar.addAction(importAction)
        self.toolBar.addSeparator()

        dumpAction = QAction(
            QtGui.QIcon(os.path.join(image_dir, 'images\Rubbish.png')),
            'Import date template', self)
        #dumpAction.triggered.connect(self.dump_data)
        dumpAction.setIconText("Dump data")
        self.toolBar.addAction(dumpAction)
        self.toolBar.addSeparator()

        self.waterfallAction = QAction(
            QtGui.QIcon(os.path.join(image_dir, r'images\waterfall.png')),
            'Waterfall plot', self)
        self.waterfallAction.triggered.connect(self.launch_waterfall)
        self.waterfallAction.setIconText("Waterfall")
        self.waterfallAction.setEnabled(False)
        self.toolBar.addAction(self.waterfallAction)

        self.spiderAction = QAction(
            QtGui.QIcon(os.path.join(image_dir, r'images\spider.png')),
            'Spider plot', self)
        self.spiderAction.triggered.connect(self.launch_spider)
        self.spiderAction.setIconText("Spider")
        self.spiderAction.setEnabled(False)
        self.toolBar.addAction(self.spiderAction)

        self.swimmerAction = QAction(
            QtGui.QIcon(os.path.join(image_dir, r'images\swimmer_stack.png')),
            'Swimmer plot', self)
        self.swimmerAction.triggered.connect(self.launch_spider)
        self.swimmerAction.setIconText("Swimmer")
        self.swimmerAction.setEnabled(False)
        self.toolBar.addAction(self.swimmerAction)
        self.toolBar.addSeparator()

        #Signal interconnections
        self.waterfall_data_signal.connect(
            self.Waterfall.on_waterfall_data_signal)
        self.waterfall_data_signal.connect(
            self.Waterfall_Plot.on_waterfall_data_signal)
        self.Waterfall.general_settings_signal.connect(
            self.Waterfall_Plot.on_general_settings_signal)

    #Launch functions
    def launch_waterfall(self):
        self.stackedWidget.setCurrentIndex(0)
        self.stackedWidget.show()

    def launch_spider(self):
        self.stackedWidget.setCurrentIndex(1)
        self.stackedWidget.show()

    def launch_swimmer(self):
        self.stackedWidget.setCurrentIndex(2)
        self.stackedWidget.show()

    def import_data(self):
        self.file_path = QFileDialog.getOpenFileName(self,
                                                     "Select Data Template",
                                                     "C:\\")[0]
        if self.file_path == '':
            pass
        else:
            self.waterfall_data = import_plot_data(self.file_path)
            self.waterfall_data_signal.emit(self.waterfall_data)
        self.waterfallAction.setEnabled(True)
        self.spiderAction.setEnabled(True)
        self.swimmerAction.setEnabled(True)
示例#40
0
    def __init__(self):
        super().__init__()

        self.F = MyFigure(width=1, height=1, dpi=100)
        self.F.plotsin()
        # 开始:
        wlayout = QtWidgets.QHBoxLayout()  # 全局布局(1个):水平

        hlayout = QHBoxLayout()  # 局部布局(4个):水平、竖直、网格、表单

        vlayout = QGridLayout()
        vlayout.setDefaultPositioning(100, 100)
        vlayout.setAlignment(Qt.AlignTop)
        vlayout.setVerticalSpacing(30)

        glayout = QGridLayout()
        glayout.setAlignment(Qt.AlignLeft)
        glayout.setRowStretch
        glayout.setHorizontalSpacing(80)
        flayout = QFormLayout()

        baud = [
            '12800', '115200', '230400', '256000', '460800', '921600',
            '1382400'
        ]
        serials = [
            'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8',
            'COM9', 'COM10', 'COM11'
        ]
        self.fasong_btn1 = QPushButton('发送', self)
        self.fasong_btn2 = QPushButton('发送', self)
        self.fasong_btn3 = QPushButton('发送', self)
        self.receive_btn = QPushButton("接收", self)
        self.receive_btn.setFixedSize(80, 60)
        self.com_box = QComboBox()
        self.com_box.addItems(baud)
        #self.bel = QLabel("串口选择")
        self.c_baud = QLabel("波特率")

        self.line_text1 = QLineEdit()
        self.line_text2 = QLineEdit()
        self.line_text3 = QLineEdit()

        # self.hwg_pic = QLabel(self) # 准备四个部件
        # self.hwg_pic.setPixmap(QPixmap("Icon/meidui.jpg"))
        # self.hwg_pic.setScaledContents(True)

        # hlayout.addWidget(self.hwg_pic)
        hlayout.addWidget(self.F)
        vlayout.setDefaultPositioning(10, 10)
        #vlayout.addWidget(self.bel,0,0)
        vlayout.addWidget(self.receive_btn, 0, 0)
        vlayout.addWidget(self.com_box, 1, 1)
        vlayout.addWidget(self.c_baud, 1, 0)

        glayout.addWidget(self.line_text1, 0, 0)
        glayout.addWidget(self.fasong_btn1, 0, 1)
        glayout.addWidget(self.line_text2, 1, 0)
        glayout.addWidget(self.fasong_btn2, 1, 1)
        glayout.addWidget(self.line_text3, 2, 0)
        glayout.addWidget(self.fasong_btn3, 2, 1)

        #菜单和工具栏
        tools_bar = QMainWindow(self)
        menubar = tools_bar.menuBar()
        #menubar = tools_bar.menuBar()

        hwg = QFrame(self)
        hwg.setFrameShape(QFrame.StyledPanel)
        hwg.setMinimumSize(100, 100)

        vwg = QFrame(self)
        vwg.setFrameShape(QFrame.StyledPanel)
        vwg.setMinimumSize(100, 100)

        gwg = QFrame(self)
        gwg.setFrameShape(QFrame.StyledPanel)
        gwg.setMinimumSize(100, 100)

        hwg.setLayout(hlayout)
        vwg.setLayout(vlayout)
        gwg.setLayout(glayout)

        splitter1 = QSplitter(Qt.Horizontal)
        splitter1.addWidget(hwg)
        splitter1.addWidget(vwg)
        splitter1.setSizes([600, 140])
        splitter2 = QSplitter(Qt.Vertical)
        splitter2.addWidget(splitter1)
        splitter2.addWidget(gwg)
        splitter2.setSizes([600, 140])

        wlayout.addWidget(splitter2)
        self.setLayout(wlayout)  # 窗体本尊设置全局布局

        self.setGeometry(300, 300, 800, 800)
        self.setWindowTitle('吴洪岩')
        self.setWindowIcon(QIcon('Icon/meidui.JPG'))
        self.show()
示例#41
0
    def initUI(self):

        self.statusBar().showMessage('Ready')

        self.left_action = QAction('上一个', self)
        self.left_action.setShortcut(QKeySequence.MoveToPreviousChar)
        self.left_action.triggered.connect(self.analyze_last_one_image)

        self.right_action = QAction('下一个', self)
        self.right_action.setShortcut(QKeySequence.MoveToNextChar)
        self.right_action.triggered.connect(self.analyze_next_one_image)

        self.rename_image_action = QAction('保存e2e文件名', self)
        self.rename_image_action.setShortcut(QKeySequence.MoveToPreviousLine)
        self.rename_image_action.triggered.connect(
            self.rename_current_image_with_info)

        self.statusBar()

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&Function')
        fileMenu.addAction(self.left_action)
        fileMenu.addAction(self.right_action)
        fileMenu.addAction(self.rename_image_action)

        self.image_window_view = HyperLprImageView()

        table_widget_header_labels = [
            "文件名", "分割识别", "置信度", "颜色", "E2E识别", "E2E置信度"
        ]

        self.hyperlpr_tableview = QTableWidget(0,
                                               len(table_widget_header_labels))
        self.hyperlpr_tableview.setHorizontalHeaderLabels(
            table_widget_header_labels)

        self.hyperlpr_tableview.setSelectionBehavior(
            QAbstractItemView.SelectItems)
        self.hyperlpr_tableview.setSelectionMode(
            QAbstractItemView.SingleSelection)
        self.hyperlpr_tableview.setEditTriggers(
            QAbstractItemView.NoEditTriggers)
        self.hyperlpr_tableview.horizontalHeader().setSectionResizeMode(
            QHeaderView.ResizeToContents)
        self.hyperlpr_tableview.setEditTriggers(
            QAbstractItemView.NoEditTriggers)

        self.hyperlpr_tableview.cellClicked.connect(
            self.recognize_one_license_plate)

        self.left_button = QPushButton("<")
        self.left_button.setFixedWidth(60)
        self.right_button = QPushButton(">")
        self.right_button.setFixedWidth(60)
        self.left_button.setEnabled(False)
        self.right_button.setEnabled(False)
        self.left_button.clicked.connect(self.analyze_last_one_image)
        self.right_button.clicked.connect(self.analyze_next_one_image)
        left_right_layout = QHBoxLayout()
        left_right_layout.addStretch()
        left_right_layout.addWidget(self.left_button)
        left_right_layout.addStretch()
        left_right_layout.addWidget(self.right_button)
        left_right_layout.addStretch()

        self.location_label = QLabel("车牌目录", self)
        self.location_text = QLineEdit(self)
        self.location_text.setEnabled(False)
        #self.location_text.setFixedWidth(300)
        self.location_button = QPushButton("...")
        self.location_button.clicked.connect(self.select_new_dir)

        self.location_layout = QHBoxLayout()
        self.location_layout.addWidget(self.location_label)
        self.location_layout.addWidget(self.location_text)
        self.location_layout.addWidget(self.location_button)
        self.location_layout.addStretch()

        self.check_box = QCheckBox("与文件名比较车牌")
        self.check_box.setChecked(True)

        self.update_file_path_button = QPushButton('批量识别')
        self.update_file_path_button.clicked.connect(
            self.batch_recognize_all_images)

        self.update_file_path_layout = QHBoxLayout()
        self.update_file_path_layout.addWidget(self.check_box)
        self.update_file_path_layout.addWidget(self.update_file_path_button)
        self.update_file_path_layout.addStretch()

        self.save_as_e2e_filename_button = QPushButton("保存e2e文件名")
        self.save_as_e2e_filename_button.setEnabled(False)
        self.save_as_e2e_filename_button.clicked.connect(
            self.rename_current_image_with_info)
        self.save_layout = QHBoxLayout()
        self.save_layout.addWidget(self.save_as_e2e_filename_button)
        self.save_layout.addStretch()

        self.top_layout = QVBoxLayout()
        self.top_layout.addLayout(left_right_layout)
        self.top_layout.addLayout(self.location_layout)
        self.top_layout.addLayout(self.update_file_path_layout)
        self.top_layout.addLayout(self.save_layout)

        function_groupbox = QGroupBox("功能区")
        function_groupbox.setLayout(self.top_layout)

        license_plate_image_label = QLabel("车牌图")
        self.license_plate_widget = QLabel("")

        block_image_label = QLabel("分割图")
        self.block_plate_widget = QLabel("")

        filename_label = QLabel("文件名:")
        self.filename_edit = QLineEdit()

        segmentation_recognition_label = QLabel("分割识别:")
        self.segmentation_recognition_edit = QLineEdit()
        self.segmentation_recognition_edit.setFont(QFont("黑体", 24, QFont.Bold))
        # self.segmentation_recognition_edit.setStyleSheet("color:red")

        confidence_label = QLabel("分割识别\n置信度")
        self.confidence_edit = QLineEdit()
        #self.confidence_edit.setFont(QFont("黑体", 24, QFont.Bold))
        # self.confidence_edit.setStyleSheet("color:red")

        plate_color_label = QLabel("车牌颜色")
        self.plate_color_edit = QLineEdit()
        self.plate_color_edit.setFont(QFont("黑体", 24, QFont.Bold))
        # self.plate_color_edit.setStyleSheet("color:red")

        e2e_recognization_label = QLabel("e2e识别:")
        self.e2e_recognization_edit = QLineEdit()
        self.e2e_recognization_edit.setFont(QFont("黑体", 24, QFont.Bold))
        # self.e2e_recognization_edit.setStyleSheet("color:red")

        e2e_confidence_label = QLabel("e2e置信度")
        self.e2e_confidence_edit = QLineEdit()
        #self.e2e_confidence_edit.setFont(QFont("黑体", 24, QFont.Bold))
        # self.e2e_confidence_edit.setStyleSheet("color:red")

        info_gridlayout = QGridLayout()
        line_index = 0
        info_gridlayout.addWidget(filename_label, line_index, 0)
        info_gridlayout.addWidget(self.filename_edit, line_index, 1)
        line_index += 1
        info_gridlayout.addWidget(license_plate_image_label, line_index, 0)
        info_gridlayout.addWidget(self.license_plate_widget, line_index, 1)
        line_index += 1
        info_gridlayout.addWidget(e2e_recognization_label, line_index, 0)
        info_gridlayout.addWidget(self.e2e_recognization_edit, line_index, 1)
        line_index += 1
        info_gridlayout.addWidget(segmentation_recognition_label, line_index,
                                  0)
        info_gridlayout.addWidget(self.segmentation_recognition_edit,
                                  line_index, 1)
        line_index += 1
        info_gridlayout.addWidget(plate_color_label, line_index, 0)
        info_gridlayout.addWidget(self.plate_color_edit, line_index, 1)
        line_index += 1
        info_gridlayout.addWidget(block_image_label, line_index, 0)
        info_gridlayout.addWidget(self.block_plate_widget, line_index, 1)
        line_index += 1
        info_gridlayout.addWidget(confidence_label, line_index, 0)
        info_gridlayout.addWidget(self.confidence_edit, line_index, 1)
        line_index += 1
        info_gridlayout.addWidget(e2e_confidence_label, line_index, 0)
        info_gridlayout.addWidget(self.e2e_confidence_edit, line_index, 1)

        info_widget = QGroupBox("分割识别&e2e")

        info_widget.setLayout(info_gridlayout)

        right_splitter = QSplitter(Qt.Vertical)
        right_splitter.addWidget(self.hyperlpr_tableview)
        right_splitter.addWidget(function_groupbox)
        right_splitter.addWidget(info_widget)
        right_splitter.setStretchFactor(0, 2)
        right_splitter.setStretchFactor(2, 1)

        main_splitter = QSplitter(Qt.Horizontal)
        main_splitter.addWidget(self.image_window_view)
        main_splitter.addWidget(right_splitter)
        main_splitter.setStretchFactor(0, 1)

        self.image_filename_list = []
        self.hyperlpr_dir_path = ""
        self.segmentation_recognition_correct_number = 0
        self.color_correct_number = 0
        self.e2e_recognization_correct_number = 0
        self.current_row = 0

        self.batch_recognization_thread = LicenseRecognizationThread()
        self.batch_recognization_thread.recognization_done_signal.connect(
            self.recognization_done_slot)
        self.batch_recognization_thread.start()

        self.start_init_signal.connect(self.read_path_and_show_one_image)

        self.setCentralWidget(main_splitter)

        self.setWindowTitle("HyperLPR车牌识别软件v1.0")

        self.start_init_signal.emit()
示例#42
0
    def _init_ui(self):
        layout = QGridLayout(self)

        self.polar_viewer = CustomImageViewer(parent=self)
        self.radial_viewer = RadialFitWidget(parent=self)
        self.fit_plot = FitPlot(parent=self)
        self.sliders_widget = SlidersWidget(parent=self)
        self.fit_button = QPushButton(FitImageButtonStatus.fit.value)
        self.apply_button = QPushButton('Apply')
        self.close_button = QPushButton('Close')
        self.close_button.clicked.connect(self.close)
        self.multi_fit_window: MultiFitWindow = MultiFitWindow(self.fit_object, self)

        self.multi_fit_window.sigFitUpdated.connect(self.set_fit)
        self.multi_fit_window.sigClosed.connect(self._close_multi_fit)
        self.fit_button.clicked.connect(self._fit_clicked)
        self.apply_button.clicked.connect(self.apply_results)
        self.radial_viewer.sigUpdateFit.connect(self._radial_roi_moved)
        self.radial_viewer.sigUpdateProfile.connect(self._profile_updated)
        self.sliders_widget.sigValueChanged.connect(self._sliders_changed)

        self.functions_box = QComboBox(self)
        self.background_box = QComboBox(self)
        self.range_strategies_box = QComboBox(self)

        self.set_as_default_button = QPushButton('Set as default options')
        self.set_as_default_button.clicked.connect(self._set_as_default)
        self.range_factor_slider = LabeledSlider('Y range factor', (0, 10), parent=self, decimals=2)
        self.range_factor_slider.valueChanged.connect(self._on_range_slider_moved)
        self.sigma_slider = LabeledSlider('Sigma', (0, 10), parent=self, decimals=2)
        self.sigma_slider.valueChanged.connect(self._on_sigma_slider_moved)
        self.fit_current_button = QPushButton(CurrentFitButtonStatus.fit.value)
        self.fit_current_button.clicked.connect(self._fit_current_clicked)
        self.update_data_button = QPushButton('Update fit')
        self.update_data_button.clicked.connect(self._update_data_button_clicked)

        self.functions_box.currentTextChanged.connect(self._change_function)
        self.background_box.currentTextChanged.connect(self._change_background)
        self.range_strategies_box.currentTextChanged.connect(self._change_range_strategy)

        self.functions_box.addItem('Fitting functions')
        for t in FittingType:
            self.functions_box.addItem(t.value)
        self.background_box.addItem('Backgrounds')
        for t in BackgroundType:
            self.background_box.addItem(t.value)
        self.range_strategies_box.addItem('Range strategy')
        for t in RangeStrategyType:
            self.range_strategies_box.addItem(t.value)

        self.selected_fit_label = QLabel('Selected Fit', self)
        self.current_image_label = QLabel('Current Image', self)

        single_image_widget = QWidget(self)

        q_splitter_h1 = QSplitter(orientation=Qt.Vertical, parent=single_image_widget)
        q_splitter_h1.addWidget(self.polar_viewer)
        q_splitter_h1.addWidget(self.radial_viewer)

        s_layout = QGridLayout(single_image_widget)
        s_layout.addWidget(self.current_image_label, 0, 0, 1, 3)
        s_layout.addWidget(q_splitter_h1, 1, 0, 1, 3)
        s_layout.addWidget(self.fit_button, 2, 0)
        s_layout.addWidget(self.apply_button, 2, 1)
        s_layout.addWidget(self.close_button, 2, 2)

        single_roi_widget = QWidget(self)

        q_scroll_area = QScrollArea(self)
        q_scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        q_scroll_area.setWidgetResizable(True)
        q_scroll_area.setGeometry(0, 0, 300, 400)

        options_widget = QWidget(self)
        options_widget.setSizePolicy(
            QSizePolicy.Expanding, QSizePolicy.Expanding
        )
        scroll_layout = QGridLayout(options_widget)
        scroll_layout.addWidget(self.background_box, 0, 0)
        scroll_layout.addWidget(self.functions_box, 1, 0)
        scroll_layout.addWidget(self.range_strategies_box, 2, 0)
        scroll_layout.addWidget(self.range_factor_slider, 3, 0)

        scroll_layout.addWidget(self.set_as_default_button, 0, 1)
        scroll_layout.addWidget(self.fit_current_button, 1, 1)
        scroll_layout.addWidget(self.update_data_button, 2, 1)
        scroll_layout.addWidget(self.sigma_slider, 3, 1)
        scroll_layout.addWidget(self.sliders_widget, 4, 0, 2, 2)

        q_scroll_area.setWidget(options_widget)

        q_splitter_h2 = QSplitter(orientation=Qt.Vertical, parent=self)
        q_splitter_h2.addWidget(self.fit_plot)
        q_splitter_h2.addWidget(q_scroll_area)
        # q_splitter_h2.addWidget(self.sliders_widget)

        sr_layout = QGridLayout(single_roi_widget)
        sr_layout.addWidget(self.selected_fit_label, 0, 0)
        sr_layout.addWidget(q_splitter_h2, 1, 0)

        q_splitter_v = QSplitter(orientation=Qt.Horizontal, parent=self)
        q_splitter_v.addWidget(self.multi_fit_window)
        q_splitter_v.addWidget(single_image_widget)
        q_splitter_v.addWidget(single_roi_widget)

        q_splitter_v.setSizes((300, 600, self.width() - 900))
        q_splitter_h1.setSizes((400, self.height() - 400))
        q_splitter_h2.setSizes((400, self.height() - 400))
        layout.addWidget(q_splitter_v, 0, 0, 2, 2)
示例#43
0
class BlockEditor(QWidget, MooseWidget):
    """
    The complete editing widget for a Block.
    The input file will only change when "Apply changes" has been clicked.
    Until then all changes only live in the widgets.
    The exceptions to this are the "Clone" and "Remove" buttons which just sends out signals to let
    others do work.
    Signals:
        needBlockList(list): When the type of a parameter references blocks (for example it is a VariableName),
            this is used to update the available options since they can change based on what the user does.
        blockRenamed(object, str): A block has been renamed. This is emitted so that the BlockTree can update the name of the block.
        blockChanged(object): Apply has been clicked for this block.
        cloneBlock(object): The user wants to clone the block we are currently editing.
        removeBlock(object): The user wants to remove the block we are currently editing.
        editingFinished(): The user is done editing this block. Typically done by closing the window.
        appliedAndClosed(object): Emit the block when the user hits the "Apply & Close" button
    """
    needBlockList = pyqtSignal(list) # list of paths that we need children for
    blockRenamed = pyqtSignal(object, str) # block with changes, old path
    blockChanged = pyqtSignal(object) # block that has changed

    cloneBlock = pyqtSignal(object) # block to clone
    removeBlock = pyqtSignal(object) # block to remove
    editingFinished = pyqtSignal()
    appliedAndClosed = pyqtSignal(object)

    def __init__(self, block, type_to_block_map, **kwds):
        """
        Sets up an editor for a block.
        Input:
            block[BlockInfo]: Block to be edited.
        """
        super(BlockEditor, self).__init__(**kwds)
        self.block = block
        self.comment_edit = CommentEditor()
        self.comment_edit.setComments(self.block.comments)
        self.comment_edit.textChanged.connect(self._blockChanged)
        self.splitter = None
        self.clone_button = None
        self.clone_shortcut = None
        self.remove_button = None
        self.apply_button = None
        self.reset_button = None
        self.new_parameter_button = None
        self.param_editor = None
        self.setWindowTitle(block.path)

        if block.types:
            self.param_editor = ParamsByType(block, type_to_block_map)
        elif block.parameters:
            self.param_editor = ParamsByGroup(block, block.orderedParameters(), type_to_block_map)
        else:
            self.param_editor = ParamsTable(block, block.orderedParameters(), type_to_block_map)

        self.param_editor.needBlockList.connect(self.needBlockList)
        self.param_editor.changed.connect(self._blockChanged)
        self.param_editor.blockRenamed.connect(self.blockRenamed)

        self._createButtons()
        self.applyChanges()
        self._current_commands = []
        self._command_index = 0
        self.user_params = []

        self.splitter = QSplitter(self)
        self.splitter.setOrientation(Qt.Vertical)
        self.splitter.setChildrenCollapsible(False)
        self.splitter.addWidget(self.param_editor)
        self.splitter.addWidget(self.comment_edit)
        self.splitter.setStretchFactor(0,2)
        self.splitter.setStretchFactor(1,1)
        self.top_layout = WidgetUtils.addLayout(vertical=True)
        self.top_layout.addWidget(self.splitter)
        self.top_layout.addLayout(self.button_layout)
        self.setLayout(self.top_layout)

        self.setup()

    def _blockChanged(self, enabled=True):
        """
        Sets the Apply and Reset buttons based on enabled.
        Input:
            enabled[bool]: Whether to set the buttons to enabled
        """
        self.apply_button.setEnabled(enabled)
        self.reset_button.setEnabled(enabled)
        self.setWindowTitle(self.block.path)

    def setWatchedBlockList(self, path, children):
        self.param_editor.setWatchedBlockList(path, children)

    def _createButtons(self):
        """
        Create allowable buttons for this Block.
        This will depend on whether this is a user added block.
        """
        self.button_layout = WidgetUtils.addLayout()

        self.close_button = WidgetUtils.addButton(self.button_layout, self, "Apply && Close", self._applyAndClose)
        self.close_button.setToolTip("Apply any changes and close the window")

        self.apply_button = WidgetUtils.addButton(self.button_layout, self, "Apply", self.applyChanges)
        self.apply_button.setEnabled(False)
        self.apply_button.setToolTip("Apply changes made")

        self.reset_button = WidgetUtils.addButton(self.button_layout, self, "Reset", self.resetChanges)
        self.reset_button.setEnabled(False)
        self.reset_button.setToolTip("Reset changes to when this window was opened")

        self.new_parameter_button = WidgetUtils.addButton(self.button_layout, self, "Add parameter", self.addUserParamPressed)
        self.new_parameter_button.setToolTip("Add a non standard parameter")

        if self.block.user_added:
            self.clone_button = WidgetUtils.addButton(self.button_layout, self, "Clone Block", self._cloneBlock)
            self.clone_shortcut = WidgetUtils.addShortcut(self, "Ctrl+N", self._cloneBlock, shortcut_with_children=True)
            self.clone_button.setToolTip("Clone this block with the same parameters")

            self.remove_button = WidgetUtils.addButton(self.button_layout, self, "Remove Block", self._removeBlock)
            self.remove_button.setToolTip("Remove this block")

    def _findFreeParamName(self, max_params=1000):
        """
        Find a free parameter name that can be safely added.
        Input:
            max_params[int]: Maximum number of tries before giving up.
        """
        base = "NewParam"
        for i in range(max_params):
            param = '%s%s' % (base, i)
            if self.param_editor.paramValue(param) == None:
                return param

    def addUserParamPressed(self):
        """
        The user wants to add a new user parameter to this block.
        """
        new_name = self._findFreeParamName()
        self._blockChanged()
        self.param_editor.addUserParam(new_name)

    def _cloneBlock(self):
        """
        The user wants to clone this block
        """
        self.cloneBlock.emit(self.block)

    def _removeBlock(self):
        """
        The user wants to remove this block.
        We ask to make sure they want to do this.
        """
        button = QMessageBox.question(self, "Confirm remove", "Are you sure you want to delete %s" % self.block.path, QMessageBox.Yes, QMessageBox.No)
        if button == QMessageBox.Yes:
            self.removeBlock.emit(self.block)
            self.hide()
            self.editingFinished.emit()

    def applyChanges(self):
        """
        Apply any changes the user has made.
        """
        self.block.comments = self.comment_edit.getComments()
        self.param_editor.save()
        self.block.changed_by_user = True
        self._blockChanged(enabled=False)
        self.blockChanged.emit(self.block)

    def _applyAndClose(self):
        """
        Apply any changes the user has made then close the window
        """
        if self.apply_button.isEnabled():
            self.applyChanges()
            self.appliedAndClosed.emit(self.block)
        self.close()

    def resetChanges(self):
        """
        Reset any changes the user has made.
        """
        self.comment_edit.setComments(self.block.comments)
        self.param_editor.reset()
        self._blockChanged(enabled=False)

    def updateWatchers(self):
        """
        This should be called after creating a BlockEditor.
        This isn't called in the constructor because the caller
        will typically need to hook up the needBlockList signal first.
        """
        self.param_editor.updateWatchers()

    def closeEvent(self, event):
        """
        The user is done editing.
        """
        self.editingFinished.emit()
示例#44
0
    def __init__(self):
        super().__init__()
        self.setWindowTitle(self.stringName)

        # Setup layout:
        base = QHBoxLayout()
        widget = QWidget()
        widget.setLayout(base)
        baseLayout = QSplitter()
        base.addWidget(baseLayout)
        self.setWidget(widget)
        buttonLayout = QVBoxLayout()
        buttonBox = QWidget()
        buttonBox.setLayout(buttonLayout)
        baseLayout.addWidget(buttonBox)

        # Comic page list and pages model
        self.comicPageList = QTableView()
        self.comicPageList.verticalHeader().setSectionsMovable(True)
        self.comicPageList.verticalHeader().setDragEnabled(True)
        self.comicPageList.verticalHeader().setDragDropMode(
            QAbstractItemView.InternalMove)
        self.comicPageList.setAcceptDrops(True)
        self.comicPageList.horizontalHeader().setStretchLastSection(True)
        self.pagesModel = QStandardItemModel()
        self.comicPageList.doubleClicked.connect(self.slot_open_page)
        self.comicPageList.setIconSize(QSize(128, 128))
        # self.comicPageList.itemDelegate().closeEditor.connect(self.slot_write_description)
        self.pagesModel.layoutChanged.connect(self.slot_write_config)
        self.pagesModel.rowsInserted.connect(self.slot_write_config)
        self.pagesModel.rowsRemoved.connect(self.slot_write_config)
        self.comicPageList.verticalHeader().sectionMoved.connect(
            self.slot_write_config)
        self.comicPageList.setModel(self.pagesModel)
        pageBox = QWidget()
        pageBox.setLayout(QVBoxLayout())
        zoomSlider = QSlider(Qt.Horizontal, None)
        zoomSlider.setRange(1, 8)
        zoomSlider.setValue(4)
        zoomSlider.setTickInterval(1)
        zoomSlider.setMinimumWidth(10)
        zoomSlider.valueChanged.connect(self.slot_scale_thumbnails)
        self.projectName = Elided_Text_Label()
        pageBox.layout().addWidget(self.projectName)
        pageBox.layout().addWidget(zoomSlider)
        pageBox.layout().addWidget(self.comicPageList)
        baseLayout.addWidget(pageBox)

        self.btn_project = QToolButton()
        self.btn_project.setPopupMode(QToolButton.MenuButtonPopup)
        self.btn_project.setSizePolicy(QSizePolicy.Minimum,
                                       QSizePolicy.Minimum)
        menu_project = QMenu()
        self.action_new_project = QAction(i18n("New Project"), self)
        self.action_new_project.triggered.connect(self.slot_new_project)
        self.action_load_project = QAction(i18n("Open Project"), self)
        self.action_load_project.triggered.connect(self.slot_open_config)
        menu_project.addAction(self.action_new_project)
        menu_project.addAction(self.action_load_project)
        self.btn_project.setMenu(menu_project)
        self.btn_project.setDefaultAction(self.action_load_project)
        buttonLayout.addWidget(self.btn_project)

        # Settings dropdown with actions for the different settings menus.
        self.btn_settings = QToolButton()
        self.btn_settings.setPopupMode(QToolButton.MenuButtonPopup)
        self.btn_settings.setSizePolicy(QSizePolicy.Minimum,
                                        QSizePolicy.Minimum)
        self.action_edit_project_settings = QAction(i18n("Project Settings"),
                                                    self)
        self.action_edit_project_settings.triggered.connect(
            self.slot_edit_project_settings)
        self.action_edit_meta_data = QAction(i18n("Meta Data"), self)
        self.action_edit_meta_data.triggered.connect(self.slot_edit_meta_data)
        self.action_edit_export_settings = QAction(i18n("Export Settings"),
                                                   self)
        self.action_edit_export_settings.triggered.connect(
            self.slot_edit_export_settings)
        menu_settings = QMenu()
        menu_settings.addAction(self.action_edit_project_settings)
        menu_settings.addAction(self.action_edit_meta_data)
        menu_settings.addAction(self.action_edit_export_settings)
        self.btn_settings.setDefaultAction(self.action_edit_project_settings)
        self.btn_settings.setMenu(menu_settings)
        buttonLayout.addWidget(self.btn_settings)
        self.btn_settings.setDisabled(True)

        # Add page drop down with different page actions.
        self.btn_add_page = QToolButton()
        self.btn_add_page.setPopupMode(QToolButton.MenuButtonPopup)
        self.btn_add_page.setSizePolicy(QSizePolicy.Minimum,
                                        QSizePolicy.Minimum)

        self.action_add_page = QAction(i18n("Add Page"), self)
        self.action_add_page.triggered.connect(self.slot_add_new_page_single)
        self.action_add_template = QAction(i18n("Add Page From Template"),
                                           self)
        self.action_add_template.triggered.connect(
            self.slot_add_new_page_from_template)
        self.action_add_existing = QAction(i18n("Add Existing Pages"), self)
        self.action_add_existing.triggered.connect(self.slot_add_page_from_url)
        self.action_remove_selected_page = QAction(i18n("Remove Page"), self)
        self.action_remove_selected_page.triggered.connect(
            self.slot_remove_selected_page)
        self.action_resize_all_pages = QAction(i18n("Batch Resize"), self)
        self.action_resize_all_pages.triggered.connect(self.slot_batch_resize)
        self.btn_add_page.setDefaultAction(self.action_add_page)
        self.action_show_page_viewer = QAction(i18n("View Page In Window"),
                                               self)
        self.action_show_page_viewer.triggered.connect(
            self.slot_show_page_viewer)
        self.action_scrape_authors = QAction(i18n("Scrape Author Info"), self)
        self.action_scrape_authors.setToolTip(
            i18n(
                "Search for author information in documents and add it to the author list. This doesn't check for duplicates."
            ))
        self.action_scrape_authors.triggered.connect(
            self.slot_scrape_author_list)
        self.action_scrape_translations = QAction(
            i18n("Scrape Text for Translation"), self)
        self.action_scrape_translations.triggered.connect(
            self.slot_scrape_translations)
        actionList = []
        menu_page = QMenu()
        actionList.append(self.action_add_page)
        actionList.append(self.action_add_template)
        actionList.append(self.action_add_existing)
        actionList.append(self.action_remove_selected_page)
        actionList.append(self.action_resize_all_pages)
        actionList.append(self.action_show_page_viewer)
        actionList.append(self.action_scrape_authors)
        actionList.append(self.action_scrape_translations)
        menu_page.addActions(actionList)
        self.btn_add_page.setMenu(menu_page)
        buttonLayout.addWidget(self.btn_add_page)
        self.btn_add_page.setDisabled(True)

        self.comicPageList.setContextMenuPolicy(Qt.ActionsContextMenu)
        self.comicPageList.addActions(actionList)

        # Export button that... exports.
        self.btn_export = QPushButton(i18n("Export Comic"))
        self.btn_export.clicked.connect(self.slot_export)
        buttonLayout.addWidget(self.btn_export)
        self.btn_export.setDisabled(True)

        self.btn_project_url = QPushButton(i18n("Copy Location"))
        self.btn_project_url.setToolTip(
            i18n(
                "Copies the path of the project to the clipboard. Useful for quickly copying to a file manager or the like."
            ))
        self.btn_project_url.clicked.connect(self.slot_copy_project_url)
        self.btn_project_url.setDisabled(True)
        buttonLayout.addWidget(self.btn_project_url)

        self.page_viewer_dialog = comics_project_page_viewer.comics_project_page_viewer(
        )

        Application.notifier().imageSaved.connect(
            self.slot_check_for_page_update)

        buttonLayout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Minimum,
                        QSizePolicy.MinimumExpanding))
示例#45
0
class MainWindow(QMainWindow):

    #    class EventFilter(QObject):
    #        def __init__(self, parent):
    #            super().__init__(parent)
    #
    #        def eventFilter(self, obj, e):
    #            #print(obj.metaObject().className())
    #
    #            if e.type() == QEvent.KeyPress or e.type() == QEvent.ShortcutOverride:
    #                key = e.key()
    #                mod = e.modifiers()
    #
    #                print(str(e) + ' ' + str(e.type()) )
    #
    #                if mod == Qt.AltModifier:
    #                    print('*'*30)
    #                    print('alt pressed')
    #                    if key == Qt.Key_Left or key == Qt.Key_Right:
    #                        print('alt-left') if key == Qt.Key_Left else print('alt-right')
    ##                       action = QAbstractItemView.MoveLeft if key == Qt.Key_Left else QAbstractItemView.MoveRight
    ##                       idx = obj.moveCursor(action, Qt.NoModifier)
    ##                       item = obj.itemFromIndex(idx)
    ##                       obj.setCurrentItem(item)
    #                        return True
    #
    #            return False

    PROGRAM_NAME = 'KiCad Schematic Component Manager'

    #--------------------------------------------------------------------------------
    class EventFilter(QObject):
        def __init__(self, parent):
            super().__init__(parent)

        def eventFilter(self, obj, e):
            if e.type() == QEvent.KeyPress or e.type(
            ) == QEvent.ShortcutOverride:
                key = e.key()
                mod = e.modifiers()

                #print(obj.focusWidget().metaObject().className())

            return False

    #--------------------------------------------------------------------------------
    def scroll_left(self):
        print('alt-left')
        if self.ToolIndex == 3 or self.ToolIndex == 2:
            self.ToolList[self.ToolIndex].finish_edit()

        self.ToolIndex -= 1
        if self.ToolIndex < 0:
            self.ToolIndex = len(self.ToolList) - 1

        print('Tool Index: ' + str(self.ToolIndex))
        self.ToolList[self.ToolIndex].setFocus()

    #--------------------------------------------------------------------------------
    def scroll_right(self):
        print('alt-right')
        if self.ToolIndex == 3 or self.ToolIndex == 2:
            self.ToolList[self.ToolIndex].finish_edit()

        self.ToolIndex += 1
        if self.ToolIndex == len(self.ToolList):
            self.ToolIndex = 0

        print('Tool Index: ' + str(self.ToolIndex))
        self.ToolList[self.ToolIndex].setFocus()

    #--------------------------------------------------------------------------------
    def mouse_change_tool(self, s):
        print('Tool ' + s)
        if s == 'CmpTable':
            self.ToolIndex = 0
        elif s == 'Selector':
            self.ToolIndex = 1
        elif s == 'Inspector':
            self.ToolIndex = 2
        elif s == 'FieldInspector':
            self.ToolIndex = 3

        if self.ToolIndex != 3:
            self.ToolList[3].finish_edit(
            )  # save field properties when leave field inspector

    #--------------------------------------------------------------------------------
    def add_user_property(self):
        self.Inspector.save_cmps()
        self.FieldInspector.save_fields()

        self.Inspector.add_property()

    #--------------------------------------------------------------------------------
    def remove_user_property(self):
        #self.Inspector.save_cmps()
        self.FieldInspector.save_fields()

        self.Inspector.remove_property()

    #--------------------------------------------------------------------------------
    def rename_user_property(self):
        #self.Inspector.save_cmps()
        self.FieldInspector.save_fields()

        self.Inspector.rename_property()

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

        self.initUI()

        self.installEventFilter(self.EventFilter(self))

        self.setFocusPolicy(Qt.WheelFocus)
        self.setTabOrder(self.CmpTable, self.Inspector)
        self.setTabOrder(self.Inspector, self.Selector)
        self.setTabOrder(self.Selector, self.FieldInspector)
        #self.setTabOrder(self.FieldInspector, self.CmpTable)

        #----------------------------------------------------
        #
        #   Application Hotkeys
        #
        self.shortcutLeft = QShortcut(QKeySequence(Qt.ALT + Qt.Key_Left), self)
        self.shortcutRight = QShortcut(QKeySequence(Qt.ALT + Qt.Key_Right),
                                       self)
        self.shortcutLeft.setContext(Qt.ApplicationShortcut)
        self.shortcutRight.setContext(Qt.ApplicationShortcut)
        self.shortcutLeft.activated.connect(self.scroll_left)
        self.shortcutRight.activated.connect(self.scroll_right)

    #--------------------------------------------------------------------------------
    def initUI(self):

        #----------------------------------------------------
        #
        #    Main Window
        #
        work_zone = QWidget(self)
        Layout = QHBoxLayout(work_zone)
        self.setCentralWidget(work_zone)

        openAction = QAction(QIcon(os.path.join(resources_path, 'open24.png')),
                             'Open', self)
        openAction.setShortcut('Ctrl+O')
        openAction.setStatusTip('Open Schematic File')
        openAction.triggered.connect(self.open_file)

        saveAction = QAction(QIcon(os.path.join(resources_path, 'save24.png')),
                             'Save', self)
        saveAction.setShortcut('Ctrl+S')
        saveAction.setStatusTip('Save Schematic File')
        saveAction.triggered.connect(self.save_file)

        saveAsAction = QAction(
            QIcon(os.path.join(resources_path, 'save-as24.png')), 'Save As...',
            self)
        saveAsAction.setShortcut('Ctrl+Shift+S')
        saveAsAction.setStatusTip('Save Schematic File As...')
        saveAsAction.triggered.connect(self.save_file_as)

        exitAction = QAction(QIcon(os.path.join(resources_path, 'exit24.png')),
                             'Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application')
        exitAction.triggered.connect(self.close)

        settingsAction = QAction(
            QIcon(os.path.join(resources_path, 'settings24.png')), 'Settings',
            self)
        settingsAction.setShortcut('Ctrl+Alt+S')
        settingsAction.setStatusTip('Edit settings')
        settingsAction.triggered.connect(self.edit_settings)

        helpAction = QAction(
            QIcon(os.path.join(resources_path, 'help_book24.png')),
            'User\'s Manual', self)
        helpAction.setShortcut('F1')
        helpAction.setStatusTip('User\'s Manual')
        helpAction.triggered.connect(self.show_user_manual_slot)

        helpSDAction = QAction(
            QIcon(os.path.join(resources_path, 'gear24.png')),
            'Settings Dialog', self)
        helpSDAction.setShortcut('Ctrl+F1')
        helpSDAction.setStatusTip('Settings Dialog Help')
        helpSDAction.triggered.connect(self.show_setting_dialog_help_slot)

        helpHKAction = QAction(
            QIcon(os.path.join(resources_path, 'rocket24.png')), 'Hotkeys',
            self)
        helpHKAction.setShortcut('Shift+F1')
        helpHKAction.setStatusTip('Hotkeys Help')
        helpHKAction.triggered.connect(self.show_hotkeys_help_slot)

        self.statusBar().showMessage('Ready')

        #--------------------------------------------
        #
        #    Main Menu
        #
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(openAction)
        fileMenu.addAction(saveAction)
        fileMenu.addAction(saveAsAction)
        fileMenu.addAction(exitAction)

        #--------------------------------------------
        #
        #    Options Menu
        #
        optionsMenu = menubar.addMenu('&Options')
        optionsMenu.addAction(settingsAction)

        #--------------------------------------------
        #
        #    Help Menu
        #
        helpMenu = menubar.addMenu('&Help')
        helpMenu.addAction(helpAction)
        helpMenu.addAction(helpSDAction)
        helpMenu.addAction(helpHKAction)

        #--------------------------------------------
        #
        #    Toolbar
        #
        toolbar = self.addToolBar('Exit')
        toolbar.addAction(exitAction)
        toolbar.addAction(openAction)
        toolbar.addAction(saveAction)
        toolbar.addAction(saveAsAction)
        toolbar.addAction(settingsAction)
        toolbar.addAction(helpAction)

        #----------------------------------------------------
        #
        #    Settings Dialog
        #

        #----------------------------------------------------
        #
        #    Components Table
        #
        self.CmpTabBox = QGroupBox('Components', self)
        self.CmpTabLayout = QVBoxLayout(self.CmpTabBox)
        self.CmpTabLayout.setContentsMargins(4, 10, 4, 4)
        self.CmpTabLayout.setSpacing(10)

        self.CmpTabLayout.setSizeConstraint(QVBoxLayout.SetMaximumSize)

        self.CmpTable = ComponentsTable(self)
        #self.CmpChooseButton = QPushButton('Choose', self)

        self.CmpTabLayout.addWidget(self.CmpTable)
        #self.CmpTabLayout.addWidget(self.CmpChooseButton)

        #----------------------------------------------------
        #
        #    Selector
        #
        self.SelectorBox = QGroupBox('Selector', self)
        self.SelectorLayout = QVBoxLayout(self.SelectorBox)
        self.SelectorLayout.setContentsMargins(4, 10, 4, 4)
        self.SelectorLayout.setSpacing(2)

        self.SelectorBtnWidget = QWidget(self)
        self.SelectorBtnLayout = QHBoxLayout(self.SelectorBtnWidget)
        self.SelectorBtnLayout.setContentsMargins(4, 10, 4, 4)
        self.SelectorBtnLayout.setSpacing(10)

        self.Selector = Selector(self)

        self.SelApplyButton = QPushButton('Apply', self)
        self.SelApplyButton.setToolTip(
            'Alt+S: Apply selection patterns to components')

        self.SelClearButton = QPushButton('Clear', self)
        self.SelClearButton.setToolTip('Alt+C: Clear selection patterns')

        self.SelTemplateButton = QPushButton('Use Component', self)
        self.SelTemplateButton.setToolTip(
            'Alt+T: Use Selected Component As Template')

        self.SelectorLayout.addWidget(self.Selector)
        self.SelectorBtnLayout.addWidget(self.SelTemplateButton)
        self.SelectorBtnLayout.addWidget(self.SelApplyButton)
        self.SelectorBtnLayout.addWidget(self.SelClearButton)
        self.SelectorLayout.addWidget(self.SelectorBtnWidget)

        self.shortcutSelApply = QShortcut(QKeySequence(Qt.ALT + Qt.Key_S),
                                          self)
        self.shortcutSelApply.activated.connect(self.Selector.apply_slot)

        self.shortcutSelClear = QShortcut(QKeySequence(Qt.ALT + Qt.Key_C),
                                          self)
        self.shortcutSelClear.activated.connect(self.Selector.clear_slot)

        self.shortcutSelTemplate = QShortcut(QKeySequence(Qt.ALT + Qt.Key_T),
                                             self)
        self.shortcutSelTemplate.activated.connect(
            self.Selector.use_comp_as_template_slot)

        #----------------------------------------------------
        #
        #    Inspector
        #
        self.Inspector = Inspector(self)
        self.FieldInspector = FieldInspector(self)

        self.InspectorBtnWidget = QWidget(self)
        self.InspectorBtnLayout = QHBoxLayout(self.InspectorBtnWidget)
        self.InspectorBtnLayout.setContentsMargins(4, 10, 4, 4)
        self.InspectorBtnLayout.setSpacing(10)

        self.AddUserProperty = QPushButton('Add Property', self)
        self.AddUserProperty.setToolTip('Alt+A: Add new user property')
        self.DeleteUserProperty = QPushButton('Delete Property', self)
        self.DeleteUserProperty.setToolTip('Alt+Delete: Delete user property')
        self.RenameUserProperty = QPushButton('Rename Property', self)
        self.RenameUserProperty.setToolTip('Alt+R: Rename user property')

        self.InspectorBox = QGroupBox('Inspector', self)
        self.InspectorSplit = QSplitter(Qt.Vertical, self)
        self.InspectorLayout = QVBoxLayout(self.InspectorBox)
        self.InspectorLayout.setContentsMargins(4, 10, 4, 4)
        self.InspectorLayout.setSpacing(2)

        self.InspectorSplit.addWidget(self.Inspector)
        self.InspectorSplit.addWidget(self.FieldInspector)
        self.InspectorLayout.addWidget(self.InspectorSplit)

        self.InspectorBtnLayout.addWidget(self.AddUserProperty)
        self.InspectorBtnLayout.addWidget(self.DeleteUserProperty)
        self.InspectorBtnLayout.addWidget(self.RenameUserProperty)

        self.InspectorLayout.addWidget(self.InspectorBtnWidget)

        self.shortcutSelApply = QShortcut(QKeySequence(Qt.ALT + Qt.Key_A),
                                          self)
        self.shortcutSelApply.activated.connect(self.add_user_property)

        self.shortcutSelApply = QShortcut(QKeySequence(Qt.ALT + Qt.Key_Delete),
                                          self)
        self.shortcutSelApply.activated.connect(self.remove_user_property)

        self.shortcutSelApply = QShortcut(QKeySequence(Qt.ALT + Qt.Key_R),
                                          self)
        self.shortcutSelApply.activated.connect(self.rename_user_property)

        #----------------------------------------------------

        self.Splitter = QSplitter(self)
        self.Splitter.addWidget(self.CmpTabBox)
        self.Splitter.addWidget(self.SelectorBox)
        self.Splitter.addWidget(self.InspectorBox)

        self.centralWidget().layout().addWidget(self.Splitter)

        #----------------------------------------------------
        #
        #     Signals and Slots connections
        #
        self.CmpTable.cells_chosen.connect(self.Inspector.load_cmp)
        self.CmpTable.cells_chosen.connect(self.Selector.comp_template_slot)
        self.CmpTable.file_load.connect(self.file_loaded_slot)
        self.CmpTable.cmps_updated.connect(self.Selector.process_comps_slot)
        self.CmpTable.cmps_selected.connect(self.set_status_text_slot)

        self.SelApplyButton.clicked.connect(self.Selector.apply_slot)
        self.SelClearButton.clicked.connect(self.Selector.clear_slot)
        self.SelTemplateButton.clicked.connect(
            self.Selector.use_comp_as_template_slot)

        self.Selector.select_comps_signal.connect(
            self.CmpTable.select_comps_slot)

        self.Inspector.load_field.connect(self.FieldInspector.load_field_slot)
        self.Inspector.update_comps.connect(self.data_changed_slot)
        self.Inspector.update_comps.connect(self.CmpTable.update_cmp_list_slot)
        self.FieldInspector.data_changed.connect(self.data_changed_slot)
        CmpMgr.file_saved.connect(self.file_saved_slot)

        self.CmpTable.mouse_click.connect(self.mouse_change_tool)
        self.Inspector.mouse_click.connect(self.mouse_change_tool)
        self.FieldInspector.mouse_click.connect(self.mouse_change_tool)

        self.Inspector.header().sectionResized.connect(
            self.FieldInspector.column_resize)

        self.AddUserProperty.clicked.connect(self.add_user_property)
        self.DeleteUserProperty.clicked.connect(self.remove_user_property)
        self.RenameUserProperty.clicked.connect(self.rename_user_property)

        #----------------------------------------------------
        self.ToolList = []
        self.ToolList.append(self.CmpTable)
        self.ToolList.append(self.Selector)
        self.ToolList.append(self.Inspector)
        self.ToolList.append(self.FieldInspector)
        self.ToolIndex = 0

        #----------------------------------------------------
        #
        #    Window
        #
        self.setWindowTitle(self.PROGRAM_NAME)
        Settings = QSettings('kicad-tools', 'Schematic Component Manager')
        #print(Settings.allKeys())
        if Settings.contains('geometry'):
            self.restoreGeometry(Settings.value('geometry'))
        else:
            self.setGeometry(100, 100, 1024, 768)

        if Settings.contains('cmptable'):
            w0, w1 = Settings.value('cmptable')
            self.CmpTable.setColumnWidth(0, int(w0))
            self.CmpTable.setColumnWidth(1, int(w1))

        if Settings.contains('selector'):
            w0, w1 = Settings.value('selector')
            self.Selector.setColumnWidth(0, int(w0))
            self.Selector.setColumnWidth(1, int(w1))

        if Settings.contains('inspector'):
            w0, w1 = Settings.value('inspector')
            self.Inspector.setColumnWidth(0, int(w0))
            self.Inspector.setColumnWidth(1, int(w1))
            self.FieldInspector.setColumnWidth(0, int(w0))
            self.FieldInspector.setColumnWidth(1, int(w1))
            #self.Inspector.setColumnWidth( 2, int(w2) )

        if Settings.contains('splitter'):
            self.Splitter.restoreState(Settings.value('splitter'))

        if Settings.contains('inssplitter'):
            self.InspectorSplit.restoreState(Settings.value('inssplitter'))

        #----------------------------------------------------
        #
        #    Process command line arguments
        #
        if len(sys.argv) > 1:
            fname = sys.argv[1]
            if os.path.exists(fname):
                self.CmpTable.load_file(fname)
            else:
                print('E: input file "' + fname + '"does not exist')

        self.show()

    #---------------------------------------------------------------------------
    def closeEvent(self, event):
        Settings = QSettings('kicad-tools', 'Schematic Component Manager')
        Settings.setValue('geometry', self.saveGeometry())
        Settings.setValue(
            'cmptable',
            [self.CmpTable.columnWidth(0),
             self.CmpTable.columnWidth(1)])
        Settings.setValue(
            'selector',
            [self.Selector.columnWidth(0),
             self.Selector.columnWidth(1)])
        Settings.setValue(
            'inspector',
            [self.Inspector.columnWidth(0),
             self.Inspector.columnWidth(1)])
        Settings.setValue('splitter', self.Splitter.saveState())
        Settings.setValue('inssplitter', self.InspectorSplit.saveState())
        QWidget.closeEvent(self, event)

    #---------------------------------------------------------------------------
    def open_file(self):
        #filename = QFileDialog.getOpenFileName(self, 'Open schematic file', '/opt/cad/kicad', 'KiCad Schematic Files (*.sch)')
        dialog = QFileDialog(self)
        dialog.setFileMode(QFileDialog.ExistingFile)
        dialog.setNameFilter('KiCad Schematic Files (*.sch)')

        filenames = []
        if dialog.exec_():
            filenames = dialog.selectedFiles()
        if len(filenames) == 0:
            return

        CmpMgr.set_curr_file_path(filenames[0])
        self.CmpTable.load_file(filenames[0])

    #---------------------------------------------------------------------------
    def save_file(self):
        self.FieldInspector.save_fields()
        self.Inspector.save_cmps()

        curr_file = CmpMgr.curr_file_path()
        message = 'Save File "' + curr_file + '"'
        print(message)
        self.statusBar().showMessage(message)

        CmpMgr.save_file(curr_file)

    #---------------------------------------------------------------------------
    def save_file_as(self):
        self.Inspector.save_cmps()
        self.FieldInspector.save_fields()
        filenames = QFileDialog.getSaveFileName(
            self, 'Save File As...', '', 'KiCad Schematic Files (*.sch)')

        if filenames[0] == '':
            return

        print('Save File As "' + filenames[0] + '"')
        CmpMgr.save_file(filenames[0])
        CmpMgr.set_curr_file_path(filenames[0])

    #---------------------------------------------------------------------------
    def file_loaded_slot(self):
        text = CmpMgr.curr_file_path()
        self.set_title(text)

    #---------------------------------------------------------------------------
    def data_changed_slot(self):
        text = CmpMgr.curr_file_path() + ' *'
        self.set_title(text)

    #---------------------------------------------------------------------------
    def file_saved_slot(self):
        text = CmpMgr.curr_file_path()
        self.set_title(text)

    #---------------------------------------------------------------------------
    def set_title(self, text=''):
        text = ' - ' + text if len(text) > 0 else ''
        self.setWindowTitle(self.PROGRAM_NAME + ' v' + VERSION + text)

    #---------------------------------------------------------------------------
    def set_status_text_slot(self, text):
        self.statusBar().showMessage(text)

    #---------------------------------------------------------------------------
    def edit_settings(self):
        print('edit settings')
        SettingsDialog = TSettingsDialog(self)
        SettingsDialog.resize(400, 400)
        SettingsDialog.Tabs.setMinimumWidth(800)
        SettingsDialog.show()

    #---------------------------------------------------------------------------
    def show_user_manual_slot(self):
        help = THelpForm(self, 'User\'s Manual', 'main.html')

    #---------------------------------------------------------------------------
    def show_setting_dialog_help_slot(self):
        help = THelpForm(self, 'Settings Dialog', 'settings.html')

    #---------------------------------------------------------------------------
    def show_hotkeys_help_slot(self):
        help = THelpForm(self, 'Hotkeys', 'hotkeys.html')
示例#46
0
class EditorWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.resize(settings().value("MainWindow/size") or QSize(1280, 720))
        self.setWindowTitle("untitled")
        if int(settings().value("MainWindow/maximized") or 0):
            self.showMaximized()

        self.setCentralWidget(QWidget())
        self.setMenuBar(QMenuBar())
        self.setStatusBar(QStatusBar())
        self.centralWidget().setLayout(QHBoxLayout())
        self.centralWidget().layout().setSpacing(0)
        self.centralWidget().layout().setContentsMargins(0, 0, 0, 0)

        self.splitter = QSplitter()
        self.centralWidget().layout().addWidget(self.splitter)

        self.projectTree = ProjectTree(self)
        # self.projectTree.hide()
        self.splitter.addWidget(self.projectTree)

        self.tabwidget = TabWidget(self)
        self.splitter.addWidget(self.tabwidget)

        self.splitter.setSizes((int(settings().value("Sizes/splitter0")
                                    or self.splitter.sizeHint().width() * .2),
                                int(settings().value("Sizes/splitter1")
                                    or self.splitter.sizeHint().width() * .8)))

        #menüler
        self.fileMenu = QMenu(self.tr("File"))
        self.newFileActionMenu = QMenu(self.tr("New"))
        self.newPlainFileAction = QAction(self.tr("File"),
                                          icon=QIcon(":/img/text-plain.svg"))
        self.newFileActionMenu.addAction(self.newPlainFileAction)
        self.newPythonFileAction = QAction(self.tr("Python File"),
                                           icon=QIcon(":/img/text-python.svg"))
        self.newFileActionMenu.addAction(self.newPythonFileAction)
        self.newDirectoryAction = QAction(self.tr("Directory"),
                                          icon=QIcon(":/img/folder.svg"))
        self.newFileActionMenu.addAction(self.newDirectoryAction)
        self.newPythonPackageAction = QAction(
            self.tr("Python Package"), icon=QIcon(":/img/folder-python.svg"))
        self.newFileActionMenu.addAction(self.newPythonPackageAction)
        self.newFileActionMenu.addSeparator()
        self.newHtmlFileAction = QAction(self.tr("Html File"),
                                         icon=QIcon(":/img/text-html.svg"))
        self.newFileActionMenu.addAction(self.newHtmlFileAction)
        self.newCssFileAction = QAction(self.tr("Css File"),
                                        icon=QIcon(":/img/text-css.svg"))
        self.newFileActionMenu.addAction(self.newCssFileAction)
        self.newJsFileAction = QAction(self.tr("JavaScript File"),
                                       icon=QIcon(":/img/text-javascript.svg"))
        self.newFileActionMenu.addAction(self.newJsFileAction)
        self.newJsonFileAction = QAction(self.tr("Json File"),
                                         icon=QIcon(":/img/text-plain.svg"))
        self.newFileActionMenu.addAction(self.newJsonFileAction)
        self.newXmlFileAction = QAction(self.tr("Xml File"),
                                        icon=QIcon(":/img/text-xml.svg"))
        self.newFileActionMenu.addAction(self.newXmlFileAction)
        self.newYamlFileAction = QAction(self.tr("Yaml File"),
                                         icon=QIcon(":/img/text-plain.svg"))
        self.newFileActionMenu.addAction(self.newYamlFileAction)
        self.newSqlFileAction = QAction(self.tr("Sqlite File"),
                                        icon=QIcon(":/img/text-sql.svg"))
        self.newFileActionMenu.addAction(self.newSqlFileAction)
        self.newMdFileAction = QAction(self.tr("Markdown File"),
                                       icon=QIcon(":/img/text-plain.svg"))
        self.newFileActionMenu.addAction(self.newMdFileAction)
        self.fileMenu.addMenu(self.newFileActionMenu)

        self.newProjectAction = QAction(self.tr("New Project"))
        self.fileMenu.addAction(self.newProjectAction)
        self.openFileAction = QAction(self.tr("Open File..."))
        self.openFileAction.setShortcut("Ctrl+O")
        self.fileMenu.addAction(self.openFileAction)
        self.openProjectAction = QAction(self.tr("Open Project..."))
        self.openProjectAction.setShortcut("Ctrl+Alt+O")
        self.fileMenu.addAction(self.openProjectAction)
        self.openRecentFileActionMenu = QMenu(self.tr("Open Recent..."))
        self.fileMenu.addMenu(self.openRecentFileActionMenu)
        self.saveFileAction = QAction(self.tr("Save"))
        self.saveFileAction.setShortcut("Ctrl+S")
        self.fileMenu.addAction(self.saveFileAction)
        self.saveAsAction = QAction(self.tr("Save As..."))
        self.saveAsAction.setShortcut("Ctrl+Alt+S")
        self.fileMenu.addAction(self.saveAsAction)
        self.fileMenu.addSeparator()
        self.closeFileAction = QAction(self.tr("Close File"))
        self.closeFileAction.setShortcut("Ctrl+W")
        self.fileMenu.addAction(self.closeFileAction)
        self.closeAllFilesAction = QAction(self.tr("Close All File"))
        self.fileMenu.addAction(self.closeAllFilesAction)
        self.fileMenu.addSeparator()
        self.exitAction = QAction(self.tr("Exit"))
        self.exitAction.setShortcut("Ctrl+Q")
        self.fileMenu.addAction(self.exitAction)
        self.menuBar().addMenu(self.fileMenu)

        self.editMenu = QMenu(self.tr("Edit"))
        self.undoAction = QAction(self.tr("Undo"))
        self.undoAction.setShortcut("Ctrl+Z")
        self.undoAction.setShortcutVisibleInContextMenu(True)
        self.editMenu.addAction(self.undoAction)
        self.redoAction = QAction(self.tr("Redo"))
        self.redoAction.setShortcut("Ctrl+Y")
        self.redoAction.setShortcutVisibleInContextMenu(True)
        self.editMenu.addAction(self.redoAction)
        self.editMenu.addSeparator()
        self.copyAction = QAction(self.tr("Copy"))
        self.copyAction.setShortcutVisibleInContextMenu(True)
        self.copyAction.setShortcut("Ctrl+C")
        self.editMenu.addAction(self.copyAction)
        self.cutAction = QAction(self.tr("Cut"))
        self.cutAction.setShortcut("Ctrl+X")
        self.cutAction.setShortcutVisibleInContextMenu(True)
        self.editMenu.addAction(self.cutAction)
        self.pasteAction = QAction(self.tr("Paste"))
        self.pasteAction.setShortcut("Ctrl+V")
        self.pasteAction.setShortcutVisibleInContextMenu(True)
        self.editMenu.addAction(self.pasteAction)
        self.editMenu.addSeparator()
        # self.wrapActionMenu = QMenu(self.tr("Wrap"))
        # self.editMenu.addMenu(self.wrapActionMenu)
        self.menuBar().addMenu(self.editMenu)

        self.findMenu = QMenu(self.tr("Find"))
        self.findAction = QAction(self.tr("Find..."))
        self.findAction.setShortcut("Ctrl+F")
        self.findMenu.addAction(self.findAction)
        self.findNextAction = QAction(self.tr("Find Next"))
        self.findNextAction.setShortcut("F3")
        self.findMenu.addAction(self.findNextAction)
        self.findPreviousAction = QAction(self.tr("Find Previous"))
        self.findPreviousAction.setShortcut("Shift+F3")
        self.findMenu.addAction(self.findPreviousAction)
        self.findMenu.addSeparator()
        self.replaceAction = QAction(self.tr("Replace"))
        self.replaceAction.setShortcut("Ctrl+H")
        self.findMenu.addAction(self.replaceAction)
        self.replaceNextAction = QAction(self.tr("Replace Next"))
        self.replaceNextAction.setShortcut("Ctrl+Shift+H")
        self.findMenu.addAction(self.replaceNextAction)
        self.menuBar().addMenu(self.findMenu)

        # self.viewMenu = QMenu(self.tr("View"))
        # self.layoutActionMenu = QMenu(self.tr("Layout"))
        # self.viewMenu.addMenu(self.layoutActionMenu)
        # self.groupsActionMenu = QMenu(self.tr("Groups"))
        # self.viewMenu.addMenu(self.groupsActionMenu)
        # self.focusGroupActionMenu = QMenu(self.tr("Focus Group"))
        # self.viewMenu.addMenu(self.focusGroupActionMenu)
        # self.moveFileGroupActionMenu = QMenu(self.tr("Move File to Group"))
        # self.viewMenu.addMenu(self.moveFileGroupActionMenu)
        # self.viewMenu.addSeparator()
        # self.syntaxActionMenu = QMenu(self.tr("Syntax"))
        # self.viewMenu.addMenu(self.syntaxActionMenu)
        # self.indentationActionMenu = QMenu(self.tr("Indentation"))
        # self.viewMenu.addMenu(self.indentationActionMenu)
        # self.lineEndingsActionMenu = QMenu(self.tr("Line Endings"))
        # self.viewMenu.addMenu(self.lineEndingsActionMenu)
        # self.viewMenu.addSeparator()
        # self.menuBar().addMenu(self.viewMenu)

        self.toolsMenu = QMenu(self.tr("Tools"))
        self.snippetsAction = QAction(self.tr("Snippets..."))
        self.toolsMenu.addAction(self.snippetsAction)
        self.toolsMenu.addSeparator()
        self.runAction = QAction(self.tr("Run"))
        self.runAction.setShortcut("F5")
        self.toolsMenu.addAction(self.runAction)
        self.runWithAction = QAction(self.tr("Run With..."))
        self.runWithAction.setShortcut("F6")
        self.toolsMenu.addAction(self.runWithAction)
        self.toolsMenu.addSeparator()
        self.recordMacroAction = QAction(self.tr("Record Macro"))
        self.toolsMenu.addAction(self.recordMacroAction)
        self.playbackMacroAction = QAction(self.tr("Playback Macro"))
        self.toolsMenu.addAction(self.playbackMacroAction)
        self.saveMacroAction = QAction(self.tr("Save Macro..."))
        self.toolsMenu.addAction(self.saveMacroAction)
        self.macrosActionMenu = QMenu(self.tr("Macros"))
        self.toolsMenu.addMenu(self.macrosActionMenu)
        self.menuBar().addMenu(self.toolsMenu)

        self.helpMenu = QMenu(self.tr("Help"))
        self.documentationAction = QAction(self.tr("Documentation"))
        self.helpMenu.addAction(self.documentationAction)
        self.donateAction = QAction(self.tr("Donate"))
        self.helpMenu.addAction(self.donateAction)
        self.helpMenu.addSeparator()
        self.checkAction = QAction(self.tr("Check for Updates..."))
        self.helpMenu.addAction(self.checkAction)
        self.changelogAction = QAction(self.tr("Changelog..."))
        self.helpMenu.addAction(self.changelogAction)
        self.aboutAction = QAction(self.tr("About Untitled Editor"))
        self.helpMenu.addAction(self.aboutAction)
        self.menuBar().addMenu(self.helpMenu)

    def setWindowTitle(self, title):
        super().setWindowTitle(title + " - " + "Untitled Editor")

    def closeEvent(self, *args, **kwargs):
        settings().setValue("Sizes/splitter0", self.projectTree.width())
        settings().setValue("Sizes/splitter1", self.tabwidget.width())
        settings().setValue("MainWindow/maximized", int(self.isMaximized()))
        settings().setValue("MainWindow/size", self.size())

        settings().sync()

    def retranslateui(self):
        pass
示例#47
0
class BrowserWindow(QMainWindow):
    class SavedWindow(object):
        def __init__(self, window=None):
            '''
            @param: window BrowserWindow
            '''
            self.windowState = QByteArray()
            self.windowGeometry = QByteArray()
            self.windowUiState = {}  # QString -> QVariant
            self.virtualDesktop = -1
            self.currentTab = -1
            self.tabs = []  # WebTab.SavedTab
            if window:
                self.init(window)

        def init(self, window):
            if window.isFullScreen():
                self.windowState = QByteArray()
            else:
                self.windowState = window.saveState()
            self.windowGeometry = window.saveGeometry()
            self.windowUiState = window._saveUiState()

            tabsCount = window.tabCount()
            for idx in range(tabsCount):
                # TabbedWebView
                webView = window.weView(idx)
                if not webView:
                    continue
                webTab = webView.webTab()
                if not webTab:
                    continue
                tab = WebTab.SavedTab(webTab)
                if not tab.isValid():
                    continue
                if webTab.isCurrentTab():
                    self.currentTab = len(self.tabs)
                self.tabs.append(tab)

        def isValid(self):
            for tab in self.tabs:
                if not tab.isValid():
                    return False
            return self.currentTab > -1

        def clear(self):
            self.windowState.clear()
            self.windowGeometry.clear()
            self.virtualDesktop = -1
            self.currentTab = -1
            self.tabs.clear()

    def __init__(self, type_, startUrl=QUrl()):
        super().__init__(None)
        self._startUrl = startUrl
        self._homepage = QUrl()
        self._windowType = type_
        self._startTab = None  # WebTab
        self._startPage = None  # WebPage
        self._mainLayout = None  # QVBoxLayout
        self._mainSplitter = None  # QSplitter
        self._tabWidget = None  # TabWidget
        self._sideBar = None  # QPointer<SideBar>
        self._sideBarManager = SideBarManager(self)
        self._statusBar = None

        self._navigationContainer = None  # NavigationContainer
        self._navigationToolbar = None  # NavigationBar
        self._bookmarksToolbar = None  # BookmarksToolbar

        self._progressBar = None  # ProgressBar
        self._ipLabel = None  # QLabel
        self._superMenu = None  # QMenu
        self._mainMenu = None  # MainMenu

        self._tabModel = None  # TabModel
        self._tabMruModel = None  # TabMruModel

        self._sideBarWidth = 0
        self._webViewWidth = 0

        # Shortcuts
        self._useTabNumberShortcuts = False
        self._useSpeedDialNumberShortcuts = False
        self._useSingleKeyShortcuts = False

        # Remember visibility of menubar and statusbar after entering Fullscreen
        self._menuBarVisible = False
        self._statusBarVisible = False
        self._htmlFullScreenView = None  # TabbedWebView
        self._hideNavigationTimer = None  # QTimer

        self._deleteOnCloseWidgets = []  # QList<QPointer<QWidget>>

        self.setAttribute(Qt.WA_DeleteOnClose)
        self.setAttribute(Qt.WA_DontCreateNativeAncestors)

        self.setObjectName('mainwindow')
        self.setWindowTitle(const.APPNAME)
        self.setProperty('private', gVar.app.isPrivate())

        self._setupUi()
        self._setupMenu()

        self._hideNavigationTimer = QTimer(self)
        self._hideNavigationTimer.setInterval(1000)
        self._hideNavigationTimer.setSingleShot(True)
        self._hideNavigationTimer.timeout.connect(self._hideNavigationSlot)

        gVar.app.settingsReloaded.connect(self._loadSettings)

        QTimer.singleShot(0, self._postLaunch)

        if gVar.app.isPrivate():
            gVar.appTools.setWmClass(
                '%s Browser (Private Window)' % const.APPNAME, self)
        else:
            gVar.appTools.setWmClass('%s Browser' % const.APPNAME, self)

    def __del__(self):
        gVar.app.plugins().emitMainWindowDeleted(self)
        for widget in self._deleteOnCloseWidgets:
            widget.deleteLater()

    def setStartTab(self, tab):
        '''
        @param: tab WebTab
        '''
        self._startTab = tab

    def setStartPage(self, page):
        '''
        @param: page WebPage
        '''
        self._startPage = page

    def restoreWindow(self, window):
        '''
        @param: window SavedWindow
        '''
        self.restoreState(window.windowState)
        self.restoreGeometry(window.windowGeometry)
        self._restoreUiState(window.windowUiState)
        if not gVar.app.isTestModeEnabled():
            self.show(
            )  # Window has to be visible before adding QWebEngineView's
        self._tabWidget.restoreState(window.tabs, window.currentTab)
        self._updateStartupFocus()

    def fullScreenNavigationVisible(self):
        return self._navigationContainer.isVisible()

    def showNavigationWithFullScreen(self):
        if self._htmlFullScreenView:
            return
        if self._hideNavigationTimer.isActive():
            self._hideNavigationTimer.stop()
        self._navigationContainer.show()

    def hideNavigationWithFullScreen(self):
        if self._tabWidget.isCurrentTabFresh():
            return
        if not self._hideNavigationTimer.isActive():
            self._hideNavigationTimer.start()

    def currentTabChanged(self):
        view = self.weView()
        self._navigationToolbar.setCurrentView(view)
        if not view:
            return

        title = view.webTab().title(True)  # allowEmpty
        if not title:
            self.setWindowTitle(const.APPNAME)
        else:
            self.setWindowTitle('%s - %s' % (title, const.APPNAME))
        self._ipLabel.setText(view.getIp())
        view.setFocus()

        self.updateLoadingActions()

        # Settings correct tab order (LocationBar -> WebSearchBar -> WebView)
        self.setTabOrder(self.locationBar(),
                         self._navigationToolbar.webSearchBar())
        self.setTabOrder(self._navigationToolbar.webSearchBar(), view)

    def updateLoadingActions(self):
        view = self.weView()
        if not view:
            return

        isLoading = view.isLoading()
        self._ipLabel.setVisible(not isLoading)
        self._progressBar.setVisible(isLoading)
        self.action('View/Stop').setEnabled(isLoading)
        self.action('View/Reload').setEnabled(not isLoading)

        if isLoading:
            self._progressBar.setValue(view.loadingProgress())
            self._navigationToolbar.showStopButton()
        else:
            self._navigationToolbar.showReloadButton()

    def addBookmark(self, url, title):
        BookmarksTools.addBookmarkDilaog(self, url, title)

    def addDeleteOnCloseWidget(self, widget):
        '''
        @param: widget QWidget
        '''
        if widget not in self._deleteOnCloseWidgets:
            self._deleteOnCloseWidgets.append(widget)

    def createToolbarsMenu(self, menu):
        self.removeActions(menu.actions())
        menu.clear()

        action = menu.addAction('&Menu Bar', self.toggleShowMenubar)
        action.setCheckable(True)
        action.setChecked(self.menuBar().isVisible())

        action = menu.addAction('&Navigation Toolbar',
                                self.toggleShowNavigationToolbar)
        action.setCheckable(True)
        action.setChecked(self._navigationToolbar.isVisible())

        action = menu.addAction('&Bookmarks Toolbar',
                                self.toggleShowBookmarksToolbar)
        action.setCheckable(True)
        action.setChecked(Settings().value(
            'Browser-View-Settings/showBookmarksToolbar', True))

        menu.addSeparator()

        action = menu.addAction('&Tabs on Top', self.toggleTabsOnTop)
        action.setCheckable(True)
        action.setChecked(gVar.appSettings.tabsOnTop)

        self.addActions(menu.actions())

    def createSidebarsMenu(self, menu):
        self._sideBarManager.createMenu(menu)

    def createEncodingMenu(self, menu):
        isoCodecs = []
        utfCodecs = []
        windowsCodecs = []
        isciiCodecs = []
        ibmCodecs = []
        otherCodecs = []
        allCodecs = []

        for mib in QTextCodec.availableMibs():
            codecName = QTextCodec.codecForMib(mib).name()
            codecName = codecName.data().decode('utf8')
            if codecName in allCodecs:
                continue
            allCodecs.append(codecName)
            if codecName.startswith('ISO'):
                isoCodecs.append(codecName)
            elif codecName.startswith('UTF'):
                utfCodecs.append(codecName)
            elif codecName.startswith('windows'):
                windowsCodecs.append(codecName)
            elif codecName.startswith('Iscii'):
                isciiCodecs.append(codecName)
            elif codecName.startswith('IBM'):
                ibmCodecs.append(codecName)
            else:
                otherCodecs.append(codecName)

        if not menu.isEmpty():
            menu.addSeperator()

        self._createEncodingSubMenu('ISO', isoCodecs, menu)
        self._createEncodingSubMenu('UTF', utfCodecs, menu)
        self._createEncodingSubMenu('Windows', windowsCodecs, menu)
        self._createEncodingSubMenu('Iscii', isciiCodecs, menu)
        self._createEncodingSubMenu('IBM', ibmCodecs, menu)
        self._createEncodingSubMenu('Other', otherCodecs, menu)

    def removeActions(self, actions):
        '''
        @param: actions QList<QAction*>
        '''
        for action in actions:
            self.removeAction(action)

    def addSideBar(self):
        '''
        @return SideBar*
        '''
        if self._sideBar:
            return self._sideBar
        self._sideBar = SideBar(self._sideBarManager, self)
        self._mainSplitter.insertWidget(0, self._sideBar)
        self._mainSplitter.setCollapsible(0, False)
        self._mainSplitter.setSizes([self._sideBarWidth, self._webViewWidth])
        return self._sideBar

    def setSideBarNone(self):
        '''
        @note: when sideBar is notified destroyed, we should clean python ref in
        window
        '''
        self._sideBar = None

    def saveSideBarSettings(self):
        if self._sideBar:
            # That +1 is important here, without it, the sidebar width would
            # decrease by 1 pixel every close
            self._sideBarWidth = self._mainSplitter.sizes()[0] + 1
            self._webViewWidth = self.width() - self._sideBarWidth
        Settings().setValue('Browser-View-Settings/SideBar',
                            self._sideBarManager.activeSideBar())

    def tabCount(self):
        return self._tabWidget.count()

    def weView(self, index=None):
        '''
        @return TabbedWebView
        '''

        if index is None:
            index = self._tabWidget.currentIndex()
        webTab = self._tabWidget.widget(index)
        if not webTab:
            return None
        return webTab.webView()

    def windowType(self):
        '''
        @return const.BrowserWindowType
        '''
        return self._windowType

    def locationBar(self):
        '''
        @return LocationBar
        '''
        return self._tabWidget.locationBars().currentWidget()

    def tabWidget(self):
        return self._tabWidget

    def bookmarksToolbar(self):
        '''
        @return BookmarksToolbar
        '''
        return self._bookmarksToolbar

    def statusBar(self):
        '''
        @return StatusBar
        '''
        return self._statusBar

    def navigationBar(self):
        '''
        @return NavigationBar
        '''
        return self._navigationToolbar

    def sideBarManager(self):
        '''
        @return SideBarManager
        '''
        return self._sideBarManager

    def ipLabel(self):
        '''
        @return QLabel
        '''
        return self._ipLabel

    def superMenu(self):
        '''
        @return QMenu
        '''
        return self._superMenu

    def homepageUrl(self):
        return self._homepage

    def action(self, name):
        '''
        @return QAction
        '''
        return self._mainMenu.action(name)

    def tabModel(self):
        '''
        @return TabModel
        '''
        return self._tabModel

    def tabMruModel(self):
        '''
        @return TabMruModel
        '''
        return self._tabMruModel

    # public Q_SIGNALS:
    startingCompleted = pyqtSignal()
    aboutToClose = pyqtSignal()

    # public Q_SLOTS:
    def addTab(self):
        self._tabWidget.addViewByUrl(QUrl(), const.NT_SelectedNewEmptyTab,
                                     True)
        self._tabWidget.setCurrentTabFresh(True)

        if self.isFullScreen():
            self.showNavigationWithFullScreen()

    def goHome(self):
        self.loadAddress(self._homepage)

    def goHomeInNewTab(self):
        self._tabWidget.addViewByUrl(self._homepage, const.NT_SelectedTab)

    def goBack(self):
        self.weView().back()

    def goForward(self):
        self.weView().forward()

    def reload(self):
        self.weView().reload()

    def reloadBypassCache(self):
        self.weView().reloadBypassCache()

    def setWindowTitle(self, title):
        if gVar.app.isPrivate():
            title = '%s (Private Browsing)' % title
        super().setWindowTitle(title)

    def showWebInspector(self):
        webView = self.weView()
        if webView and webView.webTab():
            webView.webTab().showWebInspector()

    def toggleWebInspector(self):
        webView = self.weView()
        if webView and webView.webTab():
            webView.webTab().toggleWebInspector()

    def showHistoryManager(self):
        gVar.app.browsingLibrary().showHistory(self)

    def toggleShowMenubar(self):
        self.setUpdatesEnabled(False)
        menuBar = self.menuBar()
        menuBar.setVisible(not menuBar.isVisible())
        self._navigationToolbar.setSuperMenuVisible(not menuBar.isVisible())
        self.setUpdatesEnabled(True)

        Settings().setValue('Browser-View-Settings/showMenuBar',
                            menuBar.isVisible())

        # Make sure we show Navigation Toolbar when Menu Bar is hidden
        if not self._navigationToolbar.isVisible() and not menuBar.isVisible():
            self.toggleShowNavigationToolbar()

    def toggleShowStatusBar(self):
        self.setUpdatesEnabled(False)
        self._statusBar.setVisible(not self._statusBar.isVisible())
        self.setUpdatesEnabled(True)
        Settings().setValue('Browser-View-Settings/showStatusBar',
                            self._statusBar.isVisible())

    def toggleShowBookmarksToolbar(self):
        self.setUpdatesEnabled(False)
        self._bookmarksToolbar.setVisible(
            not self._bookmarksToolbar.isVisible())
        self.setUpdatesEnabled(True)
        Settings().setValue('Browser-View-Settings/showBookmarksToolbar',
                            self._bookmarksToolbar.isVisible())
        Settings().setValue('Browser-View-Settings/instantBookmarksToolbar',
                            False)

    def toggleShowNavigationToolbar(self):
        self.setUpdatesEnabled(False)
        self._navigationToolbar.setVisible(
            not self._navigationToolbar.isVisible())
        self.setUpdatesEnabled(True)
        Settings().setValue('Browser-View-Settings/showNavigationToolbar',
                            self._navigationToolbar.isVisible())

        # Make sure we show Navigation Toolbar when Menu Bar is hidden
        if not self._navigationToolbar.isVisible() and not self.menuBar(
        ).isVisible():
            self.toggleShowMenubar()

    def toggleTabsOnTop(self, enable):
        gVar.appSettings.tabsOnTop = enable
        self._navigationContainer.toggleTabsOnTop(enable)

    def toggleFullScreen(self):
        if self._htmlFullScreenView:
            self.weView().triggerPageAction(QWebEnginePage.ExitFullScreen)
            return
        if self.isFullScreen():
            self.setWindowState(self.windowState() & ~Qt.WindowFullScreen)
        else:
            self.setWindowState(self.windowState() | Qt.WindowFullScreen)

    def requestHtmlFullScreen(self, view, enable):
        '''
        @param: view TabbedWebView
        @param: enable bool
        '''
        if enable:
            self.setWindowState(self.windowState() | Qt.WindowFullScreen)
        else:
            self.setWindowState(self.windowState() & ~Qt.WindowFullScreen)
        if self._sideBar:
            self._sideBar.setHidden(enable)
        self._htmlFullScreenView = enable and view or None

    def loadActionUrl(self, obj=None):
        if not obj:
            obj = self.sender()
        action = obj
        if isinstance(action, QAction):
            self.loadAddress(action.data().toUrl())

    def loadActionUrlInNewTab(self, obj=None):
        if not obj:
            obj = self.sender()
        action = obj
        if isinstance(action, QAction):
            self.loadAddress(action.data().toUrl(),
                             const.NT_SelectedTabAtTheEnd)

    def bookmarkPage(self):
        view = self.weView()
        BookmarksTools.addBookmarkDialog(self, view.url(), view.title())

    def bookmarkAllTabs(self):
        BookmarksTools.bookmarkAllTabsDialog(self, self._tabWidget)

    def loadAddress(self, url):
        webView = self.weView()
        if webView.webTab().isPinned():
            index = self._tabWidget.addViewByUrl(
                url, gVar.appSettings.newTabPosition)
            self.weView(index).setFocus()
        else:
            webView.setFocus()
            webView.loadByReq(LoadRequest(url))

    def showSource(self, view=None):
        if not view:
            view = self.weView()
        if not view:
            return
        view.showSource()

    # private Q_SLOTS:
    def _openLocation(self):
        if self.isFullScreen():
            self.showNavigationWithFullScreen()
        self.locationBar().setFocus()
        self.locationBar().selectAll()

    def _openFile(self):
        fileTypes = ("%s(*.html *.htm *.shtml *.shtm *.xhtml);;"
                     "%s(*.png *.jpg *.jpeg *.bmp *.gif *.svg *.tiff);;"
                     "%s(*.txt);;"
                     "%s(*.*)")
        fileTypes %= ("HTML files", "Image files", "Text files", "All files")
        filePath = gVar.appTools.getOpenFileName("MainWindow-openFile",
                                                 self, "Open file...",
                                                 QDir.homePath(), fileTypes)

        if filePath:
            self.loadAddress(QUrl.fromLocalFile(filePath))

    def _closeWindow(self):
        if const.OS_MAC:
            self.close()
            return
        if gVar.app.windowCount() > 1:
            self.close()

    def _closeTab(self):
        # Don't close pinned tabs with keyboard shortcuts (Ctrl+w, Ctrl+F4)
        webView = self.weView()
        if webView and not webView.webTab().isPinned():
            self._tabWidget.requestCloseTab()

    def _loadSettings(self):
        settings = Settings()
        # Url settings
        settings.beginGroup('Web-URL-Settings')
        self._homepage = settings.value('homepage', 'app:start', type=QUrl)
        settings.endGroup()
        # Browser Window settings
        settings.beginGroup('Browser-View-Settings')
        showStatusBar = settings.value('showStatusBar', False)
        showBookmarksToolbar = settings.value('showBookmarksToolbar', False)
        showNavigationToolbar = settings.value('showNavigationToolbar', True)
        showMenuBar = settings.value('showMenuBar', False)
        # Make sure both menubar and navigationbar are not hidden
        if not showNavigationToolbar:
            showMenuBar = True
            settings.setValue('showMenubar', True)
        settings.endGroup()

        settings.beginGroup('Shortcuts')
        self._useTabNumberShortcuts = settings.value('useTabNumberShortcuts',
                                                     True)
        self._useSpeedDialNumberShortcuts = settings.value(
            'useSpeedDialNumberShortcuts', True)
        self._useSingleKeyShortcuts = settings.value('useSingleKeyShortcuts',
                                                     False)
        settings.endGroup()

        settings.beginGroup('Web-Browser-Settings')
        quitAction = self._mainMenu.action('Standard/Quit')
        if settings.value('closeAppWithCtrlQ', True):
            quitAction.setShortcut(
                gVar.appTools.actionShortcut(QKeySequence.Quit,
                                             QKeySequence('Ctrl+Q')))
        else:
            quitAction.setShortcut(QKeySequence())
        settings.endGroup()

        self._statusBarVisible = showStatusBar
        self.statusBar().setVisible(not self.isFullScreen() and showStatusBar)
        self._bookmarksToolbar.setVisible(showBookmarksToolbar)
        self._navigationToolbar.setVisible(showNavigationToolbar)
        if not const.OS_MACOS:
            self._menuBarVisible = showMenuBar
            self.menuBar().setVisible(not self.isFullScreen() and showMenuBar)
        showSuperMenu = self.isFullScreen() or not showMenuBar
        # TODO: debug code
        showSuperMenu = True
        self._navigationToolbar.setSuperMenuVisible(showSuperMenu)

    def _postLaunch(self):  # noqa C901
        self._loadSettings()
        addTab = True
        startUrl = QUrl()

        from .MainApplication import MainApplication
        afterLaunch = gVar.app.afterLaunch()
        if afterLaunch == MainApplication.OpenBlankPage:
            startUrl = QUrl()
        elif afterLaunch == MainApplication.OpenSpeedDial:
            startUrl = QUrl('app:speeddial')
        elif afterLaunch in (MainApplication.OpenHomePage,
                             MainApplication.RestoreSession,
                             MainApplication.SelectSession):
            startUrl = QUrl(self._homepage)

        if not gVar.app.isTestModeEnabled():
            self.show()

        if self._windowType == const.BW_FirstAppWindow:
            if gVar.app.isStartingAfterCrash():
                addTab = False
                startUrl.clear()
                self._tabWidget.addViewByUrl(QUrl('app:restore'),
                                             const.NT_CleanSelectedTabAtTheEnd)
            elif afterLaunch in (MainApplication.SelectSession,
                                 MainApplication.RestoreSession):
                addTab = self._tabWidget.count() <= 0
        elif self._windowType in (const.BW_NewWindow, const.BW_MacFirstWindow):
            addTab = True
        elif self._windowType == const.BW_OtherRestoredWindow:
            addTab = False

        if not self._startUrl.isEmpty():
            startUrl = QUrl(self._startUrl)
            addTab = True
        if self._startTab:
            addTab = False
            self._tabWidget.addViewByTab(self._startTab, const.NT_SelectedTab)
        if self._startPage:
            addTab = False
            self._tabWidget.addViewByUrl(QUrl())
            self.weView().setPage(self._startPage)
        if addTab:
            self._tabWidget.addViewByUrl(startUrl,
                                         const.NT_CleanSelectedTabAtTheEnd)
            if not startUrl or startUrl == 'app:speeddial':
                self.locationBar().setFocus()
        # Someting went really wrong .. add one tab
        if self._tabWidget.count() <= 0:
            self._tabWidget.addViewByUrl(self._homepage,
                                         const.NT_SelectedTabAtTheEnd)

        gVar.app.plugins().emitMainWindowCreated(self)
        self.startingCompleted.emit()

        self.raise_()
        self.activateWindow()
        self._updateStartupFocus()

    def _webSearch(self):
        self._navigationToolbar.webSearchBar().setFocus()
        self._navigationToolbar.webSearchBar().selectAll()

    def _searchOnPage(self):
        webView = self.weView()
        if webView and webView.webTab():
            searchText = webView.page().selectedText()
            if '\n' not in searchText:
                webView.webTab().showSearchToolBar(searchText)
            else:
                webView.webTab().showSearchToolBar()

    def _changeEncoding(self):
        action = self.sender()
        if action:
            encoding = action.data()
            gVar.app.webSettings().setDefaultTextEncoding(encoding)
            Settings().setValue('Web-Browser-Settings/DefaultEncoding',
                                encoding)
            self.weView().reload()

    def _printPage(self):
        self.weView().printPage()

    def _saveSettings(self):
        if gVar.app.isPrivate():
            return
        settings = Settings()
        settings.beginGroup('Browser-View-Settings')
        settings.setValue('WindowGeometry', self.saveGeometry())

        state = self._saveUiState()
        for key, val in state.items():
            settings.setValue(key, val)

        settings.endGroup()

    def _hideNavigationSlot(self):
        view = self.weView()
        mouseInView = view and view.underMouse()
        if self.isFullScreen() and mouseInView:
            self._navigationContainer.hide()

    # private
    # override
    def event(self, event):
        '''
        @param: event QEvent
        '''
        if event.type() == QEvent.WindowStateChange:
            e = event
            assert (isinstance(e, QWindowStateChangeEvent))
            if not (e.oldState() & Qt.WindowFullScreen) and (
                    self.windowState() & Qt.WindowFullScreen):
                # Enter fullscreen
                self._statusBarVisible = self._statusBar.isVisible()
                if not const.OS_MACOS:
                    self._menuBarVisible = self.menuBar().isVisible()
                    self.menuBar().hide()
                self._statusBar.hide()

                self._navigationContainer.hide()
                self._navigationToolbar.enterFullScreen()

                # Show main menu button since menubar is hidden
                self._navigationToolbar.setSuperMenuVisible(True)
            elif (e.oldState() & Qt.WindowFullScreen
                  ) and not (self.windowState() & Qt.WindowFullScreen):
                # Leave fullscreen
                self._statusBar.setVisible(self._statusBarVisible)
                if not const.OS_MACOS:
                    self.menuBar().setVisible(self._menuBarVisible)

                self._navigationContainer.show()
                self._navigationToolbar.setSuperMenuVisible(
                    not self._menuBarVisible)
                self._navigationToolbar.leaveFullScreen()
                self._htmlFullScreenView = None

            if self._hideNavigationTimer:
                self._hideNavigationTimer.stop()

        return super().event(event)

    # override
    def resizeEvent(self, event):
        '''
        @param: event QResizeEvent
        '''
        self._bookmarksToolbar.setMaximumWidth(self.width())
        super().resizeEvent(event)

    # override
    def keyPressEvent(self, event):  # noqa C901
        '''
        @param: event QKeyEvent
        '''
        if gVar.app.plugins().processKeyPress(const.ON_BrowserWindow, self,
                                              event):
            return

        number = -1
        # TabbedWebView
        view = self.weView()
        evtKey = event.key()

        if evtKey == Qt.Key_Back:
            if view:
                view.back()
                event.accept()

        elif evtKey == Qt.Key_Forward:
            if view:
                view.forward()
                event.accept()

        elif evtKey == Qt.Key_Stop:
            if view:
                view.stop()
                event.accept()

        elif evtKey in (Qt.Key_Reload, Qt.Key_Refresh):
            if view:
                view.reload()
                event.accept()

        elif evtKey == Qt.Key_HomePage:
            self.goHome()
            event.accept()

        elif evtKey == Qt.Key_Favorites:
            gVar.app.browsingLibrary().showBookmarks(self)
            event.accept()

        elif evtKey == Qt.Key_Search:
            self.searchOnPage()
            event.accept()

        elif evtKey in (Qt.Key_F6, Qt.Key_OpenUrl):
            self.openLocation()
            event.accept()

        elif evtKey == Qt.Key_History:
            self.showHistoryManager()
            event.accept()

        elif evtKey == Qt.Key_AddFavorite:
            self.bookmarkPage()
            event.accept()

        elif evtKey == Qt.Key_News:
            self.action("Tools/RssReader").trigger()
            event.accept()

        elif evtKey == Qt.Key_Tools:
            self.action("Standard/Preferences").trigger()
            event.accept()

        elif evtKey == Qt.Key_Tab:
            if event.modifiers() == Qt.ControlModifier:
                self._tabWidget.event(event)

        elif evtKey == Qt.Key_Backtab:
            if event.modifiers() == Qt.ControlModifier + Qt.ShiftModifier:
                self._tabWidget.event(event)

        elif evtKey == Qt.Key_PageDown:
            if event.modifiers() == Qt.ControlModifier:
                self._tabWidget.nextTab()
                event.accept()

        elif evtKey == Qt.Key_PageUp:
            if event.modifiers() == Qt.ControlModifier:
                self._tabWidget.previousTab()
                event.accept()

        elif evtKey == Qt.Key_Equal:
            if view and event.modifiers() == Qt.ControlModifier:
                view.zoomIn()
                event.accept()

        elif evtKey == Qt.Key_I:
            if event.modifiers() == Qt.ControlModifier:
                self.action("Tools/SiteInfo").trigger()
                event.accept()

        elif evtKey == Qt.Key_U:
            if event.modifiers() == Qt.ControlModifier:
                self.action("View/PageSource").trigger()
                event.accept()

        elif evtKey == Qt.Key_F:
            if event.modifiers() == Qt.ControlModifier:
                self.action("Edit/Find").trigger()
                event.accept()

        elif evtKey == Qt.Key_Slash:
            if self._useSingleKeyShortcuts:
                self.action("Edit/Find").trigger()
                event.accept()

        elif evtKey == Qt.Key_1:
            number = 1
        elif evtKey == Qt.Key_2:
            number = 2
        elif evtKey == Qt.Key_3:
            number = 3
        elif evtKey == Qt.Key_4:
            number = 4
        elif evtKey == Qt.Key_5:
            number = 5
        elif evtKey == Qt.Key_6:
            number = 6
        elif evtKey == Qt.Key_7:
            number = 7
        elif evtKey == Qt.Key_8:
            number = 8
        elif evtKey == Qt.Key_9:
            number = 9

        if number != -1:
            modifiers = event.modifiers()
            if modifiers & Qt.AltModifier and self._useTabNumberShortcuts:
                if number == 9:
                    number = self._tabWidget.count()
                self._tabWidget.setCurrentIndex(number - 1)
                event.accept()
                return
            if modifiers & Qt.ControlModifier and self._useSpeedDialNumberShortcuts:
                # QUrl
                url = gVar.app.plugins().speedDial().urlForShortcut(number - 1)
                if url.isValid():
                    self.loadAddress(url)
                    event.accept()
                    return
            if modifiers == Qt.NoModifier and self._useSingleKeyShortcuts:
                if number == 1:
                    self._tabWidget.previousTab()
                if number == 2:
                    self._tabWidget.nextTab()

        super().keyPressEvent(event)

    # override
    def keyReleaseEvent(self, event):
        '''
        @param: event QKeyEvent
        '''
        if gVar.app.plugins().processKeyRelease(const.ON_BrowserWindow, self,
                                                event):
            return

        evtKey = event.key()
        if evtKey == Qt.Key_F:
            if event.modifiers() == Qt.ControlModifier:
                self.action('Edit/Find').trigger()
                event.accept()

        super().keyReleaseEvent(event)

    # override
    def closeEvent(self, event):
        '''
        @param: event QCloseEvent
        '''
        if gVar.app.isClosing():
            self._saveSettings()
            return
        settings = Settings()
        askOnClose = settings.value('Browser-Tabs-Settings/AskOnClosing', True)

        from .MainApplication import MainApplication
        if gVar.app.afterLaunch() in (MainApplication.SelectSession,
                                      MainApplication.RestoreSession
                                      ) and gVar.app.windowCount() == 1:
            askOnClose = False

        if askOnClose and self._tabWidget.normalTabsCount() > 1:
            dialog = CheckBoxDialog(QMessageBox.Yes | QMessageBox.No, self)
            dialog.setDefaultButton(QMessageBox.No)
            dialog.setText(
                "There are still %s open tabs and your session won't be stored.\n"
                % self._tabWidget.count() +
                "Are you sure you want to close this window?")
            dialog.setCheckBoxText("Don't ask again")
            dialog.setWindowTitle('There are still open tabs')
            dialog.setIcon(QMessageBox.Warning)
            if dialog.exec_() != QMessageBox.Yes:
                event.ignore()
                return
            if dialog.isChecked():
                settings.setValue('Browser-Tabs-Settings/AskOnClosing', False)

        self.aboutToClose.emit()

        self._saveSettings()
        gVar.app.closedWindowsManager().saveWindow(self)
        if gVar.app.windowCount() == 1:
            gVar.app.quitApplication()

        event.accept()

    # == private ==
    def _setupUi(self):
        settings = Settings()
        settings.beginGroup('Browser-View-Settings')
        windowGeometry = settings.value('WindowGeometry', b'')

        keys = [
            ('LocationBarWidth', int),
            ('WebSearchBarWidth', int),
            ('SideBarWidth', int),
            ('WebViewWidth', int),
            ('SideBar', str),
        ]

        uiState = {}
        for key, typ in keys:
            if settings.contains(key):
                uiState[key] = typ(settings.value(key))

        settings.endGroup()

        widget = QWidget(self)
        widget.setCursor(Qt.ArrowCursor)
        self.setCentralWidget(widget)

        self._mainLayout = QVBoxLayout(widget)
        self._mainLayout.setContentsMargins(0, 0, 0, 0)
        self._mainLayout.setSpacing(0)
        self._mainSplitter = QSplitter(self)
        self._mainSplitter.setObjectName('sidebar-splitter')
        self._tabWidget = TabWidget(self)
        self._superMenu = QMenu(self)
        self._navigationToolbar = NavigationBar(self)
        self._bookmarksToolbar = BookmarksToolbar(self)

        self._tabModel = TabModel(self, self)
        self._tabMruModel = TabMruModel(self, self)
        self._tabMruModel.setSourceModel(self._tabModel)

        self._navigationContainer = NavigationContainer(self)
        self._navigationContainer.addWidget(self._navigationToolbar)
        self._navigationContainer.addWidget(self._bookmarksToolbar)
        self._navigationContainer.setTabBar(self._tabWidget.tabBar())

        self._mainSplitter.addWidget(self._tabWidget)
        self._mainSplitter.setCollapsible(0, False)

        self._mainLayout.addWidget(self._navigationContainer)
        self._mainLayout.addWidget(self._mainSplitter)

        self._statusBar = StatusBar(self)
        self._statusBar.setObjectName('mainwindow-statusbar')
        self._statusBar.setCursor(Qt.ArrowCursor)
        self.setStatusBar(self._statusBar)
        self._progressBar = ProgressBar(self._statusBar)
        self._ipLabel = QLabel(self)
        self._ipLabel.setObjectName('statusbar-ip-label')
        self._ipLabel.setToolTip('IP Address of current page')

        self._statusBar.addPermanentWidget(self._progressBar)
        self._statusBar.addPermanentWidget(self.ipLabel())

        downloadsButton = DownloadsButton(self)
        self._statusBar.addButton(downloadsButton)
        self._navigationToolbar.addToolButton(downloadsButton)

        desktop = gVar.app.desktop()
        windowWidth = desktop.availableGeometry().width() / 1.3
        windowHeight = desktop.availableGeometry().height() / 1.3

        # Let the WM decides where to put new browser window
        if self._windowType not in (const.BW_FirstAppWindow, const.BW_MacFirstWindow) and \
                gVar.app.getWindow():
            if const.OS_WIN:
                # Windows WM places every new window in the middle of screen .. for some reason
                p = gVar.app.getWindow().geometry().topLeft()
                p.setX(p.x() + 30)
                p.setY(p.y() + 30)
                if not desktop.availableGeometry(
                        gVar.app.getWindow()).contains(p):
                    p.setX(
                        desktop.availableGeometry(gVar.app.getWindow()).x() +
                        30)
                    p.setY(
                        desktop.availableGeometry(gVar.app.getWindow()).y() +
                        30)
                self.setGeometry(QRect(p, gVar.app.getWindow().size()))
            else:
                self.resize(gVar.app.getWindow().size())
        elif not self.restoreGeometry(windowGeometry):
            if const.OS_WIN:
                self.setGeometry(
                    QRect(
                        desktop.availableGeometry(gVar.app.getWindow()).x() +
                        30,
                        desktop.availableGeometry(gVar.app.getWindow()).y() +
                        30, windowWidth, windowHeight))
            else:
                self.resize(windowWidth, windowHeight)

        self._restoreUiState(uiState)
        # Set some sane minimum width
        self.setMinimumWidth(300)

    def _setupMenu(self):
        if const.OS_MACOS:
            macMainMenu = None
            if not macMainMenu:
                macMainMenu = MainMenu(self, 0)
                macMainMenu.initMenuBar(QMenuBar(0))
                gVar.app.activeWindowChanged.connect(macMainMenu.setWindow)
            else:
                macMainMenu.setWindow(self)
        else:
            self.setMenuBar(MenuBar(self))
            self._mainMenu = MainMenu(self, self)
            self._mainMenu.initMenuBar(self.menuBar())

        self._mainMenu.initSuperMenu(self._superMenu)

        # Setup other shortcuts
        reloadBypassCacheAction = QShortcut(QKeySequence('Ctrl+F5'), self)
        reloadBypassCacheAction2 = QShortcut(QKeySequence('Ctrl+Shift+R'),
                                             self)
        reloadBypassCacheAction.activated.connect(self.reloadBypassCache)
        reloadBypassCacheAction2.activated.connect(self.reloadBypassCache)

        closeTabAction = QShortcut(QKeySequence('Ctrl+W'), self)
        closeTabAction2 = QShortcut(QKeySequence('Ctrl+F4'), self)

        closeTabAction.activated.connect(self._closeTab)
        closeTabAction2.activated.connect(self._closeTab)

        reloadAction = QShortcut(QKeySequence('Ctrl+R'), self)
        reloadAction.activated.connect(self.reload)

        openLocationAction = QShortcut(QKeySequence('Alt+D'), self)
        openLocationAction.activated.connect(self._openLocation)

        inspectorAction = QShortcut(QKeySequence('F12'), self)
        inspectorAction.activated.connect(self.toggleWebInspector)

        restoreClosedWindow = QShortcut(QKeySequence('Ctrl+Shift+N'), self)
        restoreClosedWindow.activated.connect(
            gVar.app.closedWindowsManager().restoreClosedWindow)

    def _updateStartupFocus(self):
        def _updateStartupFocusCb():
            # Scroll to current tab
            self.tabWidget().tabBar().ensureVisible()
            # Update focus
            page = self.weView().page()
            url = page.requestedUrl()
            if not self._startPage and not LocationBar.convertUrlToText(url):
                self.locationBar().setFocus()
            else:
                self.weView().setFocus()

        QTimer.singleShot(500, _updateStartupFocusCb)

    def _createEncodingAction(self, codecName, activeCodecName, menu):
        '''
        @param: codecName QString
        @param: activeCodecName QString
        @param: menu QMenu
        '''
        action = QAction(codecName, menu)
        action.setData(codecName)
        action.setCheckable(True)
        action.triggered.connect(self._changeEncoding)
        if activeCodecName.lower() == codecName.lower():
            action.setChecked(True)
        return action

    def _createEncodingSubMenu(self, name, codecNames, menu):
        '''
        @param: name QString
        @param: codecName QStringList
        @param: menu QMenu
        '''
        if not codecNames:
            return

        codecNames.sort()
        subMenu = QMenu(name, menu)
        activeCodecName = gVar.app.webSettings().defaultTextEncoding()

        group = QActionGroup(subMenu)

        for codecName in codecNames:
            act = self._createEncodingAction(codecName, activeCodecName,
                                             subMenu)
            group.addAction(act)
            subMenu.addAction(act)

        menu.addMenu(subMenu)

    def _saveUiState(self):
        '''
        @return: QHash<QStirng, QVariant>
        '''
        self.saveSideBarSettings()
        state = {}
        state['LocationBarWidth'] = self._navigationToolbar.splitter().sizes(
        )[0]
        state['WebSearchBarWidth'] = self._navigationToolbar.splitter().sizes(
        )[1]
        state['SideBarWidth'] = self._sideBarWidth
        state['WebViewWidth'] = self._webViewWidth
        state['SideBar'] = self._sideBarManager.activeSideBar()
        return state

    def _restoreUiState(self, state):
        '''
        @param: state QHash<QString, QVariant>
        '''
        locationBarWidth = state.get('LocationBarWidth', 480)
        webSearchBarWidth = state.get('WebSearchBarWidth', 140)
        self._navigationToolbar.setSplitterSizes(locationBarWidth,
                                                 webSearchBarWidth)

        self._sideBarWidth = state.get('SideBarWidth', 250)
        self._webViewWidth = state.get('WebViewWidth', 2000)
        if self._sideBar:
            self._mainSplitter.setSizes(
                [self._sideBarWidth, self._webViewWidth])
        activeSideBar = state.get('SideBar')
        if not activeSideBar and self._sideBar:
            self._sideBar.close()
        else:
            self._sideBarManager.showSideBar(activeSideBar, False)
示例#48
0
class MainWindowGUI(QMainWindow):
    def __init__(self, refresh_time=30):
        super().__init__()
        uic.loadUi(
            os.path.join(os.path.dirname(os.path.abspath(__file__)),
                         'designer', 'MainWindow.ui'), self)
        self.logger = get_logger(name=__name__)

        self.central_layout = QHBoxLayout(self.centralwidget)
        self.widget_splitter = QSplitter()

        self.camera_viewer_widget = CameraViewerWidget()
        self.analysis_dock_widget = AnalysisDockWidget(self)
        self.widget_splitter.addWidget(self.camera_viewer_widget)
        self.widget_splitter.addWidget(self.analysis_dock_widget)
        self.widget_splitter.setSizes((750, 750))
        self.central_layout.addWidget(self.widget_splitter)

        self.config_widget = ConfigWidget()
        self.config_tracking_widget = ConfigTrackingWidget()

        self.refresh_timer = QTimer()
        self.refresh_timer.timeout.connect(self.update_gui)
        self.refresh_timer.start(refresh_time)

        self.showMaximized()

        self.connect_actions()
        self.connect_buttons()
        self.connect_signals()

    def update_gui(self):
        self.logger.error('Update gui not defined')

    def connect_signals(self):
        self.config_tracking_widget.apply_config.connect(
            self.update_tracking_config)
        self.config_widget.apply_config.connect(self.update_config)

    def connect_buttons(self):
        self.analysis_dock_widget.button_histogram.clicked.connect(
            self.calculate_histogram)
        self.analysis_dock_widget.button_tracks.clicked.connect(
            self.update_tracks)

    def connect_actions(self):
        self.actionClose.triggered.connect(self.safe_close)
        self.actionLoad_Config.triggered.connect(self.load_config)
        self.actionSave_Image.triggered.connect(self.save_image)
        self.actionLoad_Data.triggered.connect(self.load_data)
        self.actionSnap_Photo.triggered.connect(self.snap)
        self.actionStart_Movie.triggered.connect(self.start_movie)
        self.actionStop_Movie.triggered.connect(self.stop_movie)
        self.actionStart_Continuous_Saves.triggered.connect(
            self.start_continuous_saves)
        self.actionStop_Continuous_Saves.triggered.connect(
            self.stop_continuous_saves)
        self.actionSet_ROI.triggered.connect(self.set_roi)
        self.actionClear_ROI.triggered.connect(self.clear_roi)
        self.actionConfiguration.triggered.connect(self.configure)
        self.actionToggle_bg_reduction.triggered.connect(
            self.background_reduction)
        self.actionStart_Tracking.triggered.connect(self.start_tracking)
        self.actionStop_Tracking.triggered.connect(self.stop_tracking)
        self.actionStart_Linking.triggered.connect(self.start_linking)
        self.actionStop_Linking.triggered.connect(self.stop_linking)
        self.actionSave_Tracks.triggered.connect(self.start_saving_tracks)
        self.actionShow_Cheatsheet.triggered.connect(self.show_cheat_sheet)
        self.actionAbout.triggered.connect(self.show_about)
        self.actionInitialize_Camera.triggered.connect(self.initialize_camera)
        self.actionUpdate_Histogram.triggered.connect(self.calculate_histogram)
        self.actionTracking_Config.triggered.connect(
            self.config_tracking_widget.show)
        self.actionConfiguration.triggered.connect(self.config_widget.show)
        self.actionAdd_Monitor_Point.triggered.connect(self.add_monitor_point)
        self.actionClear_All.triggered.connect(self.clear_monitor_points)

    def add_monitor_point(self):
        self.logger.debug('Add monitor point')

    def clear_monitor_points(self):
        self.logger.debug('Clear all monitor points')

    def initialize_camera(self):
        self.logger.debug('Initialize Camera')

    def show_about(self):
        self.logger.debug('Showing About')

    def load_config(self):
        self.logger.debug('Loading config')

    def snap(self):
        self.logger.debug('Snapped a photo')

    def save_image(self):
        self.logger.debug('Saved an image')

    def start_movie(self):
        self.logger.debug('Start a movie')

    def stop_movie(self):
        self.logger.error('Stop movie not defined')

    def start_continuous_saves(self):
        self.logger.debug('Started continuous saves')

    def stop_continuous_saves(self):
        self.logger.error('Stop continuous Saves not implemented')

    def start_tracking(self):
        self.logger.debug('Started tracking particles')

    def stop_tracking(self):
        self.logger.debug('Stopped tracking particles')

    def start_saving_tracks(self):
        self.logger.debug('Started saving tracks')

    def stop_saving_tracks(self):
        self.logger.debug('Stopped saving tracks')

    def start_linking(self):
        self.logger.debug('Started linking particles')

    def stop_linking(self):
        self.logger.debug('Stopped linking')

    def configure(self):
        self.logger.debug('Showed the config window')

    def set_roi(self):
        self.logger.debug('Setting the ROI')

    def clear_roi(self):
        self.logger.debug('Resetting the ROI')

    def background_reduction(self):
        self.logger.debug('Setting background reduction')

    def show_cheat_sheet(self):
        self.logger.debug('Showing the cheat sheet')

    def load_data(self):
        self.logger.debug('Loading data')

    def safe_close(self):
        self.logger.debug('Closing the program')
        self.close()

    def calculate_histogram(self):
        self.logger.error('Update Histogram method not defiend')

    def update_tracks(self):
        self.logger.error('Update tracks method not defined')

    def update_tracking_config(self, config):
        self.logger.error('Update Tracking config method not defined')

    def update_config(self, config):
        self.logger.error('Update Config method not defined')

    def closeEvent(self, *args, **kwargs):
        self.config_widget.close()
        self.config_tracking_widget.close()
        super(MainWindowGUI, self).closeEvent(*args, **kwargs)
示例#49
0
    def initUI(self):
#        pg.setConfigOption('background', 'w')
        self.lblTit = pg.LabelItem(justify='right')
        #Variables
        self.data_dir=''
        self.nom_dir = []
        self.numEp=1
        self.grafi=[]
        self.tam=0
        self.puntos=0

        self.sizes = np.asarray([120, 60, 30, 15])

        datos = QVBoxLayout()
        contain=QSplitter(Qt.Horizontal)
        ima = QVBoxLayout()
        
        self.glw = pg.PlotWidget()

        btn_data_dir = QPushButton('Load Files')        
        btn_data_dir.clicked.connect(self.openFile)
        
        self.lblDataDir=QLabel('')
        
        self.lytEpoch = QFormLayout()
        self.cmbEpoch = QComboBox()
        self.cmbEpoch.addItem("120")
        self.cmbEpoch.addItem("60")
        self.cmbEpoch.addItem("30")
        self.cmbEpoch.addItem("15")
        self.lytEpoch.addRow("Epoch size: ", self.cmbEpoch)
        
        self.lytFrec = QFormLayout()
        self.txtFrec = QLineEdit('200')
        self.lytFrec.addRow("Frecuencia: ",self.txtFrec)
        
        btn_do = QPushButton('DO')        
        btn_do.clicked.connect(self.showDialog)
        
        self.lytEpo = QFormLayout()
        self.cmbEpo = QComboBox()
        self.cmbEpo.setCurrentIndex=1
        self.cmbEpo.activated[str].connect(self.graficaX)
        self.lytEpo.addRow("Número de época: ", self.cmbEpo)

        datos.addWidget(btn_data_dir)
        datos.addWidget(self.lblDataDir)
        datos.addLayout(self.lytEpoch)
        datos.addLayout(self.lytFrec)
        datos.addWidget(btn_do)
        
        ima.addWidget(self.glw)
        ima.addLayout(self.lytEpo)

        bot = QWidget()
        bot.setLayout(datos)
        gra = QWidget()
        gra.setLayout(ima)
        
        
        contain.addWidget(bot)
        contain.addWidget(gra)
        self.addWidget(contain)
示例#50
0
class MainWinBase(QMainWindow):
    def __init__(self):
        super().__init__()
        self.resize(1024, 720)
        self.menubar = self.menuBar()
        self.statusbar = self.statusBar()
        self.mainTabWidget = QTabWidget()

        self.actions = {}
        self.menus = {}
        self.submenus = {}
        self.contexMenus = {}
        self.toolbars = {}
        self.status = {}
        self.docks = {}
        self.documents = {}

        self.createActions()
        self.themeCombo = QComboBox()
        self.createMenubar()
        self.createContexMenus()
        self.createToolbars()
        self.createStatusBar()
        self.createDocks()
        self.createMainWidget()

        self.setupUiActions()

    def createActions(self):
        def createAct(text,
                      tip=None,
                      shortcut=None,
                      iconimg=None,
                      checkable=False,
                      slot=None):
            action = QAction(self.tr(text), self)
            if iconimg is not None:
                action.setIcon(QIcon(iconimg))
            if shortcut is not None:
                action.setShortcut(shortcut)
            if tip is not None:
                tip = self.tr(tip)
                action.setToolTip(tip)
                action.setStatusTip(tip)
            if checkable:
                action.setCheckable(True)
            if slot is not None:
                action.triggered.connect(slot)
            return action

        def keys2str(standardkey):
            return "".join(("(", QKeySequence(standardkey).toString(), ")"))

        # self.actions["new"] = createAct(self.tr("&New", "&New"),
        #                                 self.tr("new") + keys2str(QKeySequence.New), QKeySequence.New,
        #                                 ':appres.img/NewDocument.png')
        self.actions["import"] = createAct(self.tr("&Import Image"),
                                           self.tr("Import Image"), None,
                                           ':appres.img/importimage.png')
        self.actions["replaceimage"] = createAct(
            self.tr("&Replace Image"), self.tr("Replace Image"), None,
            ':appres.img/replaceimage.png')
        self.actions["open"] = createAct(
            self.tr("&Open Project"),
            self.tr("Open") + keys2str(QKeySequence.Open), QKeySequence.Open,
            ':appres.img/open.png')
        self.actions["save"] = createAct(
            self.tr("&Save"),
            self.tr("Save") + keys2str(QKeySequence.Save), QKeySequence.Save,
            ':appres.img/save.png')
        self.actions["saveas"] = createAct(self.tr("&Save as..."),
                                           self.tr("Save as..."), None,
                                           ':appres.img/SaveAs.png')
        self.actions["export"] = createAct(
            self.tr("&ExportCurves"), self.tr("Export digitized curves data"),
            "Ctrl+Alt+E", ':appres.img/export.png')
        self.actions["close"] = createAct(self.tr("&Close"), self.tr("Close"))
        self.actions["exit"] = createAct(self.tr("&Exit"), self.tr("Exit"),
                                         "Ctrl+Q")
        self.actions["undo"] = createAct(
            self.tr("&Undo"),
            self.tr("Undo") + keys2str(QKeySequence.Undo), QKeySequence.Undo,
            ':appres.img/undo.png')
        self.actions["redo"] = createAct(
            self.tr("&Redo"),
            self.tr("Redo") + keys2str(QKeySequence.Redo), QKeySequence.Redo,
            ':appres.img/redo.png')
        self.actions["cut"] = createAct(
            self.tr("&Cut"),
            self.tr("Cut") + keys2str(QKeySequence.Cut), QKeySequence.Cut,
            ':appres.img/cut.png')
        self.actions["copy"] = createAct(
            self.tr("&Copy"),
            self.tr("Copy") + keys2str(QKeySequence.Copy), QKeySequence.Copy,
            ':appres.img/copy.png')
        self.actions["paste"] = createAct(
            self.tr("&Paste"),
            self.tr("Paste") + keys2str(QKeySequence.Paste),
            QKeySequence.Paste, ':appres.img/paste.png')
        self.actions["zoomin"] = createAct(self.tr("&ZoomIn"),
                                           self.tr("Zoom In"), "Ctrl++",
                                           ':appres.img/zoomin.png')
        self.actions["zoomout"] = createAct(self.tr("&ZoomOut"),
                                            self.tr("Zoom Out"), "Ctrl+-",
                                            ':appres.img/zoomout.png')
        self.actions["showgrid"] = createAct(self.tr("Show Axes &Grid"),
                                             self.tr("Show AxesGrid"),
                                             None,
                                             ':appres.img/grid.png',
                                             checkable=True)
        self.actions["showgrid"].setChecked(True)
        self.actions["select"] = createAct(self.tr("Select Mode"),
                                           self.tr("Select Mode"),
                                           None,
                                           ':appres.img/select.png',
                                           checkable=True)
        self.actions["axesx"] = createAct(self.tr("Set x axis postions"),
                                          self.tr("Set x axis position"),
                                          None,
                                          ':appres.img/axesx.png',
                                          checkable=True)
        self.actions["axesy"] = createAct(self.tr("Set y axis postions"),
                                          self.tr("Set y axis position"),
                                          None,
                                          ':appres.img/axesy.png',
                                          checkable=True)
        self.actions["curve"] = createAct(self.tr("&AddCurve"),
                                          self.tr("Add Curve"),
                                          None,
                                          ':appres.img/curve.png',
                                          checkable=True)
        self.actions["del"] = createAct(self.tr("&del point or axis"),
                                        self.tr("delete"), QKeySequence.Delete,
                                        ':appres.img/delete.png')
        self.actions["addcurve"] = createAct(self.tr("add a new curve"),
                                             self.tr("add a new curve"), None,
                                             ':appres.img/new.png')
        self.actions["renamecurve"] = createAct(
            self.tr("change curve name"), self.tr("change current curve name"),
            None, ':appres.img/edit.png')
        self.actions["delcurve"] = createAct(self.tr("&del curve"),
                                             self.tr("delete selected curve"),
                                             QKeySequence.Delete,
                                             ':appres.img/delete.png')

        self.actions["scalegraph"] = createAct(
            self.tr("set graph image scale"),
            self.tr("scale the graph image(background)"), None,
            ":appres.img/resizeimage.png")
        self.actions["gridsetting"] = createAct(
            self.tr("grid settings"), self.tr("set grid range and step"), None,
            ":appres.img/gridsetting.png")

        # self.actions["DisableQss"] = createAct(self.tr("&DisableQss"), self.tr("DisableQss"), checkable=True)
        # self.actions["DisableQss"].setChecked(False)
        # self.actions["ShowColor"] = createAct(self.tr("&ColorPanel"),
        #                                       self.tr("ShowColorPanel"),
        #                                       None,
        #                                       ":appres.img/color.png",
        #                                       checkable=True)
        # self.actions["ShowColor"].setChecked(True)
        self.actions["showcurves"] = createAct(
            self.tr("&CurvePanel"),
            self.tr("ShowCurvesPanel"),
            None,
            ":appres.img/view2col2right.png",
            checkable=True)
        self.actions["showfit"] = createAct(
            self.tr("Show Fit&&Interpolation Panel"),
            self.tr("ShowCurve Fit&Interpolation Panel"),
            None,
            None,
            checkable=True)
        self.actions["showcurves"].setChecked(True)

        self.actions["hidegraph"] = createAct(
            self.tr("Hide Graph"),
            self.tr("Hide the graph(background image)"),
            None,
            None,
            checkable=True)
        self.actions["showoriginalgraph"] = createAct(
            self.tr("Original Graph"),
            self.tr("Show the original graph(background image)"),
            None,
            None,
            checkable=True)

        self.actions["config"] = createAct(self.tr("&Config"),
                                           self.tr("settings"), None,
                                           ":appres.img/config.png")

        self.actions["about"] = createAct(self.tr("&About"), self.tr("About"))
        self.actions["help"] = createAct(self.tr("&Help"), self.tr("Help"))

        # self.exitAct.triggered.connect(qApp.exit)#等价于qApp.quit
        self.actions["exit"].triggered.connect(self.close)

    def createMenubar(self):
        self.menus["File"] = QMenu(self.tr("&File"))
        self.menus["Edit"] = QMenu(self.tr("&Edit"))
        self.menus["Digit"] = QMenu(self.tr("&Digit"))
        self.menus["View"] = QMenu(self.tr("&View"))
        self.menus["Config"] = QMenu(self.tr("&Config"))
        self.menus["Help"] = QMenu(self.tr("&Help"))

        editMenu = QMenu(self.tr("Text"), self.menus["Edit"])
        editMenu.setIcon(QIcon(":appres.img/edit_whitepage.png"))
        editMenu.addAction(self.actions["undo"])
        editMenu.addAction(self.actions["redo"])
        # editMenu.addSeparator()
        # editMenu.addAction(self.actions["cut"])
        # editMenu.addAction(self.actions["copy"])
        # editMenu.addAction(self.actions["paste"])

        self.menus["File"].addAction(self.actions["import"])
        self.menus["File"].addAction(self.actions["replaceimage"])
        self.menus["File"].addAction(self.actions["open"])
        self.menus["File"].addAction(self.actions["save"])
        self.menus["File"].addAction(self.actions["saveas"])
        self.menus["File"].addAction(self.actions["export"])
        self.menus["File"].addAction(self.actions["close"])
        self.menus["File"].addSeparator()
        self.menus["File"].addAction(self.actions["exit"])

        self.menus["Edit"].addAction(self.actions["undo"])
        self.menus["Edit"].addAction(self.actions["redo"])

        self.menus["Digit"].addAction(self.actions["select"])
        self.menus["Digit"].addAction(self.actions["axesx"])
        self.menus["Digit"].addAction(self.actions["axesy"])
        self.menus["Digit"].addAction(self.actions["curve"])
        self.menus["Digit"].addSeparator()
        self.menus["Digit"].addAction(self.actions["addcurve"])
        self.menus["Digit"].addAction(self.actions["renamecurve"])
        self.menus["Digit"].addAction(self.actions["del"])

        self.menus["View"].addAction(self.actions["zoomin"])
        self.menus["View"].addAction(self.actions["zoomout"])
        self.menus["View"].addSeparator()
        background = QMenu(self.tr("Graph Background"), self.menus["View"])
        background.addAction(self.actions["hidegraph"])
        background.addAction(self.actions["showoriginalgraph"])
        self.menus["View"].addMenu(background)
        self.menus["View"].addAction(self.actions["showgrid"])
        self.menus["View"].addSeparator()
        self.menus["View"].addAction(self.actions["showcurves"])
        self.menus["View"].addAction(self.actions["showfit"])
        self.menus["View"].addSeparator()

        self.menus["Config"].addAction(self.actions["config"])

        self.menus["Help"].addAction(self.actions["help"])
        self.menus["Help"].addSeparator()
        self.menus["Help"].addAction(self.actions["about"])

        for m in self.menus.values():
            self.menubar.addMenu(m)

    def createContexMenus(self):
        self.contexMenus["Edit"] = QMenu(self.tr("Edit"))
        self.contexMenus["Edit"].addAction(self.actions["cut"])
        self.contexMenus["Edit"].addAction(self.actions["copy"])
        self.contexMenus["Edit"].addAction(self.actions["paste"])

    def createToolbars(self):
        themeLabel = QLabel(self.tr("Theme "))
        # self.themeCombo = QComboBox()
        themeLabel.setToolTip(self.tr("Using system style."))
        self.themeCombo.setToolTip(self.tr("Select system style."))
        self.themeCombo.addItems(QStyleFactory.keys())
        self.themeCombo.setMinimumWidth(105)
        theme = QApplication.style().objectName()
        self.themeCombo.setCurrentIndex(
            self.themeCombo.findText(theme, Qt.MatchFixedString))
        # self.themeCombo.setEnabled(False)
        # themeCombo.activated[str].connect(qApp.setStyle)
        # themeCombo.currentTextChanged.connect(qApp.setStyle)
        # checkbox.stateChanged.connect(self.themeCombo.setEnabled)
        # checkbox.stateChanged.connect(lambda x:self.actions["DisableQss"].setChecked(checkbox.isChecked()))

        self.toolbars["Main"] = QToolBar(self.tr("Main", "toolbar"))
        self.toolbars["Main"].addWidget(themeLabel)
        self.toolbars["Main"].addWidget(self.themeCombo)

        self.toolbars["File"] = QToolBar(self.tr("File"))
        self.toolbars["File"].addAction(self.actions["import"])
        self.toolbars["File"].addAction(self.actions["open"])
        self.toolbars["File"].addAction(self.actions["save"])
        # self.toolbars["File"].addAction(self.actions["saveas"])
        self.toolbars["File"].addAction(self.actions["export"])

        self.toolbars["Edit"] = QToolBar(self.tr("Edit"))
        self.toolbars["Edit"].addAction(self.actions["undo"])
        self.toolbars["Edit"].addAction(self.actions["redo"])
        self.toolbars["Edit"].addAction(self.actions["del"])

        self.toolbars["Digitize"] = QToolBar(self.tr("Digitize"))
        self.toolbars["Digitize"].addAction(self.actions["select"])
        self.toolbars["Digitize"].addAction(self.actions["axesx"])
        self.toolbars["Digitize"].addAction(self.actions["axesy"])
        self.toolbars["Digitize"].addAction(self.actions["curve"])

        self.toolbars["Display"] = QToolBar(self.tr("Display"))
        self.toolbars["Display"].addAction(self.actions["zoomin"])
        self.toolbars["Display"].addAction(self.actions["zoomout"])
        self.toolbars["Display"].addAction(self.actions["showgrid"])

        self.toolbars["Setting"] = QToolBar(self.tr("Setting"))
        self.toolbars["Setting"].addAction(self.actions["scalegraph"])
        self.toolbars["Setting"].addAction(self.actions["gridsetting"])
        self.toolbars["Setting"].addAction(self.actions["config"])

        self.toolbars["View"] = QToolBar(self.tr("View"))
        self.toolbars["View"].addAction(self.actions["showcurves"])

        for t in self.toolbars.values():
            self.addToolBar(t)

    def createStatusBar(self):
        self.statusbar.showMessage(self.tr("Ready"))
        # self.statusbar.addWidget(QWidget(),1)
        # self.status["date"] = QLabel()
        # self.statusbar.addPermanentWidget(self.status["date"])
        # self.status["date"].setText(QDate.currentDate().toString())
        # self.status["date"].setVisible(False)

        self.status["point"] = QLabel(self.tr("Point Coordinate: 0,0"))
        self.status["pixel"] = QLabel(self.tr("Pixel Location: 0,0"))
        self.status["point"].setMinimumWidth(200)
        self.status["pixel"].setMinimumWidth(200)
        # self.status["coding"].setAlignment(Qt.AlignCenter)
        self.statusbar.addPermanentWidget(self.status["point"])
        self.statusbar.addPermanentWidget(self.status["pixel"])

    def createDocks(self):
        self.docks["curves"] = QDockWidget(self.tr("Axes and Curves"))
        self.docks["curves"].setMinimumSize(QSize(200, 200))
        self.docks["curves"].setFeatures(QDockWidget.DockWidgetMovable
                                         | QDockWidget.DockWidgetFloatable)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.docks["curves"])

        self.docks["fit"] = FitDockWidget(self.tr("Poly Fit"))
        self.docks["fit"].setMinimumSize(QSize(200, 200))
        self.docks["fit"].setFeatures(QDockWidget.DockWidgetMovable
                                      | QDockWidget.DockWidgetFloatable)
        self.addDockWidget(Qt.RightDockWidgetArea, self.docks["fit"])
        #self.tabifyDockWidget(self.docks["curves"], self.docks["fit"])
        #self.docks["curves"].raise_()
        self.docks["fit"].setVisible(False)

        self.docks["curves"].visibilityChanged.connect(
            self.actions["showcurves"].setChecked)
        self.docks["fit"].visibilityChanged.connect(
            self.actions["showfit"].setChecked)

        self.docktabwidget = QTabWidget(self.docks["curves"])
        self.docks["curves"].setWidget(self.docktabwidget)
        self.docktabwidget.setTabPosition(QTabWidget.South)
        self.axesTab = QSplitter(Qt.Vertical)  # QScrollArea()
        self.curveTab = QSplitter(Qt.Vertical)
        self.docktabwidget.addTab(self.axesTab, "axes")
        self.docktabwidget.addTab(self.curveTab, "curve")
        self.docktabwidget.setCurrentIndex(1)

        self.axesxTable = QTableView()
        self.axesyTable = QTableView()
        self.axesTab.addWidget(self.axesxTable)
        self.axesTab.addWidget(self.axesyTable)

        self.curveTable = QTableView()
        self.pointsTable = QTableView()
        # self.axesTab.setWidgetResizable(True)
        w = QWidget()
        lay = QVBoxLayout()
        lay.setContentsMargins(0, 0, 0, 0)
        self.curvePanelToolbar = QToolBar(self.curveTab)
        lay.addWidget(self.curvePanelToolbar)
        lay.addWidget(self.curveTable)
        w.setLayout(lay)
        self.curveTab.addWidget(w)
        self.curveTab.addWidget(self.pointsTable)
        self.curvePanelToolbar.addAction(self.actions["addcurve"])
        self.curvePanelToolbar.addAction(self.actions["renamecurve"])
        self.curvePanelToolbar.addAction(self.actions["delcurve"])

    def createMainWidget(self):
        self.setCentralWidget(self.mainTabWidget)
        self.mainTabWidget.setTabBarAutoHide(True)

    def setupUiActions(self):
        self.actions["showcurves"].triggered.connect(
            self.docks["curves"].setVisible)
        self.actions["showfit"].triggered.connect(self.docks["fit"].setVisible)
        self.themeCombo.currentTextChanged.connect(qApp.setStyle)

    # misc func
    def updatePixelCoordStatus(self, ptorx, y=None):
        if isinstance(ptorx, QPoint) or isinstance(ptorx, QPointF):
            self.status["pixel"].setText("Pixel Coordinate: {},{}".format(
                ptorx.x(), ptorx.y()))
        else:
            self.status["pixel"].setText("Pixel Coordinate: {},{}".format(
                ptorx, y))

    def updatePointCoordStatus(self, ptorx, y=None):
        if isinstance(ptorx, QPoint) or isinstance(ptorx, QPointF):
            self.status["point"].setText(
                "Point Coordinate: {:.0f},{:.0f}".format(ptorx.x(), ptorx.y()))
        else:
            self.status["point"].setText(
                "Point Coordinate: {:.0f},{:.0f}".format(ptorx, y))
示例#51
0
class bridgePanel(QMainWindow, QObject):
    start = pyqtSignal()
    stop = pyqtSignal()

    def __init__(self, app):
        super().__init__()
        self.bridgetreasureChest = bridgetreasureChest.bridgetreasureChest()
        self.app = app
        self.translate = QCoreApplication.translate
        self.__v2rayshellVersion = "20180302"
        self.__windowTitile = "V2Ray-shell" + " " + self.__v2rayshellVersion
        self.runv2raycore = False
        self.iconStart = QIcon()
        self.iconStop = QIcon()
        self.__iconSize = QSize(32, 32)
        self.iconStart.addPixmap(QPixmap(filePath + "/icons/start.png"),
                                 QIcon.Normal, QIcon.On)
        self.iconStop.addPixmap(QPixmap(filePath + "/icons/stop.png"),
                                QIcon.Disabled, QIcon.On)
        self.currentRowRightClicked = False
        self.v2rayshellTrayIcon = QSystemTrayIcon()
        self.v2rayshellTrayIcon.setIcon(self.iconStart)
        self.v2rayshellTrayIcon.show()

        self.radioButtonGroup = QButtonGroup()

        self.setV2RayshellLanguage()
        self.trytimes = self.bridgetreasureChest.getConnectiontrytimes()
        self.interval = self.bridgetreasureChest.getConnectioninterval()
        self.proxyTryConnect = proxyTryconnect()
        if v2rayshellDebug: self.proxyTryConnect.setresetTime(6, 3)
        else: self.proxyTryConnect.setresetTime(self.interval, self.trytimes)
        self.labelBridge = (self.translate("bridgePanel", "Start/Stop"),
                            self.translate("bridgePanel", "Host Name"),
                            self.translate("bridgePanel", "Config Name"),
                            self.translate("bridgePanel", "Proxy"),
                            self.translate("bridgePanel", "Time Lag"))
        self.checkTrayicon = QTimer()
        self.createBridgePanel()

    def createBridgePanel(self):
        self.setWindowTitle(self.__windowTitile)
        self.setWindowIcon(self.iconStart)
        menubar = self.menuBar()
        self.statusBar()

        self.actionNewV2rayConfigFile = QAction(
            self.translate("bridgePanel", "Add V2Ray-core Config File"), self)
        self.actionNewV2rayConfigFile.setShortcut(QKeySequence.New)
        self.actionNewV2rayConfigFile.setStatusTip(
            self.translate("bridgePanel", "Add V2Ray-core Config File"))

        self.actionSaveV2rayshellConfigFile = QAction(
            self.translate("bridgePanel", "Save V2Ray-shell Config File"),
            self)
        self.actionSaveV2rayshellConfigFile.setShortcut(QKeySequence.Save)
        self.actionSaveV2rayshellConfigFile.setStatusTip(
            self.translate("bridgePanel", "Save V2Ray-shell Config File"))

        self.actionReloadV2rayshellConfigFile = QAction(
            self.translate("bridgePanel", "Open V2Ray-shell Config File"),
            self)
        self.actionReloadV2rayshellConfigFile.setShortcut(QKeySequence.Open)
        self.actionReloadV2rayshellConfigFile.setStatusTip(
            self.translate("bridgePanel", "Open V2Ray-shell Config File"))

        self.actionQuitV2rayshellPanel = QAction(
            self.translate("bridgePanel", "Quit"), self)
        if sys.platform.startswith('win'):
            self.actionQuitV2rayshellPanel.setShortcut("Ctrl+Q")
        else:
            self.actionQuitV2rayshellPanel.setShortcut(QKeySequence.Quit)
        self.actionQuitV2rayshellPanel.setStatusTip(
            self.translate("bridgePanel", "Quit V2Ray-shell"))

        fileMenu = menubar.addMenu(self.translate("bridgePanel", "&File"))
        fileMenu.addAction(self.actionNewV2rayConfigFile)
        fileMenu.addSeparator()
        fileMenu.addAction(self.actionReloadV2rayshellConfigFile)
        fileMenu.addAction(self.actionSaveV2rayshellConfigFile)
        fileMenu.addSeparator()
        fileMenu.addAction(self.actionQuitV2rayshellPanel)

        self.texteditBridge = QTextEdit(self)
        self.texteditBridge.setReadOnly(True)

        self.tableWidgetBridge = QTableWidget()
        self.tableWidgetBridge.setRowCount(0)
        self.tableWidgetBridge.setColumnCount(5)
        self.tableWidgetBridge.setHorizontalHeaderLabels(self.labelBridge)
        self.tableWidgetBridge.setSelectionMode(
            QAbstractItemView.SingleSelection)
        self.tableWidgetBridge.setSelectionBehavior(
            QAbstractItemView.SelectRows)
        self.tableWidgetBridge.setEditTriggers(
            QAbstractItemView.NoEditTriggers)
        #self.tableWidgetBridge.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.tableWidgetBridge.setContextMenuPolicy(Qt.CustomContextMenu)

        self.popMenu = popMenu = QMenu(self.tableWidgetBridge)
        self.actionpopMenuAddV2rayConfigFile = QAction(
            self.translate("bridgePanel", "Add V2Ray Config File"), self)
        self.actionpopMenuAddV2rayConfigFile.setShortcut("Ctrl+n")
        self.actionpopMenuEditV2rayConfigFile = QAction(
            self.translate("bridgePanel", "Edit V2Ray Config File"), self)
        self.actionpopMenuProxyCheckTimeLag = QAction(
            self.translate("bridgePanel", "Proxy Time Lag Check..."), self)
        self.actionpopMenuDeleteRow = QAction(
            self.translate("bridgePanel", "Delete"), self)

        popMenu.addAction(self.actionpopMenuAddV2rayConfigFile)
        popMenu.addAction(self.actionpopMenuEditV2rayConfigFile)
        popMenu.addAction(self.actionpopMenuProxyCheckTimeLag)
        popMenu.addAction(self.actionpopMenuDeleteRow)

        self.actionopenV2rayshellPreferencesPanel = QAction(
            self.translate("bridgePanel", "preferences"), self)
        self.actionopenV2rayshellPreferencesPanel.setStatusTip(
            self.translate("bridgePanel", "Setting V2Ray-shell"))

        optionMenu = menubar.addMenu(self.translate("bridgePanel", "&options"))
        optionMenu.addAction(self.actionpopMenuProxyCheckTimeLag)
        optionMenu.addAction(self.actionopenV2rayshellPreferencesPanel)

        helpMenu = menubar.addMenu(self.translate("bridgePanel", "&help"))
        self.actioncheckv2raycoreupdate = QAction(
            self.translate("bridgePanel", "check V2Ray-core update"), self)
        self.actionv2rayshellBugreport = QAction(
            self.translate("bridgePanel", "Bug Report"), self)
        self.actionaboutv2rayshell = QAction(
            self.translate("bridgePanel", "About"), self)

        helpMenu.addAction(self.actioncheckv2raycoreupdate)
        helpMenu.addAction(self.actionv2rayshellBugreport)
        helpMenu.addAction(self.actionaboutv2rayshell)

        toolBar = QToolBar()
        self.actionV2rayStart = QAction(self.translate("bridgePanel", "Start"))
        self.actionV2rayStart.setIcon(self.style().standardIcon(
            getattr(QStyle, "SP_MediaPlay")))
        self.actionV2rayStop = QAction(self.translate("bridgePanel", "Stop"))
        self.actionV2rayStop.setIcon(self.style().standardIcon(
            getattr(QStyle, "SP_MediaStop")))
        toolBar.addAction(self.actionV2rayStart)
        toolBar.addAction(self.actionV2rayStop)
        self.addToolBar(toolBar)

        self.trayIconMenu = QMenu()
        self.v2rayshellTrayIcon.setContextMenu(self.trayIconMenu)

        self.trayIconMenushowhidePanel = QAction(
            self.translate("bridgePanel", "Show/Hide"))
        self.trayIconMenuclosePanel = QAction(
            self.translate("bridgePanel", "Quit"))

        self.trayIconMenu.addAction(self.trayIconMenushowhidePanel)
        self.trayIconMenu.addSeparator()
        self.trayIconMenu.addAction(self.trayIconMenuclosePanel)

        self.splitterBridge = QSplitter(Qt.Vertical)
        self.splitterBridge.addWidget(self.tableWidgetBridge)
        self.splitterBridge.addWidget(self.texteditBridge)

        self.setCentralWidget(self.splitterBridge)

        self.createBridgePanelSignals()

        self.onloadV2rayshellConfigFile(init=True)

        self.onv2raycoreStart()

        self.autocheckv2raycoreUpdate()

    def createBridgePanelSignals(self):
        self.actionNewV2rayConfigFile.triggered.connect(
            self.tableWidgetBridgeAddNewV2rayConfigFile)
        self.actionReloadV2rayshellConfigFile.triggered.connect(
            self.onloadV2rayshellConfigFile)
        self.actionSaveV2rayshellConfigFile.triggered.connect(
            self.onsaveV2rayshellConfigFile)
        self.actionopenV2rayshellPreferencesPanel.triggered.connect(
            self.createBridgepreferencesPanel)
        self.actionpopMenuAddV2rayConfigFile.triggered.connect(
            self.tableWidgetBridgeAddNewV2rayConfigFile)
        self.actionpopMenuEditV2rayConfigFile.triggered.connect(
            self.oncreatenauticalChartPanel)
        self.actionpopMenuDeleteRow.triggered.connect(
            self.tableWidgetBridgeDelete)
        self.actionpopMenuProxyCheckTimeLag.triggered.connect(
            self.onproxyserverTimeLagTest)
        self.actioncheckv2raycoreupdate.triggered.connect(
            self.onopenv2rayupdatePanel)
        self.actionv2rayshellBugreport.triggered.connect(self.bugReportPanel)
        self.actionQuitV2rayshellPanel.triggered.connect(self.close)
        self.actionV2rayStart.triggered.connect(self.onv2raycoreStart)
        self.actionV2rayStop.triggered.connect(self.onv2raycoreStop)
        self.actionaboutv2rayshell.triggered.connect(self.about)
        self.radioButtonGroup.buttonClicked.connect(self.onradioButtonClicked)
        self.tableWidgetBridge.cellDoubleClicked.connect(
            self.ontableWidgetBridgecellDoubleClicked)
        self.tableWidgetBridge.customContextMenuRequested.connect(
            self.ontableWidgetBridgeRightClicked)
        self.v2rayshellTrayIcon.activated.connect(self.restorebridgePanel)
        self.trayIconMenushowhidePanel.triggered.connect(
            self.onsystemTrayIconMenushowhidebridgePanel)
        self.trayIconMenuclosePanel.triggered.connect(self.close)
        self.proxyTryConnect.reconnectproxy.connect(self.swapNextConfigFile)
        self.start.connect(self.onupdateinstallFinishedstartNewV2raycore)
        self.stop.connect(self.onv2raycoreStop)
        self.checkTrayicon.timeout.connect(self.checkSystemTrayIconStatus)
        self.checkTrayicon.start(1000 * 60)

    def checkSystemTrayIconStatus(self):
        """
        maybe auto startup will missing trayicon
        """
        if not self.v2rayshellTrayIcon.isVisible():
            self.v2rayshellTrayIcon.show()
        else:
            self.checkTrayicon.disconnect()

    def setV2RayshellLanguage(self):
        self.trans = QTranslator()
        language = self.bridgetreasureChest.getLanguage()
        allLanguages = self.bridgetreasureChest.getAllLanguage()
        if language and allLanguages:
            if language in allLanguages:
                self.trans.load(allLanguages[language])
                self.app.installTranslator(self.trans)

    def autocheckv2raycoreUpdate(self):
        self.bridgeSingal = (self.start, self.stop)
        self.v2rayshellautoUpdate = updatePanel.autoCheckUpdate(
            bridgetreasureChest=self.bridgetreasureChest,
            bridgeSingal=self.bridgeSingal)

    def event(self, event):
        if (event.type() == QEvent.WindowStateChange and self.isMinimized()):
            self.setWindowFlags(self.windowFlags() & ~Qt.Tool)
            self.v2rayshellTrayIcon.show()
            return True
        else:
            return super(bridgePanel, self).event(event)

    def onsystemTrayIconMenushowhidebridgePanel(self):
        if self.isHidden():
            self.showNormal()
        elif self.isVisible():
            self.hide()

    def restorebridgePanel(self, reason):
        if reason == QSystemTrayIcon.Trigger:
            if self.isVisible():
                self.hide()
            elif self.isHidden():
                self.showNormal()

    def close(self):
        super(bridgePanel, self).close()
        self.v2rayshellTrayIcon.hide()
        self.onv2raycoreStop()

    def closeEvent(self, event):
        self.close()
        event.accept()
        sys.exit(self.app.exec_())

    def onv2raycoreStop(self):
        if (self.runv2raycore):
            self.runv2raycore.stop.emit()
        try:
            # force stop checking proxy time lag
            del self.autoCheckTimer
        except Exception:
            pass

    def onupdateinstallFinishedstartNewV2raycore(self):
        self.onloadV2rayshellConfigFile(init=True)
        self.onv2raycoreStart()

    def onv2raycoreStart(self):
        currentActiveRow = False
        rowCount = self.tableWidgetBridge.rowCount()
        for i in range(rowCount):
            currentActiveRow = self.tableWidgetBridge.cellWidget(i, 0)
            if currentActiveRow.isChecked():
                self.texteditBridge.clear()
                option = self.tableWidgetBridge.item(i, 2)
                if option:
                    option = '-config="{}" -format=json'.format(option.text())
                else:
                    option = ""
                filePath = self.bridgetreasureChest.getV2raycoreFilePath()
                if (filePath == False or filePath == ""):
                    filePath = "v2ray"
                self.runv2raycore = runV2raycore.runV2raycore(
                    outputTextEdit=self.texteditBridge,
                    v2rayPath=filePath,
                    v2rayOption=option,
                    bridgetreasureChest=self.bridgetreasureChest)

                self.runv2raycore.start.emit()
                self.autocheckProxy(i)
                break
            else:
                del currentActiveRow

    def autocheckProxy(self, row):
        # TODO
        """
        Frequent access to the server may cause suspicion of DDOS attacks, 
        which may put the VPS server at risk.
        """
        enableAutoCheck = self.bridgetreasureChest.getConnectionEnable()

        if (enableAutoCheck):
            self.proxyStatus = proxyTest.proxyStatus()
            self.autoCheckTimer = QTimer()
            invervalTime = self.bridgetreasureChest.getConnectioninterval()
            timeout = self.bridgetreasureChest.getConnectiontimeout()
            proxyAddress = self.getProxyAddressFromTableWidget(row)

            if proxyAddress:
                self.autoCheckTimer.timeout.connect(
                    lambda: self.startCheckProxy(timeout=timeout,
                                                 proxyAddress=proxyAddress,
                                                 row=row,
                                                 proxyStatus=self.proxyStatus))

                self.bridgetreasureChest.setProxy(proxyAddress)

                if v2rayshellDebug: self.autoCheckTimer.start(6000)
                else: self.autoCheckTimer.start(1000 * invervalTime)

                self.autoCheckTimer.singleShot(
                    100,
                    lambda: self.startCheckProxy(timeout=timeout,
                                                 proxyAddress=proxyAddress,
                                                 row=row,
                                                 proxyStatus=self.proxyStatus))

    def setTableWidgetTimelag(self, row, proxyStatus):
        newlabelTimelag = self.setlabelTimeLagColor(proxyStatus)
        oldlabelTimelag = self.tableWidgetBridge.cellWidget(row, 4)
        del oldlabelTimelag
        self.tableWidgetBridge.setCellWidget(row, 4, newlabelTimelag)
        self.tableWidgetBridge.resizeColumnsToContents()

    def startCheckProxy(self, timeout, proxyAddress, row, proxyStatus):
        if (proxyAddress):
            proxyStatus.clear()
            proxyStatus.signal.connect(
                lambda: self.setTableWidgetTimelag(row, proxyStatus))

            self.proxy = proxyTest.proxyTest(proxyprotocol=proxyAddress[0],
                                             proxyhostname=proxyAddress[1],
                                             proxyhostport=int(
                                                 proxyAddress[2]),
                                             getproxyStatus=proxyStatus,
                                             timeout=int(timeout))

    def setlabelTimeLagColor(self, proxyStatus=False):
        labelTimeLag = QLabel()
        if (proxyStatus and not proxyStatus.getProxyError()):
            labelFont = QFont()
            labelFont.setPointSize(12)
            labelFont.setBold(True)
            labelTimeLag.setFont(labelFont)
            forestGreen = "QLabel {color: rgb(34, 139, 34)}"
            darkOrange = "QLabel {color: rgb(255, 140, 0)}"
            red = "QLabel {color: rgb(194,24,7)}"

            if (proxyStatus.getElapsedTime() < 260):
                labelTimeLag.setStyleSheet(forestGreen)
            elif (proxyStatus.getElapsedTime() > 420):
                labelTimeLag.setStyleSheet(red)
            else:
                labelTimeLag.setStyleSheet(darkOrange)
            labelTimeLag.setText("{} ms".format(
                str(proxyStatus.getElapsedTime())))

            return labelTimeLag

        elif (proxyStatus and proxyStatus.getProxyError()):
            labelTimeLag.setText("{}:{}".format(
                proxyStatus.getProxyErrorString(),
                proxyStatus.getProxyErrorCode()))

            self.proxyTryConnect.trytimesDecrease()
            return labelTimeLag

    def swapNextConfigFile(self):
        self.onv2raycoreStop()
        try:
            self.trytimes = self.bridgetreasureChest.getConnectiontrytimes()
            self.interval = self.bridgetreasureChest.getConnectioninterval()
            self.proxyTryConnect.stopperiodicCheckProxyStatus()
            if v2rayshellDebug: self.proxyTryConnect.setresetTime(6, 3)
            else:
                self.proxyTryConnect.setresetTime(self.interval, self.trytimes)
        except Exception:
            self.proxyTryConnect.setresetTime(60, 3)

        if (self.bridgetreasureChest.connectionisSwitch()):
            ### swap next row's configFile
            buttons = self.radioButtonGroup.buttons()
            buttonsNumber = len(buttons)
            activeRow = False
            for i in range(buttonsNumber):
                if buttons[i].isChecked():
                    buttons[i].setChecked(False)
                    if i == buttonsNumber - 1:
                        buttons[0].setChecked(True)
                        activeRow = 0
                        break
                    else:
                        buttons[i + 1].setChecked(True)
                        activeRow = i + 1
                    break

            ### change the row icons
            for i in range(buttonsNumber):
                widget = self.tableWidgetBridge.cellWidget(i, 0)
                if (widget):
                    widget.setIcon(self.iconStop)
                    widget.setIconSize(self.__iconSize)
                    if (widget.isChecked()):
                        pass
            widget = self.tableWidgetBridge.cellWidget(activeRow, 0)
            if widget:
                widget.setIcon(self.iconStart)
                widget.setIconSize(self.__iconSize)

        self.onv2raycoreStart()

    def onopenv2rayupdatePanel(self):
        currentActiveRow = False
        rowCount = self.tableWidgetBridge.rowCount()
        currentRow = False
        for i in range(rowCount):
            currentActiveRow = self.tableWidgetBridge.cellWidget(i, 0)
            if currentActiveRow.isChecked():
                currentRow = i
                break

        if (currentActiveRow and currentActiveRow.isChecked()):
            proxy = self.tableWidgetBridge.item(currentRow, 3)
            proxy = proxy.text().split(":")
            protocol = QNetworkProxy.Socks5Proxy
            if (proxy[0] == "socks"):
                protocol = QNetworkProxy.Socks5Proxy
            elif (proxy[0] == "http"):
                protocol = QNetworkProxy.HttpProxy
            hostName = proxy[1]
            hostPort = int(proxy[2])

            v2rayAPI = updatePanel.v2rayAPI()
            self.createupdatePanel = updatePanel.v2rayUpdatePanel(
                v2rayapi=v2rayAPI,
                protocol=protocol,
                proxyhostName=hostName,
                port=hostPort,
                bridgetreasureChest=self.bridgetreasureChest)
            self.createupdatePanel.createPanel()
            self.createupdatePanel.setAttribute(Qt.WA_DeleteOnClose)
            self.createupdatePanel.setWindowIcon(self.iconStart)
            self.createupdatePanel.setWindowTitle(
                self.translate("bridgePanel", "Check V2Ray-core update"))
            self.createupdatePanel.resize(QSize(1024, 320))
            self.createupdatePanel.move(
                QApplication.desktop().screen().rect().center() -
                self.createupdatePanel.rect().center())
            self.createupdatePanel.show()
            self.createupdatePanel.exec_()
        else:
            self.noPoxyServerRunning()

    def ontableWidgetBridgeRightClicked(self, pos):
        index = self.tableWidgetBridge.indexAt(pos)
        clickedRow.rightClickedRow = index.row()
        clickedRow.mousePos = QCursor().pos()
        self.popMenu.move(QCursor().pos())
        self.popMenu.show()

    def ontableWidgetBridgecellDoubleClicked(self, row, column):
        if (column == 1):
            hostName, ok = QInputDialog.getText(
                self, self.translate("bridgePanel", 'Host Name'),
                self.translate("bridgePanel", 'Enter Host Name:'))
            if (ok):
                self.tableWidgetBridge.setItem(row, column,
                                               QTableWidgetItem(str(hostName)))
                self.tableWidgetBridge.resizeColumnsToContents()
        elif (column == 2):
            fileNames = self.onopenV2rayConfigJSONFile()
            if (fileNames):
                for fileName in fileNames:
                    self.tableWidgetBridge.setItem(
                        row, column, QTableWidgetItem(str(fileName)))
                    self.tableWidgetBridge.resizeColumnsToContents()
        elif (column == 3):
            self.onproxyserverTimeLagTest()
        elif (column == 4):
            self.onproxyserverTimeLagTest()

    def getProxyAddressFromTableWidget(self, row):
        proxy = self.tableWidgetBridge.item(row, 3)
        try:
            proxy = proxy.text().split(":")
        except Exception:
            return False

        if (proxy[0] == "socks"):
            proxy[0] = QNetworkProxy.Socks5Proxy
        elif (proxy[0] == "http"):
            proxy[0] = QNetworkProxy.HttpProxy

        if len(proxy) < 3: return False
        else: return proxy

    def onproxyserverTimeLagTest(self):
        proxyStatus = proxyTest.proxyStatus()
        """
        right clicked mouse button pop a menu check proxy
        """
        currentActiveRow = False
        rowCount = self.tableWidgetBridge.rowCount()
        currentRow = False
        for i in range(rowCount):
            currentActiveRow = self.tableWidgetBridge.cellWidget(i, 0)
            if currentActiveRow.isChecked():
                currentRow = i
                break
        if (currentActiveRow and currentActiveRow.isChecked()):
            proxy = self.getProxyAddressFromTableWidget(currentRow)
            protocol = proxy[0]
            hostName = proxy[1]
            hostPort = int(proxy[2])

            proxy = proxyTest.proxyTestPanel(proxyhostname=hostName,
                                             proxyhostport=hostPort,
                                             proxyprotocol=protocol,
                                             getproxyStatus=proxyStatus)
            proxy.createproxyTestPanel()
            proxy.setAttribute(Qt.WA_DeleteOnClose)
            proxy.setWindowTitle(
                self.translate("bridgePanel", "Proxy Time Lag Check"))
            proxy.setWindowIcon(self.iconStart)
            proxy.resize(QSize(600, 480))
            proxy.move(QApplication.desktop().screen().rect().center() -
                       proxy.rect().center())
            proxy.show()
            proxy.exec_()
        else:
            self.noPoxyServerRunning()

    def noPoxyServerRunning(self):
        warningPanel = QDialog()
        warningPanel.setAttribute(Qt.WA_DeleteOnClose)
        warningPanel.setWindowTitle(self.translate("bridgePanel",
                                                   "Warnnig..."))
        warningPanel.setWindowIcon(self.iconStop)
        labelMsg = QLabel(
            self.translate(
                "bridgePanel",
                "There no any server is running, \n[File]->[Add V2Ray-core Config File] (Ctrl+n) add a config.json."
            ))
        vbox = QVBoxLayout()
        vbox.addWidget(labelMsg)
        warningPanel.setLayout(vbox)
        warningPanel.move(QApplication.desktop().screen().rect().center() -
                          warningPanel.rect().center())
        warningPanel.open()
        warningPanel.exec_()

    def getProxyAddressFromJSONFile(self, filePath):
        from bridgehouse.editMap.port import treasureChest, openV2rayJSONFile
        tempTreasureChest = treasureChest.treasureChest()
        openV2rayJSONFile.openV2rayJSONFile(
            filePath, tempTreasureChest, disableLog=True).initboundJSONData()
        inbound = tempTreasureChest.getInbound()
        if (inbound):
            protocol = inbound["protocol"]
            ipAddress = inbound["listen"]
            port = inbound["port"]
            if (protocol == "socks" or protocol == "http"):
                return "{}:{}:{}".format(protocol, ipAddress, port)
            else:
                return False
        else:
            return False

    def onradioButtonClicked(self, e):
        rowCount = self.tableWidgetBridge.rowCount()
        #radioButtonClickedRow = 0
        for i in range(rowCount):
            widget = self.tableWidgetBridge.cellWidget(i, 0)
            if (widget):
                widget.setIcon(self.iconStop)
                widget.setIconSize(self.__iconSize)
                if (widget.isChecked()):
                    #radioButtonClickedRow = i
                    pass
        e.setIcon(self.iconStart)
        e.setIconSize(self.__iconSize)

    def onloadV2rayshellConfigFile(self, init=False):
        """
        when the script first start, and auto load v2ray-shell config file.
        """
        if init:
            self.settingv2rayshelltableWidget()
        else:

            def openV2rayshellConfigFile():
                options = QFileDialog.Options()
                filePath, _ = QFileDialog.getOpenFileName(
                    self,
                    self.translate("bridgePanel",
                                   "Open V2Ray-sehll Config File"),
                    "",
                    "V2Ray-shell config file (*.v2rayshell)",
                    options=options)
                if (filePath):
                    self.bridgetreasureChest.clear()
                    self.tableWidgetBridge.setRowCount(0)
                    self.bridgetreasureChest.initbridgeJSONData(
                        v2rayshellConfigFileName=filePath)
                    self.settingv2rayshelltableWidget()

            openV2rayshellConfigFile()

    def onopenV2rayConfigJSONFile(self):
        """
        open a new v2ray config file to tabelWidget
        """
        options = QFileDialog.Options()
        filePaths, _ = QFileDialog.getOpenFileNames(
            self,
            self.translate("bridgePanel", "Open V2Ray-core Config File"),
            "",
            """
                                                  V2Ray config file (*.json);;
                                                  All File (*);;
                                                  """,
            options=options)

        if (filePaths):
            return filePaths
        else:
            return False

    def createBridgepreferencesPanel(self):
        self.createpreferencesPanel = bridgePreference.bridgepreferencesPanel(
            self.bridgetreasureChest)
        self.createpreferencesPanel.setAttribute(Qt.WA_DeleteOnClose)
        self.createpreferencesPanel.createpreferencesPanel()
        self.createpreferencesPanel.setWindowIcon(self.iconStart)
        self.createpreferencesPanel.move(
            QApplication.desktop().screen().rect().center() -
            self.createpreferencesPanel.rect().center())
        self.createpreferencesPanel.open()
        self.createpreferencesPanel.exec_()

    def settingv2rayshelltableWidget(self):
        v2rayConfigFiles = self.bridgetreasureChest.getV2raycoreconfigFiles()
        if not v2rayConfigFiles: return
        v2rayConfigFilesNumber = len(v2rayConfigFiles)
        if (v2rayConfigFilesNumber > 0):
            self.tableWidgetBridge.setRowCount(0)
            for i in range(v2rayConfigFilesNumber):
                try:
                    enable = bool(v2rayConfigFiles[i]["enable"])
                    hostName = str(v2rayConfigFiles[i]["hostName"])
                    configFileName = str(v2rayConfigFiles[i]["configFileName"])
                except Exception:
                    pass

                radioButtonStopStart = QRadioButton(self)
                radioButtonStopStart.setIcon(
                    self.iconStop if not enable else self.iconStart)
                radioButtonStopStart.setChecked(True if enable else False)
                radioButtonStopStart.setIconSize(self.__iconSize)
                self.radioButtonGroup.addButton(radioButtonStopStart)
                self.tableWidgetBridge.setRowCount(i + 1)
                self.tableWidgetBridge.setCellWidget(i, 0,
                                                     radioButtonStopStart)
                self.tableWidgetBridge.setItem(i, 1,
                                               QTableWidgetItem(hostName))
                self.tableWidgetBridge.setItem(
                    i, 2, QTableWidgetItem(configFileName))
                self.tableWidgetBridge.setItem(
                    i, 3,
                    QTableWidgetItem(
                        self.getProxyAddressFromJSONFile(configFileName)))
                self.tableWidgetBridge.resizeColumnsToContents()
                #self.tableWidgetBridge.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

    def onsaveV2rayshellConfigFile(self):
        self.bridgetreasureChest.clearconfigFiles()
        rowCount = self.tableWidgetBridge.rowCount()
        for i in range(rowCount):
            enable = self.tableWidgetBridge.cellWidget(i, 0)
            if enable and enable.isChecked():
                enable = True
            else:
                enable = False

            hostName = self.tableWidgetBridge.item(i, 1)
            if hostName:
                hostName = hostName.text()
            else:
                hostName = ""

            config = self.tableWidgetBridge.item(i, 2)
            if config:
                config = config.text()
            else:
                config = ""
            self.bridgetreasureChest.setV2raycoreconfigFiles(
                enable, hostName, configFileName=config)
        self.bridgetreasureChest.save.emit()

    def oncreatenauticalChartPanel(self):
        v2rayConfigFileName = self.tableWidgetBridge.item(
            clickedRow.rightClickedRow, 2)
        if (v2rayConfigFileName):
            nc = nauticalChartPanel.nauticalChartPanel(
                v2rayConfigFileName.text())
            nc.setAttribute(Qt.WA_DeleteOnClose)
            nc.createPanel()
            nc.setWindowTitle(
                self.translate("bridgePanel", "V2Ray config file edit"))
            nc.setWindowIcon(self.iconStart)
            nc.setGeometry(0, 0, 1024, 768)
            # move widget to center
            nc.move(QApplication.desktop().screen().rect().center() -
                    nc.rect().center())
            nc.show()
            nc.exec_()

    def tableWidgetBridgeAddNewV2rayConfigFile(self):
        configFileNames = self.onopenV2rayConfigJSONFile()
        if (configFileNames):
            for configFileName in configFileNames:
                rowCount = self.tableWidgetBridge.rowCount()
                radioButtonStopStart = QRadioButton(self)
                radioButtonStopStart.setIcon(self.iconStop)
                radioButtonStopStart.setIconSize(self.__iconSize)
                self.radioButtonGroup.addButton(radioButtonStopStart)

                self.tableWidgetBridge.setRowCount(rowCount + 1)
                self.tableWidgetBridge.setCellWidget(rowCount, 0,
                                                     radioButtonStopStart)
                self.tableWidgetBridge.setItem(rowCount, 1,
                                               QTableWidgetItem(""))
                self.tableWidgetBridge.setItem(
                    rowCount, 2, QTableWidgetItem(configFileName))
                self.tableWidgetBridge.setItem(
                    rowCount, 3,
                    QTableWidgetItem(
                        self.getProxyAddressFromJSONFile(configFileName)))
                self.tableWidgetBridge.resizeColumnsToContents()
        else:
            pass

    def tableWidgetBridgeDelete(self):
        self.tableWidgetBridge.removeRow(clickedRow.rightClickedRow)

    def validateV2rayJSONFile(self, JSONData):
        """
        simply validate a V2Ray json file.
        """
        try:
            JSONData["inbound"]
            JSONData["outbound"]
        except KeyError:
            return False
        else:
            return True

    def about(self):
        NineteenEightySeven = QLabel(
            self.translate(
                "bridgePanel",
                """Across the Great Wall, we can reach every corner in the world."""
            ))  ### Crossing the Great Wall to Join the World
        Timeless = QLabel(
            self.translate(
                "bridgePanel",
                """You weren't thinking about that when you were creating it.\nBecause if you did? You never would have gone through with it."""
            ))
        DwayneRichardHipp = QLabel(
            self.translate(
                "bridgePanel",
                """May you do good and not evil.\nMay you find forgiveness for yourself and forgive others.\nMay you share freely, never taking more than you give."""
            ))
        vbox = QVBoxLayout()
        vbox.addWidget(NineteenEightySeven)
        vbox.addWidget(Timeless)
        vbox.addWidget(DwayneRichardHipp)

        dialogAbout = QDialog()
        dialogAbout.setAttribute(Qt.WA_DeleteOnClose)
        dialogAbout.setWindowTitle(
            self.translate("bridgePanel", "About V2Ray-shell"))
        dialogAbout.setWindowIcon(self.iconStart)
        dialogAbout.move(QApplication.desktop().screen().rect().center() -
                         dialogAbout.rect().center())
        dialogAbout.setLayout(vbox)
        dialogAbout.open()
        dialogAbout.exec_()

    def bugReportPanel(self):
        self.bugReport = bugReport.bugReport()
        self.bugReport.setAttribute(Qt.WA_DeleteOnClose)
        self.bugReport.setWindowTitle(
            self.translate("bridgePanel", "Bug Report"))
        self.bugReport.setWindowIcon(self.iconStart)
        self.bugReport.createPanel()
        self.bugReport.show()
        self.bugReport.setGeometry(250, 150, 1024, 768)
示例#52
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.title = 'Convolutional Neural Network'
        self.left = 300
        self.top = 300
        self.width = 960
        self.height = 560
        self.first_run = True
        self.current_save = None
        self.running = False
        self.iteration_stats = []
        self.settings = QSettings("Theo Styles",
                                  "Convolutional Neural Network")
        self.img_size = self.settings.value("img_size", 44)
        self.init_ui()

    def update_progress(self, amount=0, status="Running"):
        self.left_area.progressModule.progress.setText(status + " - " +
                                                       str(amount) + "%")
        self.left_area.progressModule.progress.setValue(amount)

    def testing_finished(self, cls_pred):
        self.running = False
        self.main_area_reports.focus()
        for i, prob_array in enumerate(cls_pred):
            image = self.dataset.testing_images[i]
            pred_index = np.argmax(prob_array)
            prob = prob_array[pred_index]
            labelForDigit = self.dataset.labels[pred_index]
            for set in self.main_area_neural.sets:
                if set.name == labelForDigit:
                    item = set.add_image(image)
                    if prob <= 0.5:
                        item.set_important()

        self.toolbar.enable_action(0, 0)

    def run_neural_net(self):
        self.left_area.progressModule.progress.setDefault()
        self.obj = RunNeuralNet(self.dataset, self.img_size,
                                len(self.main_area_neural.sets))  # no parent!
        self.thread = QThread()  # no parent!

        self.obj.moveToThread(self.thread)
        self.obj.one_iteration.connect(self.update_progress)
        self.obj.testing_finished.connect(self.testing_finished)
        self.thread.started.connect(self.obj.long_running)

        self.thread.start()
        self.toolbar.disable_action(0, 0)

    def add_toolbar_clicked(self):
        folder_name = QFileDialog.getExistingDirectory(
            self, "Select Directory With Testing Images")

        if folder_name:
            self.main_area_neural.top_widget.setVisible(True)
            self.main_area_neural.initial_image_grid_visible = True
            if self.main_area_neural.empty_label:
                self.main_area_neural.empty_label.setText(
                    "Now create sets by selecting images and using the + button to the right of the images!"
                )
            self.main_area_neural.initial_image_grid.populate_from_folder(
                folder_name, self.update_progress)

    def export_sets(self):
        sets = self.main_area_neural.sets
        if len(sets) == 0:
            ErrorDialog.dialog(self, "There are no sets to export")
            return

        folder_name = QFileDialog.getExistingDirectory(
            self, "Select a directory to export to")

        if folder_name:
            self.left_area.progressModule.progress.setDefault()
            self.obj = SaveLoad(sets=self.main_area_neural.sets,
                                folder_name=folder_name)  # no parent!
            self.thread = QThread()  # no parent!

            self.obj.moveToThread(self.thread)
            self.obj.one_iteration.connect(self.update_progress)
            self.thread.started.connect(self.obj.export_sets)

            self.thread.start()

    def run_clicked(self):
        sets = self.main_area_neural.sets

        if len(sets) == 0:
            return ErrorDialog.dialog(
                self,
                "Please create at least one set before running the neural network"
            )

        if self.running:
            return ErrorDialog.dialog(self,
                                      "The neural network is already running")

        itemNames = []
        itemData = []
        setCount = 0
        total_incorrect = 0
        self.running = True

        for set in sets:
            setCount += 1
            itemCount = len(set.all_images)
            total_incorrect += set.incorrectly_classified_local
            set.incorrectly_classified_local = 0
            for index in range(itemCount):
                item = set.all_images[index]
                if item == None: continue
                itemNames.append(set.name)
                itemData.append(item.imageData)
            set.clear()

        self.iteration_stats.append(total_incorrect)
        self.dataset.add_sets_to_training_data(setCount, itemNames, itemData)

        if self.first_run or self.main_area_neural.initial_image_grid_visible:
            all_image_count = self.main_area_neural.initial_image_grid.count()
            testing_images = []
            for index in range(all_image_count):
                item = self.main_area_neural.initial_image_grid.item(index)
                if item == None: continue
                testing_images.append(item.imageData)
            self.main_area_neural.initial_image_grid.clear()
            self.main_area_neural.top_widget.setVisible(False)
            self.main_area_neural.initial_image_grid_visible = False
            self.dataset.set_testing_data(testing_images)
        else:
            self.dataset.new_testing_data()

        self.first_run = False

        self.run_neural_net()

    def finished_opening_sets(self):
        self.dataset.new_testing_data()
        self.main_area_reports.focus()

    def set_iteration_stats(self, iteration_stats):
        self.iteration_stats = iteration_stats

    def open_sets(self):
        fileName, filter = QFileDialog.getOpenFileName(
            self, 'Open sets save', PathHelpers.getPath("saves"),
            "Set Files (*.sets)")

        if fileName:
            self.current_save = fileName
            self.main_area_neural.clear_sets()
            self.left_area.progressModule.progress.setDefault()
            self.obj = SaveLoad(self.current_save)  # no parent!
            self.thread = QThread()  # no parent!

            self.obj.moveToThread(self.thread)
            self.obj.one_iteration.connect(self.update_progress)
            self.obj.create_set.connect(self.main_area_neural.create_new_set)
            self.obj.add_to_training_set.connect(
                self.main_area_neural.add_images_to_set)
            self.obj.add_to_testing_set.connect(
                self.dataset.add_to_testing_data)
            self.obj.set_iteration_stats.connect(self.set_iteration_stats)
            self.obj.set_classified_info.connect(
                self.main_area_neural.set_classified_for_set)
            self.obj.finished.connect(self.finished_opening_sets)
            self.thread.started.connect(self.obj.load_images)

            self.thread.start()

    def save_sets_as(self):
        self.current_save = None
        self.save_sets()

    def save_sets(self):

        if self.current_save:
            fileName = self.current_save
        else:
            fileName, filter = QFileDialog.getSaveFileName(
                self, 'Save sets', PathHelpers.getPath("saves"),
                "Set Files (*.sets)")

        if fileName:
            sets = self.main_area_neural.sets[:]
            if self.main_area_neural.trash_set:
                sets.append(self.main_area_neural.trash_set)
            self.current_save = fileName
            self.left_area.progressModule.progress.setDefault()
            self.obj = SaveLoad(
                self.current_save,
                sets,
                self.dataset.all_testing_images,
                iteration_stats=self.iteration_stats)  # no parent!
            self.thread = QThread()  # no parent!

            self.obj.moveToThread(self.thread)
            self.obj.one_iteration.connect(self.update_progress)
            self.thread.started.connect(self.obj.save_images)

            self.thread.start()

    def deleted_set(self, set_name):
        self.datapanel.delete_training_row(set_name)

    def added_to_set(self, set_name):
        self.datapanel.increment_training_table(set_name)

    def removed_from_set(self, set_name):
        self.datapanel.decrement_training_table(set_name)

    def set_testing_amount(self, amount):
        self.datapanel.set_testing_amount(amount)

    def switch_to_neural(self):
        self.left_area.menu.setCurrentRow(0)

    def switch_to_reports(self):
        self.left_area.menu.setCurrentRow(1)

    def switch_to_settings(self):
        self.left_area.menu.setCurrentRow(2)

    def menu_changed(self, index):
        sets = self.main_area_neural.sets[:]
        if self.main_area_neural.trash_set:
            sets.append(self.main_area_neural.trash_set)
        self.main_area_neural.setVisible(False)
        self.main_area_settings.setVisible(False)
        self.main_area_reports.setVisible(False)
        if index == 0:
            self.main_area_neural.setVisible(True)
        elif index == 1:
            self.main_area_reports.setVisible(True)
            self.main_area_reports.focus(sets, self.iteration_stats)
        elif index == 2:
            self.main_area_settings.setVisible(True)
            self.main_area_settings.changed()

    def view_all_training(self):
        sets = self.main_area_neural.sets[:]
        if self.main_area_neural.trash_set:
            sets.append(self.main_area_neural.trash_set)

        self.training_window = TrainingWindow(self, sets)
        self.training_window.show()

    def view_all_testing(self):
        self.testing_window = TestingWindow(self,
                                            self.dataset.all_testing_images)
        self.testing_window.show()

    def exit_app(self):
        sys.exit(0)

    def about_clicked(self):
        d = QDialog(self)
        layout = QVBoxLayout()
        d.setLayout(layout)
        layout.addWidget(
            QLabel("Convolutional Neural Network - Created By Theo Styles"))
        layout.addWidget(QLabel("Credits:"))
        layout.addWidget(
            QLabel("Play icon made by Google from www.flaticon.com"))
        layout.addWidget(
            QLabel("Plus icon made by Madebyoliver from www.flaticon.com"))
        layout.addWidget(
            QLabel("Export icon made by Popcic from www.flaticon.com"))
        layout.addWidget(
            QLabel("Up arrow icon made by Google from www.flaticon.com"))
        layout.addWidget(
            QLabel("Down arrow icon made by Google from www.flaticon.com"))
        layout.addWidget(
            QLabel("Tick icon made by Eleonor Wang from www.flaticon.com"))
        d.setWindowTitle("About")
        d.exec_()

    def init_ui(self):
        self.settings = QSettings("Theo Styles",
                                  "Convolutional Neural Network")
        self.settings.setValue("test", 1)
        self.dataset = DataSet(self.img_size)
        self.dataset.test_set_changed.connect(self.set_testing_amount)
        qss_file = open(
            PathHelpers.getPath("GUI/Stylesheets/default.qss")).read()
        self.setStyleSheet(qss_file)

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

        self.main_grid = QSplitter()
        self.main_grid.setObjectName("verticalSplitter")

        self.main_grid.setContentsMargins(0, 0, 0, 0)

        self.right_layout = QVBoxLayout()
        self.right_widget = QWidget()
        self.right_widget.setLayout(self.right_layout)

        self.right_grid = QSplitter()
        self.right_grid.setObjectName("verticalSplitter")

        self.right_layout.setContentsMargins(0, 0, 0, 0)
        self.right_layout.setSpacing(0)
        self.right_grid.setContentsMargins(0, 0, 0, 0)

        self.right_stacking = QWidget()
        self.right_stacking_grid = QGridLayout()
        self.right_stacking.setLayout(self.right_stacking_grid)
        self.right_grid.addWidget(self.right_stacking)

        self.right_stacking_grid.setContentsMargins(0, 0, 0, 0)
        self.right_stacking_grid.setSpacing(0)

        self.main_area_neural = NeuralNetSection()
        self.main_area_neural.added_to_set.connect(self.added_to_set)
        self.main_area_neural.removed_from_set.connect(self.removed_from_set)
        self.main_area_neural.deleted_set.connect(self.deleted_set)
        self.right_stacking_grid.addWidget(self.main_area_neural, 0, 0)

        self.main_area_settings = SettingsSection()
        self.right_stacking_grid.addWidget(self.main_area_settings, 0, 0)
        self.main_area_settings.setVisible(False)

        self.main_area_reports = ReportsSection(self.main_area_neural.sets,
                                                self.iteration_stats)
        self.right_stacking_grid.addWidget(self.main_area_reports, 0, 0)
        self.main_area_reports.setVisible(False)

        self.datapanel = DataInfoPanel()
        self.datapanel.clicked_training_view_all_sig.connect(
            self.view_all_training)
        self.datapanel.clicked_testing_view_all_sig.connect(
            self.view_all_testing)
        self.right_grid.addWidget(self.datapanel)

        self.right_grid.setStretchFactor(0, 10)
        self.right_grid.setStretchFactor(1, 11)

        self.left_area = MenuPanel()
        self.left_area.selectedItem.connect(self.menu_changed)

        self.toolbar = ToolbarPanel()
        self.toolbar.run_clicked.connect(self.run_clicked)
        self.toolbar.add_clicked.connect(self.add_toolbar_clicked)
        self.toolbar.export_clicked.connect(self.export_sets)

        self.right_layout.addWidget(self.toolbar)
        self.right_layout.addWidget(self.right_grid)

        self.main_grid.addWidget(self.left_area)
        self.main_grid.addWidget(self.right_widget)

        self.setCentralWidget(self.main_grid)
        self.main_grid.setStretchFactor(0, 6)
        self.main_grid.setStretchFactor(1, 10)

        save_action = QAction("&Save", self)
        save_action.setShortcut("Ctrl+S")
        save_action.setStatusTip('Save the current sets')
        save_action.triggered.connect(self.save_sets)

        save_action_as = QAction("&Save As", self)
        save_action_as.setStatusTip('New save for the current sets')
        save_action_as.triggered.connect(self.save_sets_as)

        open_action = QAction("&Open", self)
        open_action.setShortcut("Ctrl+O")
        open_action.setStatusTip('Open a sets save file')
        open_action.triggered.connect(self.open_sets)

        exit_action = QAction("&Exit", self)
        exit_action.setStatusTip('Exit the application')
        exit_action.triggered.connect(self.exit_app)

        menubar = self.menuBar()
        file_menu = menubar.addMenu('&File')
        file_menu.addAction(open_action)
        file_menu.addAction(save_action)
        file_menu.addAction(save_action_as)
        file_menu.addAction(exit_action)

        neural_action = QAction("&Neural Net", self)
        neural_action.setStatusTip('View the neural network')
        neural_action.triggered.connect(self.switch_to_neural)

        reports_action = QAction("&Reports", self)
        reports_action.setStatusTip('View reports and statistics')
        reports_action.triggered.connect(self.switch_to_reports)

        settings_action = QAction("&Settings", self)
        settings_action.setStatusTip('View settings')
        settings_action.triggered.connect(self.switch_to_settings)

        view_menu = menubar.addMenu('&View')
        view_menu.addAction(neural_action)
        view_menu.addAction(reports_action)
        view_menu.addAction(settings_action)

        import_action = QAction("&Import folder", self)
        import_action.setStatusTip('Import a folder of images')
        import_action.triggered.connect(self.add_toolbar_clicked)

        export_action = QAction("&Export sets", self)
        export_action.setStatusTip('Export sets to folder')
        export_action.triggered.connect(self.export_sets)

        settings_action = QAction("&Settings", self)
        settings_action.setStatusTip('View settings')
        settings_action.triggered.connect(self.switch_to_settings)

        tools_menu = menubar.addMenu('&Tools')
        tools_menu.addAction(import_action)
        tools_menu.addAction(export_action)

        run_action = QAction("&Run Neural Network", self)
        run_action.setStatusTip('Start running the neural network')
        run_action.triggered.connect(self.run_clicked)

        run_menu = menubar.addMenu('&Run')
        run_menu.addAction(run_action)

        about_action = QAction("&About", self)
        about_action.setStatusTip('About the application')
        about_action.triggered.connect(self.about_clicked)

        help_menu = menubar.addMenu('&Help')
        help_menu.addAction(about_action)

        self.show()
示例#53
0
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        # 在初始化之前设置pg,因为初始化会写死配置,无法在更改
        # pg.setConfigOption('foreground', 'd')
        # 使曲线看起来光滑
        pg.setConfigOptions(antialias=True)
        # 设置文字的字体
        font = QFont()
        font.setFamily("Microsoft Yahei")
        font.setPointSize(11)

        self.setMinimumHeight(750)
        self.setMinimumWidth(1000)
        # self.setFixedSize(1000, 750)

        # 统一设置按钮的字体
        btn_list = []

        # 设置题目和状态栏
        self.setWindowTitle("心电平台检测")

        # 设置状态栏
        self.status = self.statusBar()
        self.status.showMessage("检测~")

        # 整体布局
        pagelayout = QVBoxLayout()

        # 顶层按钮布局
        top = QFrame(self)
        top.setFrameShape(QFrame.StyledPanel)
        btn_layout = QHBoxLayout(top)
        self.data_com = QComboBox()
        delegate = QStyledItemDelegate()
        self.data_com.setItemDelegate(delegate)
        self.data_com.addItem("选择心电数据")
        self.data_com.setFixedSize(200, 40)
        self.data_com.setFont(font)
        set_btn = QPushButton("设置")
        help_btn = QPushButton("帮助")
        save_btn = QPushButton("存储")
        back_btn = QPushButton("回放")
        fig_btn = QPushButton("截图")
        patient_table_btn = QPushButton("病例表")
        self.stop_btn = QPushButton("暂停")
        btn_list.append(set_btn)
        btn_list.append(help_btn)
        btn_list.append(save_btn)
        btn_list.append(back_btn)
        btn_list.append(self.stop_btn)
        btn_list.append(fig_btn)
        btn_list.append(patient_table_btn)
        btn_layout.addWidget(self.data_com)
        btn_layout.addWidget(set_btn)
        btn_layout.addWidget(help_btn)
        btn_layout.addWidget(save_btn)
        btn_layout.addWidget(self.stop_btn)
        btn_layout.addWidget(back_btn)
        btn_layout.addWidget(fig_btn)
        btn_layout.addWidget(patient_table_btn)

        for btn in btn_list:
            btn.setFont(font)
            btn.setFixedSize(100, 40)

        # 以此统计病人数量
        self.patient = 0
        for i in range(0, 10):
            self.patient += 1
            self.data_com.addItem(str(100 + i))

        # 底层布局
        bottom = QFrame(self)
        bottom.setFrameShape(QFrame.StyledPanel)
        self.bottom_layout = QStackedLayout(bottom)

        # 1. 绘图区域
        plot_widget = QWidget(bottom)
        plot_layout = QHBoxLayout()
        win = pg.GraphicsLayoutWidget()
        self.p = win.addPlot()
        self.p.getAxis("bottom").tickFont = font
        self.p.getAxis("left").tickFont = font
        # 背景透明
        win.setBackground(background=None)
        plot_layout.addWidget(win)
        plot_widget.setLayout(plot_layout)
        self.bottom_layout.addWidget(plot_widget)

        # 2. 帮助文档
        help_widget = QWidget(bottom)
        help_layout = QHBoxLayout()
        self.help_text = QTextEdit()
        self.help_text.setReadOnly(True)
        help_layout.addWidget(self.help_text)
        help_widget.setLayout(help_layout)
        self.bottom_layout.addWidget(help_widget)
        help_btn.clicked.connect(self.show_help)

        # 3. 设置
        set_widget = QWidget(bottom)
        set_layout = QVBoxLayout()
        theme_layout = QHBoxLayout()
        self.theme_white_radio = QRadioButton("白色主题")
        self.theme_white_radio.setFixedWidth(120)
        self.theme_black_radio = QRadioButton("黑色主题")
        theme_label = QLabel("主题颜色选择")
        theme_label.setFixedWidth(120)
        theme_layout.addWidget(theme_label)
        theme_layout.addWidget(self.theme_white_radio)
        theme_layout.addWidget(self.theme_black_radio)
        line_width_layout = QHBoxLayout()
        line_width = QLabel("设置线宽(范围1-4)")
        line_width.setFixedWidth(150)
        line_width_layout.addWidget(line_width)
        self.line_width_spin = QSpinBox()
        self.line_width_spin.setMinimum(1)
        self.line_width_spin.setMaximum(4)
        line_width_layout.addWidget(self.line_width_spin)
        set_layout.addLayout(theme_layout)
        set_layout.addLayout(line_width_layout)
        set_widget.setLayout(set_layout)
        self.bottom_layout.addWidget(set_widget)
        self.theme_white_radio.toggled.connect(self.change_status)
        self.theme_black_radio.toggled.connect(self.change_status)
        set_btn.clicked.connect(self.set_)

        # 暂停与启动的切换
        self.stop_btn.clicked.connect(self.stop_)

        # 截图功能
        fig_btn.clicked.connect(self.save_fig)

        # 回放功能
        back_btn.clicked.connect(self.back_show)

        # 保存数据功能
        save_widget = QWidget(bottom)
        save_layout = QHBoxLayout()
        save_label = QLabel("请选择保存数据的区间")
        save_label.setFixedHeight(40)
        self.left_interval = QLineEdit()
        self.left_interval.setFixedHeight(40)
        self.left_interval.setPlaceholderText("起始点,左区间")
        self.right_interval = QLineEdit()
        self.right_interval.setFixedHeight(40)
        self.right_interval.setPlaceholderText("终止点,右区间")
        save_confirm_btn = QPushButton("确认")
        save_confirm_btn.setFixedHeight(40)
        save_layout.addWidget(save_label)
        save_layout.addWidget(self.left_interval)
        save_layout.addWidget(self.right_interval)
        save_layout.addWidget(save_confirm_btn)
        save_widget.setLayout(save_layout)
        save_btn.clicked.connect(self.save_widget_)
        save_confirm_btn.clicked.connect(self.save_data)
        self.bottom_layout.addWidget(save_widget)

        # 病例表的填写
        table_widget = QWidget(bottom)
        table_layout = QHBoxLayout()
        self.patient_table = QTableWidget()
        self.patient_table.setColumnCount(9)
        self.patient_table.setRowCount(self.patient)
        self.patient_table.setHorizontalHeaderLabels([
            '标号', '年龄', '性别', '用药', '房性早博', '室性早博', '心室融合心博', '右束支传导阻塞心博',
            '左束支传导阻塞心博'
        ])
        # self.patient_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.patient_table.resizeColumnsToContents()
        self.patient_table.verticalHeader().setVisible(False)
        table_layout.addWidget(self.patient_table)
        table_widget.setLayout(table_layout)
        self.bottom_layout.addWidget(table_widget)
        patient_table_btn.clicked.connect(self.show_table)

        # 设置最终的窗口布局与控件-------------------------------------
        splitter = QSplitter(Qt.Vertical)
        splitter.addWidget(top)
        splitter.addWidget(bottom)

        widget = QWidget()
        pagelayout.addWidget(splitter)
        widget.setLayout(pagelayout)
        self.setCentralWidget(widget)

        # 计时器 当时间到了就出发绘图函数
        self.timer = QTimer()
        self.timer.timeout.connect(self.update)

        # 记录当前用户
        self.people = ""
        # 当用户改变时出发函数 重新绘图
        self.data_com.currentIndexChanged.connect(self.show_ecg1)
        self.data_com.view().pressed.connect(self.show_ecg)
        # 读取数据的标志
        self.flag = 0
        # 帮助文档的标志
        self.help = 0
        # 暂停的标志
        self.stop = 0
示例#54
0
class MainWindow(QMainWindow):
    """Pyspread main window"""

    gui_update = pyqtSignal(dict)

    def __init__(self, filepath: str = None, reset_settings: bool = False):
        """
        :param filepath: File path for inital file to be opened
        :param reset_settings: Ignore stored `QSettings` and use defaults

        """

        super().__init__()

        self._loading = True

        self.settings = Settings(self, reset_settings=reset_settings)
        self.workflows = Workflows(self)
        self.undo_stack = QUndoStack(self)
        self.refresh_timer = QTimer()

        self._init_widgets()

        self.main_window_actions = MainWindowActions(self)

        self._init_window()
        self._init_toolbars()

        self.settings.restore()
        if self.settings.signature_key is None:
            self.settings.signature_key = genkey()

        # Update recent files in the file menu
        self.menuBar().file_menu.history_submenu.update()

        # Update toolbar toggle checkboxes
        self.update_action_toggles()

        # Update the GUI so that everything matches the model
        cell_attributes = self.grid.model.code_array.cell_attributes
        attributes = cell_attributes[self.grid.current]
        self.on_gui_update(attributes)

        self._loading = False
        self._previous_window_state = self.windowState()

        # Open initial file if provided by the command line
        if filepath is not None:
            if self.workflows.filepath_open(filepath):
                self.workflows.update_main_window_title()
            else:
                msg = "File '{}' could not be opened.".format(filepath)
                self.statusBar().showMessage(msg)

    def _init_window(self):
        """Initialize main window components"""

        self.setWindowTitle(APP_NAME)
        self.setWindowIcon(Icon.pyspread)

        self.safe_mode_widget = QSvgWidget(str(IconPath.warning), self)
        msg = "%s is in safe mode.\nExpressions are not evaluated." % APP_NAME
        self.safe_mode_widget.setToolTip(msg)
        self.statusBar().addPermanentWidget(self.safe_mode_widget)
        self.safe_mode_widget.hide()

        # Disable the approve fiel menu button
        self.main_window_actions.approve.setEnabled(False)

        self.setMenuBar(MenuBar(self))

    def resizeEvent(self, event: QEvent):
        """Overloaded, aborts on self._loading

        :param event: Resize event

        """

        if self._loading:
            return

        super(MainWindow, self).resizeEvent(event)

    def closeEvent(self, event: QEvent = None):
        """Overloaded, allows saving changes or canceling close

        :param event: Any QEvent

        """

        if event:
            event.ignore()
        self.workflows.file_quit()  # has @handle_changed_since_save decorator

    def _init_widgets(self):
        """Initialize widgets"""

        self.widgets = Widgets(self)

        self.entry_line = Entryline(self)
        self.grid = Grid(self)

        self.macro_panel = MacroPanel(self, self.grid.model.code_array)

        self.main_splitter = QSplitter(Qt.Vertical, self)
        self.setCentralWidget(self.main_splitter)

        self.main_splitter.addWidget(self.entry_line)
        self.main_splitter.addWidget(self.grid)
        self.main_splitter.addWidget(self.grid.table_choice)
        self.main_splitter.setSizes([self.entry_line.minimumHeight(),
                                     9999, 20])

        self.macro_dock = QDockWidget("Macros", self)
        self.macro_dock.setObjectName("Macro Panel")
        self.macro_dock.setWidget(self.macro_panel)
        self.addDockWidget(Qt.RightDockWidgetArea, self.macro_dock)

        self.macro_dock.installEventFilter(self)

        self.gui_update.connect(self.on_gui_update)
        self.refresh_timer.timeout.connect(self.on_refresh_timer)

    def eventFilter(self, source: QWidget, event: QEvent) -> bool:
        """Overloaded event filter for handling QDockWidget close events

        Updates the menu if the macro panel is closed.

        :param source: Source widget of event
        :param event: Any QEvent

        """

        if event.type() == QEvent.Close \
           and isinstance(source, QDockWidget) \
           and source.windowTitle() == "Macros":
            self.main_window_actions.toggle_macro_panel.setChecked(False)
        return super().eventFilter(source, event)

    def _init_toolbars(self):
        """Initialize the main window toolbars"""

        self.main_toolbar = MainToolBar(self)
        self.macro_toolbar = MacroToolbar(self)
        self.find_toolbar = FindToolbar(self)
        self.format_toolbar = FormatToolbar(self)

        self.addToolBar(self.main_toolbar)
        self.addToolBar(self.macro_toolbar)
        self.addToolBar(self.find_toolbar)
        self.addToolBarBreak()
        self.addToolBar(self.format_toolbar)

    def update_action_toggles(self):
        """Updates the toggle menu check states"""

        self.main_window_actions.toggle_main_toolbar.setChecked(
                self.main_toolbar.isVisibleTo(self))

        self.main_window_actions.toggle_macro_toolbar.setChecked(
                self.macro_toolbar.isVisibleTo(self))

        self.main_window_actions.toggle_format_toolbar.setChecked(
                self.format_toolbar.isVisibleTo(self))

        self.main_window_actions.toggle_find_toolbar.setChecked(
                self.find_toolbar.isVisibleTo(self))

        self.main_window_actions.toggle_entry_line.setChecked(
                self.entry_line.isVisibleTo(self))

        self.main_window_actions.toggle_macro_panel.setChecked(
                self.macro_dock.isVisibleTo(self))

    @property
    def safe_mode(self) -> bool:
        """Returns safe_mode state. In safe_mode cells are not evaluated."""

        return self.grid.model.code_array.safe_mode

    @safe_mode.setter
    def safe_mode(self, value: bool):
        """Sets safe mode.

        This triggers the safe_mode icon in the statusbar.

        If safe_mode changes from True to False then caches are cleared and
        macros are executed.

        :param value: Safe mode

        """

        if self.grid.model.code_array.safe_mode == bool(value):
            return

        self.grid.model.code_array.safe_mode = bool(value)

        if value:  # Safe mode entered
            self.safe_mode_widget.show()
            # Enable approval menu entry
            self.main_window_actions.approve.setEnabled(True)
        else:  # Safe_mode disabled
            self.safe_mode_widget.hide()
            # Disable approval menu entry
            self.main_window_actions.approve.setEnabled(False)
            # Clear result cache
            self.grid.model.code_array.result_cache.clear()
            # Execute macros
            self.macro_panel.on_apply()

    def on_print(self):
        """Print event handler"""

        # Create printer
        printer = QPrinter(mode=QPrinter.HighResolution)

        # Get print area
        self.print_area = PrintAreaDialog(self, self.grid).area
        if self.print_area is None:
            return

        # Create print dialog
        dialog = QPrintDialog(printer, self)
        if dialog.exec_() == QPrintDialog.Accepted:
            self.on_paint_request(printer)

    def on_preview(self):
        """Print preview event handler"""

        # Create printer
        printer = QPrinter(mode=QPrinter.HighResolution)

        # Get print area
        self.print_area = PrintAreaDialog(self, self.grid).area
        if self.print_area is None:
            return

        # Create print preview dialog
        dialog = PrintPreviewDialog(printer)

        dialog.paintRequested.connect(self.on_paint_request)
        dialog.exec_()

    def on_paint_request(self, printer: QPrinter):
        """Paints to printer

        :param printer: Target printer

        """

        painter = QPainter(printer)
        option = QStyleOptionViewItem()
        painter.setRenderHints(QPainter.SmoothPixmapTransform
                               | QPainter.SmoothPixmapTransform)

        page_rect = printer.pageRect()

        rows = list(self.workflows.get_paint_rows(self.print_area))
        columns = list(self.workflows.get_paint_columns(self.print_area))
        if not rows or not columns:
            return

        zeroidx = self.grid.model.index(0, 0)
        zeroidx_rect = self.grid.visualRect(zeroidx)

        minidx = self.grid.model.index(min(rows), min(columns))
        minidx_rect = self.grid.visualRect(minidx)

        maxidx = self.grid.model.index(max(rows), max(columns))
        maxidx_rect = self.grid.visualRect(maxidx)

        grid_width = maxidx_rect.x() + maxidx_rect.width() - minidx_rect.x()
        grid_height = maxidx_rect.y() + maxidx_rect.height() - minidx_rect.y()
        grid_rect = QRectF(minidx_rect.x() - zeroidx_rect.x(),
                           minidx_rect.y() - zeroidx_rect.y(),
                           grid_width, grid_height)

        self.settings.print_zoom = min(page_rect.width() / grid_width,
                                       page_rect.height() / grid_height)

        with painter_save(painter):
            painter.scale(self.settings.print_zoom, self.settings.print_zoom)

            # Translate so that the grid starts at upper left paper edge
            painter.translate(zeroidx_rect.x() - minidx_rect.x(),
                              zeroidx_rect.y() - minidx_rect.y())

            # Draw grid cells
            self.workflows.paint(painter, option, grid_rect, rows, columns)

        self.settings.print_zoom = None

    def on_fullscreen(self):
        """Fullscreen toggle event handler"""

        if self.windowState() == Qt.WindowFullScreen:
            self.setWindowState(self._previous_window_state)
        else:
            self._previous_window_state = self.windowState()
            self.setWindowState(Qt.WindowFullScreen)

    def on_approve(self):
        """Approve event handler"""

        if ApproveWarningDialog(self).choice:
            self.safe_mode = False

    def on_clear_globals(self):
        """Clear globals event handler"""

        self.grid.model.code_array.result_cache.clear()

        # Clear globals
        self.grid.model.code_array.clear_globals()
        self.grid.model.code_array.reload_modules()

    def on_preferences(self):
        """Preferences event handler (:class:`dialogs.PreferencesDialog`) """

        data = PreferencesDialog(self).data

        if data is not None:
            max_file_history_changed = \
                self.settings.max_file_history != data['max_file_history']

            # Dialog has been approved --> Store data to settings
            for key in data:
                if key == "signature_key" and not data[key]:
                    data[key] = genkey()
                self.settings.__setattr__(key, data[key])

            # Immediately adjust file history in menu
            if max_file_history_changed:
                self.menuBar().file_menu.history_submenu.update()

    def on_dependencies(self):
        """Dependancies installer (:class:`installer.InstallerDialog`) """

        dial = DependenciesDialog(self)
        dial.exec_()

    def on_undo(self):
        """Undo event handler"""

        self.undo_stack.undo()

    def on_redo(self):
        """Undo event handler"""

        self.undo_stack.redo()

    def on_toggle_refresh_timer(self, toggled: bool):
        """Toggles periodic timer for frozen cells

        :param toggled: Toggle state

        """

        if toggled:
            self.refresh_timer.start(self.settings.refresh_timeout)
        else:
            self.refresh_timer.stop()

    def on_refresh_timer(self):
        """Event handler for self.refresh_timer.timeout

        Called for periodic updates of frozen cells.
        Does nothing if either the entry_line or a cell editor is active.

        """

        if not self.entry_line.hasFocus() \
           and self.grid.state() != self.grid.EditingState:
            self.grid.refresh_frozen_cells()

    def _toggle_widget(self, widget: QWidget, action_name: str, toggled: bool):
        """Toggles widget visibility and updates toggle actions

        :param widget: Widget to be toggled shown or hidden
        :param action_name: Name of action from Action class
        :param toggled: Toggle state

        """

        if toggled:
            widget.show()
        else:
            widget.hide()

        self.main_window_actions[action_name].setChecked(widget.isVisible())

    def on_toggle_main_toolbar(self, toggled: bool):
        """Main toolbar toggle event handler

        :param toggled: Toggle state

        """

        self._toggle_widget(self.main_toolbar, "toggle_main_toolbar", toggled)

    def on_toggle_macro_toolbar(self, toggled: bool):
        """Macro toolbar toggle event handler

        :param toggled: Toggle state

        """

        self._toggle_widget(self.macro_toolbar, "toggle_macro_toolbar",
                            toggled)

    def on_toggle_format_toolbar(self, toggled: bool):
        """Format toolbar toggle event handler

        :param toggled: Toggle state

        """

        self._toggle_widget(self.format_toolbar, "toggle_format_toolbar",
                            toggled)

    def on_toggle_find_toolbar(self, toggled: bool):
        """Find toolbar toggle event handler

        :param toggled: Toggle state

        """

        self._toggle_widget(self.find_toolbar, "toggle_find_toolbar", toggled)

    def on_toggle_entry_line(self, toggled: bool):
        """Entryline toggle event handler

        :param toggled: Toggle state

        """

        self._toggle_widget(self.entry_line, "toggle_entry_line", toggled)

    def on_toggle_macro_panel(self, toggled: bool):
        """Macro panel toggle event handler

        :param toggled: Toggle state

        """

        self._toggle_widget(self.macro_dock, "toggle_macro_panel", toggled)

    def on_manual(self):
        """Show manual browser"""

        dialog = ManualDialog(self)
        dialog.show()

    def on_tutorial(self):
        """Show tutorial browser"""

        dialog = TutorialDialog(self)
        dialog.show()

    def on_about(self):
        """Show about message box"""

        about_msg_template = "<p>".join((
            "<b>%s</b>" % APP_NAME,
            "A non-traditional Python spreadsheet application",
            "Version {version}",
            "Created by:<br>{devs}",
            "Documented by:<br>{doc_devs}",
            "Copyright:<br>Martin Manns",
            "License:<br>{license}",
            '<a href="https://pyspread.gitlab.io">pyspread.gitlab.io</a>',
            ))

        devs = "Martin Manns, Jason Sexauer<br>Vova Kolobok, mgunyho, " \
               "Pete Morgan"

        doc_devs = "Martin Manns, Bosko Markovic, Pete Morgan"

        about_msg = about_msg_template.format(
                    version=VERSION, license=LICENSE,
                    devs=devs, doc_devs=doc_devs)
        QMessageBox.about(self, "About %s" % APP_NAME, about_msg)

    def on_gui_update(self, attributes: CellAttributes):
        """GUI update that shall be called on each cell change

        :param attributes: Attributes of current cell

        """

        widgets = self.widgets
        menubar = self.menuBar()

        is_bold = attributes.fontweight == QFont.Bold
        self.main_window_actions.bold.setChecked(is_bold)

        is_italic = attributes.fontstyle == QFont.StyleItalic
        self.main_window_actions.italics.setChecked(is_italic)

        underline_action = self.main_window_actions.underline
        underline_action.setChecked(attributes.underline)

        strikethrough_action = self.main_window_actions.strikethrough
        strikethrough_action.setChecked(attributes.strikethrough)

        renderer = attributes.renderer
        widgets.renderer_button.set_current_action(renderer)
        widgets.renderer_button.set_menu_checked(renderer)

        freeze_action = self.main_window_actions.freeze_cell
        freeze_action.setChecked(attributes.frozen)

        lock_action = self.main_window_actions.lock_cell
        lock_action.setChecked(attributes.locked)
        self.entry_line.setReadOnly(attributes.locked)

        button_action = self.main_window_actions.button_cell
        button_action.setChecked(attributes.button_cell is not False)

        rotation = "rotate_{angle}".format(angle=int(attributes.angle))
        widgets.rotate_button.set_current_action(rotation)
        widgets.rotate_button.set_menu_checked(rotation)
        widgets.justify_button.set_current_action(attributes.justification)
        widgets.justify_button.set_menu_checked(attributes.justification)
        widgets.align_button.set_current_action(attributes.vertical_align)
        widgets.align_button.set_menu_checked(attributes.vertical_align)

        border_action = self.main_window_actions.border_group.checkedAction()
        if border_action is not None:
            icon = border_action.icon()
            menubar.format_menu.border_submenu.setIcon(icon)
            self.format_toolbar.border_menu_button.setIcon(icon)

        border_width_action = \
            self.main_window_actions.border_width_group.checkedAction()
        if border_width_action is not None:
            icon = border_width_action.icon()
            menubar.format_menu.line_width_submenu.setIcon(icon)
            self.format_toolbar.line_width_button.setIcon(icon)

        if attributes.textcolor is None:
            text_color = self.grid.palette().color(QPalette.Text)
        else:
            text_color = QColor(*attributes.textcolor)
        widgets.text_color_button.color = text_color

        if attributes.bgcolor is None:
            bgcolor = self.grid.palette().color(QPalette.Base)
        else:
            bgcolor = QColor(*attributes.bgcolor)
        widgets.background_color_button.color = bgcolor

        if attributes.textfont is None:
            widgets.font_combo.font = QFont().family()
        else:
            widgets.font_combo.font = attributes.textfont
        widgets.font_size_combo.size = attributes.pointsize

        merge_cells_action = self.main_window_actions.merge_cells
        merge_cells_action.setChecked(attributes.merge_area is not None)
示例#55
0
class MainWindow(QMainWindow):

    frame = None
    jupyter_widget = None
    browser_widget = None
    addon_list = []
    current_addon = None  # currently shown addon

    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        self.setWindowTitle(main_window_title)
        self.setWindowIcon(QIcon(os.path.join(utils.get_exe_folder(), 
                           'appicon.ico')))

        self.init_jupyter_widget()
        self.init_addon_menu()  
        self.init_splitter()
        self.init_statusbar()
        self.init_help_menu()
        self.setCentralWidget(self.frame)

    def closeEvent(self, event):
        # close all the plots
        # plt.close("all")
        # nothing to close as
        # all the plots are in
        # console
        pass

    def init_help_menu(self):
        menubar = self.menuBar()
        self.__help_menu = menubar.addMenu('Help')

        action = QAction('User guide', self)
        self.__help_menu.addAction(action)
        action.triggered.connect(self.on_help_user_guide)

        action = QAction('License', self)
        self.__help_menu.addAction(action)
        action.triggered.connect(self.on_help_license)

        action = QAction('About...', self)
        self.__help_menu.addAction(action)
        action.triggered.connect(self.on_help_about)

    def on_help_license(self, q):
        self.browser_widget.load_page(license_url)

    def on_help_user_guide(self, q):
        self.browser_widget.load_page(user_guide_url)

    def on_help_about(self, q):
        # main_window_title, app_name, app_version
        text = (app_name + ' version ' + app_version
                + '.\nby ' + author + '.')
        QMessageBox.about(self, main_window_title, text)

    def init_statusbar(self):
        self.status_bar = QStatusBar()
        self.setStatusBar(self.status_bar)

    def init_splitter(self):
        self.frame = QFrame()
        self.frame.setFrameShape(QFrame.StyledPanel)
        hbox = QHBoxLayout()  # here should be no 'self' argument
        self.browser_widget = bv.BrowserWidget(self)
        self.top_splitter = QSplitter(Qt.Horizontal)
        frame = QFrame()
        layout = QVBoxLayout()
        for addon in self.addon_list:
            layout.addWidget(addon)
            addon.hide()
        frame.setLayout(layout)        
        self.top_splitter.addWidget(frame)
        self.current_addon = self.addon_list[0]
        self.current_addon.show_itself()
        self.top_splitter.addWidget(self.browser_widget)
        self.top_splitter.setSizes([100, 200])

        handle_width = 6

        # https://stackoverflow.com/questions/2545577/qsplitter-becoming-undistinguishable-between-qwidget-and-qtabwidget
        self.top_splitter.setOpaqueResize(False)
        self.top_splitter.setChildrenCollapsible(False)
        self.top_splitter.setHandleWidth(handle_width)

        splitter2 = QSplitter(Qt.Vertical)
        splitter2.addWidget(self.top_splitter)
        splitter2.addWidget(self.jupyter_widget)
        splitter2.setOpaqueResize(False)
        splitter2.setChildrenCollapsible(False)
        splitter2.setHandleWidth(handle_width)

        hbox.addWidget(splitter2)

        self.frame.setLayout(hbox)

    def init_jupyter_widget(self):
        self.jupyter_widget = make_jupyter_widget_with_kernel()

    def shutdown_kernel(self):
        print('Shutting down kernel...')
        self.jupyter_widget.kernel_client.stop_channels()
        self.jupyter_widget.kernel_manager.shutdown_kernel()

    def init_addon_menu(self):
        self.__menubar = self.menuBar()
        addon_list = addon_data.addon_list
        self.__addon_menu = self.__menubar.addMenu('Addons')
        for addon_group in addon_list:
            group_menu = self.__addon_menu.addMenu(addon_group.menu_name)
            for addon in addon_group.addons:
                action = QAction(addon.menu_name, self)
                group_menu.addAction(action)
                self.inputs_widget = InputsWidget(self, addon)
                action.triggered.connect(self.inputs_widget.show_itself)
                self.addon_list.append(self.inputs_widget)
示例#56
0
    def __init__(self, host, port, path, parent=None):
        super().__init__(parent)

        self.path = path
        self.maze_files = sorted(
            fname.relative_to(self.path)
            for fname in self.path.glob('**/*.txt') if fname.is_file())

        self.setWindowTitle('Micromouse maze simulator')
        self.resize(800, 600)

        self.history = []

        self.status = QStatusBar()
        self.setStatusBar(self.status)

        self.search = QLineEdit()
        self.search.textChanged.connect(self.filter_mazes)

        self.files = QListWidget()
        self.files.currentItemChanged.connect(self.list_value_changed)

        self.graphics = GraphicsLayoutWidget()
        viewbox = self.graphics.addViewBox()
        viewbox.setAspectLocked()
        self.maze = MazeItem()
        viewbox.addItem(self.maze)

        self.slider = QSlider(QtCore.Qt.Horizontal)
        self.slider.setSingleStep(1)
        self.slider.setPageStep(10)
        self.slider.setTickPosition(QSlider.TicksAbove)
        self.slider.valueChanged.connect(self.slider_value_changed)
        self.reset()

        files_layout = QVBoxLayout()
        files_layout.setContentsMargins(0, 0, 0, 0)
        files_layout.addWidget(self.search)
        files_layout.addWidget(self.files)
        files_widget = QWidget()
        files_widget.setLayout(files_layout)
        graphics_layout = QVBoxLayout()
        graphics_layout.setContentsMargins(0, 0, 0, 0)
        graphics_layout.addWidget(self.graphics)
        graphics_layout.addWidget(self.slider)
        graphics_widget = QWidget()
        graphics_widget.setLayout(graphics_layout)
        central_splitter = QSplitter()
        central_splitter.addWidget(files_widget)
        central_splitter.addWidget(graphics_widget)

        main_layout = QVBoxLayout()
        main_layout.addWidget(central_splitter)
        main_layout.setContentsMargins(4, 4, 4, 4)
        main_widget = QWidget()
        main_widget.setLayout(main_layout)

        self.setCentralWidget(main_widget)
        self.filter_mazes('')

        self.context = zmq.Context()
        self.reply = self.context.socket(zmq.PUSH)
        self.reply.connect('inproc://reply')

        self.thread = QtCore.QThread()
        self.zeromq_listener = ZMQListener(self.context, host=host, port=port)
        self.zeromq_listener.moveToThread(self.thread)

        self.thread.started.connect(self.zeromq_listener.loop)
        self.zeromq_listener.message.connect(self.signal_received)

        QtCore.QTimer.singleShot(0, self.thread.start)
示例#57
0
    def __init__(self, persepolis_setting):
        super().__init__()
        # MainWindow
        self.persepolis_setting = persepolis_setting

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

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

        if ui_direction == 'rtl':
            self.setLayoutDirection(Qt.RightToLeft)

        elif ui_direction in 'ltr':
            self.setLayoutDirection(Qt.LeftToRight)



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

        self.setWindowTitle(
            QCoreApplication.translate("mainwindow_ui_tr",
                                       "Persepolis Download Manager"))
        self.setWindowIcon(
            QIcon.fromTheme('persepolis', QIcon(':/persepolis.svg')))

        self.centralwidget = QWidget(self)
        self.verticalLayout = QVBoxLayout(self.centralwidget)
        # enable drag and drop
        self.setAcceptDrops(True)
        # frame
        self.frame = QFrame(self.centralwidget)

        # download_table_horizontalLayout
        download_table_horizontalLayout = QHBoxLayout()
        tabels_splitter = QSplitter(Qt.Horizontal)
        # category_tree
        self.category_tree_qwidget = QWidget(self)
        category_tree_verticalLayout = QVBoxLayout()
        self.category_tree = CategoryTreeView(self)
        category_tree_verticalLayout.addWidget(self.category_tree)

        self.category_tree_model = QStandardItemModel()
        self.category_tree.setModel(self.category_tree_model)
        category_table_header = [
            QCoreApplication.translate("mainwindow_ui_tr", 'Category')
        ]

        self.category_tree_model.setHorizontalHeaderLabels(
            category_table_header)
        self.category_tree.header().setStretchLastSection(True)

        self.category_tree.header().setDefaultAlignment(Qt.AlignCenter)

        # queue_panel
        self.queue_panel_widget = QWidget(self)

        queue_panel_verticalLayout_main = QVBoxLayout(self.queue_panel_widget)
        # queue_panel_show_button
        self.queue_panel_show_button = QPushButton(self)

        queue_panel_verticalLayout_main.addWidget(self.queue_panel_show_button)
        # queue_panel_widget_frame
        self.queue_panel_widget_frame = QFrame(self)
        self.queue_panel_widget_frame.setFrameShape(QFrame.StyledPanel)
        self.queue_panel_widget_frame.setFrameShadow(QFrame.Raised)

        queue_panel_verticalLayout_main.addWidget(
            self.queue_panel_widget_frame)

        queue_panel_verticalLayout = QVBoxLayout(self.queue_panel_widget_frame)
        queue_panel_verticalLayout_main.setContentsMargins(50, -1, 50, -1)

        # start_end_frame
        self.start_end_frame = QFrame(self)

        # start time
        start_verticalLayout = QVBoxLayout(self.start_end_frame)
        self.start_checkBox = QCheckBox(self)
        start_verticalLayout.addWidget(self.start_checkBox)

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

        start_frame_verticalLayout = QVBoxLayout(self.start_frame)

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

        start_verticalLayout.addWidget(self.start_frame)
        # end time

        self.end_checkBox = QCheckBox(self)
        start_verticalLayout.addWidget(self.end_checkBox)

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

        end_frame_verticalLayout = QVBoxLayout(self.end_frame)

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

        start_verticalLayout.addWidget(self.end_frame)

        self.reverse_checkBox = QCheckBox(self)
        start_verticalLayout.addWidget(self.reverse_checkBox)

        queue_panel_verticalLayout.addWidget(self.start_end_frame)

        # limit_after_frame
        self.limit_after_frame = QFrame(self)
        # limit_checkBox
        limit_verticalLayout = QVBoxLayout(self.limit_after_frame)
        self.limit_checkBox = QCheckBox(self)
        limit_verticalLayout.addWidget(self.limit_checkBox)
        # limit_frame
        self.limit_frame = QFrame(self)
        self.limit_frame.setFrameShape(QFrame.StyledPanel)
        self.limit_frame.setFrameShadow(QFrame.Raised)
        limit_verticalLayout.addWidget(self.limit_frame)

        limit_frame_verticalLayout = QVBoxLayout(self.limit_frame)
        # limit_spinBox
        limit_frame_horizontalLayout = QHBoxLayout()
        self.limit_spinBox = QDoubleSpinBox(self)
        self.limit_spinBox.setMinimum(1)
        self.limit_spinBox.setMaximum(1023)
        limit_frame_horizontalLayout.addWidget(self.limit_spinBox)
        # limit_comboBox
        self.limit_comboBox = QComboBox(self)
        self.limit_comboBox.addItem("")
        self.limit_comboBox.addItem("")
        limit_frame_horizontalLayout.addWidget(self.limit_comboBox)
        limit_frame_verticalLayout.addLayout(limit_frame_horizontalLayout)
        # limit_pushButton
        self.limit_pushButton = QPushButton(self)
        limit_frame_verticalLayout.addWidget(self.limit_pushButton)

        # after_checkBox
        self.after_checkBox = QtWidgets.QCheckBox(self)
        limit_verticalLayout.addWidget(self.after_checkBox)
        # after_frame
        self.after_frame = QtWidgets.QFrame(self)
        self.after_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.after_frame.setFrameShadow(QtWidgets.QFrame.Raised)
        limit_verticalLayout.addWidget(self.after_frame)

        after_frame_verticalLayout = QVBoxLayout(self.after_frame)
        # after_comboBox
        self.after_comboBox = QComboBox(self)
        self.after_comboBox.addItem("")

        after_frame_verticalLayout.addWidget(self.after_comboBox)
        # after_pushButton
        self.after_pushButton = QPushButton(self)
        after_frame_verticalLayout.addWidget(self.after_pushButton)

        queue_panel_verticalLayout.addWidget(self.limit_after_frame)
        category_tree_verticalLayout.addWidget(self.queue_panel_widget)

        # keep_awake_checkBox
        self.keep_awake_checkBox = QCheckBox(self)
        queue_panel_verticalLayout.addWidget(self.keep_awake_checkBox)

        self.category_tree_qwidget.setLayout(category_tree_verticalLayout)
        tabels_splitter.addWidget(self.category_tree_qwidget)

        # download table widget
        self.download_table_content_widget = QWidget(self)
        download_table_content_widget_verticalLayout = QVBoxLayout(
            self.download_table_content_widget)

        self.download_table = DownloadTableWidget(self)
        download_table_content_widget_verticalLayout.addWidget(
            self.download_table)
        tabels_splitter.addWidget(self.download_table_content_widget)

        self.download_table.setColumnCount(13)
        self.download_table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.download_table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.download_table.verticalHeader().hide()

        # hide gid and download dictioanry section
        self.download_table.setColumnHidden(8, True)
        self.download_table.setColumnHidden(9, True)

        download_table_header = [
            QCoreApplication.translate("mainwindow_ui_tr", 'File Name'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Status'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Size'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Downloaded'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Percentage'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Connections'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Transfer rate'),
            QCoreApplication.translate("mainwindow_ui_tr",
                                       'Estimated time left'), 'Gid',
            QCoreApplication.translate("mainwindow_ui_tr", 'Link'),
            QCoreApplication.translate("mainwindow_ui_tr", 'First try date'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Last try date'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Category')
        ]

        self.download_table.setHorizontalHeaderLabels(download_table_header)

        # fixing the size of download_table when window is Maximized!
        self.download_table.horizontalHeader().setSectionResizeMode(0)
        self.download_table.horizontalHeader().setStretchLastSection(True)

        tabels_splitter.setStretchFactor(0, 3)  # category_tree width
        tabels_splitter.setStretchFactor(1, 10)  # ratio of tables's width
        download_table_horizontalLayout.addWidget(tabels_splitter)
        self.frame.setLayout(download_table_horizontalLayout)
        self.verticalLayout.addWidget(self.frame)
        self.setCentralWidget(self.centralwidget)

        # menubar
        self.menubar = QMenuBar(self)
        self.menubar.setGeometry(QRect(0, 0, 600, 24))
        self.setMenuBar(self.menubar)
        fileMenu = self.menubar.addMenu(
            QCoreApplication.translate("mainwindow_ui_tr", '&File'))
        editMenu = self.menubar.addMenu(
            QCoreApplication.translate("mainwindow_ui_tr", '&Edit'))
        viewMenu = self.menubar.addMenu(
            QCoreApplication.translate("mainwindow_ui_tr", '&View'))
        downloadMenu = self.menubar.addMenu(
            QCoreApplication.translate("mainwindow_ui_tr", '&Download'))
        queueMenu = self.menubar.addMenu(
            QCoreApplication.translate("mainwindow_ui_tr", '&Queue'))
        videoFinderMenu = self.menubar.addMenu(
            QCoreApplication.translate("mainwindow_ui_tr", 'V&ideo Finder'))
        helpMenu = self.menubar.addMenu(
            QCoreApplication.translate("mainwindow_ui_tr", '&Help'))

        # viewMenu submenus
        sortMenu = viewMenu.addMenu(
            QCoreApplication.translate("mainwindow_ui_tr", 'Sort by'))
        # statusbar
        self.statusbar = QStatusBar(self)
        self.setStatusBar(self.statusbar)
        self.statusbar.showMessage(
            QCoreApplication.translate("mainwindow_ui_tr",
                                       "Persepolis Download Manager"))
        # toolBar
        self.toolBar2 = QToolBar(self)
        self.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar2)
        self.toolBar2.setWindowTitle(
            QCoreApplication.translate("mainwindow_ui_tr", 'Menu'))
        self.toolBar2.setFloatable(False)
        self.toolBar2.setMovable(False)

        self.toolBar = QToolBar(self)
        self.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
        self.toolBar.setWindowTitle(
            QCoreApplication.translate("mainwindow_ui_tr", 'Toolbar'))
        self.toolBar.setFloatable(False)
        self.toolBar.setMovable(False)

        #toolBar and menubar and actions
        self.videoFinderAddLinkAction = QAction(
            QIcon(icons + 'video_finder'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Find Video Links'),
            self,
            statusTip=QCoreApplication.translate(
                "mainwindow_ui_tr",
                'Download video or audio from Youtube, Vimeo, etc...'),
            triggered=self.showVideoFinderAddLinkWindow)

        QShortcut(QKeySequence('Ctrl+I'), self,
                  self.showVideoFinderAddLinkWindow)

        videoFinderMenu.addAction(self.videoFinderAddLinkAction)

        self.stopAllAction = QAction(QIcon(icons + 'stop_all'),
                                     QCoreApplication.translate(
                                         "mainwindow_ui_tr",
                                         'Stop all active downloads'),
                                     self,
                                     statusTip='Stop all active downloads',
                                     triggered=self.stopAllDownloads)
        downloadMenu.addAction(self.stopAllAction)

        self.sort_file_name_Action = QAction(QCoreApplication.translate(
            "mainwindow_ui_tr", 'File name'),
                                             self,
                                             triggered=self.sortByName)
        sortMenu.addAction(self.sort_file_name_Action)

        self.sort_file_size_Action = QAction(QCoreApplication.translate(
            "mainwindow_ui_tr", 'File size'),
                                             self,
                                             triggered=self.sortBySize)
        sortMenu.addAction(self.sort_file_size_Action)

        self.sort_first_try_date_Action = QAction(
            QCoreApplication.translate("mainwindow_ui_tr", 'First try date'),
            self,
            triggered=self.sortByFirstTry)
        sortMenu.addAction(self.sort_first_try_date_Action)

        self.sort_last_try_date_Action = QAction(QCoreApplication.translate(
            "mainwindow_ui_tr", 'Last try date'),
                                                 self,
                                                 triggered=self.sortByLastTry)
        sortMenu.addAction(self.sort_last_try_date_Action)

        self.sort_download_status_Action = QAction(QCoreApplication.translate(
            "mainwindow_ui_tr", 'Download status'),
                                                   self,
                                                   triggered=self.sortByStatus)
        sortMenu.addAction(self.sort_download_status_Action)

        self.trayAction = QAction(
            QCoreApplication.translate("mainwindow_ui_tr",
                                       'Show system tray icon'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr",
                                                 "Show/Hide system tray icon"),
            triggered=self.showTray)
        self.trayAction.setCheckable(True)
        viewMenu.addAction(self.trayAction)

        self.showMenuBarAction = QAction(
            QCoreApplication.translate("mainwindow_ui_tr", 'Show menubar'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr",
                                                 'Show menubar'),
            triggered=self.showMenuBar)
        self.showMenuBarAction.setCheckable(True)
        viewMenu.addAction(self.showMenuBarAction)

        self.showSidePanelAction = QAction(
            QCoreApplication.translate("mainwindow_ui_tr", 'Show side panel'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr",
                                                 'Show side panel'),
            triggered=self.showSidePanel)
        self.showSidePanelAction.setCheckable(True)
        viewMenu.addAction(self.showSidePanelAction)

        self.minimizeAction = QAction(
            QIcon(icons + 'minimize'),
            QCoreApplication.translate("mainwindow_ui_tr",
                                       'Minimize to system tray'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr",
                                                 "Minimize to system tray"),
            triggered=self.minMaxTray)
        QShortcut(QKeySequence('Ctrl+W'), self, self.minMaxTray)

        viewMenu.addAction(self.minimizeAction)

        self.addlinkAction = QAction(
            QIcon(icons + 'add'),
            QCoreApplication.translate("mainwindow_ui_tr",
                                       'Add New Download Link'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr",
                                                 "Add New Download Link"),
            triggered=self.addLinkButtonPressed)
        QShortcut(QKeySequence('Ctrl+N'), self, self.addLinkButtonPressed)
        fileMenu.addAction(self.addlinkAction)

        self.addtextfileAction = QAction(
            QIcon(icons + 'file'),
            QCoreApplication.translate("mainwindow_ui_tr",
                                       'Import links from text file'),
            self,
            statusTip=QCoreApplication.translate(
                "mainwindow_ui_tr",
                'Create a Text file and put links in it.line by line!'),
            triggered=self.importText)
        fileMenu.addAction(self.addtextfileAction)

        self.resumeAction = QAction(
            QIcon(icons + 'play'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Resume Download'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr",
                                                 "Resume Download"),
            triggered=self.resumeButtonPressed)
        QShortcut(QKeySequence('Ctrl+R'), self, self.resumeButtonPressed)
        downloadMenu.addAction(self.resumeAction)

        self.pauseAction = QAction(
            QIcon(icons + 'pause'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Pause Download'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr",
                                                 "Pause Download"),
            triggered=self.pauseButtonPressed)
        QShortcut(QKeySequence('Ctrl+C'), self, self.pauseButtonPressed)
        downloadMenu.addAction(self.pauseAction)

        self.stopAction = QAction(
            QIcon(icons + 'stop'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Stop Download'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr",
                                                 "Stop/Cancel Download"),
            triggered=self.stopButtonPressed)
        QShortcut(QKeySequence('Ctrl+S'), self, self.stopButtonPressed)
        downloadMenu.addAction(self.stopAction)

        self.propertiesAction = QAction(
            QIcon(icons + 'setting'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Properties'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr",
                                                 "Properties"),
            triggered=self.propertiesButtonPressed)
        QShortcut(QKeySequence('Ctrl+P'), self, self.propertiesButtonPressed)
        downloadMenu.addAction(self.propertiesAction)

        self.progressAction = QAction(
            QIcon(icons + 'window'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Progress'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr",
                                                 "Progress"),
            triggered=self.progressButtonPressed)
        QShortcut(QKeySequence('Ctrl+Z'), self, self.progressButtonPressed)
        downloadMenu.addAction(self.progressAction)

        self.openFileAction = QAction(
            QIcon(icons + 'file'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Open file'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr",
                                                 'Open file'),
            triggered=self.openFile)
        fileMenu.addAction(self.openFileAction)

        self.openDownloadFolderAction = QAction(
            QIcon(icons + 'folder'),
            QCoreApplication.translate("mainwindow_ui_tr",
                                       'Open download folder'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr",
                                                 'Open download folder'),
            triggered=self.openDownloadFolder)
        fileMenu.addAction(self.openDownloadFolderAction)

        self.openDefaultDownloadFolderAction = QAction(
            QIcon(icons + 'folder'),
            QCoreApplication.translate("mainwindow_ui_tr",
                                       'Open default download folder'),
            self,
            statusTip=QCoreApplication.translate(
                "mainwindow_ui_tr", 'Open default download folder'),
            triggered=self.openDefaultDownloadFolder)
        fileMenu.addAction(self.openDefaultDownloadFolderAction)

        self.exitAction = QAction(
            QIcon(icons + 'exit'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Exit'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Exit"),
            triggered=self.closeEvent)
        QShortcut(QKeySequence('Ctrl+Q'), self, self.closeEvent)
        fileMenu.addAction(self.exitAction)

        self.clearAction = QAction(QIcon(icons + 'multi_remove'),
                                   QCoreApplication.translate(
                                       "mainwindow_ui_tr",
                                       'Clear download list'),
                                   self,
                                   statusTip=QCoreApplication.translate(
                                       "mainwindow_ui_tr",
                                       'Clear all items in download list'),
                                   triggered=self.clearDownloadList)
        editMenu.addAction(self.clearAction)

        self.removeSelectedAction = QAction(
            QIcon(icons + 'remove'),
            QCoreApplication.translate("mainwindow_ui_tr",
                                       'Remove selected downloads from list'),
            self,
            statusTip=QCoreApplication.translate(
                "mainwindow_ui_tr", 'Remove selected downloads form list'),
            triggered=self.removeSelected)
        editMenu.addAction(self.removeSelectedAction)
        self.removeSelectedAction.setEnabled(False)

        self.deleteSelectedAction = QAction(
            QIcon(icons + 'trash'),
            QCoreApplication.translate("mainwindow_ui_tr",
                                       'Delete selected download files'),
            self,
            statusTip=QCoreApplication.translate(
                "mainwindow_ui_tr", 'Delete selected download files'),
            triggered=self.deleteSelected)
        editMenu.addAction(self.deleteSelectedAction)
        self.deleteSelectedAction.setEnabled(False)

        self.createQueueAction = QAction(
            QIcon(icons + 'add_queue'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Create new queue'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr",
                                                 'Create new download queue'),
            triggered=self.createQueue)
        queueMenu.addAction(self.createQueueAction)

        self.removeQueueAction = QAction(
            QIcon(icons + 'remove_queue'),
            QCoreApplication.translate("mainwindow_ui_tr",
                                       'Remove this queue'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr",
                                                 'Remove this queue'),
            triggered=self.removeQueue)
        queueMenu.addAction(self.removeQueueAction)

        self.startQueueAction = QAction(
            QIcon(icons + 'start_queue'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Start this queue'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr",
                                                 'Start this queue'),
            triggered=self.startQueue)
        queueMenu.addAction(self.startQueueAction)

        self.stopQueueAction = QAction(
            QIcon(icons + 'stop_queue'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Stop this queue'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr",
                                                 'Stop this queue'),
            triggered=self.stopQueue)
        queueMenu.addAction(self.stopQueueAction)

        self.moveUpSelectedAction = QAction(
            QIcon(icons + 'multi_up'),
            QCoreApplication.translate("mainwindow_ui_tr",
                                       'Move up selected items'),
            self,
            statusTip=QCoreApplication.translate(
                "mainwindow_ui_tr",
                'Move currently selected items up by one row'),
            triggered=self.moveUpSelected)
        queueMenu.addAction(self.moveUpSelectedAction)

        self.moveDownSelectedAction = QAction(
            QIcon(icons + 'multi_down'),
            QCoreApplication.translate("mainwindow_ui_tr",
                                       'Move down selected items'),
            self,
            statusTip=QCoreApplication.translate(
                "mainwindow_ui_tr",
                'Move currently selected items down by one row'),
            triggered=self.moveDownSelected)
        queueMenu.addAction(self.moveDownSelectedAction)

        self.preferencesAction = QAction(
            QIcon(icons + 'preferences'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Preferences'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr",
                                                 'Preferences'),
            triggered=self.openPreferences,
            menuRole=5)
        editMenu.addAction(self.preferencesAction)

        self.aboutAction = QAction(
            QIcon(icons + 'about'),
            QCoreApplication.translate("mainwindow_ui_tr", 'About'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'About'),
            triggered=self.openAbout,
            menuRole=4)
        helpMenu.addAction(self.aboutAction)

        self.issueAction = QAction(
            QIcon(icons + 'about'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Report an issue'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr",
                                                 'Report an issue'),
            triggered=self.reportIssue)
        helpMenu.addAction(self.issueAction)

        self.updateAction = QAction(
            QIcon(icons + 'about'),
            QCoreApplication.translate("mainwindow_ui_tr",
                                       'Check for newer version'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr",
                                                 'Check for newer release'),
            triggered=self.newUpdate)
        helpMenu.addAction(self.updateAction)

        self.logAction = QAction(
            QIcon(icons + 'about'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Show log file'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Help'),
            triggered=self.showLog)
        helpMenu.addAction(self.logAction)

        self.helpAction = QAction(
            QIcon(icons + 'about'),
            QCoreApplication.translate("mainwindow_ui_tr", 'Help'),
            self,
            statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Help'),
            triggered=self.persepolisHelp)
        helpMenu.addAction(self.helpAction)

        self.qmenu = MenuWidget(self)

        self.toolBar2.addWidget(self.qmenu)

        # labels
        self.queue_panel_show_button.setText(
            QCoreApplication.translate("mainwindow_ui_tr", "Hide options"))
        self.start_checkBox.setText(
            QCoreApplication.translate("mainwindow_ui_tr", "Start Time"))

        self.end_checkBox.setText(
            QCoreApplication.translate("mainwindow_ui_tr", "End Time"))

        self.reverse_checkBox.setText(
            QCoreApplication.translate("mainwindow_ui_tr",
                                       "Download bottom of\n the list first"))

        self.limit_checkBox.setText(
            QCoreApplication.translate("mainwindow_ui_tr", "Limit Speed"))
        self.limit_comboBox.setItemText(0, "KiB/s")
        self.limit_comboBox.setItemText(1, "MiB/s")
        self.limit_pushButton.setText(
            QCoreApplication.translate("mainwindow_ui_tr", "Apply"))

        self.after_checkBox.setText(
            QCoreApplication.translate("mainwindow_ui_tr", "After download"))
        self.after_comboBox.setItemText(
            0, QCoreApplication.translate("mainwindow_ui_tr", "Shut Down"))

        self.keep_awake_checkBox.setText(
            QCoreApplication.translate("mainwindow_ui_tr",
                                       "Keep system awake!"))
        self.keep_awake_checkBox.setToolTip(
            QCoreApplication.translate(
                "mainwindow_ui_tr",
                "<html><head/><body><p>This option is preventing system from going to sleep.\
            This is necessary if your power manager is suspending system automatically. </p></body></html>"
            ))

        self.after_pushButton.setText(
            QCoreApplication.translate("mainwindow_ui_tr", "Apply"))
示例#58
0
    def __init__(self):
        super().__init__()
        self.flag=0
        self.chatTextField=QLineEdit(self)
        self.chatTextField.resize(480,100)
        self.chatTextField.move(10,350)
        self.btnSend=QPushButton("Send",self)
        self.btnSend.resize(480,30)
        self.btnSendFont=self.btnSend.font()
        self.btnSendFont.setPointSize(15)
        self.btnSend.setFont(self.btnSendFont)
        self.btnSend.move(10,460)
        self.btnSend.setStyleSheet("background-color: #F7CE16")
        # self.btnSend.clicked.connect(self.send)
 
        self.chatBody=QVBoxLayout(self)
        
        splitter=QSplitter(QtCore.Qt.Vertical)
 
        self.chat = QTextEdit()
        self.chat.setReadOnly(True)
 
        splitter.addWidget(self.chat)
        splitter.addWidget(self.chatTextField)
        splitter.setSizes([400,100])
 
        splitter2=QSplitter(QtCore.Qt.Vertical)
        splitter2.addWidget(splitter)
        splitter2.addWidget(self.btnSend)
        splitter2.setSizes([200,10])
 
        self.chatBody.addWidget(splitter2)
 
        self.setWindowTitle("Chat")
        self.resize(500, 500)

 
# class ClientThread(Thread):
#     def __init__(self,window): 
#         Thread.__init__(self) 
#         self.window=window
  
#     def run(self): 
#        host = socket.gethostname() 
#        port = 80
#        BUFFER_SIZE = 2000
#        global tcpClientA
#        tcpClientA = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
#        tcpClientA.connect((host, port))
        
#        while True:
#            data = tcpClientA.recv(BUFFER_SIZE)
#            window.chat.append(data.decode("utf-8"))
#        tcpClientA.close() 
 
 
# if __name__ == '__main__':
#     app = QApplication(sys.argv)
#     window = Window()
#     clientThread=ClientThread(window)
#     clientThread.start()
#     window.exec()
#     sys.exit(app.exec_())
示例#59
0
class FTracePanel(QWidget):
    def __init__(self, app, flags=None, *args, **kwargs):
        super().__init__(flags, *args, **kwargs)
        self.app = app

        self.kernel = app.get_dwarf().get_kernel()
        self.ftrace = self.kernel.get_ftrace()
        self.trace_read_dialog = None

        layout = QVBoxLayout()

        central_layout = QVBoxLayout()

        self.options = QSplitter()
        self.filter_functions = QTextEdit()
        self.filter_events = QTextEdit()
        self.options_list = QListWidget()

        self.setup_options_view()

        central_layout.addWidget(self.options)

        self.buttons = QHBoxLayout()
        self.btn_pause = QPushButton('pause')
        self.btn_trace = QPushButton('start')
        self.btn_read = QPushButton('read')

        self.btn_pause.setEnabled(False)

        self.btn_pause.clicked.connect(self.pause_clicked)
        self.btn_trace.clicked.connect(self.trace_clicked)
        self.btn_read.clicked.connect(self.read_clicked)

        self.buttons.addWidget(self.btn_pause)
        self.buttons.addWidget(self.btn_trace)
        self.buttons.addWidget(self.btn_read)

        layout.addLayout(self.buttons)
        layout.addLayout(central_layout)

        self.setLayout(layout)

    def append_data(self, data):
        if self.trace_read_dialog is not None:
            self.trace_read_dialog.append(data)

    def disable_options_view(self):
        self.btn_pause.setEnabled(True)
        self.btn_trace.setText('stop')
        self.btn_read.setEnabled(False)
        self.options_list.setEnabled(False)
        self.filter_events.setEnabled(False)
        self.filter_functions.setEnabled(False)

    def enable_options_view(self):
        self.btn_pause.setEnabled(False)
        self.btn_trace.setText('start')
        self.btn_read.setEnabled(True)
        self.options_list.setEnabled(True)
        self.filter_events.setEnabled(True)
        self.filter_functions.setEnabled(True)

    def setup_options_view(self):
        self.options.setOrientation(Qt.Horizontal)
        self.options.setHandleWidth(1)

        filter_functions_layout = QVBoxLayout()
        filter_functions_layout.addWidget(QLabel("Filter functions"))

        bar = QScrollBar()
        bar.setFixedHeight(0)
        bar.setFixedWidth(0)

        self.filter_functions.setHorizontalScrollBar(bar)
        self.filter_functions.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.filter_functions.setPlainText(self.ftrace.get_current_filters())
        self.filter_functions.setPlaceholderText("*SyS_open*")
        filter_functions_layout.addWidget(self.filter_functions)

        filter_events_layout = QVBoxLayout()
        filter_events_layout.addWidget(QLabel("Filter events"))

        bar = QScrollBar()
        bar.setFixedHeight(0)
        bar.setFixedWidth(0)

        self.filter_events.setHorizontalScrollBar(bar)
        self.filter_events.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.filter_events.setPlainText(self.ftrace.get_current_events())
        self.filter_events.setPlaceholderText('raw_syscalls:sys_exit\nraw_syscalls:sys_enter')
        filter_events_layout.addWidget(self.filter_events)

        filter_functions_widget = QWidget()
        filter_functions_widget.setLayout(filter_functions_layout)
        filter_events_widget = QWidget()
        filter_events_widget.setLayout(filter_events_layout)

        options_list_layout = QVBoxLayout()
        options_list_layout.addWidget(QLabel("Options"))

        for option in self.ftrace.get_options():
            if len(option) < 1:
                continue

            q = NotEditableListWidgetItem()
            q.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)

            if not option.startswith('no'):
                q.setCheckState(Qt.Checked)
                q.setText(option)
            else:
                q.setCheckState(Qt.Unchecked)
                q.setText(option[2:])
            self.options_list.addItem(q)

        options_list_layout.addWidget(self.options_list)

        options_list_widget = QWidget()
        options_list_widget.setLayout(options_list_layout)

        self.options.addWidget(filter_functions_widget)
        self.options.addWidget(filter_events_widget)
        self.options.addWidget(options_list_widget)

    def pause_clicked(self):
        if self.ftrace.state == FTrace.STATE_TRACING:
            self.ftrace.pause()
            self.btn_read.setEnabled(True)
            self.btn_trace.setText("resume")

    def read_clicked(self):
        self.trace_read_dialog = FTraceReadDialog()

        self.ftrace.read_trace_async()

        self.trace_read_dialog.show()

    def trace_clicked(self):
        if self.ftrace.state == FTrace.STATE_TRACING:
            self.ftrace.stop()
            self.enable_options_view()
        elif self.ftrace.state == FTrace.STATE_NOT_TRACING:
            self.ftrace.set_current_events(self.filter_events.toPlainText())
            self.ftrace.set_current_filters(self.filter_functions.toPlainText())

            for i in range(0, self.options_list.count()):
                item = self.options_list.item(i)
                option = item.text()
                enabled = True
                if item.checkState() == Qt.Unchecked:
                    enabled = False
                self.ftrace.set_option(option, enabled)

            self.ftrace.start()
            self.disable_options_view()
        else:
            self.ftrace.start()
            self.disable_options_view()
示例#60
0
class CMWMain(QWidget):
    def __init__(self, **kwargs):
        QWidget.__init__(self, parent=None, flags=Qt.WindowStaysOnTopHint)

        cp.cmwmain = self
        self.set_input_pars(**kwargs)

        from psana.graphqt.CMWMainTabs import CMWMainTabs  # AFTER set_input_pars !!!!\
        self.wlog = cp.wlog = QWLoggerStd(cp, show_buttons=False)

        repoman = RepoManager(kwargs['logdir'], dettype=None)
        repoman.save_record_at_start(sys.argv[0].rsplit('/')[-1])

        self.wtab = CMWMainTabs()

        self.vspl = QSplitter(Qt.Vertical)
        self.vspl.addWidget(self.wtab)
        self.vspl.addWidget(self.wlog)

        self.mbox = QHBoxLayout()
        self.mbox.addWidget(self.vspl)

        self.setLayout(self.mbox)

        self.set_style()
        #self.set_tool_tips()

    def set_input_pars(self, **kwa):

        cp.kwargs = kwa

        self.xywh = cp.main_win_pos_x .value(),\
                    cp.main_win_pos_y .value(),\
                    cp.main_win_width .value(),\
                    cp.main_win_height.value()

        x, y, w, h = self.xywh
        self.setGeometry(x, y, w, h)
        logger.info('set preserved window geometry x,y,w,h: %d,%d,%d,%d' %
                    (x, y, w, h))
        #logger.info(log_rec_at_start())

        self.main_win_pos_x = cp.main_win_pos_x
        self.main_win_pos_y = cp.main_win_pos_y
        self.main_win_width = cp.main_win_width
        self.main_win_height = cp.main_win_height

        host = kwa.get('host', None)
        port = kwa.get('port', None)
        cp.user = kwa.get('user', None)
        cp.upwd = kwa.get('upwd', None)
        exp = kwa.get('experiment', None)
        det = kwa.get('detector', None)
        logdir = kwa.get('logdir', None)
        loglevel = kwa.get('loglevel', 'DEBUG').upper()
        savecfg = kwa.get('savecfg', False)
        if isinstance(loglevel, str): loglevel = loglevel.upper()

        if is_in_command_line(None, '--host'): cp.cdb_host.setValue(host)
        if is_in_command_line(None, '--port'): cp.cdb_port.setValue(port)
        if is_in_command_line('-e', '--experiment'): cp.exp_name.setValue(exp)
        if is_in_command_line('-d', '--detector'): cp.data_source.setValue(det)
        if is_in_command_line('-l', '--loglevel'):
            cp.log_level.setValue(loglevel)
        if is_in_command_line('-L', '--logdir'): cp.log_prefix.setValue(logdir)

        cp.save_cp_at_exit.setValue(savecfg)

        if loglevel == 'DEBUG':
            print(40 * '_')
            print_kwargs(kwa)

    def set_tool_tips(self):
        self.setToolTip('Calibration Management GUI')

    def set_style(self):
        self.setMinimumSize(500, 400)
        self.layout().setContentsMargins(0, 0, 0, 0)
        spl_pos = cp.main_vsplitter.value()
        w_height = self.main_win_height.value()
        self.vspl.setSizes((
            spl_pos,
            w_height - spl_pos,
        ))

    def closeEvent(self, e):
        logger.debug('closeEvent')
        #try: self.wspe.close()
        #except: pass
        self.wtab.close()
        self.on_save()
        QWidget.closeEvent(self, e)
        cp.wlog = None

    def key_usage(self):
        return 'Keys:'\
               '\n  V - view/hide tabs'\
               '\n'

    if __name__ == "__main__":

        def keyPressEvent(self, e):
            logger.debug('keyPressEvent, key=%s' % e.key())
            if e.key() == Qt.Key_Escape: self.close()
            elif e.key() == Qt.Key_V: self.wtab.view_hide_tabs()
            else: logger.info(self.key_usage())

    def on_save(self):

        point, size = self.mapToGlobal(QPoint(
            -5, -22)), self.size()  # Offset (-5,-22) for frame size.
        x, y, w, h = point.x(), point.y(), size.width(), size.height()
        msg = 'save window geometry x,y,w,h: %d,%d,%d,%d' % (x, y, w, h)
        logger.info(msg)
        print(msg)

        #Save main window position and size
        self.main_win_pos_x.setValue(x)
        self.main_win_pos_y.setValue(y)
        self.main_win_width.setValue(w)
        self.main_win_height.setValue(h)

        spl_pos = self.vspl.sizes()[0]
        msg = 'Save main v-splitter position %d' % spl_pos
        logger.debug(msg)

        cp.main_vsplitter.setValue(spl_pos)

        if cp.save_cp_at_exit.value():
            cp.printParameters()
            cp.saveParametersInFile()  # see ConfigParameters