Example #1
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()
    def __init__(self, parent=None):
        super(_s_CentralWidget, self).__init__(parent)
        self.parent = parent
        #This variables are used to save the splitter sizes before hide
        self._splitterMainSizes = None
        self._splitterAreaSizes = None
        self.lateralPanel = None

        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(0, 0, 0, 0)
        hbox.setSpacing(0)
        #Create Splitters to divide the UI in: MainPanel, Explorer, Misc
        self._splitterArea = QSplitter(Qt.Horizontal)
        self._splitterMain = QSplitter(Qt.Vertical)

        #Create scrollbar for follow mode
        self.scrollBar = QScrollBar(Qt.Vertical, self)
        self.scrollBar.setFixedWidth(20)
        self.scrollBar.setToolTip('Follow Mode: Scroll the Editors together')
        self.scrollBar.hide()
        self.scrollBar.valueChanged[int].connect(self.move_follow_scrolls)

        #Add to Main Layout
        hbox.addWidget(self.scrollBar)
        hbox.addWidget(self._splitterArea)
Example #3
0
    def setupUI(self):
        """Create User Interface.
        """
        sourceWidget = self.widgetSource()
        frameWidget = self.widgetFrame()
        parametersWidget = self.widgetParameters()

        leftSide = QWidget()
        leftSide.setLayout(parametersWidget)
        rightSide = QWidget()
        rightSide.setLayout(frameWidget)
        self.hsplitter = QSplitter(QtCore.Qt.Horizontal)
        self.hsplitter.addWidget(leftSide)
        self.hsplitter.addWidget(rightSide)
        self.hsplitter.setStretchFactor(0, 1)
        self.hsplitter.setStretchFactor(1, 10)

        downSide = QWidget()
        downSide.setLayout(self.widgetDebug())
        self.vsplitter = QSplitter(QtCore.Qt.Vertical)
        self.vsplitter.addWidget(self.hsplitter)
        self.vsplitter.addWidget(downSide)
        self.vsplitter.setStretchFactor(0, 10)
        self.vsplitter.setStretchFactor(1, 1)

        mainLayout = QVBoxLayout()
        mainLayout.addLayout(sourceWidget)
        mainLayout.addWidget(self.vsplitter)
        self.setLayout(mainLayout)
        self.setGeometry(300, 300, 800, 600)
        self.show()
Example #4
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()
Example #5
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)
Example #6
0
   def initUI(self):
      self.content = QWidget()

      self.hbox = QHBoxLayout(self.content)
      self.setCentralWidget(self.content)

      self.friend_list = QListWidget()
      self.friend_list.itemClicked.connect(self.friendClicked)

      self.message_scroll = QScrollArea()
      self.message_scroll.setWidgetResizable(True)
      #TODO have a setting to disable this
      self.message_scroll.verticalScrollBar().rangeChanged.connect(self.scrollBottom)

      self.message_input = MessageInput()
      self.message_input.sendMessage.connect(self.sendMessage)

      self.message_split = QSplitter(Qt.Vertical)
      self.message_split.addWidget(self.message_scroll)
      self.message_split.addWidget(self.message_input)

      self.main_split = QSplitter(Qt.Horizontal)
      self.main_split.addWidget(self.friend_list)
      self.main_split.addWidget(self.message_split)

      self.hbox.addWidget(self.main_split)

      self.show()
    def __init__(self, orientation=Qt.Vertical):
        QSplitter.__init__(self, orientation)
        self.pfile = None
        self._hsplitter = QSplitter(Qt.Horizontal)

        self.lateral_widget = lateral_widget.LateralWidget()
        self._hsplitter.addWidget(self.lateral_widget)
        self.table_widget = table_widget.TableWidget()
        self._hsplitter.addWidget(self.table_widget)

        self.addWidget(self._hsplitter)

        self.query_container = query_container.QueryContainer(self)
        self.addWidget(self.query_container)

        self.modified = False

        self.__nquery = 1

        # Connections
        # FIXME
        self.lateral_widget.itemClicked.connect(
            lambda: self.table_widget.stacked.setCurrentIndex(
                self.lateral_widget.row()))
        # For change table widget item when up/down
        # see issue #39
        self.lateral_widget.itemSelectionChanged.connect(
            lambda: self.table_widget.stacked.setCurrentIndex(
                self.lateral_widget.row()))
        self.query_container.saveEditor['PyQt_PyObject'].connect(
            self.save_query)
        self.setSizes([1, 1])
Example #8
0
 def _setupUi(self):
     self.resize(558, 447)
     self.mainLayout = QVBoxLayout(self)
     self.mainLayout.setSpacing(0)
     self.mainLayout.setContentsMargins(0, 0, 0, 0)
     self.splitterView = QSplitter()
     self.splitterView.setChildrenCollapsible(False)
     self.splitterView.setOrientation(Qt.Vertical)
     self.subSplitterView = QSplitter()
     self.subSplitterView.setChildrenCollapsible(False)
     self.treeView = TreeView(self)
     self.treeView.setAcceptDrops(True)
     self.treeView.setFrameShape(QFrame.NoFrame)
     self.treeView.setFrameShadow(QFrame.Plain)
     self.treeView.setEditTriggers(QAbstractItemView.EditKeyPressed|QAbstractItemView.SelectedClicked)
     self.treeView.setDragEnabled(True)
     self.treeView.setDragDropMode(QAbstractItemView.InternalMove)
     self.treeView.setUniformRowHeights(True)
     self.treeView.setAllColumnsShowFocus(True)
     self.treeView.setSelectionMode(QAbstractItemView.ExtendedSelection)
     self.treeView.header().setStretchLastSection(False)
     self.subSplitterView.addWidget(self.treeView)
     self.pieChart = PieChartView(self)
     self.pieChart.setMinimumSize(300, 0)
     self.subSplitterView.addWidget(self.pieChart)
     self.splitterView.addWidget(self.subSplitterView)
     self.graphView = LineGraphView(self)
     self.graphView.setMinimumSize(0, 200)
     self.splitterView.addWidget(self.graphView)
     self.splitterView.setStretchFactor(0, 1)
     self.splitterView.setStretchFactor(1, 0)
     self.subSplitterView.setStretchFactor(0, 1)
     self.subSplitterView.setStretchFactor(1, 0)
     self.mainLayout.addWidget(self.splitterView)
Example #9
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()
    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()
Example #11
0
    def doIt(self):
        self.box = QHBoxLayout(self) # cria uma box para receber os widgets

        self.gridAStar = Grid(self.width, self.height) # cria um grid para admin os widgets
        self.gridAStar.changed.connect(self.reDoAStar) # quando a land muda chama o reDo
        self.gridAStar.setFrameShape(QFrame.StyledPanel) # seta o formato do frame para um quadrado

        self.gridDfs = Grid(self.width, self.height)
        self.gridDfs.changed.connect(self.reDoDfs) # quando a land muda chama o reDo
        self.dfsDestroyed = False
        self.gridDfs.setFrameShape(QFrame.StyledPanel)

        self.right = Settings(self.gridAStar, self.gridDfs)  # right rrecebe as congiguracoes de campo
        self.right.changed.connect(self.reDo) # quando a land muda chama o reDo
        self.right.setFrameShape(QFrame.StyledPanel) # seta o formato do frame para um quadrado

        self.splitterV = QSplitter(Qt.Vertical) #reorganiza os qFrame's de acordo com o splitter
        self.splitterV.addWidget(self.gridAStar)
        self.splitterV.addWidget(self.gridDfs)

        self.splitterH = QSplitter(Qt.Horizontal)
        self.splitterH.addWidget(self.splitterV)
        self.splitterH.addWidget(self.right)

        self.box.addWidget(self.splitterH) # adiciona o splitter ao boox
        self.setLayout(self.box) # organiza tudo de acordo com o layout da box
        self.setWindowTitle('Path Finder')

        self.reDo() #  chama a classe para refazer
        self.show()
Example #12
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)
Example #13
0
 def __init__(self, parent):
     """
     Constructor
     
     @param parent parent widget (QWidget)
     """
     self.tabWidgets = []
     
     QSplitter.__init__(self, parent)
     ViewManager.__init__(self)
     self.setChildrenCollapsible(False)
     
     tw = TabWidget(self)
     self.addWidget(tw)
     self.tabWidgets.append(tw)
     self.currentTabWidget = tw
     self.currentTabWidget.showIndicator(True)
     tw.currentChanged.connect(self.__currentChanged)
     tw.installEventFilter(self)
     tw.tabBar().installEventFilter(self)
     self.setOrientation(Qt.Vertical)
     self.__inRemoveView = False
     
     self.maxFileNameChars = Preferences.getUI(
         "TabViewManagerFilenameLength")
     self.filenameOnly = Preferences.getUI("TabViewManagerFilenameOnly")
Example #14
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)
    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()))
Example #16
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
Example #17
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)
Example #18
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))
 def showEvent(self, event):
     QSplitter.showEvent(self, event)
     qsettings = QSettings(settings.SETTINGS_PATH, QSettings.IniFormat)
     hsizes = qsettings.value('hsplitter_sizes', None)
     if hsizes is not None:
         self._hsplitter.restoreState(hsizes)
     else:
         self._hsplitter.setSizes([1, self._hsplitter.width() / 3])
     vsizes = qsettings.value('vsplitter_sizes', None)
     if vsizes is not None:
         self.restoreState(vsizes)
     else:
         self.setSizes([self.height() / 3, self.height() / 3])
Example #20
0
    def __init__(self):
        QSplitter.__init__(self)
        self.setObjectName("main_container")
        self.main_tab = tab_manager.TabManager()
        self.secundary_tab = tab_manager.TabManager()
        self.secundary_tab.hide()
        self.tab = self.main_tab
        self.addWidget(self.main_tab)
        self.addWidget(self.secundary_tab)
        Amaru.load_component("main_container", self)

        self.fileChanged.connect(self._file_changed)
        self.tab.currentChanged[int].connect(self._current_tab_changed)
        self.tab.allTabsClosed.connect(self._all_tabs_closed)
Example #21
0
    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)
Example #22
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()
Example #23
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")
Example #24
0
File: interface.py Project: asb/mu
    def setup(self, theme):
        """
        Sets up the window.

        Defines the various attributes of the window and defines how the user
        interface is laid out.
        """
        self.theme = theme
        # Give the window a default icon, title and minimum size.
        self.setWindowIcon(load_icon(self.icon))
        self.update_title()
        self.setMinimumSize(800, 600)

        self.widget = QWidget()
        self.splitter = QSplitter(Qt.Vertical)

        widget_layout = QVBoxLayout()
        self.widget.setLayout(widget_layout)

        self.button_bar = ButtonBar(self.widget)
        self.tabs = QTabWidget()
        self.tabs.setTabsClosable(True)
        self.tabs.tabCloseRequested.connect(self.tabs.removeTab)

        widget_layout.addWidget(self.button_bar)
        widget_layout.addWidget(self.splitter)

        self.splitter.addWidget(self.tabs)

        self.addWidget(self.widget)
        self.setCurrentWidget(self.widget)

        self.set_theme(theme)
        self.show()
        self.autosize_window()
Example #25
0
File: util.py Project: jopohl/urh
def set_splitter_stylesheet(splitter: QSplitter):
    splitter.setHandleWidth(4)
    bgcolor = constants.BGCOLOR.lighter(150)
    r, g, b, a = bgcolor.red(), bgcolor.green(), bgcolor.blue(), bgcolor.alpha()
    splitter.setStyleSheet("QSplitter::handle:vertical {{margin: 4px 0px; "
                           "background-color: qlineargradient(x1:0, y1:0, x2:1, y2:0, "
                           "stop:0.2 rgba(255, 255, 255, 0),"
                           "stop:0.5 rgba({0}, {1}, {2}, {3}),"
                           "stop:0.8 rgba(255, 255, 255, 0));"
                           "image: url(:/icons/icons/splitter_handle_horizontal.svg);}}"
                           "QSplitter::handle:horizontal {{margin: 4px 0px; "
                           "background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
                           "stop:0.2 rgba(255, 255, 255, 0),"
                           "stop:0.5 rgba({0}, {1}, {2}, {3}),"
                           "stop:0.8 rgba(255, 255, 255, 0));"
                           "image: url(:/icons/icons/splitter_handle_vertical.svg);}}".format(r, g, b, a))
Example #26
0
    def setup(self, theme, api=None):
        """
        Sets up the window.

        Defines the various attributes of the window and defines how the user
        interface is laid out.
        """
        self.theme = theme
        self.api = api if api else []
        # Give the window a default icon, title and minimum size.
        self.setWindowIcon(load_icon(self.icon))
        self.update_title()
        self.setMinimumSize(926, 600)

        self.widget = QWidget()
        self.splitter = QSplitter(Qt.Vertical)

        widget_layout = QVBoxLayout()
        self.widget.setLayout(widget_layout)

        self.button_bar = ButtonBar(self.widget)

        widget_layout.addWidget(self.button_bar)
        widget_layout.addWidget(self.splitter)
        self.tabs = FileTabs()
        self.splitter.addWidget(self.tabs)

        self.addWidget(self.widget)
        self.setCurrentWidget(self.widget)

        self.set_theme(theme)
        self.show()
        self.autosize_window()
Example #27
0
 def populate_central_widget(self):
     self.vertical_widgets = collections.OrderedDict()
     
     self.horizontal_splitter = QSplitter(
         Qt.Horizontal, self.vertical_splitter)
     self.horizontal_widgets = collections.OrderedDict()
     self.vertical_widgets["horizontal_splitter"] = self.horizontal_splitter
     
     Alter.invoke_all(
         'main_window_add_vertical_widget',
         self.vertical_widgets,
         self
     )
     for widget in self.vertical_widgets.values():
         self.vertical_splitter.addWidget(widget)
     
     Alter.invoke_all(
         'main_window_add_horizontal_widget',
         self.horizontal_widgets,
         self.vertical_splitter
     )
     for widget in self.horizontal_widgets.values():
         self.horizontal_splitter.addWidget(widget)
     
     #restore horizontal splitter state
     state = ModuleManager.core['settings'].Settings.value(
         self.KEY_H_SPLITTER_STATE,
         None
     )
     if state:
         self.horizontal_splitter.restoreState(state)
Example #28
0
    def __init__(self):
        # Parent constructor(s)
        QMainWindow.__init__(self)

        self.controller = None

        # Main widget
        self.mainWidget = QWidget(self)
        self.setCentralWidget(self.mainWidget)
        self.setWindowTitle("dotEd")

        # Menu
        self.createMenu()

        # Status bar just for a test
        self.statusBar().showMessage("Double click to create a node")

        # Layout/Splitter which will contain all widgets
        self.splitter = QSplitter(Qt.Horizontal)
        layout = QVBoxLayout(self.mainWidget)
        layout.addWidget(self.splitter)

        # Clear graph button
        clearGraphButton = QPushButton("Clear graph")
        clearGraphButton.clicked.connect(self.onClearGraph)
        layout.addWidget(clearGraphButton)
Example #29
0
    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)
Example #30
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)
    def initUI(self):
        """Override."""
        self._cw = QSplitter(Qt.Vertical)

        for img, fom_hist, roi_hist in zip(self._poi_imgs, self._poi_fom_hists,
                                           self._poi_roi_hists):
            rw = QSplitter(Qt.Vertical)
            rw.addWidget(fom_hist)
            rw.addWidget(roi_hist)

            w = QSplitter()
            w.addWidget(img)
            w.addWidget(rw)

            w.setSizes([self._TOTAL_W / 2, self._TOTAL_W / 2])
            self._cw.addWidget(w)

        self.setCentralWidget(self._cw)
        self._cw.setHandleWidth(self._SPLITTER_HANDLE_WIDTH)
Example #32
0
class LossVisualizer(QWidget):
    def __init__(self, mat_output_node: GMaterialOutputNode):
        super().__init__(parent=None)
        self._mat_out_node = mat_output_node

        # Declare widgets
        self._layout = QGridLayout()
        self._splitter = QSplitter(Qt.Horizontal)
        self._plot = PlotWidget3D()
        self._canvas = self._plot.get_canvas()
        self._fig_ax = self._plot.get_axis()
        self._table_widget = QTableWidget(self)
        self._p1_res = IntInput(0, 100)
        self._p2_res = IntInput(0, 100)
        self._plot_button = QPushButton("Plot Loss")
        self._start_gd_button = QPushButton("Start Gradient Descent")

        # Declare data
        self._item_queue = FIFOQueue(maxsize=2)
        self._bg_brush_selected = QBrush(QColor("#8bf9b0"))
        self._bg_brush_default = QBrush(QColor("#ffffff"))
        self._settings = None
        self._target_image = None
        self._target_matrix = None
        self._out_node = None
        self._thread = None
        self._gd = None
        self._p1 = None
        self._p2 = None
        self._hist_p1 = []
        self._hist_p2 = []
        self._plot_line3d = None
        self._progress_dialog = None

        self._init()
        self._list_parameters()

    def _init(self):
        self.setWindowTitle("Loss Visualizer")

        # Setup table widget
        self._table_widget.setColumnCount(3)
        self._table_widget.setHorizontalHeaderLabels(
            ["Parameter", "Min", "Max"])
        self._table_widget.setColumnWidth(1, 50)
        self._table_widget.setColumnWidth(2, 50)

        # Setup plot
        self._fig_ax.set_title("Loss Surface")
        self._fig_ax.set_xlabel("Parameter ?")
        self._fig_ax.set_ylabel("Parameter ?")
        self._fig_ax.set_zlabel("Loss Value")

        # Setup resolution input
        self._p1_res.set_value(20)
        self._p2_res.set_value(20)
        p1_module = Module("Param 1 Res.", self._p1_res)
        p2_module = Module("Param 2 Res.", self._p2_res)

        # Setup buttons
        self._plot_button.clicked.connect(self._plot_loss)
        self._start_gd_button.clicked.connect(self._start_gd)
        self._start_gd_button.setEnabled(False)

        # Add widgets to layout
        self._splitter.addWidget(self._table_widget)
        self._splitter.addWidget(self._plot)
        self._layout.addWidget(self._splitter, 0, 0, 1, 5)
        self._layout.addWidget(p1_module, 1, 1)
        self._layout.addWidget(p2_module, 1, 2)
        self._layout.addWidget(self._plot_button, 1, 3)
        self._layout.addWidget(self._start_gd_button, 1, 4)

        self.setLayout(self._layout)

    def _list_parameters(self):
        _, param_dict = self._mat_out_node.get_backend_node().render(
            10, 10, retain_graph=True)
        row = 0
        self._table_widget.setRowCount(len(param_dict))

        for key in param_dict:
            param = param_dict[key]
            param.set_modified_arg(key)
            limits = param.get_limits()
            diff = limits[1] - limits[0]
            min_item = FloatInput(limits[0] - diff, limits[1] + diff)
            min_item.set_value(limits[0])
            max_item = FloatInput(limits[0] - diff, limits[1] + diff)
            max_item.set_value(limits[1])
            item = CheckboxItem(key, content={"param": param, "index": -1})
            item.state_changed.connect(self._item_state_changed)
            self._table_widget.setCellWidget(row, 0, item)
            self._table_widget.setCellWidget(row, 1, min_item)
            self._table_widget.setCellWidget(row, 2, max_item)

            row += 1

            if param.is_vector():
                item.set_checkable(False)
                item.setEnabled(False)

                for i in range(param.shape()[1]):
                    self._table_widget.insertRow(row)
                    min_item = FloatInput(limits[0], limits[1])
                    min_item.set_value(limits[0])
                    max_item = FloatInput(limits[0], limits[1])
                    max_item.set_value(limits[1])
                    sub_item = CheckboxItem("  [{}]".format(i),
                                            content={
                                                "param": param,
                                                "index": i
                                            })
                    sub_item.state_changed.connect(self._item_state_changed)
                    self._table_widget.setCellWidget(row, 0, sub_item)
                    self._table_widget.setCellWidget(row, 1, min_item)
                    self._table_widget.setCellWidget(row, 2, max_item)
                    row += 1

        self._table_widget.resizeColumnToContents(0)
        self._table_widget.resizeRowsToContents()

    def _checked_items(
            self) -> typing.List[typing.Tuple[QWidget, QWidget, QWidget]]:
        checked = []

        for i in range(self._table_widget.rowCount()):
            item = self._table_widget.cellWidget(i, 0)
            min_item = self._table_widget.cellWidget(i, 1)
            max_item = self._table_widget.cellWidget(i, 2)
            if item.get_state() == Qt.Checked:
                checked.append((item, min_item, max_item))

        return checked

    def _item_state_changed(self, item: CheckboxItem):
        if item.get_state() == Qt.Checked:
            if self._item_queue.is_full():
                first_item = self._item_queue.pop()
                first_item.set_state(Qt.Unchecked)

            self._item_queue.put(item)
        elif item.get_state() == Qt.Unchecked:
            if item in self._item_queue:
                self._item_queue.remove(item)

    def _plot_loss(self):
        self._fig_ax.clear()

        W, H = self._settings.render_width, self._settings.render_height
        R1, R2 = self._p1_res.get_gl_value(), self._p2_res.get_gl_value()
        progress_dialog = QProgressDialog("Calculating loss surface...",
                                          "Cancel", 0, R1 - 1, self)
        progress_dialog.setWindowTitle("Calculating")
        progress_dialog.setWindowModality(Qt.WindowModal)
        progress_dialog.setMinimumDuration(1)

        self._target_matrix = image_funcs.image_to_tensor(
            self._target_image, (W, H))
        loss_surface = np.empty((R1, R2))
        loss_f = self._settings.loss_func(**self._settings.loss_args)
        checked_items = self._checked_items()

        item1 = checked_items[0][0]
        item1_min = checked_items[0][1].get_gl_value()
        item1_max = checked_items[0][2].get_gl_value()
        self._fig_ax.set_xlabel(item1.label)
        self._p1: Parameter = item1.content["param"]
        p1_index = item1.content["index"]
        self._p1.save_value()
        p1_values = torch.from_numpy(
            np.linspace(item1_min, item1_max, num=R1, endpoint=True))

        item2 = checked_items[1][0]
        item2_min = checked_items[1][1].get_gl_value()
        item2_max = checked_items[1][2].get_gl_value()
        self._fig_ax.set_ylabel(item2.label)
        self._p2: Parameter = item2.content["param"]
        p2_index = item2.content["index"]
        self._p2.save_value()
        p2_values = torch.from_numpy(
            np.linspace(item2_min, item2_max, num=R2, endpoint=True))

        min_loss = np.finfo(np.float32).max
        min_loss_p1 = None
        min_loss_p2 = None

        for i in range(R1):
            self._p1.set_value(p1_values[i], index=p1_index)
            progress_dialog.setValue(i)

            if progress_dialog.wasCanceled():
                return

            for j in range(R2):
                self._p2.set_value(p2_values[j], index=p2_index)
                r, _ = self._mat_out_node.get_backend_node().render(
                    W, H, retain_graph=True)
                loss = loss_f(
                    r, self._target_matrix).detach().clone().cpu().numpy()

                if loss < min_loss:
                    min_loss = loss
                    min_loss_p1 = self._p1.get_value(p1_index)
                    min_loss_p2 = self._p2.get_value(p2_index)

                loss_surface[i, j] = loss

            _logger.info("{:.2f}% complete...".format((i + 1) / R1 * 100))

        P1, P2 = torch.meshgrid([p1_values, p2_values])
        self._p1.restore_value()
        self._p2.restore_value()

        self._fig_ax.plot_surface(P1, P2, loss_surface, cmap=plt.cm.viridis)
        self._fig_ax.set_zlim(bottom=0)

        # Add min value marker
        self._fig_ax.plot([min_loss_p1], [min_loss_p2], [min_loss],
                          marker='+',
                          color="#ff00ff",
                          markersize=14,
                          markeredgewidth=2.5)
        # self._fig_ax.text(min_loss_p1, min_loss_p2, min_loss * 1.1, "Minimum Loss = {:.4f}".format(float(min_loss)), color='#ff00ff')

        self._canvas.draw()
        self._start_gd_button.setEnabled(True)

    def _start_gd(self):
        self._hist_p2 = np.empty(self._settings.max_iter)
        self._hist_p1 = np.empty(self._settings.max_iter)

        self._progress_dialog = QProgressDialog(
            "Performing Gradient Descent...", "Cancel", 0,
            self._settings.max_iter, self)
        self._progress_dialog.setWindowTitle("Calculating")
        self._progress_dialog.setWindowModality(Qt.WindowModal)
        self._progress_dialog.setMinimumDuration(1)

        checked_items = self._checked_items()
        params = {
            i[0].content["param"].get_modified_arg(): i[0].content["param"]
            for i in checked_items
        }

        self._gd = GradientDescent(self._target_image, self._out_node,
                                   self._settings)
        self._gd.set_active_parameters(params)
        self._thread = QThread()
        self._gd.iteration_done.connect(self._gd_callback)
        self._gd.moveToThread(self._thread)
        self._thread.started.connect(self._gd.run)
        self._gd.finished.connect(self._finish_gradient_descent)

        _logger.debug("Started Gradient Descent Thread...")

        self._thread.start()

    def _gd_callback(self, info: dict):
        params = info["params"]
        i = info["iter"]
        loss = info["loss"]
        self._progress_dialog.setValue(i)

        if self._progress_dialog.wasCanceled():
            self._gd.stop()
            self._thread.quit()

        x = params[self._p1.get_modified_arg()]
        y = params[self._p2.get_modified_arg()]
        self._hist_p1[i] = x
        self._hist_p2[i] = y
        _logger.debug("{}. Loss: {}, P1: {}, P2: {}".format(i, loss, x, y))

    def _finish_gradient_descent(self, params, loss_hist, _):

        if self._thread.isRunning():
            _logger.info("Stopping Gradient Descent Thread...")
            self._gd.stop()
            self._thread.quit()
            self._gd.restore_params()

        self._progress_dialog.setValue(self._progress_dialog.maximum())

        # Plot dis shit!
        num_iter = len(loss_hist)
        x = params[self._p1.get_modified_arg()]
        y = params[self._p2.get_modified_arg()]
        self._hist_p1[num_iter - 1] = x.get_value()
        self._hist_p2[num_iter - 1] = y.get_value()
        xs = self._hist_p1[0:num_iter]
        ys = self._hist_p2[0:num_iter]
        self._fig_ax.set_title("HSV Shader Loss Surface", fontsize=18)
        self._fig_ax.plot(xs,
                          ys,
                          loss_hist,
                          color="#ff656dff",
                          marker="o",
                          mfc="#c44e52ff",
                          mec="#ff656dff",
                          lw=2)
        self._fig_ax.set_xlabel("Hue")
        self._fig_ax.set_ylabel("Saturation")
        self._fig_ax.set_zlabel("Loss")
        self._canvas.draw()
        self._canvas.flush_events()

    def open(self, settings: GradientDescentSettings, target: Image,
             mat_out_node: GMaterialOutputNode):
        if target is None:
            msg = QMessageBox(
                QMessageBox.Warning, "Need to set Target Texture!",
                "Can not open loss visualizer because target texture is not set."
            )
            msg.exec()
        else:
            self._settings = settings
            self._target_image = target
            self._out_node = mat_out_node
            super().show()
Example #33
0
class MainWindow(QWidget):
    def __init__(self, game):
        super().__init__()

        self.__model = None
        self.__game = game
        self.__game_widget = GameWidget(game)
        self.__game_widget.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
        game.start(self.__game_widget)

        self.__models = [
            OneDimensionalModelWrapper1(),
            OneDimensionalModelWrapper2(),
            OneDimensionalModelWrapper3(),
            OneDimensionalModelWrapper(),
            TwoDimensionalModelWrapper(),
        ]
        for model in self.__models:
            model.model_changing_callback = self.model_changing

        self.__model_plot = PlotWidget()
        self.__model_label = QLabel("Model")
        self.__model_selector = QComboBox(self)

        self.__config_layout = QGridLayout(self)
        self.__config_layout.setColumnStretch(1, 2)
        self.__config_layout.addWidget(self.__model_label)
        self.__config_layout.addWidget(self.__model_selector)
        self.__config_widget = QGroupBox(self)
        self.__config_widget.setLayout(self.__config_layout)

        self.__left_side_layout = QVBoxLayout(self)
        self.__left_side_layout.addWidget(self.__config_widget)
        self.__left_side_layout.addWidget(self.__game_widget)
        self.__left_side_widget = QWidget(self)
        self.__left_side_widget.setLayout(self.__left_side_layout)

        self.__splitter = QSplitter(Qt.Horizontal)
        self.__splitter.addWidget(self.__left_side_widget)
        self.__splitter.addWidget(self.__model_plot)
        self.__splitter.setStretchFactor(0, 4)
        self.__splitter.setStretchFactor(1, 1)

        self.__layout = QHBoxLayout(self)
        self.__layout.addWidget(self.__splitter)
        self.setLayout(self.__layout)

        self.__model_selector.currentIndexChanged.connect(self.model_changed)
        for model in self.__models:
            self.__model_selector.addItem(model.get_name())

    def model_changing(self, model, changing):
        if changing:
            self.__game.set_model(None)
        else:
            self.__game.set_model(self.__model)
            self.__model_plot.set_model(model)

    def __remove_current_model_config_widgets(self):
        if self.__model is None:
            return
        for old_widget in self.__model.get_config_widgets():
            old_widget.hide()
            self.__config_layout.removeWidget(old_widget)
        self.__config_layout.setColumnStretch(1, 2)

    def __add_current_model_config_widgets(self):
        if self.__model is None:
            return
        for new_widget in self.__model.get_config_widgets():
            new_widget.show()
            self.__config_layout.addWidget(new_widget)
        self.__config_layout.setColumnStretch(1, 2)

    def model_changed(self, index):
        self.__game.stop()

        self.__remove_current_model_config_widgets()
        self.__model = self.__models[index]
        self.__model.clear_points()
        self.__add_current_model_config_widgets()

        self.__model_plot.set_model(self.__model)
        self.__game.set_model(self.__model)
        self.__game.restart()
class PrioritizeDialog(QDialog):
    def __init__(self, parent, app, **kwargs):
        flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint
        super().__init__(parent, flags, **kwargs)
        self._setupUi()
        self.model = PrioritizeDialogModel(app=app.model)
        self.categoryList = ComboboxModel(model=self.model.category_list,
                                          view=self.categoryCombobox)
        self.criteriaList = ListviewModel(model=self.model.criteria_list,
                                          view=self.criteriaListView)
        self.prioritizationList = PrioritizationList(
            model=self.model.prioritization_list,
            view=self.prioritizationListView)
        self.model.view = self

        self.addCriteriaButton.clicked.connect(self.model.add_selected)
        self.removeCriteriaButton.clicked.connect(self.model.remove_selected)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

    def _setupUi(self):
        self.setWindowTitle(tr("Re-Prioritize duplicates"))
        self.resize(700, 400)

        # widgets
        msg = tr(
            "Add criteria to the right box and click OK to send the dupes that correspond the "
            "best to these criteria to their respective group's "
            "reference position. Read the help file for more information.")
        self.promptLabel = QLabel(msg)
        self.promptLabel.setWordWrap(True)
        self.categoryCombobox = QComboBox()
        self.criteriaListView = QListView()
        self.addCriteriaButton = QPushButton(
            self.style().standardIcon(QStyle.SP_ArrowRight), "")
        self.removeCriteriaButton = QPushButton(
            self.style().standardIcon(QStyle.SP_ArrowLeft), "")
        self.prioritizationListView = QListView()
        self.prioritizationListView.setAcceptDrops(True)
        self.prioritizationListView.setDragEnabled(True)
        self.prioritizationListView.setDragDropMode(
            QAbstractItemView.InternalMove)
        self.prioritizationListView.setSelectionBehavior(
            QAbstractItemView.SelectRows)
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok)

        # layout
        self.mainLayout = QVBoxLayout(self)
        self.mainLayout.addWidget(self.promptLabel)
        self.splitter = QSplitter()
        sp = self.splitter.sizePolicy()
        sp.setVerticalPolicy(QSizePolicy.Expanding)
        self.splitter.setSizePolicy(sp)
        self.leftSide = QWidget()
        self.leftWidgetsLayout = QVBoxLayout()
        self.leftWidgetsLayout.addWidget(self.categoryCombobox)
        self.leftWidgetsLayout.addWidget(self.criteriaListView)
        self.leftSide.setLayout(self.leftWidgetsLayout)
        self.splitter.addWidget(self.leftSide)
        self.rightSide = QWidget()
        self.rightWidgetsLayout = QHBoxLayout()
        self.addRemoveButtonsLayout = QVBoxLayout()
        self.addRemoveButtonsLayout.addItem(verticalSpacer())
        self.addRemoveButtonsLayout.addWidget(self.addCriteriaButton)
        self.addRemoveButtonsLayout.addWidget(self.removeCriteriaButton)
        self.addRemoveButtonsLayout.addItem(verticalSpacer())
        self.rightWidgetsLayout.addLayout(self.addRemoveButtonsLayout)
        self.rightWidgetsLayout.addWidget(self.prioritizationListView)
        self.rightSide.setLayout(self.rightWidgetsLayout)
        self.splitter.addWidget(self.rightSide)
        self.mainLayout.addWidget(self.splitter)
        self.mainLayout.addWidget(self.buttonBox)
Example #35
0
    def initUI(self):      
       
        hbox = QHBoxLayout(self)

        topleft = QFrame(self)
        topleft.setFrameShape(QFrame.StyledPanel)
        #add button in left frame
        btn = QPushButton('button', topleft)
        btn.setFixedSize(50, 20)
        btn.move(50,50)
        
        
        
 
        topright = QFrame(self)
        topright.setFrameShape(QFrame.StyledPanel)
        #add text Edit in right frame
        
        self.text2=QTextEdit('textedit2 ',topright)
        self.text2.setFixedSize(100,100)
       
        
      
        bottom = QFrame(self)
        bottom.setFrameShape(QFrame.StyledPanel)
        self.text1=QTextEdit(' ',bottom)
        self.text1.setFixedSize(100,100)
        btn.clicked.connect(self.aaaa)

       
        def aaaa(self):
            print('1')
            textfrlabel=self.text2.text()
            print('2')
            self.text1.setText(textfrlabel)


        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()
Example #36
0
    def __init__(self, parent=None):  # pylint: disable=too-many-statements
        super(ModulesPanel, self).__init__(parent)
        self._app_window = parent

        if self._app_window.dwarf is None:
            print('ModulesPanel created before Dwarf exists')
            return

        self._app_window.dwarf.onSetModules.connect(self.set_modules)
        self._app_window.dwarf.onModuleLoaded.connect(self.on_module_loaded)

        self._uppercase_hex = True
        self._sized = False
        self.setContentsMargins(0, 0, 0, 0)

        # setup models
        self.modules_list = None
        self.modules_model = QStandardItemModel(0, 4, self)
        self.modules_model.setHeaderData(0, Qt.Horizontal, 'Name')
        self.modules_model.setHeaderData(1, Qt.Horizontal, 'Base')
        self.modules_model.setHeaderData(1, Qt.Horizontal, Qt.AlignCenter,
                                         Qt.TextAlignmentRole)
        self.modules_model.setHeaderData(2, Qt.Horizontal, 'Size')
        self.modules_model.setHeaderData(2, Qt.Horizontal, Qt.AlignCenter,
                                         Qt.TextAlignmentRole)
        self.modules_model.setHeaderData(3, Qt.Horizontal, 'Path')

        self.imports_list = None
        self.imports_model = QStandardItemModel(0, 4, self)
        self.imports_model.setHeaderData(0, Qt.Horizontal, 'Import')
        self.imports_model.setHeaderData(1, Qt.Horizontal, 'Address')
        self.imports_model.setHeaderData(1, Qt.Horizontal, Qt.AlignCenter,
                                         Qt.TextAlignmentRole)
        self.imports_model.setHeaderData(2, Qt.Horizontal, 'Module')
        self.imports_model.setHeaderData(2, Qt.Horizontal, Qt.AlignCenter,
                                         Qt.TextAlignmentRole)
        self.imports_model.setHeaderData(3, Qt.Horizontal, 'Type')

        self.exports_list = None
        self.exports_model = QStandardItemModel(0, 3, self)
        self.exports_model.setHeaderData(0, Qt.Horizontal, 'Export')
        self.exports_model.setHeaderData(1, Qt.Horizontal, 'Address')
        self.exports_model.setHeaderData(1, Qt.Horizontal, Qt.AlignCenter,
                                         Qt.TextAlignmentRole)
        self.exports_model.setHeaderData(2, Qt.Horizontal, 'Type')

        self.symbols_list = None
        self.symbols_model = QStandardItemModel(0, 3, self)
        self.symbols_model.setHeaderData(0, Qt.Horizontal, 'Symbol')
        self.symbols_model.setHeaderData(1, Qt.Horizontal, 'Address')
        self.symbols_model.setHeaderData(1, Qt.Horizontal, Qt.AlignCenter,
                                         Qt.TextAlignmentRole)
        self.symbols_model.setHeaderData(2, Qt.Horizontal, 'Type')

        # setup ui
        self.modules_list = DwarfListView()
        self.modules_list.setContextMenuPolicy(Qt.CustomContextMenu)
        self.modules_list.customContextMenuRequested.connect(
            self._on_modules_contextmenu)
        self.modules_list.setEditTriggers(self.modules_list.NoEditTriggers)
        self.modules_list.clicked.connect(self._module_clicked)
        self.modules_list.doubleClicked.connect(self._module_dblclicked)
        self.modules_list.setModel(self.modules_model)
        self.modules_list.header().setSectionResizeMode(
            0, QHeaderView.ResizeToContents)
        self.modules_list.header().setSectionResizeMode(
            1, QHeaderView.ResizeToContents)
        self.modules_list.header().setSectionResizeMode(
            2, QHeaderView.ResizeToContents)
        self.modules_list.selectionModel().selectionChanged.connect(
            self._module_clicked)

        self.addWidget(self.modules_list)

        v_splitter = QSplitter(Qt.Vertical)
        self.imports_list = DwarfListView()
        self.imports_list.setContextMenuPolicy(Qt.CustomContextMenu)
        self.imports_list.customContextMenuRequested.connect(
            self._on_imports_contextmenu)
        self.imports_list.setEditTriggers(self.modules_list.NoEditTriggers)
        self.imports_list.doubleClicked.connect(self._import_dblclicked)
        self.imports_list.setModel(self.imports_model)
        self.imports_list.header().setSectionResizeMode(
            0, QHeaderView.ResizeToContents)
        self.imports_list.header().setSectionResizeMode(
            1, QHeaderView.ResizeToContents)
        self.imports_list.header().setSectionResizeMode(
            2, QHeaderView.ResizeToContents)
        self.imports_list.setVisible(False)
        self.exports_list = DwarfListView()
        self.exports_list.setContextMenuPolicy(Qt.CustomContextMenu)
        self.exports_list.customContextMenuRequested.connect(
            self._on_exports_contextmenu)
        self.exports_list.setEditTriggers(self.modules_list.NoEditTriggers)
        self.exports_list.doubleClicked.connect(self._export_dblclicked)
        self.exports_list.setModel(self.exports_model)
        self.exports_list.header().setSectionResizeMode(
            0, QHeaderView.ResizeToContents)
        self.exports_list.header().setSectionResizeMode(
            1, QHeaderView.ResizeToContents)
        self.exports_list.header().setSectionResizeMode(
            2, QHeaderView.ResizeToContents)
        self.exports_list.setVisible(False)
        self.symbols_list = DwarfListView()
        self.symbols_list.setContextMenuPolicy(Qt.CustomContextMenu)
        self.symbols_list.doubleClicked.connect(self._symbol_dblclicked)
        self.symbols_list.setModel(self.symbols_model)
        self.symbols_list.header().setSectionResizeMode(
            0, QHeaderView.ResizeToContents)
        self.symbols_list.header().setSectionResizeMode(
            1, QHeaderView.ResizeToContents)
        self.symbols_list.header().setSectionResizeMode(
            2, QHeaderView.ResizeToContents)
        self.symbols_list.setVisible(False)
        v_splitter.addWidget(self.imports_list)
        v_splitter.addWidget(self.exports_list)
        v_splitter.addWidget(self.symbols_list)
        v_splitter.setSizes([100, 100, 100])
        self.addWidget(v_splitter)
Example #37
0
    def __init__(self, h, v, parent=None):
        super(MyGUI, self).__init__(parent)

        self.points = obj.PointObjects({
            '_ids':
            ['tether_Atrium', 'tether_Ventricle', 'AVCanal', 'Midline'],
            'colors': ['#6eadd8', '#ff7f0e', 'red', '#c4c4c4'],
            'markers': ['o', 'o', 'X', '-x'],
            'ms': [3, 3, 5, 5],
            'is_instance': [0, 0, 0, 0],
            'coords': [np.array([])] * 4
        })
        self.file_name = ''
        self.stacks = np.zeros((3, 3, 2, v, h))
        self.channels = ['ch0', 'ch1']
        self.widgets = {}

        self.createLoadSaveGroupBox()
        self.createObjectsControlGroupBox()
        self.createTZCControlGroupBox()
        self.createCanvas2DGroupBox()
        self.createCanvas3DGroupBox()

        self.setEnableState(False)

        mainLayout = QVBoxLayout()

        split3 = QSplitter(Qt.Vertical)
        split3.setMinimumWidth(0)

        split1 = QSplitter(Qt.Horizontal)
        split2 = QSplitter(Qt.Horizontal)

        split3.addWidget(self.groupObjectsControl)
        split3.addWidget(self.groupTZCControl)
        split2.addWidget(self.groupCanvas2DBox)
        split2.addWidget(self.groupCanvas3DBox)
        split1.addWidget(split3)
        split1.addWidget(split2)

        mainLayout.addWidget(self.groupLoadSave)
        mainLayout.addWidget(split1)

        self.setLayout(mainLayout)
        self.resize(1.2 * 960, 1.2 * 413)
        self.setWindowTitle('Manual annotation tool')
        QApplication.setStyle('Macintosh')
Example #38
0
    def __InitView(self):
        '''
                  初始化界面
        '''
        self.setFixedSize(800, 600)
        self.setWindowTitle("画笔")

        # 新建一个水平布局作为本窗体的主布局
        main_layout = QHBoxLayout(self)
        # 设置主布局内边距以及控件间距为10px
        main_layout.setSpacing(10)

        # 在主界面左侧放置画板
        main_layout.addWidget(self.__paintBoard)

        # 新建垂直子布局用于放置按键
        sub_layout = QVBoxLayout()

        # 设置此子布局和内部控件的间距为10px
        sub_layout.setContentsMargins(10, 10, 10, 10)

        self.__btn_Clear = QPushButton("清空画板")
        self.__btn_Clear.setParent(self)  # 设置父对象为本界面

        # 将按键按下信号与画板清空函数相关联
        self.__btn_Clear.clicked.connect(self.__paintBoard.Clear)
        sub_layout.addWidget(self.__btn_Clear)

        self.__btn_Quit = QPushButton("退出")
        self.__btn_Quit.setParent(self)  # 设置父对象为本界面
        self.__btn_Quit.clicked.connect(self.Quit)
        sub_layout.addWidget(self.__btn_Quit)

        self.__btn_Save = QPushButton("保存作品")
        self.__btn_Save.setParent(self)
        self.__btn_Save.clicked.connect(self.on_btn_Save_Clicked)
        sub_layout.addWidget(self.__btn_Save)

        self.__cbtn_Eraser = QCheckBox("  使用橡皮擦")
        self.__cbtn_Eraser.setParent(self)
        self.__cbtn_Eraser.clicked.connect(self.on_cbtn_Eraser_clicked)
        sub_layout.addWidget(self.__cbtn_Eraser)

        splitter = QSplitter(self)  # 占位符
        sub_layout.addWidget(splitter)

        self.__label_penThickness = QLabel(self)
        self.__label_penThickness.setText("画笔粗细")
        self.__label_penThickness.setFixedHeight(20)
        sub_layout.addWidget(self.__label_penThickness)

        self.__spinBox_penThickness = QSpinBox(self)
        self.__spinBox_penThickness.setMaximum(20)
        self.__spinBox_penThickness.setMinimum(2)
        self.__spinBox_penThickness.setValue(10)  # 默认粗细为10
        self.__spinBox_penThickness.setSingleStep(2)  # 最小变化值为2
        self.__spinBox_penThickness.valueChanged.connect(
            self.on_PenThicknessChange
        )  # 关联spinBox值变化信号和函数on_PenThicknessChange
        sub_layout.addWidget(self.__spinBox_penThickness)

        self.__label_penColor = QLabel(self)
        self.__label_penColor.setText("画笔颜色")
        self.__label_penColor.setFixedHeight(20)
        sub_layout.addWidget(self.__label_penColor)

        self.__comboBox_penColor = QComboBox(self)
        self.__fillColorList(self.__comboBox_penColor)  # 用各种颜色填充下拉列表
        self.__comboBox_penColor.currentIndexChanged.connect(
            self.on_PenColorChange)  # 关联下拉列表的当前索引变更信号与函数on_PenColorChange
        sub_layout.addWidget(self.__comboBox_penColor)

        main_layout.addLayout(sub_layout)  # 将子布局加入主布局
Example #39
0
    def initUI(self):

        hbox = QHBoxLayout(self)

        # 칸마다 경계를 나누기 위해 StyledPanel 사용
        topleft = QFrame(self)
        topleft.setFrameShape(QFrame.StyledPanel)

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

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

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

        # 수평 Splitter 생성, 두 개의 프레임 추가
        splitter1 = QSplitter(Qt.Horizontal)
        splitter1.addWidget(topleft)
        splitter1.addWidget(topright)

        splitter2 = QSplitter(Qt.Horizontal)
        splitter2.addWidget(bottomleft)
        splitter2.addWidget(bottomright)

        # 수직 Splitter 생성, 두 개의 수평 Splitter 추가
        splitter3 = QSplitter(Qt.Vertical)
        splitter3.addWidget(splitter1)
        splitter3.addWidget(splitter2)

        hbox.addWidget(splitter3)
        self.setLayout(hbox)

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('QSplitter')
        self.show()
Example #40
0
class Visualization:
    def __init__(self, world):
        """
        Main Interface between the OpenGL stuff and the simulator.
        Initializes the camera, and the opengl-widget.
        controlls the speed of the simulation.
        :param world: the world class
        """
        self._world = world
        self._last_light_rotation = 0
        self._rounds_per_second = 10
        self._reset_flag = False
        self._running = False
        self._app = None
        self._viewer = None
        self._gui = None
        self._splitter = None
        self._recording = False
        self._animation = world.config_data.animation
        self._auto_animation = world.config_data.auto_animation
        self._manual_animation_speed = world.config_data.manual_animation_speed
        self.light_rotation = False
        self.grid_size = world.grid.size

        # create the QApplication
        self._app = QApplication([])

        # create camera for the visualization
        # if grid is 2D, set to orthographic projection (it is better for 2D)
        if self._world.grid.get_dimension_count() == 2:
            self._camera = Camera(
                self._world.config_data.window_size_x,
                self._world.config_data.window_size_y,
                self._world.config_data.look_at, self._world.config_data.phi,
                self._world.config_data.theta, self._world.config_data.radius,
                self._world.config_data.fov,
                self._world.config_data.cursor_offset,
                self._world.config_data.render_distance, "ortho",
                self._world.grid.get_scaling())
        else:
            self._camera = Camera(
                self._world.config_data.window_size_x,
                self._world.config_data.window_size_y,
                self._world.config_data.look_at, self._world.config_data.phi,
                self._world.config_data.theta, self._world.config_data.radius,
                self._world.config_data.fov,
                self._world.config_data.cursor_offset,
                self._world.config_data.render_distance, "perspective",
                self._world.grid.get_scaling())

        # create the opengl widget
        self._viewer = OGLWidget(self._world, self._camera)
        self._viewer.glInit()
        self.recorder = Recorder(self._world, self._viewer)

        # create and show the main Window
        self._splitter = QSplitter()
        self._splitter.closeEvent = close
        self._splitter.setMinimumWidth(self._world.config_data.window_size_x)
        self._splitter.setMinimumHeight(self._world.config_data.window_size_y)
        self._splitter.setWindowTitle("Simulator")

        self._splitter.show()

        # create gui
        # creating the gui has to happen after showing the window, so the gui can access
        # opengl variables and programs during creation
        self._gui_module = importlib.import_module('components.gui.' +
                                                   self._world.config_data.gui)

        # the key press handler
        def key_press_event(event):
            self._gui_module.key_handler(event.key(), self._world, self)

        # loading key handler from gui module
        if "key_handler" in dir(self._gui_module):
            self._viewer.keyPressEventHandler = key_press_event
            self._splitter.keyPressEvent = key_press_event
        else:
            show_msg("No key_handler(key, vis) function found in gui module!",
                     Level.WARNING, self._splitter)

        # loading gui from gui module
        if "create_gui" in dir(self._gui_module):
            self._gui = self._gui_module.create_gui(self._world, self)
            if self._gui is not None and issubclass(self._gui.__class__,
                                                    QWidget):
                self._splitter.addWidget(self._gui)
                self._splitter.keyPressEvent = self._viewer.keyPressEvent
                self._splitter.keyReleaseEvent = self._viewer.keyReleaseEvent
                self._splitter.addWidget(self._viewer)
                self._splitter.setSizes([
                    self._world.config_data.window_size_x * 0.25,
                    self._world.config_data.window_size_x * 0.75
                ])
            else:
                # noinspection PyUnresolvedReferences
                show_msg(
                    "The create_gui(world, vis) function in gui module didn't return a QWidget."
                    + "Expected a QWidget or a subclass, but got %s." %
                    self._gui.__class__.__name__, Level.WARNING,
                    self._splitter)
                self._splitter.addWidget(self._viewer)

        else:
            show_msg(
                "No create_gui(world, vis) function found in gui module. GUI not created",
                Level.INFO, self._splitter)
            self._splitter.addWidget(self._viewer)

        # waiting for the simulation window to be fully active
        while not self._splitter.windowHandle().isExposed():
            self._process_events()
        # first update and draw call.
        self._viewer.update_scene()

    def is_recording(self):
        return self._recording

    def _process_events(self):
        self._app.processEvents()
        if self._reset_flag:
            raise ResetException()

    def reset(self):
        """
        stops the simulation.
        deletes all data in the visualization.
        resets the camera
        :return:
        """
        self._reset_flag = False
        self._running = False
        self._viewer.agent_offset_data = {}
        self._viewer.agent_update_flag = True
        self._viewer.item_offset_data = {}
        self._viewer.item_update_flag = True
        self._viewer.location_offset_data = {}
        self._viewer.location_update_flag = True
        self._viewer.update_data()
        self._camera.reset()
        self._viewer.update_scene()

    def wait_for_thread(self, thread: Thread, window_message, window_title):
        """
        executes a thread and shows a loading window till the thread stops.
        blocks the gui, while thread runs.
        :param thread: the thread
        :param window_message: the displayed message
        :param window_title: the title of the loading window
        :return:
        """

        loading_window = LoadingWindow(window_message, window_title)
        if self._gui is not None and issubclass(self._gui.__class__, QWidget):
            self._gui.setDisabled(True)
        thread.start()
        while thread.is_alive():
            try:
                self._process_events()
            except VisualizationError as ve:
                show_msg(ve, Level.CRITICAL, self._splitter)
                exit(1)
        thread.join()
        loading_window.close()
        self._gui.setDisabled(False)

    def rotate_light(self):
        """
        rotates the light direction at a steady degrees/second velocity independent of the CPU-clock or framerate.
        :return:
        """
        # rotation of light only in 3d
        if self._world.grid.get_dimension_count() > 2:
            # 20° per second rotation
            if self._last_light_rotation == 0:
                self._last_light_rotation = time.perf_counter()
            else:
                angle = (time.perf_counter() - self._last_light_rotation) * 20
                self._last_light_rotation = time.perf_counter()
                self._viewer.rotate_light(angle)
                self._viewer.glDraw()

    def start_stop(self):
        """
        starts and pauses the simulation
        :return:
        """
        self._running = not self._running

    def _wait_while_not_running(self):
        """
        helper function.
        waits until the running flag is set.
        :return:
        """
        sleep_time = 1.0 / 120.0
        self._process_events()
        if self.light_rotation:
            self.rotate_light()
        while not self._running:
            # sleeping for 1/120 secs, for responsive GUI
            time.sleep(sleep_time)
            if self.light_rotation:
                self.rotate_light()
            self._process_events()

    def animate(self, round_start_time, speed):
        """
        loop for animating the movement of agents and carried items
        :param round_start_time: the start of the round
        :param speed: speed of the animation in 1/steps. less or equal zero = automatic mode
        """
        if speed < 0:
            # draw at location according to the passed time and the rps
            half_round_time = (1.0 / self._rounds_per_second) / 2.0
            now = time.perf_counter()
            while (now - round_start_time) < half_round_time:
                self._viewer.set_animation_percentage(
                    min(1, (now - round_start_time) / half_round_time))
                self._process_events()
                self._viewer.glDraw()
                now = time.perf_counter()
        else:
            # draw at location according to the selected animation speed
            for i in range(1, max(1, speed)):
                self._viewer.set_animation_percentage(float(i / max(1, speed)))
                self._process_events()
                self._viewer.glDraw()

        self._viewer.set_animation_percentage(1)
        self._viewer.glDraw()

        # reset the previous position after animation.
        # not reseting it causes a visual bug if the matter didn't move.
        for agent in self._viewer.agent_offset_data:
            current_data = self._viewer.agent_offset_data[agent]
            self._viewer.agent_offset_data[agent] = (current_data[0],
                                                     current_data[1],
                                                     agent.coordinates,
                                                     current_data[3])
        for item in self._viewer.item_offset_data:
            current_data = self._viewer.item_offset_data[item]
            self._viewer.item_offset_data[item] = (current_data[0],
                                                   current_data[1],
                                                   item.coordinates,
                                                   current_data[3])
        self._viewer.agent_update_flag = True
        self._viewer.item_update_flag = True

    def run(self, round_start_timestamp):
        """
        main function for running the simulation with the visualization.
        At this time, its just error handling here.. the simulation and drawing stuff starts in the run_iteration method
        :param round_start_timestamp: timestamp of the start of the round.
        :return:
        """
        try:
            self._run_iteration(round_start_timestamp)
        except VisualizationError as ve:
            if ve.level == Level.INFO:
                show_msg(ve.msg, ve.level, self.get_main_window())
            if ve.level == Level.CRITICAL:
                show_msg(ve.msg, ve.level, self.get_main_window())
                exit(1)
            if ve.level == Level.WARNING:
                try:
                    self._run_iteration(round_start_timestamp)
                    show_msg(ve.msg, ve.level, self.get_main_window())
                except VisualizationError as ve:
                    show_msg(ve.msg, ve.level, self.get_main_window())
                    if ve.level != Level.INFO:
                        exit(1)

    def _run_iteration(self, round_start_timestamp):
        """
        Controls the "waiting time", so the rounds_per_second value is being kept at the specified value.
        :param round_start_timestamp: timestamp of the start of the round.
        :return:
        """
        # update and draw/animate scene
        self._viewer.update_data()
        if self._animation:
            self.animate(
                round_start_timestamp,
                -1 if self._auto_animation else self._manual_animation_speed)
        else:
            self._viewer.glDraw()

        # waiting until simulation starts
        self._wait_while_not_running()

        # record round
        if self._recording:
            self.recorder.record_round()
            self._splitter.setWindowTitle("Simulator, recorded: %d rounds" %
                                          len(self.recorder.records))

        # waiting until enough time passed to do the next simulation round.
        time_elapsed = time.perf_counter() - round_start_timestamp
        # sleeping time - max 1/120 s for a responsive GUI
        sleep_time = min(1.0 / 120, (1.0 / self._rounds_per_second) / 10.0)
        max_wait_time = 1 / self._rounds_per_second
        while time_elapsed < max_wait_time:
            time.sleep(sleep_time)
            # check if still running... if not wait (important for low rounds_per_second values)
            self._wait_while_not_running()
            time_elapsed = time.perf_counter() - round_start_timestamp

    def remove_agent(self, agent):
        """
        removes an agent from the visualization.
        it wont be deleted immediately! not until the next round.
        if you want an immediate deletion of the agent, then call this function, then, update_data and after that
        glDraw of the OpenGLWidget.

        :param agent: the agent (not the id, the instance) to be deleted
        :return:
        """
        self._viewer.agent_update_flag = True
        if agent in self._viewer.agent_offset_data:
            del self._viewer.agent_offset_data[agent]

    def agent_changed(self, agent):
        """
        updates the offset, color and carry data of the agent in the visualization.
        it wont be an immediate update. it will update in the beginning of the next "run" call / after current round.
        :param agent: the agent that has changed (the instance)
        :return:
        """
        self._viewer.agent_update_flag = True
        prev_pos = agent.coordinates
        if agent in self._viewer.agent_offset_data:
            prev_pos = self._viewer.agent_offset_data[agent][0]
        self._viewer.agent_offset_data[agent] = (agent.coordinates,
                                                 agent.color, prev_pos, 1.0 if
                                                 agent.is_carried() else 0.0)

    def remove_item(self, item):
        """
        removes an item from the visualization.
        :param item: the item (not the id, the instance) to be deleted
        :return:
        """
        self._viewer.item_update_flag = True
        if item in self._viewer.item_offset_data:
            del self._viewer.item_offset_data[item]

    def item_changed(self, item):
        """
        updates the offset, color and carry data of the item in the visualization.
        :param item: the item ( not the id, the instance) to be deleted
        :return:
        """
        self._viewer.item_update_flag = True
        prev_pos = item.coordinates
        if item in self._viewer.item_offset_data:
            prev_pos = self._viewer.item_offset_data[item][0]

        self._viewer.item_offset_data[item] = (item.coordinates, item.color,
                                               prev_pos, 1.0
                                               if item.is_carried() else 0.0)

    def remove_location(self, location):
        """
        removes a location from the visualization.
        :param location: the location (not the id, the instance) to be deleted
        :return:
        """
        self._viewer.location_update_flag = True
        if location in self._viewer.location_offset_data:
            del self._viewer.location_offset_data[location]

    def location_changed(self, location):
        """
        updates the offset and color data of the location in the visualization.
        :param location: the location ( not the id, the instance) to be deleted
        :return:
        """
        self._viewer.location_update_flag = True
        self._viewer.location_offset_data[location] = (location.coordinates,
                                                       location.color)

    def update_visualization_data(self):
        self._viewer.update_data()

    # setters and getters for various variables in the visualization

    def set_rounds_per_second(self, rounds_per_second):
        self._rounds_per_second = rounds_per_second

    def get_rounds_per_second(self):
        return self._rounds_per_second

    def reset_camera_position(self):
        self._camera.reset()
        self._viewer.update_scene()

    def set_field_of_view(self, fov: float):
        self._camera.set_fov(fov)
        self._viewer.update_programs_projection_matrix()
        self._viewer.update_cursor_data()
        self._viewer.glDraw()

    def get_field_of_view(self):
        return self._camera.get_fov()

    def set_drag_sensitivity(self, s: float):
        self._viewer.drag_sensitivity = s

    def get_drag_sensitivity(self):
        return self._viewer.drag_sensitivity

    def set_zoom_sensitivity(self, s: float):
        self._viewer.zoom_sensitivity = s

    def get_zoom_sensitivity(self):
        return self._viewer.zoom_sensitivity

    def set_rotation_sensitivity(self, s: float):
        self._viewer.rotation_sensitivity = s

    def get_rotation_sensitivity(self):
        return self._viewer.rotation_sensitivity

    def get_projection_type(self):
        return self._camera.get_projection_type()

    def set_projection_type(self, projection_type):
        self._camera.set_projection_type(projection_type)
        self._viewer.update_programs_projection_matrix()
        self._viewer.glDraw()

    def get_background_color(self):
        return self._viewer.background

    def set_background_color(self, color):
        self._viewer.set_background_color(color)

    def get_grid_line_color(self):
        return self._viewer.programs["grid"].get_line_color()

    def set_grid_line_color(self, color):
        self._viewer.programs["grid"].set_line_color(color)

    def get_grid_border_color(self):
        return self._viewer.programs["grid"].get_border_color()

    def set_grid_border_color(self, color):
        self._viewer.programs["grid"].set_border_color(color)

    def get_grid_line_width(self):
        return self._viewer.programs["grid"].width

    def set_grid_line_width(self, width):
        self._viewer.programs["grid"].set_width(width)
        self._viewer.glDraw()

    def get_grid_line_scaling(self):
        return self._viewer.programs["grid"].get_line_scaling()

    def set_grid_line_scaling(self, scaling):
        self._viewer.programs["grid"].set_line_scaling(scaling)
        self._viewer.glDraw()

    def get_grid_coordinates_color(self):
        return self._viewer.programs["grid"].get_model_color()

    def set_grid_coordinates_color(self, color):
        self._viewer.programs["grid"].set_model_color(color)
        self._viewer.glDraw()

    def get_grid_coordinates_scaling(self):
        return self._viewer.programs["grid"].get_model_scaling()

    def set_grid_coordinates_scaling(self, scaling):
        self._viewer.programs["grid"].set_model_scaling(scaling)
        self._viewer.glDraw()

    def get_render_distance(self):
        return self._camera.get_render_distance()

    def set_render_distance(self, render_distance):
        self._camera.set_render_distance(render_distance)
        self._viewer.update_programs_projection_matrix()
        self._viewer.glDraw()

    def get_show_lines(self):
        return self._viewer.programs["grid"].show_lines

    def set_show_lines(self, show_lines: bool):
        self._viewer.programs["grid"].show_lines = show_lines
        self._viewer.glDraw()

    def get_show_border(self):
        return self._viewer.programs["grid"].show_border

    def set_show_border(self, show_border: bool):
        self._viewer.programs["grid"].show_border = show_border
        self._viewer.glDraw()

    def get_show_coordinates(self):
        return self._viewer.programs["grid"].show_coordinates

    def set_show_coordinates(self, show_coordinates: bool):
        self._viewer.programs["grid"].show_coordinates = show_coordinates
        self._viewer.glDraw()

    def get_show_center(self):
        return self._viewer.show_center

    def set_show_center(self, show_center: bool):
        self._viewer.show_center = show_center
        self._viewer.glDraw()

    def get_show_focus(self):
        return self._viewer.show_focus

    def set_show_focus(self, show_focus: bool):
        self._viewer.show_focus = show_focus
        self._viewer.glDraw()

    def take_screenshot(self, quick):
        self._viewer.take_screenshot(quick)

    def recalculate_grid(self, size):
        self.grid_size = size
        self._viewer.programs["grid"].update_offsets(
            self._world.grid.get_box(size))
        self._viewer.glDraw()

    def get_agent_scaling(self):
        return self._viewer.programs["agent"].get_model_scaling()

    def set_agent_scaling(self, scaling):
        self._viewer.programs["agent"].set_model_scaling(scaling)
        self._viewer.glDraw()

    def get_item_scaling(self):
        return self._viewer.programs["item"].get_model_scaling()

    def set_item_scaling(self, scaling):
        self._viewer.programs["item"].set_model_scaling(scaling)
        self._viewer.glDraw()

    def get_location_scaling(self):
        return self._viewer.programs["location"].get_model_scaling()

    def set_location_scaling(self, scaling):
        self._viewer.programs["location"].set_model_scaling(scaling)
        self._viewer.glDraw()

    def set_on_cursor_click_matter_type(self, matter_type):
        if matter_type == MatterType.ITEM or matter_type == MatterType.AGENT or matter_type == MatterType.LOCATION:
            self._viewer.cursor_type = matter_type
            self._viewer.update_cursor_data()

    def is_running(self):
        return self._running

    def get_added_matter_color(self):
        return self._viewer.added_matter_color

    def set_added_matter_color(self, color):
        self._viewer.added_matter_color = color

    def start_recording(self):
        self.recorder.record_round()
        self._splitter.setWindowTitle("Simulator, recorded: %d rounds" %
                                      len(self.recorder.records))
        self._recording = True

    def get_viewer_res(self):
        return self._viewer.width(), self._viewer.height()

    def stop_recording(self):
        self._recording = False

    def export_recording(self):
        if len(self.recorder.records) == 0:
            show_msg("No rounds recorded. Nothing to export.", Level.INFO,
                     self._splitter)
            return
        if self._running:
            self.start_stop()
        self._viewer.set_show_info_frame(False)
        self._viewer.set_enable_cursor(False)
        if "set_disable_sim" in dir(self._gui_module):
            self._gui_module.set_disable_sim(True)
        else:
            show_msg(
                "No 'set_disable_sim(disable_flag)' function in gui module found."
                "\nRunning simulation within recording mode may result in undefined behavior!",
                Level.WARNING, self._splitter)

        self.recorder.show(self.do_export)

        # loop
        while self.recorder.is_open():
            self._process_events()

        # go back to the main window
        if "set_disable_sim" in dir(self._gui_module):
            self._gui_module.set_disable_sim(False)

        self._viewer.agent_update_flag = True
        self._viewer.item_update_flag = True
        self._viewer.location_update_flag = True
        self._viewer.update_data()
        self._viewer.set_show_info_frame(True)
        self._viewer.set_enable_cursor(True)

    def do_export(self, rps, width, height, codec, first_frame_idx,
                  last_frame_idx, animation):

        if not os.path.exists("outputs/videos") or not os.path.isdir(
                "outputs/videos"):
            os.mkdir("outputs/videos")
        directory = "."
        if os.path.exists("outputs/videos") and os.path.isdir(
                "outputs/videos"):
            directory = "outputs/videos"
        path = TopQFileDialog(self._splitter).getSaveFileName(
            options=(TopQFileDialog.Options()),
            filter="*.mp4;;*.avi;;*.mkv",
            directory=directory)
        if path[0] == '':
            return

        if path[0].endswith("mp4") or path[0].endswith(
                ".avi") or path[0].endswith(".mkv"):
            fullpath = path[0]
        else:
            fullpath = path[0] + path[1].replace('*', '')

        if animation:
            animation_steps = int(30 / rps)
            if animation_steps < 1:
                animation_steps = 1
        else:
            animation_steps = 1

        writer = cv2.VideoWriter(fullpath, cv2.VideoWriter_fourcc(*codec),
                                 rps * animation_steps, (width, height))
        self._viewer.setDisabled(True)
        # creating and opening loading window
        lw = LoadingWindow("", "Exporting Video...")
        lw.show()
        out_of = (last_frame_idx - first_frame_idx + 1) * animation_steps
        for i in range(first_frame_idx - 1, last_frame_idx):
            # render and write frame
            self._viewer.inject_record_data(self.recorder.records[i])
            # animate
            for j in range(1, animation_steps + 1):
                # process events so the gui thread does respond to interactions..
                self._process_events()
                # update loading windows text and progress bar
                processing = (i - first_frame_idx + 1) * animation_steps + j
                lw.set_message("Please wait!\nExporting frame %d/%d..." %
                               (processing, out_of))
                lw.set_progress(processing, out_of)
                self._viewer.set_animation_percentage(j / animation_steps)
                self._viewer.glDraw()
                img = self._viewer.get_frame_cv(width, height)
                writer.write(img)
        self._viewer.inject_record_data(self.recorder.records[last_frame_idx -
                                                              1])
        writer.release()
        lw.close()
        self._viewer.setDisabled(False)
        self._viewer.resizeGL(self._viewer.width(), self._viewer.height())
        self._viewer.update_scene()
        show_msg("Video exported successfully!", Level.INFO, self._splitter)

    def delete_recording(self):
        self.recorder = Recorder(self._world, self._viewer)
        self._splitter.setWindowTitle("Simulator")

    def set_antialiasing(self, value):
        if value <= 0:
            self._viewer.disable_aa()
        else:
            self._viewer.enable_aa(value)

    def take_vector_screenshot(self):
        if self._world.grid.__class__.__name__ == "TriangularGrid":
            if not os.path.exists("outputs/screenshots") or not os.path.isdir(
                    "outputs/screenshots"):
                os.mkdir("outputs/screenshots")
            directory = "."
            if os.path.exists("outputs/screenshots") and os.path.isdir(
                    "outputs/screenshots"):
                directory = "outputs/screenshots"

            path = TopQFileDialog(self._splitter).getSaveFileName(
                options=(TopQFileDialog.Options()),
                filter="*.svg",
                directory=directory)
            if path[0] == '':
                return

            if path[0].endswith(".svg"):
                create_svg(self._world, path[0])
            else:
                create_svg(self._world, path[0] + ".svg")
        else:
            show_msg(
                "Not implemented yet.\nWorks only with Triangular Grid for now!\nSorry!",
                Level.WARNING, self._splitter)

    def set_animation(self, animation):
        if not animation:
            self._viewer.set_animation_percentage(1)
        self._animation = animation

    def get_animation(self):
        return self._animation

    def set_auto_animation(self, auto_animation):
        self._auto_animation = auto_animation

    def get_auto_animation(self):
        return self._auto_animation

    def set_manual_animation_speed(self, manual_animation_speed):
        self._manual_animation_speed = manual_animation_speed

    def get_manual_animation_speed(self):
        return self._manual_animation_speed

    def get_main_window(self):
        return self._splitter

    def set_reset_flag(self):
        self._reset_flag = True
Example #41
0
    def __init__(self, world):
        """
        Main Interface between the OpenGL stuff and the simulator.
        Initializes the camera, and the opengl-widget.
        controlls the speed of the simulation.
        :param world: the world class
        """
        self._world = world
        self._last_light_rotation = 0
        self._rounds_per_second = 10
        self._reset_flag = False
        self._running = False
        self._app = None
        self._viewer = None
        self._gui = None
        self._splitter = None
        self._recording = False
        self._animation = world.config_data.animation
        self._auto_animation = world.config_data.auto_animation
        self._manual_animation_speed = world.config_data.manual_animation_speed
        self.light_rotation = False
        self.grid_size = world.grid.size

        # create the QApplication
        self._app = QApplication([])

        # create camera for the visualization
        # if grid is 2D, set to orthographic projection (it is better for 2D)
        if self._world.grid.get_dimension_count() == 2:
            self._camera = Camera(
                self._world.config_data.window_size_x,
                self._world.config_data.window_size_y,
                self._world.config_data.look_at, self._world.config_data.phi,
                self._world.config_data.theta, self._world.config_data.radius,
                self._world.config_data.fov,
                self._world.config_data.cursor_offset,
                self._world.config_data.render_distance, "ortho",
                self._world.grid.get_scaling())
        else:
            self._camera = Camera(
                self._world.config_data.window_size_x,
                self._world.config_data.window_size_y,
                self._world.config_data.look_at, self._world.config_data.phi,
                self._world.config_data.theta, self._world.config_data.radius,
                self._world.config_data.fov,
                self._world.config_data.cursor_offset,
                self._world.config_data.render_distance, "perspective",
                self._world.grid.get_scaling())

        # create the opengl widget
        self._viewer = OGLWidget(self._world, self._camera)
        self._viewer.glInit()
        self.recorder = Recorder(self._world, self._viewer)

        # create and show the main Window
        self._splitter = QSplitter()
        self._splitter.closeEvent = close
        self._splitter.setMinimumWidth(self._world.config_data.window_size_x)
        self._splitter.setMinimumHeight(self._world.config_data.window_size_y)
        self._splitter.setWindowTitle("Simulator")

        self._splitter.show()

        # create gui
        # creating the gui has to happen after showing the window, so the gui can access
        # opengl variables and programs during creation
        self._gui_module = importlib.import_module('components.gui.' +
                                                   self._world.config_data.gui)

        # the key press handler
        def key_press_event(event):
            self._gui_module.key_handler(event.key(), self._world, self)

        # loading key handler from gui module
        if "key_handler" in dir(self._gui_module):
            self._viewer.keyPressEventHandler = key_press_event
            self._splitter.keyPressEvent = key_press_event
        else:
            show_msg("No key_handler(key, vis) function found in gui module!",
                     Level.WARNING, self._splitter)

        # loading gui from gui module
        if "create_gui" in dir(self._gui_module):
            self._gui = self._gui_module.create_gui(self._world, self)
            if self._gui is not None and issubclass(self._gui.__class__,
                                                    QWidget):
                self._splitter.addWidget(self._gui)
                self._splitter.keyPressEvent = self._viewer.keyPressEvent
                self._splitter.keyReleaseEvent = self._viewer.keyReleaseEvent
                self._splitter.addWidget(self._viewer)
                self._splitter.setSizes([
                    self._world.config_data.window_size_x * 0.25,
                    self._world.config_data.window_size_x * 0.75
                ])
            else:
                # noinspection PyUnresolvedReferences
                show_msg(
                    "The create_gui(world, vis) function in gui module didn't return a QWidget."
                    + "Expected a QWidget or a subclass, but got %s." %
                    self._gui.__class__.__name__, Level.WARNING,
                    self._splitter)
                self._splitter.addWidget(self._viewer)

        else:
            show_msg(
                "No create_gui(world, vis) function found in gui module. GUI not created",
                Level.INFO, self._splitter)
            self._splitter.addWidget(self._viewer)

        # waiting for the simulation window to be fully active
        while not self._splitter.windowHandle().isExposed():
            self._process_events()
        # first update and draw call.
        self._viewer.update_scene()
    def _layoutUI(self):
        """Layout the graphical user interface.

        The standard layout will consist of three columns:
        The activation maps are shown in the left column.
        The center column contains widgets for displaying and selecting
        the input data.
        The right column contains controls for selecting network and
        network layer.
        """

        #
        # Activations (left column)
        #
        activationLayout = QVBoxLayout()
        activationLayout.addWidget(self._activationView)
        # FIXME[layout]
        self._activationView.setMinimumWidth(200)
        self._activationView.resize(400, self._activationView.height())

        activationBox = QGroupBox('Activation')
        activationBox.setLayout(activationLayout)

        #
        # Input data (center column)
        #
        inputLayout = QVBoxLayout()
        inputLayout.addWidget(self._dataInspector)

        inputBox = QGroupBox('Input')
        inputBox.setLayout(inputLayout)

        #
        # Network (right column)
        #
        rightLayout = QVBoxLayout()
        networkBox = QGroupBox("Network")
        networkLayout = QVBoxLayout()
        row = QHBoxLayout()
        row.addWidget(self._networkSelector, stretch=2)
        row.addWidget(self._networkPrepareButton, stretch=1)
        networkLayout.addLayout(row)
        networkLayout.addWidget(self._layerSelector)
        networkBox.setLayout(networkLayout)
        rightLayout.addWidget(networkBox)

        # classes
        rightLayout.addWidget(self._classesViewBox)

        #
        # Attach widgets to window
        #
        splitter = QSplitter(Qt.Horizontal)
        splitter.addWidget(activationBox)
        splitter.addWidget(inputBox)

        rightWidget = QWidget()
        rightWidget.setLayout(rightLayout)
        rightLayout.setContentsMargins(0, 0, 0, 0)
        splitter.addWidget(rightWidget)

        layout = QHBoxLayout()
        layout.addWidget(splitter)
        self.setLayout(layout)
Example #43
0
class CGWMain(QWZMQListener):

    _name = 'CGWMain'

    def __init__(self, parser=None):

        self.proc_parser(parser)

        if __name__ != "__main__":
            daq_control.set_daq_control(
                DaqControl(host=self.host,
                           platform=self.platform,
                           timeout=self.timeout))
            QWZMQListener.__init__(self,
                                   host=self.host,
                                   platform=self.platform,
                                   timeout=self.timeout)
        else:  # emulator mode for TEST ONLY
            QWZMQListener.__init__(self, is_normal=False)

        self.init_daq_control_parameters()  # cach parameters in cp

        self.wlogr = QWLoggerStd(log_level=self.loglevel, instrument=cp.instr,\
                                 log_prefix=self.logdir, show_buttons=False)

        logger.debug('logger started with log_level:%s instrument:%s' %
                     (self.loglevel, cp.instr))

        cp.cgwmain = self

        self.main_win_width = cp.main_win_width
        self.main_win_height = cp.main_win_height
        self.main_win_pos_x = cp.main_win_pos_x
        self.main_win_pos_y = cp.main_win_pos_y

        #icon.set_icons()

        self.wconf = CGWMainConfiguration()
        self.wtabs = CGWMainTabs()

        self.vspl = QSplitter(Qt.Vertical)
        self.vspl.addWidget(self.wconf)
        self.vspl.addWidget(self.wtabs)
        self.vspl.addWidget(self.wlogr)

        self.mbox = QHBoxLayout()
        self.mbox.addWidget(self.vspl)
        self.setLayout(self.mbox)

        self.set_style()
        #self.set_tool_tips()
        #self.connect_signals_to_slots()
        #self.move(self.pos()) # + QPoint(self.width()+5, 0))

    def connect_signals_to_slots(self):
        pass
        #self.connect(self.wbut.but_reset, QtCore.SIGNAL('clicked()'), self.on_but_reset)
        #self.connect(self.wbut.but_save,  QtCore.SIGNAL('clicked()'), self.on_but_save)

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

    def proc_parser(self, parser=None):
        self.parser = parser

        if parser is None:
            self.loglevel = 'DEBUG'
            self.logdir = 'logdir'
            self.expert = None
            return

        (popts, pargs) = parser.parse_args()
        self.args = pargs
        self.opts = vars(popts)
        self.defs = vars(parser.get_default_values())

        #host       = popts.host     # self.opts['host']
        #port       = popts.port # self.opts['port']
        #cp.user    = popts.user
        #cp.upwd    = popts.upwd
        #exp        = popts.experiment
        #det        = popts.detector
        self.logdir = popts.logdir
        self.loglevel = popts.loglevel.upper()
        self.host = popts.host
        self.platform = popts.platform
        self.timeout = popts.timeout
        self.expname = popts.expname
        self.uris = popts.uris  # 'mcbrowne:psana@psdb-dev:9306'
        self.expert = popts.expert  # bool

        #if host     != self.defs['host']       : cp.cdb_host.setValue(host)
        #if host     != self.defs['host']       : cp.cdb_host.setValue(host)
        #if port     != self.defs['port']       : cp.cdb_port.setValue(port)
        #if exp      != self.defs['experiment'] : cp.exp_name.setValue(exp)
        #if det      != self.defs['detector']   : cp.data_source.setValue(det)
        #if loglevel != self.defs['loglevel']   : cp.log_level.setValue(loglevel)
        #if logdir   != self.defs['logdir']     : cp.log_prefix.setValue(logdir)

        #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)

        #if self.loglevel == 'DEBUG' :
        #    print(40*'_')
        #    print_parser(parser)
        #    print_kwargs(self.opts)
#------------------------------

    def init_daq_control_parameters(self):
        cp.s_transition, cp.s_state, cp.s_cfgtype, cp.s_recording, _platform = daq_control_get_status(
        )

        #cp.instr = self.expname[:3].upper()
        cp.instr = daq_control_get_instrument()

        print('XXXXXX daq_control_get_instrument(): %s' % cp.instr)

        if cp.instr is None: cp.instr = 'TST'

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

    def set_tool_tips(self):
        pass
        #self.setToolTip('DAQ control')

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

    def sizeHint(self):
        """Set default window size
        """
        return QSize(370, 810)

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

    def set_style(self):
        self.setWindowTitle("DAQ Control")
        self.layout().setContentsMargins(0, 0, 0, 0)
        self.setMinimumSize(300, 700)

        self.wconf.setFixedHeight(80)

        self.setGeometry(self.main_win_pos_x .value(),\
                         self.main_win_pos_y .value(),\
                         self.main_win_width .value(),\
                         self.main_win_height.value())
        #w_height = self.main_win_height.value()

        #self.layout().setContentsMargins(0,0,0,0)

        from psdaq.control_gui.QWIcons import icon, QIcon

        icon.set_icons()
        #self.setWindowIcon(icon.icon_button_ok)
        self.setWindowIcon(icon.icon_lcls)

        #pmap = icon.icon_lcls.pixmap(QSize(200,100)) # change icon.pixmap size
        #self.setWindowIcon(QIcon(pmap))

        #w = self.main_win_width.value()
        #spl_pos = cp.main_vsplitter.value()
        #self.vspl.setSizes((spl_pos,w_height-spl_pos,))

        #self.wrig.setMinimumWidth(350)
        #self.wrig.setMaximumWidth(450)

        #self.wrig.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Ignored)
        #self.hspl.moveSplitter(w*0.5,0)

        #self.setFixedSize(800,500)
        #self.setMinimumSize(500,800)

        #self.setStyleSheet("background-color:blue; border: 0px solid green")
        #self.setAttribute(QtCore.Qt.WA_TranslucentBackground)

        #self.        setStyleSheet(style.styleBkgd)
        #self.butSave.setStyleSheet(style.styleButton)
        #self.butExit.setStyleSheet(style.styleButton)
        #self.butELog.setStyleSheet(style.styleButton)
        #self.butFile.setStyleSheet(style.styleButton)

        #self.butELog    .setVisible(False)
        #self.butFBrowser.setVisible(False)

        #self.but1.raise_()

    def closeEvent(self, e):
        logger.debug('%s.closeEvent' % self._name)

        resp = confirm_or_cancel_dialog_box(parent=None,
                                            text='Close window?',\
                                            title='Confirm or cancel')
        if not resp:
            logger.warning('Closing window is cancelled')
            e.ignore()
            return

        logger.debug('Closing window is confirmed')

        # save app-configuration parameters
        #try :
        #    self.on_save()
        #except Exception as ex:
        #    print('Exception: %s' % ex)

        try:
            self.wtabs.close()
            self.wconf.close()
            self.wlogr.close()
        except Exception as ex:
            print('Exception: %s' % ex)

        QWZMQListener.closeEvent(self, e)

        #print('Exit CGWMain.closeEvent')

        cp.cgwmain = None

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

#    def __del__(self) :
#        logger.debug('In CGConfigParameters d-tor')
#        #if self.save_cp_at_exit.value() :
#        if True :
#            self.on_save()

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

#def resizeEvent(self, e):
#logger.debug('CGWMain.resizeEvent: %s' % str(self.size()))
#QWZMQListener.resizeEvent(self, e)

#def moveEvent(self, e) :
#logger.debug('moveEvent', self._name)
#self.position = self.mapToGlobal(self.pos())
#self.position = self.pos()
#logger.debug('moveEvent - pos:' + str(self.position), __name__)
#logger.info('CGWMain.moveEvent - move window to x,y: ', str(self.mapToGlobal(QPoint(0,0))))
#self.wimg.move(self.pos() + QPoint(self.width()+5, 0))
#pass

    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 main window x,y,w,h : %d, %d, %d, %d' % (x, y, w, h)
        logger.info(msg)  #, self._name)
        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)

        cp.printParameters()
        cp.saveParametersInFile()

        #if cp.save_log_at_exit.value() :
        #    pass
        # ?????
        #log.saveLogInFile(cp.log_file.value())
        #print('Saved log file: %s' % cp.log_file.value())
        #log.saveLogTotalInFile(fnm.log_file_total())

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

    def on_zmq_poll(self):
        """Re-implementation of the superclass QWZMQListener method for zmq message processing.
        """
        t0_sec = time()
        self.zmq_notifier.setEnabled(False)
        flags = self.zmq_socket.getsockopt(zmq.EVENTS)
        flag = 'UNKNOWN'
        msg = ''
        if flags & zmq.POLLIN:
            while self.zmq_socket.getsockopt(zmq.EVENTS) & zmq.POLLIN:
                flag = 'POLLIN'
                msg = self.zmq_socket.recv_multipart()
                self.process_zmq_message(msg)
                #self.setWindowTitle(str(msg))
        elif flags & zmq.POLLOUT:
            flag = 'POLLOUT'
        elif flags & zmq.POLLERR:
            flag = 'POLLERR'
        else:
            pass

        self.zmq_notifier.setEnabled(True)
        _flags = self.zmq_socket.getsockopt(
            zmq.EVENTS
        )  # WITHOUT THIS LINE IT WOULD NOT CALL on_read_msg AGAIN!
        logger.debug('CGWMain.on_zmq_poll Flag zmq.%s in %d msg: %s' % (flag, flags, msg)\
                   + '\n    poll processing time = %.6f sec' % (time()-t0_sec))
        if _flags & zmq.POLLIN: self.on_zmq_poll()

    def process_zmq_message(self, msg):
        #print('==== msg: %s' % str(msg))

        wcoll = cp.cgwmaincollection
        wctrl = cp.cgwmaintabuser if cp.cgwmaintabuser is not None else\
                cp.cgwmaincontrol

        try:
            for rec in msg:
                jo = json.loads(rec)
                #  jo['header'] # {'key': 'status', 'msg_id': '0918505109-317821000', 'sender_id': None}
                #  jo['body']   # {'state': 'allocated', 'transition': 'alloc'}

                if jo['header']['key'] == 'status':
                    body = jo['body']
                    cp.s_transition = body['transition']
                    cp.s_state = body['state']
                    cp.s_cfgtype = body['config_alias']  # BEAM/NO BEAM
                    cp.s_recording = body['recording']  # True/False
                    cp.s_platform = body.get('platform', None)  # dict

                    #====
                    if wctrl is not None: wctrl.set_but_ctrls()
                    self.wconf.set_config_type(cp.s_cfgtype)
                    if wcoll is not None: wcoll.update_table()
                    logger.info('zmq msg transition:%s state:%s config:%s recording:%s'%\
                                (cp.s_transition, cp.s_state, cp.s_cfgtype, cp.s_recording))

                elif jo['header']['key'] == 'error':
                    body = jo['body']
                    logger.error('received error msg: %s' % body['err_info'])

                    ## grab status directly (not from error message)
                    #status = daq_control_get_status()
                    #if status is None :
                    #    logger.warning('process_zmq_message on error: STATUS IS NOT AVAILABLE')
                    #    return

                    #transition, state, cfgtype, recording = status
                    #if wctrl is not None : wctrl.set_but_ctrls()
                    #self.wconf.set_config_type(cfgtype)
                    #if wcoll is not None : wcoll.update_table()

                else:
                    sj = json.dumps(jo, indent=2, sort_keys=False)
                    logger.debug('received jason:\n%s' % sj)

        except KeyError as ex:
            logger.warning('CGWMain.process_zmq_message: %s\nError: %s' %
                           (str(msg), ex))

        except Exception as ex:
            logger.warning('CGWMain.process_zmq_message: %s\nError: %s' %
                           (str(msg), ex))

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

    if __name__ == "__main__":

        def key_usage(self):
            return 'Keys:'\
                   '\n  V - view/hide tabs'\
                   '\n'

        def keyPressEvent(self, e):
            #print('keyPressEvent, key=', 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())
Example #44
0
class PlotWidgetContainer(QWidget):
    def __init__(self, modelRoot, *args, **kwargs):
        super(PlotWidgetContainer, self).__init__(*args)
        self.modelRoot = modelRoot
        if len(moose.wildcardFind(modelRoot + "/##[ISA=ChemCompt]")) == 0:
            self.modelType = ELECTRICAL
        else:
            self.modelType = CHEMICAL

        self.model = moose.element(self.modelRoot)
        if self.modelRoot != "/":
            self.modelRoot = self.findModelPath(self.modelRoot)
            if moose.exists(modelRoot + "/data"):
                self.data = moose.element(self.modelRoot + "/data")
            else:
                self.data = moose.Neutral(self.modelRoot + "/data")
        else:
            self.data = moose.element("/data")

        self._layout = QVBoxLayout()
        self.graphs = QSplitter()
        self.graphs.setOrientation(QtCore.Qt.Vertical)
        self.graphsArea = QScrollArea()
        self.rowIndex = 0
        self.graphs.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.setAcceptDrops(True)
        self.graphsArea.setWidget(self.graphs)
        self.graphsArea.setWidgetResizable(True)
        self.graphWidgets = []
        self._layout.addWidget(self.graphsArea)
        self.setLayout(self._layout)

        for graph in self.data.children:
            self.addPlotWidget(graph=graph)

        if len(self.data.children) == 0:
            self.addPlotWidget()

    def mooseIsInstance(self, element, classNames):
        return moose.element(element).__class__.__name__ in classNames

    def findModelPath(self, element):
        child = element
        while not self.mooseIsInstance(element, "Shell"):
            child = moose.element(element).path
            element = moose.element(element).parent
        return child

    def deleteWidget(self, graphWidget):
        # print("Deleted => ", graphWidget)
        self.graphWidgets.remove(graphWidget)
        graphWidget.setParent(None)
        graphWidget.close()

    def createMenuBar(self):
        bar = sidebar.sidebar()
        bar.addAction(
            sidebar.add_graph_action(bar, lambda event: self.addPlotWidget()))
        return bar

    def addPlotWidget(self, row=None, col=0, graph=None):
        if graph == None:
            graph = moose.Neutral(self.data.path + "/graph_" +
                                  str(self.rowIndex))

        if row == None:
            row = self.rowIndex

        #if self.modelType == ELECTRICAL:
        #    for axes in list(widget.canvas.axes.values()):
        #        axes.set_ylim(bottom = -0.07, top= 0.03)

        # FIXME:
        # Has been removed? See #23
        #  widget = default.PlotWidget(self.model, graph, self.rowIndex, self)
        ## self.graphs.addWidget(widget)
        ## self.rowIndex += 1
        ## self.graphWidgets.append(widget)
        ## widget.widgetClosedSignal.connect(self.deleteWidget)
        ## widget.addGraph.connect(lambda event : self.addPlotWidget())
        ## return widget

    def showPlotView(self):
        pass

    def setModelRoot(self, *args):
        pass

    def getMenus(self, *args):
        return []

    def setDataRoot(self, *args):
        pass

    def updatePlots(self):
        for graphWidget in self.graphWidgets:
            graphWidget.updatePlots()

    def rescalePlots(self):
        for graphWidget in self.graphWidgets:
            graphWidget.rescalePlots()

    def extendXAxes(self, xlim):
        for graphWidget in self.graphWidgets:
            graphWidget.extendXAxes(xlim)

    def plotAllData(self):
        for graphWidget in self.graphWidgets:
            graphWidget.plotAllData()
class PulseOfInterestWindow(_AbstractPlotWindow):
    """PulseOfInterestWindow class."""
    _title = "Pulse-of-interest"

    _TOTAL_W, _TOTAL_H = config['GUI_PLOT_WINDOW_SIZE']

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

        self._poi_imgs = [
            PoiImageView(0, parent=self),
            PoiImageView(0, parent=self)
        ]
        self._poi_fom_hists = [
            PoiFomHist(0, parent=self),
            PoiFomHist(0, parent=self)
        ]
        self._poi_roi_hists = [
            PoiRoiHist(0, parent=self),
            PoiRoiHist(0, parent=self)
        ]

        self.initUI()
        self.initConnections()

        self.resize(self._TOTAL_W, self._TOTAL_H)

        self.setMinimumSize(0.6 * self._TOTAL_W, 0.6 * self._TOTAL_H)

        self.update()

    def initUI(self):
        """Override."""
        self._cw = QSplitter(Qt.Vertical)

        for img, fom_hist, roi_hist in zip(self._poi_imgs, self._poi_fom_hists,
                                           self._poi_roi_hists):
            rw = QSplitter(Qt.Vertical)
            rw.addWidget(fom_hist)
            rw.addWidget(roi_hist)

            w = QSplitter()
            w.addWidget(img)
            w.addWidget(rw)

            w.setSizes([self._TOTAL_W / 2, self._TOTAL_W / 2])
            self._cw.addWidget(w)

        self.setCentralWidget(self._cw)
        self._cw.setHandleWidth(self._SPLITTER_HANDLE_WIDTH)

    def initConnections(self):
        """Override."""
        mediator = self._mediator

        mediator.poi_index_change_sgn.connect(self._updatePoiIndex)
        mediator.poi_window_initialized_sgn.emit()

    def _updatePoiIndex(self, poi_idx, pulse_idx):
        self._poi_imgs[poi_idx].setPulseIndex(pulse_idx)
        self._poi_fom_hists[poi_idx].setPulseIndex(pulse_idx)
        self._poi_roi_hists[poi_idx].setPulseIndex(pulse_idx)
Example #46
0
class MainWindow(QMainWindow):
    receiveUpdateSignal = pyqtSignal(str)
    errorSignal = pyqtSignal(str)
    showSerialComboboxSignal = pyqtSignal()
    isDetectSerialPort = False
    receiveCount = 0
    sendCount = 0
    isScheduledSending = False
    DataPath = "./"
    isHideSettings = False
    isHideFunctinal = True
    app = None
    isWaveOpen = False

    def __init__(self,app):
        super().__init__()
        self.app = app
        pathDirList = sys.argv[0].replace("\\", "/").split("/")
        pathDirList.pop()
        self.DataPath = os.path.abspath("/".join(str(i) for i in pathDirList))
        if not os.path.exists(self.DataPath + "/" + parameters.strDataDirName):
            pathDirList.pop()
            self.DataPath = os.path.abspath("/".join(str(i) for i in pathDirList))
        self.DataPath = (self.DataPath + "/" + parameters.strDataDirName).replace("\\", "/")
        self.initWindow()
        self.initTool()
        self.initEvent()
        self.programStartGetSavedParameters()
        return

    def __del__(self):
        return
    def initTool(self):
        self.com = serial.Serial()
        return

    def initWindow(self):
        QToolTip.setFont(QFont('SansSerif', 10))
        # main layout
        frameWidget = QWidget()
        mainWidget = QSplitter(Qt.Horizontal)
        frameLayout = QVBoxLayout()
        self.settingWidget = QWidget()
        self.settingWidget.setProperty("class","settingWidget")
        self.receiveSendWidget = QSplitter(Qt.Vertical)
        self.functionalWiget = QWidget()
        settingLayout = QVBoxLayout()
        sendReceiveLayout = QVBoxLayout()
        sendFunctionalLayout = QVBoxLayout()
        mainLayout = QHBoxLayout()
        self.settingWidget.setLayout(settingLayout)
        self.receiveSendWidget.setLayout(sendReceiveLayout)
        self.functionalWiget.setLayout(sendFunctionalLayout)
        mainLayout.addWidget(self.settingWidget)
        mainLayout.addWidget(self.receiveSendWidget)
        mainLayout.addWidget(self.functionalWiget)
        mainLayout.setStretch(0,2)
        mainLayout.setStretch(1, 6)
        mainLayout.setStretch(2, 2)
        menuLayout = QHBoxLayout()
        mainWidget.setLayout(mainLayout)
        frameLayout.addLayout(menuLayout)
        frameLayout.addWidget(mainWidget)
        frameWidget.setLayout(frameLayout)
        self.setCentralWidget(frameWidget)

        # option layout
        self.settingsButton = QPushButton()
        self.skinButton = QPushButton("")
        # self.waveButton = QPushButton("")
        self.aboutButton = QPushButton()
        self.functionalButton = QPushButton()
        self.encodingCombobox = ComboBox()
        self.encodingCombobox.addItem("ASCII")
        self.encodingCombobox.addItem("UTF-8")
        self.encodingCombobox.addItem("UTF-16")
        self.encodingCombobox.addItem("GBK")
        self.encodingCombobox.addItem("GB2312")
        self.encodingCombobox.addItem("GB18030")
        self.settingsButton.setProperty("class", "menuItem1")
        self.skinButton.setProperty("class", "menuItem2")
        self.aboutButton.setProperty("class", "menuItem3")
        self.functionalButton.setProperty("class", "menuItem4")
        # self.waveButton.setProperty("class", "menuItem5")
        self.settingsButton.setObjectName("menuItem")
        self.skinButton.setObjectName("menuItem")
        self.aboutButton.setObjectName("menuItem")
        self.functionalButton.setObjectName("menuItem")
        # self.waveButton.setObjectName("menuItem")
        menuLayout.addWidget(self.settingsButton)
        menuLayout.addWidget(self.skinButton)
        # menuLayout.addWidget(self.waveButton)
        menuLayout.addWidget(self.aboutButton)
        menuLayout.addStretch(0)
        menuLayout.addWidget(self.encodingCombobox)
        menuLayout.addWidget(self.functionalButton)


        # widgets receive and send area
        self.receiveArea = QTextEdit()
        self.sendArea = QTextEdit()
        self.clearReceiveButtion = QPushButton(parameters.strClearReceive)
        self.sendButtion = QPushButton(parameters.strSend)
        self.sendHistory = ComboBox()
        sendWidget = QWidget()
        sendAreaWidgetsLayout = QHBoxLayout()
        sendWidget.setLayout(sendAreaWidgetsLayout)
        buttonLayout = QVBoxLayout()
        buttonLayout.addWidget(self.clearReceiveButtion)
        buttonLayout.addStretch(1)
        buttonLayout.addWidget(self.sendButtion)
        sendAreaWidgetsLayout.addWidget(self.sendArea)
        sendAreaWidgetsLayout.addLayout(buttonLayout)
        sendReceiveLayout.addWidget(self.receiveArea)
        sendReceiveLayout.addWidget(sendWidget)
        sendReceiveLayout.addWidget(self.sendHistory)
        sendReceiveLayout.setStretch(0, 7)
        sendReceiveLayout.setStretch(1, 2)
        sendReceiveLayout.setStretch(2, 1)

        # widgets serial settings
        serialSettingsGroupBox = QGroupBox(parameters.strSerialSettings)
        serialSettingsLayout = QGridLayout()
        serialReceiveSettingsLayout = QGridLayout()
        serialSendSettingsLayout = QGridLayout()
        serialPortLabek = QLabel(parameters.strSerialPort)
        serailBaudrateLabel = QLabel(parameters.strSerialBaudrate)
        serailBytesLabel = QLabel(parameters.strSerialBytes)
        serailParityLabel = QLabel(parameters.strSerialParity)
        serailStopbitsLabel = QLabel(parameters.strSerialStopbits)
        self.serialPortCombobox = ComboBox()
        self.serailBaudrateCombobox = ComboBox()
        self.serailBaudrateCombobox.addItem("9600")
        self.serailBaudrateCombobox.addItem("19200")
        self.serailBaudrateCombobox.addItem("38400")
        self.serailBaudrateCombobox.addItem("57600")
        self.serailBaudrateCombobox.addItem("115200")
        self.serailBaudrateCombobox.setCurrentIndex(4)
        self.serailBaudrateCombobox.setEditable(True)
        self.serailBytesCombobox = ComboBox()
        self.serailBytesCombobox.addItem("5")
        self.serailBytesCombobox.addItem("6")
        self.serailBytesCombobox.addItem("7")
        self.serailBytesCombobox.addItem("8")
        self.serailBytesCombobox.setCurrentIndex(3)
        self.serailParityCombobox = ComboBox()
        self.serailParityCombobox.addItem("None")
        self.serailParityCombobox.addItem("Odd")
        self.serailParityCombobox.addItem("Even")
        self.serailParityCombobox.addItem("Mark")
        self.serailParityCombobox.addItem("Space")
        self.serailParityCombobox.setCurrentIndex(0)
        self.serailStopbitsCombobox = ComboBox()
        self.serailStopbitsCombobox.addItem("1")
        self.serailStopbitsCombobox.addItem("1.5")
        self.serailStopbitsCombobox.addItem("2")
        self.serailStopbitsCombobox.setCurrentIndex(0)
        self.checkBoxRts = QCheckBox("rts")
        self.checkBoxDtr = QCheckBox("dtr")
        self.serialOpenCloseButton = QPushButton(parameters.strOpen)
        serialSettingsLayout.addWidget(serialPortLabek,0,0)
        serialSettingsLayout.addWidget(serailBaudrateLabel, 1, 0)
        serialSettingsLayout.addWidget(serailBytesLabel, 2, 0)
        serialSettingsLayout.addWidget(serailParityLabel, 3, 0)
        serialSettingsLayout.addWidget(serailStopbitsLabel, 4, 0)
        serialSettingsLayout.addWidget(self.serialPortCombobox, 0, 1)
        serialSettingsLayout.addWidget(self.serailBaudrateCombobox, 1, 1)
        serialSettingsLayout.addWidget(self.serailBytesCombobox, 2, 1)
        serialSettingsLayout.addWidget(self.serailParityCombobox, 3, 1)
        serialSettingsLayout.addWidget(self.serailStopbitsCombobox, 4, 1)
        serialSettingsLayout.addWidget(self.checkBoxRts, 5, 0,1,1)
        serialSettingsLayout.addWidget(self.checkBoxDtr, 5, 1,1,1)
        serialSettingsLayout.addWidget(self.serialOpenCloseButton, 6, 0,1,2)
        serialSettingsGroupBox.setLayout(serialSettingsLayout)
        settingLayout.addWidget(serialSettingsGroupBox)

        # serial receive settings
        serialReceiveSettingsGroupBox = QGroupBox(parameters.strSerialReceiveSettings)
        self.receiveSettingsAscii = QRadioButton(parameters.strAscii)
        self.receiveSettingsHex = QRadioButton(parameters.strHex)
        self.receiveSettingsAscii.setChecked(True)
        self.receiveSettingsAutoLinefeed = QCheckBox(parameters.strAutoLinefeed)
        self.receiveSettingsAutoLinefeedTime = QLineEdit(parameters.strAutoLinefeedTime)
        self.receiveSettingsAutoLinefeed.setMaximumWidth(75)
        self.receiveSettingsAutoLinefeedTime.setMaximumWidth(75)
        serialReceiveSettingsLayout.addWidget(self.receiveSettingsAscii,1,0,1,1)
        serialReceiveSettingsLayout.addWidget(self.receiveSettingsHex,1,1,1,1)
        serialReceiveSettingsLayout.addWidget(self.receiveSettingsAutoLinefeed, 2, 0, 1, 1)
        serialReceiveSettingsLayout.addWidget(self.receiveSettingsAutoLinefeedTime, 2, 1, 1, 1)
        serialReceiveSettingsGroupBox.setLayout(serialReceiveSettingsLayout)
        settingLayout.addWidget(serialReceiveSettingsGroupBox)

        # serial send settings
        serialSendSettingsGroupBox = QGroupBox(parameters.strSerialSendSettings)
        self.sendSettingsAscii = QRadioButton(parameters.strAscii)
        self.sendSettingsHex = QRadioButton(parameters.strHex)
        self.sendSettingsAscii.setChecked(True)
        self.sendSettingsScheduledCheckBox = QCheckBox(parameters.strScheduled)
        self.sendSettingsScheduled = QLineEdit(parameters.strScheduledTime)
        self.sendSettingsScheduledCheckBox.setMaximumWidth(75)
        self.sendSettingsScheduled.setMaximumWidth(75)
        self.sendSettingsCFLF = QCheckBox(parameters.strCRLF)
        self.sendSettingsCFLF.setChecked(False)
        serialSendSettingsLayout.addWidget(self.sendSettingsAscii,1,0,1,1)
        serialSendSettingsLayout.addWidget(self.sendSettingsHex,1,1,1,1)
        serialSendSettingsLayout.addWidget(self.sendSettingsScheduledCheckBox, 2, 0, 1, 1)
        serialSendSettingsLayout.addWidget(self.sendSettingsScheduled, 2, 1, 1, 1)
        serialSendSettingsLayout.addWidget(self.sendSettingsCFLF, 3, 0, 1, 2)
        serialSendSettingsGroupBox.setLayout(serialSendSettingsLayout)
        settingLayout.addWidget(serialSendSettingsGroupBox)

        settingLayout.setStretch(0, 5)
        settingLayout.setStretch(1, 2.5)
        settingLayout.setStretch(2, 2.5)

        # right functional layout
        self.addButton = QPushButton(parameters.strAdd)
        functionalGroupBox = QGroupBox(parameters.strFunctionalSend)
        functionalGridLayout = QGridLayout()
        functionalGridLayout.addWidget(self.addButton,0,1)
        functionalGroupBox.setLayout(functionalGridLayout)
        sendFunctionalLayout.addWidget(functionalGroupBox)
        self.isHideFunctinal = True
        self.hideFunctional()

        # main window
        self.statusBarStauts = QLabel()
        self.statusBarStauts.setMinimumWidth(80)
        self.statusBarStauts.setText("<font color=%s>%s</font>" %("#008200", parameters.strReady))
        self.statusBarSendCount = QLabel(parameters.strSend+"(bytes): "+"0")
        self.statusBarReceiveCount = QLabel(parameters.strReceive+"(bytes): "+"0")
        self.statusBar().addWidget(self.statusBarStauts)
        self.statusBar().addWidget(self.statusBarSendCount,2)
        self.statusBar().addWidget(self.statusBarReceiveCount,3)
        # self.statusBar()

        self.resize(800, 500)
        self.MoveToCenter()
        self.setWindowTitle(parameters.appName+" V"+str(helpAbout.versionMajor)+"."+str(helpAbout.versionMinor))
        icon = QIcon()
        print("icon path:"+self.DataPath+"/"+parameters.appIcon)
        icon.addPixmap(QPixmap(self.DataPath+"/"+parameters.appIcon), QIcon.Normal, QIcon.Off)
        self.setWindowIcon(icon)
        if sys.platform == "win32":
            ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("comtool")
        self.show()
        print("config file path:",os.getcwd()+"comtool.settings.config")
        return

    def initEvent(self):
        self.serialOpenCloseButton.clicked.connect(self.openCloseSerial)
        self.sendButtion.clicked.connect(self.sendData)
        self.receiveUpdateSignal.connect(self.updateReceivedDataDisplay)
        self.clearReceiveButtion.clicked.connect(self.clearReceiveBuffer)
        self.serialPortCombobox.clicked.connect(self.portComboboxClicked)
        self.sendSettingsHex.clicked.connect(self.onSendSettingsHexClicked)
        self.sendSettingsAscii.clicked.connect(self.onSendSettingsAsciiClicked)
        self.errorSignal.connect(self.errorHint)
        self.showSerialComboboxSignal.connect(self.showCombobox)
        # self.showBaudComboboxSignal.connect(self.showBaudCombobox)
        self.sendHistory.currentIndexChanged.connect(self.sendHistoryIndexChanged)
        self.settingsButton.clicked.connect(self.showHideSettings)
        self.skinButton.clicked.connect(self.skinChange)
        self.aboutButton.clicked.connect(self.showAbout)
        self.addButton.clicked.connect(self.functionAdd)
        self.functionalButton.clicked.connect(self.showHideFunctional)
        self.sendArea.currentCharFormatChanged.connect(self.sendAreaFontChanged)
        # self.waveButton.clicked.connect(self.openWaveDisplay)
        self.checkBoxRts.clicked.connect(self.rtsChanged)
        self.checkBoxDtr.clicked.connect(self.dtrChanged)

        self.myObject=MyClass(self)
        slotLambda = lambda: self.indexChanged_lambda(self.myObject)
        self.serialPortCombobox.currentIndexChanged.connect(slotLambda)


    # @QtCore.pyqtSlot(str)
    def indexChanged_lambda(self, obj):
        mainObj = obj.arg
        # print("item changed:",mainObj.serialPortCombobox.currentText())
        self.serialPortCombobox.setToolTip(mainObj.serialPortCombobox.currentText())


    def openCloseSerialProcess(self):
        try:
            if self.com.is_open:
                self.receiveProgressStop = True
                self.com.close()
                self.serialOpenCloseButton.setText(parameters.strOpen)
                self.statusBarStauts.setText("<font color=%s>%s</font>" % ("#f31414", parameters.strClosed))
                self.serialPortCombobox.setDisabled(False)
                self.serailBaudrateCombobox.setDisabled(False)
                self.serailParityCombobox.setDisabled(False)
                self.serailStopbitsCombobox.setDisabled(False)
                self.serailBytesCombobox.setDisabled(False)
                self.programExitSaveParameters()
            else:
                try:
                    self.com.baudrate = int(self.serailBaudrateCombobox.currentText())
                    self.com.port = self.serialPortCombobox.currentText().split(" ")[0]
                    self.com.bytesize = int(self.serailBytesCombobox.currentText())
                    self.com.parity = self.serailParityCombobox.currentText()[0]
                    self.com.stopbits = float(self.serailStopbitsCombobox.currentText())
                    self.com.timeout = None
                    if self.checkBoxRts.isChecked():
                        self.com.rts = False
                    else:
                        self.com.rts = True
                    if self.checkBoxDtr.isChecked():
                        self.com.dtr = False
                    else:
                        self.com.dtr = True

                    self.serialOpenCloseButton.setDisabled(True)
                    self.com.open()
                    print("open success")
                    print(self.com)
                    self.serialOpenCloseButton.setText(parameters.strClose)
                    self.statusBarStauts.setText("<font color=%s>%s</font>" % ("#008200", parameters.strReady))
                    self.serialPortCombobox.setDisabled(True)
                    self.serailBaudrateCombobox.setDisabled(True)
                    self.serailParityCombobox.setDisabled(True)
                    self.serailStopbitsCombobox.setDisabled(True)
                    self.serailBytesCombobox.setDisabled(True)
                    self.serialOpenCloseButton.setDisabled(False)
                    receiveProcess = threading.Thread(target=self.receiveData)
                    receiveProcess.setDaemon(True)
                    receiveProcess.start()
                except Exception as e:
                    self.com.close()
                    self.receiveProgressStop = True
                    self.errorSignal.emit( parameters.strOpenFailed +"\n"+ str(e))
                    self.serialOpenCloseButton.setDisabled(False)
        except Exception:
            pass
        return

    def openCloseSerial(self):
        t = threading.Thread(target=self.openCloseSerialProcess)
        t.setDaemon(True)
        t.start()
        return

    def rtsChanged(self):
        if self.checkBoxRts.isChecked():
            self.com.setRTS(False)
        else:
            self.com.setRTS(True)
    
    def dtrChanged(self):
        if self.checkBoxDtr.isChecked():
            self.com.setDTR(False)
        else:
            self.com.setDTR(True)

    def portComboboxClicked(self):
        self.detectSerialPort()

    def getSendData(self):
        data = self.sendArea.toPlainText()
        if self.sendSettingsCFLF.isChecked():
            data = data.replace("\n", "\r\n")
        if self.sendSettingsHex.isChecked():
            if self.sendSettingsCFLF.isChecked():
                data = data.replace("\r\n", " ")
            else:
                data = data.replace("\n", " ")
            data = self.hexStringB2Hex(data)
            if data == -1:
                self.errorSignal.emit( parameters.strWriteFormatError)
                return -1
        else:
            data = data.encode(self.encodingCombobox.currentText(),"ignore")
        return data

    def sendData(self):
        try:
            if self.com.is_open:
                data = self.getSendData()
                if data == -1:
                    return
                print(self.sendArea.toPlainText())
                print("send:",data)
                self.sendCount += len(data)
                self.com.write(data)
                data = self.sendArea.toPlainText()
                self.sendHistoryFindDelete(data)
                self.sendHistory.insertItem(0,data)
                self.sendHistory.setCurrentIndex(0)
                self.receiveUpdateSignal.emit("")
                # scheduled send
                if self.sendSettingsScheduledCheckBox.isChecked():
                    if not self.isScheduledSending:
                        t = threading.Thread(target=self.scheduledSend)
                        t.setDaemon(True)
                        t.start()
        except Exception as e:
            self.errorSignal.emit(parameters.strWriteError)
            print(e)
        return

    def scheduledSend(self):
        self.isScheduledSending = True
        while self.sendSettingsScheduledCheckBox.isChecked():
            self.sendData()
            try:
                time.sleep(int(self.sendSettingsScheduled.text().strip())/1000)
            except Exception:
                self.errorSignal.emit(parameters.strTimeFormatError)
        self.isScheduledSending = False
        return

    def receiveData(self):
        self.receiveProgressStop = False
        self.timeLastReceive = 0
        while(not self.receiveProgressStop):
            try:
                # length = self.com.in_waiting
                length = max(1, min(2048, self.com.in_waiting))
                bytes = self.com.read(length)
                if bytes!= None:

                    # if self.isWaveOpen:
                    #     self.wave.displayData(bytes)
                    self.receiveCount += len(bytes)
                    if self.receiveSettingsHex.isChecked():
                        strReceived = self.asciiB2HexString(bytes)
                        self.receiveUpdateSignal.emit(strReceived)
                    else:
                        self.receiveUpdateSignal.emit(bytes.decode(self.encodingCombobox.currentText(),"ignore"))
                    if self.receiveSettingsAutoLinefeed.isChecked():
                        if time.time() - self.timeLastReceive> int(self.receiveSettingsAutoLinefeedTime.text())/1000:
                            if self.sendSettingsCFLF.isChecked():
                                self.receiveUpdateSignal.emit("\r\n")
                            else:
                                self.receiveUpdateSignal.emit("\n")
                            self.timeLastReceive = time.time()
            except Exception as e:
                print("receiveData error")
                if self.com.is_open and not self.serialPortCombobox.isEnabled():
                    self.openCloseSerial()
                    self.serialPortCombobox.clear()
                    self.detectSerialPort()
                print(e)
            # time.sleep(0.009)
        return

    def updateReceivedDataDisplay(self,str):
        if str != "":
            curScrollValue = self.receiveArea.verticalScrollBar().value()
            self.receiveArea.moveCursor(QTextCursor.End)
            endScrollValue = self.receiveArea.verticalScrollBar().value()
            self.receiveArea.insertPlainText(str)
            if curScrollValue < endScrollValue:
                self.receiveArea.verticalScrollBar().setValue(curScrollValue)
            else:
                self.receiveArea.moveCursor(QTextCursor.End)
        self.statusBarSendCount.setText("%s(bytes):%d" %(parameters.strSend ,self.sendCount))
        self.statusBarReceiveCount.setText("%s(bytes):%d" %(parameters.strReceive ,self.receiveCount))
        return

    def onSendSettingsHexClicked(self):

        data = self.sendArea.toPlainText().replace("\n","\r\n")
        data = self.asciiB2HexString(data.encode())
        self.sendArea.clear()
        self.sendArea.insertPlainText(data)
        return

    def onSendSettingsAsciiClicked(self):
        try:
            data = self.sendArea.toPlainText().replace("\n"," ").strip()
            self.sendArea.clear()
            if data != "":
                data = self.hexStringB2Hex(data).decode(self.encodingCombobox.currentText(),'ignore')
                self.sendArea.insertPlainText(data)
        except Exception as e:
            # QMessageBox.information(self,parameters.strWriteFormatError,parameters.strWriteFormatError)
            print("format error");
        return

    def sendHistoryIndexChanged(self):
        self.sendArea.clear()
        self.sendArea.insertPlainText(self.sendHistory.currentText())
        return

    def clearReceiveBuffer(self):
        self.receiveArea.clear()
        self.receiveCount = 0;
        self.sendCount = 0;
        self.receiveUpdateSignal.emit(None)
        return

    def MoveToCenter(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())
        return

    def errorHint(self,str):
        QMessageBox.information(self, str, str)
        return

    def closeEvent(self, event):

        reply = QMessageBox.question(self, 'Sure To Quit?',
                                     "Are you sure to quit?", QMessageBox.Yes |
                                     QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            self.com.close()
            self.receiveProgressStop = True
            self.programExitSaveParameters()
            event.accept()
        else:
            event.ignore()

    def findSerialPort(self):
        self.port_list = list(serial.tools.list_ports.comports())
        return self.port_list

    def portChanged(self):
        self.serialPortCombobox.setCurrentIndex(0)
        self.serialPortCombobox.setToolTip(str(self.portList[0]))

    def detectSerialPort(self):
        if not self.isDetectSerialPort:
            self.isDetectSerialPort = True
            t = threading.Thread(target=self.detectSerialPortProcess)
            t.setDaemon(True)
            t.start()

    def showCombobox(self):
        self.serialPortCombobox.showPopup()

    def detectSerialPortProcess(self):
        while(1):
            portList = self.findSerialPort()
            if len(portList)>0:
                currText = self.serialPortCombobox.currentText()
                self.serialPortCombobox.clear()
                for i in portList:
                    showStr = str(i[0])+" "+str(i[1])
                    self.serialPortCombobox.addItem(showStr)    
                index = self.serialPortCombobox.findText(currText)
                if index>=0:
                    self.serialPortCombobox.setCurrentIndex(index)
                else:
                    self.serialPortCombobox.setCurrentIndex(0)
                break
            time.sleep(1)
        self.showSerialComboboxSignal.emit()
        self.isDetectSerialPort = False
        return

    def sendHistoryFindDelete(self,str):
        self.sendHistory.removeItem(self.sendHistory.findText(str))
        return

    def test(self):
        print("test")
        return

    def asciiB2HexString(self,strB):
        strHex = binascii.b2a_hex(strB).upper()
        return re.sub(r"(?<=\w)(?=(?:\w\w)+$)", " ", strHex.decode())+" "

    def hexStringB2Hex(self,hexString):
        dataList = hexString.split(" ")
        j = 0
        for i in dataList:
            if len(i) > 2:
                return -1
            elif len(i) == 1:
                dataList[j] = "0" + i
            j += 1
        data = "".join(dataList)
        try:
            data = bytes.fromhex(data)
        except Exception:
            return -1
        print(data)
        return data

    def programExitSaveParameters(self):
        paramObj = parameters.ParametersToSave()
        paramObj.baudRate = self.serailBaudrateCombobox.currentIndex()
        paramObj.dataBytes = self.serailBytesCombobox.currentIndex()
        paramObj.parity = self.serailParityCombobox.currentIndex()
        paramObj.stopBits = self.serailStopbitsCombobox.currentIndex()
        paramObj.skin = self.param.skin
        if self.receiveSettingsHex.isChecked():
            paramObj.receiveAscii = False
        if not self.receiveSettingsAutoLinefeed.isChecked():
            paramObj.receiveAutoLinefeed = False
        else:
            paramObj.receiveAutoLinefeed = True
        paramObj.receiveAutoLindefeedTime = self.receiveSettingsAutoLinefeedTime.text()
        if self.sendSettingsHex.isChecked():
            paramObj.sendAscii = False
        if not self.sendSettingsScheduledCheckBox.isChecked():
            paramObj.sendScheduled = False
        paramObj.sendScheduledTime = self.sendSettingsScheduled.text()
        if not self.sendSettingsCFLF.isChecked():
            paramObj.useCRLF = False
        paramObj.sendHistoryList.clear()
        for i in range(0,self.sendHistory.count()):
            paramObj.sendHistoryList.append(self.sendHistory.itemText(i))
        if self.checkBoxRts.isChecked():
            paramObj.rts = 1
        else:
            paramObj.rts = 0
        if self.checkBoxDtr.isChecked():
            paramObj.dtr = 1
        else:
            paramObj.dtr = 0
        paramObj.encodingIndex = self.encodingCombobox.currentIndex()
        f = open("comtool.settings.config","wb")
        f.truncate()
        pickle.dump(paramObj, f)
        pickle.dump(paramObj.sendHistoryList,f)
        f.close()
        return

    def programStartGetSavedParameters(self):
        paramObj = parameters.ParametersToSave()
        try:
            f = open("comtool.settings.config", "rb")
            paramObj = pickle.load( f)
            paramObj.sendHistoryList = pickle.load(f)
            f.close()
        except Exception as e:
            f = open("comtool.settings.config", "wb")
            f.close()
        self.serailBaudrateCombobox.setCurrentIndex(paramObj.baudRate)
        self.serailBytesCombobox.setCurrentIndex(paramObj.dataBytes)
        self.serailParityCombobox.setCurrentIndex(paramObj.parity)
        self.serailStopbitsCombobox.setCurrentIndex(paramObj.stopBits)
        if paramObj.receiveAscii == False:
            self.receiveSettingsHex.setChecked(True)
        if paramObj.receiveAutoLinefeed == False:
            self.receiveSettingsAutoLinefeed.setChecked(False)
        else:
            self.receiveSettingsAutoLinefeed.setChecked(True)
        self.receiveSettingsAutoLinefeedTime.setText(paramObj.receiveAutoLindefeedTime)
        if paramObj.sendAscii == False:
            self.sendSettingsHex.setChecked(True)
        if paramObj.sendScheduled == False:
            self.sendSettingsScheduledCheckBox.setChecked(False)
        else:
            self.sendSettingsScheduledCheckBox.setChecked(True)
        self.sendSettingsScheduled.setText(paramObj.sendScheduledTime)
        if paramObj.useCRLF == False:
            self.sendSettingsCFLF.setChecked(False)
        else:
            self.sendSettingsCFLF.setChecked(True)
        for i in range(0, len(paramObj.sendHistoryList)):
            str = paramObj.sendHistoryList[i]
            self.sendHistory.addItem(str)
        if paramObj.rts == 0:
            self.checkBoxRts.setChecked(False)
        else:
            self.checkBoxRts.setChecked(True)
        if paramObj.dtr == 0:
            self.checkBoxDtr.setChecked(False)
        else:
            self.checkBoxDtr.setChecked(True)
        self.encodingCombobox.setCurrentIndex(paramObj.encodingIndex)
        self.param = paramObj
        return

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Control:
            self.keyControlPressed = True
        elif event.key() == Qt.Key_Return or event.key()==Qt.Key_Enter:
            if self.keyControlPressed:
                self.sendData()
        elif event.key() == Qt.Key_L:
            if self.keyControlPressed:
                self.sendArea.clear()
        elif event.key() == Qt.Key_K:
            if self.keyControlPressed:
                self.receiveArea.clear()
        return

    def keyReleaseEvent(self,event):
        if event.key() == Qt.Key_Control:
            self.keyControlPressed = False
        return

    def sendAreaFontChanged(self,font):
        print("font changed")

        return

    def functionAdd(self):
        QMessageBox.information(self, "On the way", "On the way")
        return

    def showHideSettings(self):
        if self.isHideSettings:
            self.showSettings()
            self.isHideSettings = False
        else:
            self.hideSettings()
            self.isHideSettings = True
        return

    def showSettings(self):
        self.settingWidget.show()
        self.settingsButton.setStyleSheet(
            parameters.strStyleShowHideButtonLeft.replace("$DataPath",self.DataPath))
        return;

    def hideSettings(self):
        self.settingWidget.hide()
        self.settingsButton.setStyleSheet(
            parameters.strStyleShowHideButtonRight.replace("$DataPath", self.DataPath))
        return;

    def showHideFunctional(self):
        if self.isHideFunctinal:
            self.showFunctional()
            self.isHideFunctinal = False
        else:
            self.hideFunctional()
            self.isHideFunctinal = True
        return

    def showFunctional(self):
        self.functionalWiget.show()
        self.functionalButton.setStyleSheet(
            parameters.strStyleShowHideButtonRight.replace("$DataPath",self.DataPath))
        return;

    def hideFunctional(self):
        self.functionalWiget.hide()
        self.functionalButton.setStyleSheet(
            parameters.strStyleShowHideButtonLeft.replace("$DataPath", self.DataPath))
        return;

    def skinChange(self):
        if self.param.skin == 1: # light
            file = open(self.DataPath + '/assets/qss/style-dark.qss', "r")
            self.param.skin = 2
        else: # elif self.param.skin == 2: # dark
            file = open(self.DataPath + '/assets/qss/style.qss', "r")
            self.param.skin = 1
        self.app.setStyleSheet(file.read().replace("$DataPath", self.DataPath))
        return

    def showAbout(self):
        QMessageBox.information(self, "About","<h1 style='color:#f75a5a';margin=10px;>"+parameters.appName+
                                '</h1><br><b style="color:#08c7a1;margin = 5px;">V'+str(helpAbout.versionMajor)+"."+
                                str(helpAbout.versionMinor)+"."+str(helpAbout.versionDev)+
                                "</b><br><br>"+helpAbout.date+"<br><br>"+helpAbout.strAbout())
        return

    def action1(self):
        print("action1")
        return

    def autoUpdateDetect(self):
        auto = autoUpdate.AutoUpdate()
        if auto.detectNewVersion():
            auto.OpenBrowser()

    def openDevManagement(self):
        os.system('start devmgmt.msc')
Example #47
0
Model/view documentation can be found at
http://doc.qt.nokia.com/latest/model-view-programming.html.
"""
import sys

from PyQt5.QtCore import QDir
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QColumnView
from PyQt5.QtWidgets import QFileSystemModel
from PyQt5.QtWidgets import QSplitter
from PyQt5.QtWidgets import QTreeView

if __name__ == '__main__':
    app = QApplication(sys.argv)
    # Splitter to show 2 views in same widget easily.
    splitter = QSplitter()
    # The model.
    model = QFileSystemModel()
    # You can setRootPath to any path.
    model.setRootPath(QDir.rootPath())
    # List of views.
    views = []
    for ViewType in (QColumnView, QTreeView):
        # Create the view in the splitter.
        view = ViewType(splitter)
        # Set the model of the view.
        view.setModel(model)
        # # Set the root index of the view as the user's home directory.
        view.setRootIndex(model.index(QDir.homePath()))
    # Show the splitter.
    splitter.show()
Example #48
0
    def initUI(self):
        hbox = QHBoxLayout()

        top = QFrame()
        top.setFrameShape(QFrame.Box)

        midleft = QFrame()
        midleft.setFrameShape(QFrame.StyledPanel)

        midright = QFrame()
        midright.setFrameShape(QFrame.Panel)

        bottom = QFrame()
        bottom.setFrameShape(QFrame.WinPanel)
        bottom.setFrameShadow(QFrame.Sunken)

        splitter1 = QSplitter(Qt.Horizontal)
        splitter1.addWidget(midleft)
        splitter1.addWidget(midright)

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

        hbox.addWidget(splitter2)
        self.setLayout(hbox)

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('QSplitter')
        self.show()
Example #49
0
class UIController(object):
    documentModifiedText = ""
    documentStatusBarText = "untitled"

    def __init__(self):
        self.mainWidget = scripterdialog.ScripterDialog(self)
        self.actionToolbar = QToolBar('toolBar', self.mainWidget)
        self.menu_bar = QMenuBar(self.mainWidget)

        self.actionToolbar.setObjectName('toolBar')
        self.menu_bar.setObjectName('menuBar')

        self.actions = []

        self.mainWidget.setWindowModality(Qt.NonModal)

    def initialize(self, scripter):
        self.editor = pythoneditor.CodeEditor(scripter)
        self.tabWidget = QTabWidget()
        self.statusBar = Elided_Text_Label()
        self.statusBar.setMainText('untitled')
        self.splitter = QSplitter()
        self.splitter.setOrientation(Qt.Vertical)
        self.highlight = syntax.PythonHighlighter(self.editor.document(), syntaxstyles.DefaultSyntaxStyle())
        p = self.editor.palette()
        p.setColor(QPalette.Base, syntaxstyles.DefaultSyntaxStyle()['background'].foreground().color())
        p.setColor(QPalette.Text, syntaxstyles.DefaultSyntaxStyle()['foreground'].foreground().color())
        self.editor.setPalette(p)

        self.scripter = scripter

        self.loadMenus()
        self.loadWidgets()
        self.loadActions()
        self._readSettings()  # sets window size

        vbox = QVBoxLayout(self.mainWidget)
        vbox.addWidget(self.menu_bar)
        vbox.addWidget(self.actionToolbar)
        self.splitter.addWidget(self.editor)
        self.splitter.addWidget(self.tabWidget)
        vbox.addWidget(self.splitter)
        vbox.addWidget(self.statusBar)

        self.mainWidget.setWindowTitle(i18n("Scripter"))
        self.mainWidget.setSizeGripEnabled(True)
        self.mainWidget.show()
        self.mainWidget.activateWindow()

        self.editor.undoAvailable.connect(self.setStatusModified)

    def loadMenus(self):
        self.addMenu('File', 'File')

    def addMenu(self, menuName, parentName):
        parent = self.menu_bar.findChild(QObject, parentName)
        self.newMenu = None

        if parent:
            self.newMenu = parent.addMenu(menuName)
        else:
            self.newMenu = self.menu_bar.addMenu(menuName)

        self.newMenu.setObjectName(menuName)

        return self.newMenu

    def loadActions(self):
        module_path = 'scripter.ui_scripter.actions'
        actions_module = importlib.import_module(module_path)
        modules = []

        for class_path in actions_module.action_classes:
            _module = class_path[:class_path.rfind(".")]
            _klass = class_path[class_path.rfind(".") + 1:]
            modules.append(dict(module='{0}.{1}'.format(module_path, _module),
                                klass=_klass))

        for module in modules:
            m = importlib.import_module(module['module'])
            action_class = getattr(m, module['klass'])
            obj = action_class(self.scripter)
            parent = self.mainWidget.findChild(QObject, obj.parent)
            self.actions.append(dict(action=obj, parent=parent))

        for action in self.actions:
            action['parent'].addAction(action['action'])

    def loadWidgets(self):
        modulePath = 'scripter.ui_scripter.tabwidgets'
        widgetsModule = importlib.import_module(modulePath)
        modules = []

        for class_path in widgetsModule.widgetClasses:
            _module = class_path[:class_path.rfind(".")]
            _klass = class_path[class_path.rfind(".") + 1:]
            modules.append(dict(module='{0}.{1}'.format(modulePath, _module),
                                klass=_klass))

        for module in modules:
            m = importlib.import_module(module['module'])
            widgetClass = getattr(m, module['klass'])
            obj = widgetClass(self.scripter)
            self.tabWidget.addTab(obj, obj.objectName())

    def invokeAction(self, actionName):
        for action in self.actions:
            if action['action'].objectName() == actionName:
                method = getattr(action['action'], actionName)
                if method:
                    return method()

    def findTabWidget(self, widgetName, childName=''):
        for index in range(self.tabWidget.count()):
            widget = self.tabWidget.widget(index)
            if widget.objectName() == widgetName:
                if childName:
                    widget = widget.findChild(QObject, childName)
                return widget

    def showException(self, exception):
        QMessageBox.critical(self.editor, i18n("Error Running Script"), str(exception))

    def setDocumentEditor(self, document):
        self.editor.clear()
        self.editor.moveCursor(QTextCursor.Start)
        self.editor._documentModified = False
        self.editor.setPlainText(document.data)
        self.editor.moveCursor(QTextCursor.End)

    def setStatusBar(self, value='untitled'):
        self.documentStatusBarText = value
        self.statusBar.setMainText(self.documentStatusBarText + self.documentModifiedText)

    def setStatusModified(self):
        self.documentModifiedText = ""
        if (self.editor._documentModified is True):
            self.documentModifiedText = " [Modified]"
        self.statusBar.setMainText(self.documentStatusBarText + self.documentModifiedText)

    def setActiveWidget(self, widgetName):
        widget = self.findTabWidget(widgetName)

        if widget:
            self.tabWidget.setCurrentWidget(widget)

    def setStepped(self, status):
        self.editor.setStepped(status)

    def clearEditor(self):
        self.editor.clear()

    def repaintDebugArea(self):
        self.editor.repaintDebugArea()

    def closeScripter(self):
        self.mainWidget.close()

    def _writeSettings(self):
        """ _writeSettings is a method invoked when the scripter starts, making
            control inversion. Actions can implement a writeSettings method to
            save your own settings without this method to know about it. """

        self.scripter.settings.beginGroup('scripter')

        document = self.scripter.documentcontroller.activeDocument
        if document:
            self.scripter.settings.setValue('activeDocumentPath', document.filePath)
        else:
            self.scripter.settings.setValue('activeDocumentPath', '')

        self.scripter.settings.setValue('editorFontSize', self.editor.fontInfo().pointSize())

        for action in self.actions:
            writeSettings = getattr(action['action'], "writeSettings", None)
            if callable(writeSettings):
                writeSettings()

        #  Window Geometry
        rect = self.mainWidget.geometry()
        self.scripter.settings.setValue(KEY_GEOMETRY, rect)

        self.scripter.settings.endGroup()

    def _readSettings(self):
        """ It's similar to _writeSettings, but reading the settings when the ScripterDialog is closed. """

        self.scripter.settings.beginGroup('scripter')

        activeDocumentPath = self.scripter.settings.value('activeDocumentPath', '')

        if activeDocumentPath:
            if QFileInfo(activeDocumentPath).exists():
                document = self.scripter.documentcontroller.openDocument(activeDocumentPath)
                self.setStatusBar(document.filePath)
                self.setDocumentEditor(document)

        for action in self.actions:
            readSettings = getattr(action['action'], "readSettings", None)
            if callable(readSettings):
                readSettings()

        pointSize = self.scripter.settings.value('editorFontSize', str(self.editor.fontInfo().pointSize()))
        self.editor.setFontSize(int(pointSize))

        # Window Geometry
        rect = self.scripter.settings.value(KEY_GEOMETRY, DEFAULT_GEOMETRY)
        self.mainWidget.setGeometry(rect)

        self.scripter.settings.endGroup()

    def _saveSettings(self):
        self.scripter.settings.sync()
Example #50
0
    def initWindow(self):
        QToolTip.setFont(QFont('SansSerif', 10))
        # main layout
        frameWidget = QWidget()
        mainWidget = QSplitter(Qt.Horizontal)
        frameLayout = QVBoxLayout()
        self.settingWidget = QWidget()
        self.settingWidget.setProperty("class","settingWidget")
        self.receiveSendWidget = QSplitter(Qt.Vertical)
        self.functionalWiget = QWidget()
        settingLayout = QVBoxLayout()
        sendReceiveLayout = QVBoxLayout()
        sendFunctionalLayout = QVBoxLayout()
        mainLayout = QHBoxLayout()
        self.settingWidget.setLayout(settingLayout)
        self.receiveSendWidget.setLayout(sendReceiveLayout)
        self.functionalWiget.setLayout(sendFunctionalLayout)
        mainLayout.addWidget(self.settingWidget)
        mainLayout.addWidget(self.receiveSendWidget)
        mainLayout.addWidget(self.functionalWiget)
        mainLayout.setStretch(0,2)
        mainLayout.setStretch(1, 6)
        mainLayout.setStretch(2, 2)
        menuLayout = QHBoxLayout()
        mainWidget.setLayout(mainLayout)
        frameLayout.addLayout(menuLayout)
        frameLayout.addWidget(mainWidget)
        frameWidget.setLayout(frameLayout)
        self.setCentralWidget(frameWidget)

        # option layout
        self.settingsButton = QPushButton()
        self.skinButton = QPushButton("")
        # self.waveButton = QPushButton("")
        self.aboutButton = QPushButton()
        self.functionalButton = QPushButton()
        self.encodingCombobox = ComboBox()
        self.encodingCombobox.addItem("ASCII")
        self.encodingCombobox.addItem("UTF-8")
        self.encodingCombobox.addItem("UTF-16")
        self.encodingCombobox.addItem("GBK")
        self.encodingCombobox.addItem("GB2312")
        self.encodingCombobox.addItem("GB18030")
        self.settingsButton.setProperty("class", "menuItem1")
        self.skinButton.setProperty("class", "menuItem2")
        self.aboutButton.setProperty("class", "menuItem3")
        self.functionalButton.setProperty("class", "menuItem4")
        # self.waveButton.setProperty("class", "menuItem5")
        self.settingsButton.setObjectName("menuItem")
        self.skinButton.setObjectName("menuItem")
        self.aboutButton.setObjectName("menuItem")
        self.functionalButton.setObjectName("menuItem")
        # self.waveButton.setObjectName("menuItem")
        menuLayout.addWidget(self.settingsButton)
        menuLayout.addWidget(self.skinButton)
        # menuLayout.addWidget(self.waveButton)
        menuLayout.addWidget(self.aboutButton)
        menuLayout.addStretch(0)
        menuLayout.addWidget(self.encodingCombobox)
        menuLayout.addWidget(self.functionalButton)


        # widgets receive and send area
        self.receiveArea = QTextEdit()
        self.sendArea = QTextEdit()
        self.clearReceiveButtion = QPushButton(parameters.strClearReceive)
        self.sendButtion = QPushButton(parameters.strSend)
        self.sendHistory = ComboBox()
        sendWidget = QWidget()
        sendAreaWidgetsLayout = QHBoxLayout()
        sendWidget.setLayout(sendAreaWidgetsLayout)
        buttonLayout = QVBoxLayout()
        buttonLayout.addWidget(self.clearReceiveButtion)
        buttonLayout.addStretch(1)
        buttonLayout.addWidget(self.sendButtion)
        sendAreaWidgetsLayout.addWidget(self.sendArea)
        sendAreaWidgetsLayout.addLayout(buttonLayout)
        sendReceiveLayout.addWidget(self.receiveArea)
        sendReceiveLayout.addWidget(sendWidget)
        sendReceiveLayout.addWidget(self.sendHistory)
        sendReceiveLayout.setStretch(0, 7)
        sendReceiveLayout.setStretch(1, 2)
        sendReceiveLayout.setStretch(2, 1)

        # widgets serial settings
        serialSettingsGroupBox = QGroupBox(parameters.strSerialSettings)
        serialSettingsLayout = QGridLayout()
        serialReceiveSettingsLayout = QGridLayout()
        serialSendSettingsLayout = QGridLayout()
        serialPortLabek = QLabel(parameters.strSerialPort)
        serailBaudrateLabel = QLabel(parameters.strSerialBaudrate)
        serailBytesLabel = QLabel(parameters.strSerialBytes)
        serailParityLabel = QLabel(parameters.strSerialParity)
        serailStopbitsLabel = QLabel(parameters.strSerialStopbits)
        self.serialPortCombobox = ComboBox()
        self.serailBaudrateCombobox = ComboBox()
        self.serailBaudrateCombobox.addItem("9600")
        self.serailBaudrateCombobox.addItem("19200")
        self.serailBaudrateCombobox.addItem("38400")
        self.serailBaudrateCombobox.addItem("57600")
        self.serailBaudrateCombobox.addItem("115200")
        self.serailBaudrateCombobox.setCurrentIndex(4)
        self.serailBaudrateCombobox.setEditable(True)
        self.serailBytesCombobox = ComboBox()
        self.serailBytesCombobox.addItem("5")
        self.serailBytesCombobox.addItem("6")
        self.serailBytesCombobox.addItem("7")
        self.serailBytesCombobox.addItem("8")
        self.serailBytesCombobox.setCurrentIndex(3)
        self.serailParityCombobox = ComboBox()
        self.serailParityCombobox.addItem("None")
        self.serailParityCombobox.addItem("Odd")
        self.serailParityCombobox.addItem("Even")
        self.serailParityCombobox.addItem("Mark")
        self.serailParityCombobox.addItem("Space")
        self.serailParityCombobox.setCurrentIndex(0)
        self.serailStopbitsCombobox = ComboBox()
        self.serailStopbitsCombobox.addItem("1")
        self.serailStopbitsCombobox.addItem("1.5")
        self.serailStopbitsCombobox.addItem("2")
        self.serailStopbitsCombobox.setCurrentIndex(0)
        self.checkBoxRts = QCheckBox("rts")
        self.checkBoxDtr = QCheckBox("dtr")
        self.serialOpenCloseButton = QPushButton(parameters.strOpen)
        serialSettingsLayout.addWidget(serialPortLabek,0,0)
        serialSettingsLayout.addWidget(serailBaudrateLabel, 1, 0)
        serialSettingsLayout.addWidget(serailBytesLabel, 2, 0)
        serialSettingsLayout.addWidget(serailParityLabel, 3, 0)
        serialSettingsLayout.addWidget(serailStopbitsLabel, 4, 0)
        serialSettingsLayout.addWidget(self.serialPortCombobox, 0, 1)
        serialSettingsLayout.addWidget(self.serailBaudrateCombobox, 1, 1)
        serialSettingsLayout.addWidget(self.serailBytesCombobox, 2, 1)
        serialSettingsLayout.addWidget(self.serailParityCombobox, 3, 1)
        serialSettingsLayout.addWidget(self.serailStopbitsCombobox, 4, 1)
        serialSettingsLayout.addWidget(self.checkBoxRts, 5, 0,1,1)
        serialSettingsLayout.addWidget(self.checkBoxDtr, 5, 1,1,1)
        serialSettingsLayout.addWidget(self.serialOpenCloseButton, 6, 0,1,2)
        serialSettingsGroupBox.setLayout(serialSettingsLayout)
        settingLayout.addWidget(serialSettingsGroupBox)

        # serial receive settings
        serialReceiveSettingsGroupBox = QGroupBox(parameters.strSerialReceiveSettings)
        self.receiveSettingsAscii = QRadioButton(parameters.strAscii)
        self.receiveSettingsHex = QRadioButton(parameters.strHex)
        self.receiveSettingsAscii.setChecked(True)
        self.receiveSettingsAutoLinefeed = QCheckBox(parameters.strAutoLinefeed)
        self.receiveSettingsAutoLinefeedTime = QLineEdit(parameters.strAutoLinefeedTime)
        self.receiveSettingsAutoLinefeed.setMaximumWidth(75)
        self.receiveSettingsAutoLinefeedTime.setMaximumWidth(75)
        serialReceiveSettingsLayout.addWidget(self.receiveSettingsAscii,1,0,1,1)
        serialReceiveSettingsLayout.addWidget(self.receiveSettingsHex,1,1,1,1)
        serialReceiveSettingsLayout.addWidget(self.receiveSettingsAutoLinefeed, 2, 0, 1, 1)
        serialReceiveSettingsLayout.addWidget(self.receiveSettingsAutoLinefeedTime, 2, 1, 1, 1)
        serialReceiveSettingsGroupBox.setLayout(serialReceiveSettingsLayout)
        settingLayout.addWidget(serialReceiveSettingsGroupBox)

        # serial send settings
        serialSendSettingsGroupBox = QGroupBox(parameters.strSerialSendSettings)
        self.sendSettingsAscii = QRadioButton(parameters.strAscii)
        self.sendSettingsHex = QRadioButton(parameters.strHex)
        self.sendSettingsAscii.setChecked(True)
        self.sendSettingsScheduledCheckBox = QCheckBox(parameters.strScheduled)
        self.sendSettingsScheduled = QLineEdit(parameters.strScheduledTime)
        self.sendSettingsScheduledCheckBox.setMaximumWidth(75)
        self.sendSettingsScheduled.setMaximumWidth(75)
        self.sendSettingsCFLF = QCheckBox(parameters.strCRLF)
        self.sendSettingsCFLF.setChecked(False)
        serialSendSettingsLayout.addWidget(self.sendSettingsAscii,1,0,1,1)
        serialSendSettingsLayout.addWidget(self.sendSettingsHex,1,1,1,1)
        serialSendSettingsLayout.addWidget(self.sendSettingsScheduledCheckBox, 2, 0, 1, 1)
        serialSendSettingsLayout.addWidget(self.sendSettingsScheduled, 2, 1, 1, 1)
        serialSendSettingsLayout.addWidget(self.sendSettingsCFLF, 3, 0, 1, 2)
        serialSendSettingsGroupBox.setLayout(serialSendSettingsLayout)
        settingLayout.addWidget(serialSendSettingsGroupBox)

        settingLayout.setStretch(0, 5)
        settingLayout.setStretch(1, 2.5)
        settingLayout.setStretch(2, 2.5)

        # right functional layout
        self.addButton = QPushButton(parameters.strAdd)
        functionalGroupBox = QGroupBox(parameters.strFunctionalSend)
        functionalGridLayout = QGridLayout()
        functionalGridLayout.addWidget(self.addButton,0,1)
        functionalGroupBox.setLayout(functionalGridLayout)
        sendFunctionalLayout.addWidget(functionalGroupBox)
        self.isHideFunctinal = True
        self.hideFunctional()

        # main window
        self.statusBarStauts = QLabel()
        self.statusBarStauts.setMinimumWidth(80)
        self.statusBarStauts.setText("<font color=%s>%s</font>" %("#008200", parameters.strReady))
        self.statusBarSendCount = QLabel(parameters.strSend+"(bytes): "+"0")
        self.statusBarReceiveCount = QLabel(parameters.strReceive+"(bytes): "+"0")
        self.statusBar().addWidget(self.statusBarStauts)
        self.statusBar().addWidget(self.statusBarSendCount,2)
        self.statusBar().addWidget(self.statusBarReceiveCount,3)
        # self.statusBar()

        self.resize(800, 500)
        self.MoveToCenter()
        self.setWindowTitle(parameters.appName+" V"+str(helpAbout.versionMajor)+"."+str(helpAbout.versionMinor))
        icon = QIcon()
        print("icon path:"+self.DataPath+"/"+parameters.appIcon)
        icon.addPixmap(QPixmap(self.DataPath+"/"+parameters.appIcon), QIcon.Normal, QIcon.Off)
        self.setWindowIcon(icon)
        if sys.platform == "win32":
            ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("comtool")
        self.show()
        print("config file path:",os.getcwd()+"comtool.settings.config")
        return
Example #51
0
class MainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.cur_file = ""
        self.splitter = QSplitter()
        self.text_edit = QTextEdit("")
        self.preview = QWebEngineView()
        self.preview.setMinimumWidth(300)
        self.setWindowTitle("Markdown [*]")
        self.splitter.addWidget(self.text_edit)
        self.splitter.addWidget(self.preview)
        self.setCentralWidget(self.splitter)
        self.createMenus()
        self.createStatusBar()
        self.readSettings()
        self.text_edit.document().contentsChanged.connect(
            self.documentWasModified)
        self.text_edit.textChanged.connect(self.textChanged)

    def closeEvent(self, event):
        if self.maybeSave():
            self.writeSettings()
            event.accept()
        else:
            event.ignore()

    def documentWasModified(self):
        self.setWindowModified(self.text_edit.document().isModified())

    def createMenus(self):
        new_icon = QIcon("./assets/new.png")
        open_icon = QIcon("./assets/open.png")
        save_icon = QIcon("./assets/save.png")
        save_as_icon = QIcon("./assets/save_as.png")
        exit_icon = QIcon("./assets/exit.png")

        new_act = QAction(new_icon, "&New", self)
        new_act.setShortcuts(QKeySequence.New)
        new_act.setStatusTip("Create a new file")
        new_act.triggered.connect(self.newFile)

        open_act = QAction(open_icon, "&Open", self)
        open_act.setShortcuts(QKeySequence.Open)
        open_act.setStatusTip("Open an existing file")
        open_act.triggered.connect(self.open)

        save_act = QAction(save_icon, "&Save", self)
        save_act.setShortcuts(QKeySequence.Save)
        save_act.setStatusTip("Save the document to disk")
        save_act.triggered.connect(self.save)

        save_as_act = QAction(save_as_icon, "Save &As...", self)
        save_as_act.setShortcuts(QKeySequence.SaveAs)
        save_as_act.setStatusTip("Save the document under a new name")
        save_as_act.triggered.connect(self.saveAs)

        exit_act = QAction(exit_icon, "E&xit", self)
        exit_act.setShortcuts(QKeySequence.Quit)
        exit_act.setStatusTip("Exit the application")
        exit_act.triggered.connect(self.close)

        about_act = QAction("&About", self)
        about_act.triggered.connect(self.about)
        about_act.setStatusTip("Show the application's About box")

        file_menu = self.menuBar().addMenu("&File")
        file_menu.addAction(new_act)
        file_menu.addAction(open_act)
        file_menu.addAction(save_act)
        file_menu.addAction(save_as_act)
        file_menu.addSeparator()
        file_menu.addAction(exit_act)

        help_menu = self.menuBar().addMenu("&Help")
        help_menu.addAction(about_act)

        file_tool_bar = self.addToolBar("File")
        file_tool_bar.addAction(new_act)
        file_tool_bar.addAction(open_act)
        file_tool_bar.addAction(save_act)

    def createStatusBar(self):
        self.statusBar().showMessage("Ready")

    def about(self):
        QMessageBox.about(
            self, "About Markdown", "This app demonstrates how to "
            "write modern GUI applications using Qt, with a menu bar, "
            "toolbars, and a status bar.")

    def newFile(self):
        if self.maybeSave():
            self.text_edit.clear()
        self.setCurrentFile("")

    def open(self):
        if self.maybeSave():
            fileName = QFileDialog.getOpenFileName(self)[0]
        if fileName:
            self.loadFile(fileName)

    def save(self):
        if not self.cur_file:
            return self.saveAs()
        else:
            return self.saveFile(self.cur_file)

    def saveAs(self):
        dialog = QFileDialog(self)
        dialog.setWindowModality(Qt.WindowModal)
        dialog.setAcceptMode(QFileDialog.AcceptSave)
        if dialog.exec() != QDialog.Accepted:
            return False
        return self.saveFile(dialog.selectedFiles()[0])

    def maybeSave(self):
        if not self.text_edit.document().isModified():
            return True
        ret = QMessageBox.warning(
            self, "Qt Demo", "The document has been modified.\n"
            "Do you want to save your changes?",
            QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel)
        if ret == QMessageBox.Save:
            return self.save()
        elif ret == QMessageBox.Cancel:
            return False
        return True

    def loadFile(self, fileName):
        with open(fileName, mode="r") as f:
            text = f.read()

        QApplication.setOverrideCursor(Qt.WaitCursor)
        self.setCurrentFile(fileName)
        self.text_edit.setPlainText(text)
        self.text_edit.document().setModified(False)
        self.setWindowModified(False)
        QApplication.restoreOverrideCursor()
        self.statusBar().showMessage("File loaded", 2000)

    def saveFile(self, fileName):
        QApplication.setOverrideCursor(Qt.WaitCursor)
        with open(fileName, "w") as f:
            f.write(self.text_edit.toPlainText())
        QApplication.restoreOverrideCursor()

        self.setCurrentFile(fileName)
        self.text_edit.document().setModified(False)
        self.setWindowModified(False)
        self.statusBar().showMessage("File saved", 2000)

    def setCurrentFile(self, fileName):
        self.cur_file = fileName
        shown_name = self.cur_file
        if not self.cur_file:
            shown_name = "untitled.txt"
        self.setWindowFilePath(shown_name)

    def writeSettings(self):
        settings = QSettings(QCoreApplication.organizationName(),
                             QCoreApplication.applicationName())
        settings.setValue("geometry", self.saveGeometry())

    def readSettings(self):
        settings = QSettings(QCoreApplication.organizationName(),
                             QCoreApplication.applicationName())
        geometry = settings.value("geometry", QByteArray())
        if not geometry:
            availableGeometry = QApplication.desktop().availableGeometry(self)
            self.resize(availableGeometry.width() / 3,
                        availableGeometry.height() / 2)
            self.move((availableGeometry.width() - self.width()) / 2,
                      (availableGeometry.height() - self.height()) / 2)
        else:
            self.restoreGeometry(geometry)

    def textChanged(self):
        path = os.getcwd()
        html = "<html><head><link href=\"assets/pastie.css\" rel=\"stylesheet\" type=\"text/css\"/></head><body>"
        html += markdown2.markdown(self.text_edit.toPlainText(), ...,
                                   extras=["fenced-code-blocks"])
        html += "</body></html>"
        self.preview.setHtml(html, baseUrl=QUrl("file://" + path + "/"))
Example #52
0
class SessionUi(QTabWidget):
    TAB_MODULES = 0
    TAB_RANGES = 1
    TAB_DATA = 2
    TAB_ASM = 3

    def __init__(self, app, *__args):
        super().__init__(*__args)

        self.app = app

        self.setTabsClosable(True)
        self.setMovable(True)
        self.tabCloseRequested.connect(self.removeTab)
        self.setContentsMargins(2, 2, 2, 2)
        self.setStyleSheet("""
            QListWidget:hover,
            QTableWidget:hover {
                border: 1px solid transparent;
            }
            QTabWidget QFrame{
                border: 0;
            }
            
            QTabWidget::pane {
                border: 0px solid transparent;
                border-radius: 0px;
                padding: 0px;
                margin: 0px;
            }
            
            QTabWidget::pane:selected {
                background-color: transparent;
                border: 0px solid transparent;
            }
            
            QWidget {
                padding: 0;
                margin-top: 2px;
                margin-right: 2px;
                margin-left: 1px;
            }
        """)

        self.session_panel = QSplitter()

        self.modules_panel = None
        self.ranges_panel = None
        self.registers_panel = None
        self.memory_panel = None
        self.log_panel = None
        self.backtrace_panel = None
        self.hooks_panel = None
        self.contexts_panel = None

        self.data_panel = DataPanel(self.app)
        self.asm_panel = AsmPanel(self.app)

        self.session_panel.addWidget(self.build_left_column())
        self.session_panel.addWidget(self.build_central_content())

        self.session_panel.setHandleWidth(1)
        self.session_panel.setStretchFactor(0, 2)
        self.session_panel.setStretchFactor(1, 6)
        self.session_panel.setContentsMargins(0, 0, 0, 0)

        self.modules_panel = ModulesPanel(self.app)
        self.ranges_panel = RangesPanel(self.app)

        self.addTab(self.session_panel, 'session')
        bt = self.tabBar().tabButton(0, QTabBar.LeftSide)
        if not bt:
            bt = self.tabBar().tabButton(0, QTabBar.RightSide)
        if bt:
            bt.resize(0, 0)

    def add_main_tabs(self):
        self.add_dwarf_tab(SessionUi.TAB_MODULES)
        self.add_dwarf_tab(SessionUi.TAB_RANGES)

    def build_left_column(self):
        splitter = QSplitter()
        splitter.setHandleWidth(1)
        splitter.setOrientation(Qt.Vertical)
        splitter.setContentsMargins(0, 0, 0, 0)

        self.hooks_panel = HooksPanel(self.app)
        splitter.addWidget(self.hooks_panel)

        self.contexts_panel = ContextsPanel(self.app)
        splitter.addWidget(self.contexts_panel)

        self.backtrace_panel = BacktracePanel(self.app)
        splitter.addWidget(self.backtrace_panel)

        return splitter

    def build_central_content(self):
        main_panel = QSplitter(self)
        main_panel.setHandleWidth(1)
        main_panel.setOrientation(Qt.Vertical)
        main_panel.setContentsMargins(0, 0, 0, 0)

        self.registers_panel = RegistersPanel(self.app, 0, 4)
        main_panel.addWidget(self.registers_panel)

        self.memory_panel = MemoryPanel(self.app)
        main_panel.addWidget(self.memory_panel)

        self.log_panel = LogPanel(self.app)
        main_panel.addWidget(self.log_panel)

        main_panel.setStretchFactor(0, 1)
        main_panel.setStretchFactor(1, 3)
        main_panel.setStretchFactor(2, 1)
        return main_panel

    def on_script_loaded(self):
        self.add_main_tabs()

    def on_script_destroyed(self):
        for i in range(0, self.count()):
            if i > 0:
                self.removeTab(i)

        self.log_panel.clear()
        self.data_panel.clear()

        self.asm_panel.range = None

        self.hooks_panel.setRowCount(0)
        self.hooks_panel.resizeColumnsToContents()
        self.hooks_panel.horizontalHeader().setStretchLastSection(True)

        self.ranges_panel.setRowCount(0)
        self.ranges_panel.resizeColumnsToContents()
        self.ranges_panel.horizontalHeader().setStretchLastSection(True)

        self.modules_panel.setRowCount(0)
        self.modules_panel.resizeColumnsToContents()
        self.modules_panel.horizontalHeader().setStretchLastSection(True)

        self.contexts_panel.setRowCount(0)
        self.contexts_panel.resizeColumnsToContents()
        self.contexts_panel.horizontalHeader().setStretchLastSection(True)

        self.backtrace_panel.setRowCount(0)
        self.backtrace_panel.resizeColumnsToContents()
        self.backtrace_panel.horizontalHeader().setStretchLastSection(True)

        self.registers_panel.setRowCount(0)
        self.registers_panel.resizeColumnsToContents()
        self.registers_panel.horizontalHeader().setStretchLastSection(True)

        self.memory_panel.on_script_destroyed()

    def close_tab(self, index):
        self.removeTab(index)

    def add_dwarf_tab(self, tab_id, request_focus=False):
        if tab_id == SessionUi.TAB_DATA:
            self.addTab(self.data_panel, 'data')
            if request_focus:
                self.setCurrentWidget(self.hooks_panel)
        elif tab_id == SessionUi.TAB_MODULES:
            self.addTab(self.modules_panel, 'modules')
            if request_focus:
                self.setCurrentWidget(self.modules_panel)
        elif tab_id == SessionUi.TAB_RANGES:
            self.addTab(self.ranges_panel, 'ranges')
            if request_focus:
                self.setCurrentWidget(self.ranges_panel)
        elif tab_id == SessionUi.TAB_ASM:
            self.addTab(self.asm_panel, 'asm')
            if request_focus:
                self.setCurrentWidget(self.asm_panel)

    def add_search_tab(self, search_panel_widget, search_label):
        if len(search_label) > 5:
            search_label = search_label[:4] + '...'
        self.addTab(search_panel_widget, 'search - %s' % search_label)
        self.setCurrentWidget(search_panel_widget)

    def disasm(self, ptr=0, _range=None):
        self.add_dwarf_tab(SessionUi.TAB_ASM, True)
        if _range:
            self.asm_panel.disasm(_range=_range)
        else:
            self.asm_panel.read_memory(ptr)

    def request_session_ui_focus(self):
        self.setCurrentWidget(self.session_panel)
    def setup(self):
        self.setupUi(self)

        loadAct = QAction('&Open', self)
        loadAct.setShortcut('Ctrl+O')
        loadAct.setStatusTip('Load data')
        loadAct.triggered.connect(lambda: self.onLoadClicked(0))

        surfAct = QAction('&Open Surface', self)
        surfAct.setShortcut('Ctrl+S')
        surfAct.setStatusTip('Surf data')
        surfAct.triggered.connect(lambda: self.onLoadClicked(1))

        exitAct = QAction('&Exit', self)
        exitAct.setShortcut('ALT+F4')
        exitAct.setStatusTip('Exit application')
        exitAct.triggered.connect(self.close)

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(loadAct)
        fileMenu.addAction(surfAct)
        fileMenu.addAction(exitAct)

        self.vtk_widgets = [
            Viewer2D(self.vtk_panel, 0),
            Viewer2D(self.vtk_panel, 1),
            Viewer2D(self.vtk_panel, 2)
        ]

        # Make all views share the same cursor object
        for i in range(3):
            self.vtk_widgets[i].viewer.SetResliceCursor(
                self.vtk_widgets[0].viewer.GetResliceCursor())

        # Cursor representation (anti-alias)
        for i in range(3):
            for j in range(3):
                prop = self.vtk_widgets[i].viewer.GetResliceCursorWidget(
                ).GetResliceCursorRepresentation().GetResliceCursorActor(
                ).GetCenterlineProperty(j)
                renderLinesAsTubes(prop)

        # Make 3D viewer
        picker = vtk.vtkCellPicker()
        picker.SetTolerance(0.005)

        ipwProp = vtk.vtkProperty()
        ren = vtk.vtkRenderer()
        interactor = QVTKRenderWindowInteractor()

        # Gradient background
        ren.SetBackground(245.0 / 255.0, 245.0 / 255.0, 245.0 / 255.0)
        ren.SetBackground2(170.0 / 255.0, 170.0 / 255.0, 170.0 / 255.0)
        ren.GradientBackgroundOn()

        interactor.GetRenderWindow().AddRenderer(ren)
        self.vtk_widgets.append(interactor)

        # Create plane widgets
        self.planeWidget = []
        for i in range(3):
            pw = vtk.vtkImagePlaneWidget()
            pw.SetInteractor(interactor)
            pw.SetPicker(picker)
            pw.RestrictPlaneToVolumeOn()
            color = [0.0, 0.0, 0.0]
            color[i] = 1
            pw.GetPlaneProperty().SetColor(color)
            pw.SetTexturePlaneProperty(ipwProp)
            pw.TextureInterpolateOn()
            pw.SetResliceInterpolateToLinear()
            pw.DisplayTextOn()
            pw.SetDefaultRenderer(ren)

            prop = pw.GetPlaneProperty()
            renderLinesAsTubes(prop)
            pw.SetPlaneProperty(prop)

            prop = pw.GetSelectedPlaneProperty()
            renderLinesAsTubes(prop)
            pw.SetSelectedPlaneProperty(prop)

            prop = pw.GetCursorProperty()
            renderLinesAsTubes(prop)
            pw.SetCursorProperty(prop)

            prop = pw.GetTextProperty()
            prop.SetColor(black)
            pw.Modified()
            # Set background for 2D views
            for j in range(3):
                color[j] = color[j] / 4.0
            self.vtk_widgets[i].viewer.GetRenderer().SetBackground(color)
            self.vtk_widgets[i].interactor.Disable()
            self.planeWidget.append(pw)

        # Annotation
        cornerAnnotation = vtk.vtkCornerAnnotation()
        cornerAnnotation.SetLinearFontScaleFactor(2)
        cornerAnnotation.SetNonlinearFontScaleFactor(1)
        cornerAnnotation.SetMaximumFontSize(20)
        cornerAnnotation.SetText(vtk.vtkCornerAnnotation.UpperLeft, '3D')
        cornerAnnotation.GetTextProperty().SetColor(1, 1, 1)
        cornerAnnotation.SetWindowLevel(
            self.vtk_widgets[0].viewer.GetWindowLevel())
        ren.AddViewProp(cornerAnnotation)

        self.establishCallbacks()

        # Show widgets but hide non-existing data
        for i in range(3):
            self.vtk_widgets[i].show()
            self.vtk_widgets[i].viewer.GetImageActor().SetVisibility(False)

        # Layouts
        horz_layout0 = QHBoxLayout()
        vert_splitter = QSplitter(Qt.Vertical)
        horz_splitter0 = QSplitter(Qt.Horizontal)
        horz_splitter0.addWidget(self.vtk_widgets[0])
        horz_splitter0.addWidget(self.vtk_widgets[1])
        vert_splitter.addWidget(horz_splitter0)
        horz_splitter1 = QSplitter(Qt.Horizontal)
        horz_splitter1.addWidget(self.vtk_widgets[2])
        horz_splitter1.addWidget(self.vtk_widgets[3])
        vert_splitter.addWidget(horz_splitter1)
        horz_layout0.addWidget(vert_splitter)
        horz_layout0.setContentsMargins(0, 0, 0, 0)
        self.vtk_panel.setLayout(horz_layout0)

        vert_layout = QVBoxLayout()

        # Sagittal/Coronal/Axial planes - not used
        horz_layout1 = QHBoxLayout()
        self.btnSagittal = QPushButton("S")
        self.btnSagittal.setCheckable(True)
        self.btnSagittal.setChecked(True)
        horz_layout1.addWidget(self.btnSagittal)
        self.btnCoronal = QPushButton("C")
        self.btnCoronal.setCheckable(True)
        self.btnCoronal.setChecked(True)
        horz_layout1.addWidget(self.btnCoronal)
        self.btnAxial = QPushButton("A")
        self.btnAxial.setCheckable(True)
        self.btnAxial.setChecked(True)
        horz_layout1.addWidget(self.btnAxial)

        self.btnSagittal.clicked.connect(self.togglePlanes)
        self.btnCoronal.clicked.connect(self.togglePlanes)
        self.btnAxial.clicked.connect(self.togglePlanes)

        verticalSpacer = QSpacerItem(10, 10, QSizePolicy.Minimum,
                                     QSizePolicy.Expanding)
        vert_layout.addSpacerItem(verticalSpacer)

        # Misalignment
        groupBox = QGroupBox("Misalignment")
        vert_layout.addWidget(groupBox)
        mis_layout = QVBoxLayout()

        # Local and reset
        horzSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding,
                                 QSizePolicy.Minimum)
        self.btnLocal = QCheckBox("local")
        self.btnReset = QPushButton("Reset")
        self.btnReset.clicked.connect(self.onResetOffset)

        # Misalignment buttons
        horz_layout4 = QHBoxLayout()
        horz_layout4.addWidget(self.btnLocal)
        horz_layout4.addSpacerItem(horzSpacer)
        horz_layout4.addWidget(self.btnReset)
        mis_layout.addItem(horz_layout4)

        # Misalignment sliders
        [(self.sliderTX, self.btnTransX), (self.sliderTY, self.btnTransY),
         (self.sliderTZ, self.btnTransZ), (self.sliderRX, self.btnRotX),
         (self.sliderRY, self.btnRotY), (self.sliderRZ, self.btnRotZ)
         ] = self.createMisAlignment(mis_layout, self.onOrientationClicked)
        groupBox.setLayout(mis_layout)

        # Movement
        groupBox = QGroupBox("Movement")
        vert_layout.addWidget(groupBox)
        groupLayout = QVBoxLayout()

        # Local and reset
        horzSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding,
                                 QSizePolicy.Minimum)

        # TODO: Return values
        self.btnMoveLocal = QCheckBox("local")
        self.btnReset1 = QPushButton("Reset")
        self.btnReset1.clicked.connect(self.onResetMovement)

        # Movement sliders
        layout = QHBoxLayout()
        layout.addWidget(self.btnMoveLocal)
        layout.addSpacerItem(horzSpacer)
        layout.addWidget(self.btnReset1)
        groupLayout.addItem(layout)

        [
            (self.sliderMTX, self.sliderMTY, self.sliderMTZ),
            (self.sliderMRX, self.sliderMRY, self.sliderMRZ)
        ] = self.createMovement(groupLayout, self.onSliderPressed, self.onMove)
        groupBox.setLayout(groupLayout)

        self.frame.setLayout(vert_layout)
Example #54
0
    def initUi(self):

        layout = QGridLayout()

        horizontal_splitter = QSplitter(Qt.Horizontal)

        left_groupbox = QGroupBox('left group box')
        right_groupbox = QGroupBox('right group box')

        horizontal_splitter.addWidget(left_groupbox)
        horizontal_splitter.addWidget(right_groupbox)

        vertical_splitter_1 = QSplitter(Qt.Vertical)

        horizontal_layout_left = QHBoxLayout()

        left_groupbox_1 = QGroupBox('left top group box')
        left_groupbox_2 = QGroupBox('left bottom group box')
        vertical_splitter_1.addWidget(left_groupbox_1)
        vertical_splitter_1.addWidget(left_groupbox_2)

        horizontal_layout_left.addWidget(vertical_splitter_1)
        left_groupbox.setLayout(horizontal_layout_left)

        vertical_splitter_2 = QSplitter(Qt.Vertical)

        horizontal_layout_right = QHBoxLayout()

        right_groupbox_1 = QGroupBox('right top group box')
        right_groupbox_2 = QGroupBox('right bottom group box')
        vertical_splitter_2.addWidget(right_groupbox_1)
        vertical_splitter_2.addWidget(right_groupbox_2)

        horizontal_layout_right.addWidget(vertical_splitter_2)
        right_groupbox.setLayout(horizontal_layout_right)

        layout.addWidget(horizontal_splitter)
        self.setLayout(layout)
Example #55
0
    def __init__(self, app, *__args):
        super().__init__(*__args)

        self.app = app

        self.setTabsClosable(True)
        self.setMovable(True)
        self.tabCloseRequested.connect(self.removeTab)
        self.setContentsMargins(2, 2, 2, 2)
        self.setStyleSheet("""
            QListWidget:hover,
            QTableWidget:hover {
                border: 1px solid transparent;
            }
            QTabWidget QFrame{
                border: 0;
            }
            
            QTabWidget::pane {
                border: 0px solid transparent;
                border-radius: 0px;
                padding: 0px;
                margin: 0px;
            }
            
            QTabWidget::pane:selected {
                background-color: transparent;
                border: 0px solid transparent;
            }
            
            QWidget {
                padding: 0;
                margin-top: 2px;
                margin-right: 2px;
                margin-left: 1px;
            }
        """)

        self.session_panel = QSplitter()

        self.modules_panel = None
        self.ranges_panel = None
        self.registers_panel = None
        self.memory_panel = None
        self.log_panel = None
        self.backtrace_panel = None
        self.hooks_panel = None
        self.contexts_panel = None

        self.data_panel = DataPanel(self.app)
        self.asm_panel = AsmPanel(self.app)

        self.session_panel.addWidget(self.build_left_column())
        self.session_panel.addWidget(self.build_central_content())

        self.session_panel.setHandleWidth(1)
        self.session_panel.setStretchFactor(0, 2)
        self.session_panel.setStretchFactor(1, 6)
        self.session_panel.setContentsMargins(0, 0, 0, 0)

        self.modules_panel = ModulesPanel(self.app)
        self.ranges_panel = RangesPanel(self.app)

        self.addTab(self.session_panel, 'session')
        bt = self.tabBar().tabButton(0, QTabBar.LeftSide)
        if not bt:
            bt = self.tabBar().tabButton(0, QTabBar.RightSide)
        if bt:
            bt.resize(0, 0)
Example #56
0
class Window(QStackedWidget):
    """
    Defines the look and characteristics of the application's main window.
    """

    title = "Mu"
    icon = "icon"

    _zoom_in = pyqtSignal(int)
    _zoom_out = pyqtSignal(int)

    def set_clipboard(self, clipboard):
        self.clipboard = clipboard

    def zoom_in(self):
        """
        Handles zooming in.
        """
        self._zoom_in.emit(2)

    def zoom_out(self):
        """
        Handles zooming out.
        """
        self._zoom_out.emit(2)

    def connect_zoom(self, widget):
        """
        Connects a referenced widget to the zoom related signals.
        """
        self._zoom_in.connect(widget.zoomIn)
        self._zoom_out.connect(widget.zoomOut)

    @property
    def current_tab(self):
        """
        Returns the currently focussed tab.
        """
        return self.tabs.currentWidget()

    def get_load_path(self, folder):
        """
        Displays a dialog for selecting a file to load. Returns the selected
        path. Defaults to start in the referenced folder.
        """
        path, _ = QFileDialog.getOpenFileName(self.widget, 'Open file', folder,
                                              '*.py *.hex')
        logger.debug('Getting load path: {}'.format(path))
        return path

    def get_save_path(self, folder):
        """
        Displays a dialog for selecting a file to save. Returns the selected
        path. Defaults to start in the referenced folder.
        """
        path, _ = QFileDialog.getSaveFileName(self.widget, 'Save file', folder)
        logger.debug('Getting save path: {}'.format(path))
        return path

    def get_microbit_path(self, folder):
        """
        Displays a dialog for locating the location of the BBC micro:bit in the
        host computer's filesystem. Returns the selected path. Defaults to
        start in the referenced folder.
        """
        path = QFileDialog.getExistingDirectory(self.widget,
                                                'Locate BBC micro:bit', folder,
                                                QFileDialog.ShowDirsOnly)
        logger.debug('Getting micro:bit path: {}'.format(path))
        return path

    def add_tab(self, path, text):
        """
        Adds a tab with the referenced path and text to the editor.
        """
        new_tab = EditorPane(path, text, self.api)
        new_tab_index = self.tabs.addTab(new_tab, new_tab.label)

        @new_tab.modificationChanged.connect
        def on_modified():
            self.tabs.setTabText(new_tab_index, new_tab.label)

        self.tabs.setCurrentIndex(new_tab_index)
        self.connect_zoom(new_tab)
        self.set_theme(self.theme)
        new_tab.setFocus()

    @property
    def tab_count(self):
        """
        Returns the number of active tabs.
        """
        return self.tabs.count()

    @property
    def widgets(self):
        """
        Returns a list of references to the widgets representing tabs in the
        editor.
        """
        return [self.tabs.widget(i) for i in range(self.tab_count)]

    @property
    def modified(self):
        """
        Returns a boolean indication if there are any modified tabs in the
        editor.
        """
        for widget in self.widgets:
            if widget.isModified():
                return True
        return False

    def add_filesystem(self, home):
        """
        Adds the file system pane to the application.
        """
        self.fs = FileSystemPane(self.splitter, home)
        self.splitter.addWidget(self.fs)
        self.splitter.setSizes([66, 33])
        self.fs.setFocus()
        self.connect_zoom(self.fs)

    def add_repl(self, repl):
        """
        Adds the REPL pane to the application.
        """
        self.repl = REPLPane(port=repl.port,
                             clipboard=self.clipboard,
                             theme=self.theme)
        self.splitter.addWidget(self.repl)
        self.splitter.setSizes([66, 33])
        self.repl.setFocus()
        self.connect_zoom(self.repl)

    def remove_filesystem(self):
        """
        Removes the file system pane from the application.
        """
        self.fs.setParent(None)
        self.fs.deleteLater()
        self.fs = None

    def remove_repl(self):
        """
        Removes the REPL pane from the application.
        """
        self.repl.setParent(None)
        self.repl.deleteLater()
        self.repl = None

    def set_theme(self, theme):
        """
        Sets the theme for the REPL and editor tabs.
        """
        self.setStyleSheet(DAY_STYLE)
        self.theme = theme
        new_theme = DayTheme
        new_icon = 'theme'
        if theme == 'night':
            new_theme = NightTheme
            new_icon = 'theme_day'
            self.setStyleSheet(NIGHT_STYLE)
        for widget in self.widgets:
            widget.set_theme(new_theme)
        self.button_bar.slots['theme'].setIcon(load_icon(new_icon))
        if hasattr(self, 'repl') and self.repl:
            self.repl.set_theme(theme)

    def show_message(self, message, information=None, icon=None, parent=None):
        """
        Displays a modal message to the user.

        If information is passed in this will be set as the additional
        informative text in the modal dialog.

        Since this mechanism will be used mainly for warning users that
        something is awry the default icon is set to "Warning". It's possible
        to override the icon to one of the following settings: NoIcon,
        Question, Information, Warning or Critical.
        """
        message_box = QMessageBox(parent)
        message_box.setText(message)
        message_box.setWindowTitle('Mu')
        if information:
            message_box.setInformativeText(information)
        if icon and hasattr(message_box, icon):
            message_box.setIcon(getattr(message_box, icon))
        else:
            message_box.setIcon(message_box.Warning)
        logger.debug(message)
        logger.debug(information)
        message_box.exec()

    def show_confirmation(self,
                          message,
                          information=None,
                          icon=None,
                          parent=None):
        """
        Displays a modal message to the user to which they need to confirm or
        cancel.

        If information is passed in this will be set as the additional
        informative text in the modal dialog.

        Since this mechanism will be used mainly for warning users that
        something is awry the default icon is set to "Warning". It's possible
        to override the icon to one of the following settings: NoIcon,
        Question, Information, Warning or Critical.
        """
        message_box = QMessageBox(parent)
        message_box.setText(message)
        message_box.setWindowTitle('Mu')
        if information:
            message_box.setInformativeText(information)
        if icon and hasattr(message_box, icon):
            message_box.setIcon(getattr(message_box, icon))
        else:
            message_box.setIcon(message_box.Warning)
        message_box.setStandardButtons(message_box.Cancel | message_box.Ok)
        message_box.setDefaultButton(message_box.Cancel)
        logger.debug(message)
        logger.debug(information)
        return message_box.exec()

    def update_title(self, filename=None):
        """
        Updates the title bar of the application. If a filename (representing
        the name of the file currently the focus of the editor) is supplied,
        append it to the end of the title.
        """
        title = self.title
        if filename:
            title += ' - ' + filename
        self.setWindowTitle(title)

    def autosize_window(self):
        """
        Makes the editor 80% of the width*height of the screen and centres it.
        """
        screen = QDesktopWidget().screenGeometry()
        w = int(screen.width() * 0.8)
        h = int(screen.height() * 0.8)
        self.resize(w, h)
        size = self.geometry()
        self.move((screen.width() - size.width()) / 2,
                  (screen.height() - size.height()) / 2)

    def reset_annotations(self):
        """
        Resets the state of annotations on the current tab.
        """
        self.current_tab.reset_annotations()

    def annotate_code(self, feedback):
        """
        Given a list of annotations about the code in the current tab, add
        the annotations to the editor window so the user can make appropriate
        changes.
        """
        self.current_tab.annotate_code(feedback)

    def setup(self, theme, api=None):
        """
        Sets up the window.

        Defines the various attributes of the window and defines how the user
        interface is laid out.
        """
        self.theme = theme
        self.api = api if api else []
        # Give the window a default icon, title and minimum size.
        self.setWindowIcon(load_icon(self.icon))
        self.update_title()
        self.setMinimumSize(926, 600)

        self.widget = QWidget()
        self.splitter = QSplitter(Qt.Vertical)

        widget_layout = QVBoxLayout()
        self.widget.setLayout(widget_layout)

        self.button_bar = ButtonBar(self.widget)

        widget_layout.addWidget(self.button_bar)
        widget_layout.addWidget(self.splitter)
        self.tabs = FileTabs()
        self.splitter.addWidget(self.tabs)

        self.addWidget(self.widget)
        self.setCurrentWidget(self.widget)

        self.set_theme(theme)
        self.show()
        self.autosize_window()
Example #57
0
class MainWidget(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        #init Text edit
        self.textEdit = TextEdit(self)
        self.textEdit.textChanged.connect(self.textChanged)
        self.bTextChanged = False
        self.bTextSaved = True
        self.bCursorPosChanged = False
        #init Tool bar
        self.toolBar = ToolBar(self)
        initToolBar(self)
        #init textSplitter
        self.textSplitter = QSplitter(Qt.Horizontal, self)
        self.textSplitter.addWidget(self.textEdit)
        #init textBrowser
        self.bShowPW = False
        self.textBrowser = None
        #init timer
        self.timer = None

        #init layout
        self.centerVBox = QVBoxLayout()
        self.centerVBox.addWidget(self.textSplitter)
        self.centerVBox.addWidget(self.toolBar)
        self.centerVBox.setSpacing(0)
        self.centerVBox.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self.centerVBox)

        #init tile
        self.updateWindowTitle()
        #init position
        screen = QDesktopWidget().screenGeometry()
        self.setGeometry(screen.width() / 4,
                         screen.height() / 6,
                         screen.width() / 2,
                         screen.height() * 2 / 3)
        self.show()

    # Text Edit
    def textChanged(self):
        if self.bTextChanged == False:
            self.bTextChanged = True
        if self.bTextSaved == True:
            self.bTextSaved = False

    def resetTextChangedFlag(self):
        self.bTextChanged = False

    def isTextChanged(self):
        return self.bTextChanged

    def resetTextSavedFlag(self):
        self.bTextSaved = True

    def isTextSaved(self):
        return self.bTextSaved

    def cursorPosChanged(self):
        if self.bCursorPosChanged == False:
            self.bCursorPosChanged = True

    def resetCursorPosChangedFlag(self):
        self.bCursorPosChanged = False

    def isCursorPosChanged(self):
        return self.bCursorPosChanged

    def getPlainText(self):
        return self.textEdit.toPlainText()

    def setPlainText(self, data):
        self.textEdit.setPlainText(data)

    # Text Browser
    def togglePreviewWindow(self):
        self.setUpdatesEnabled(False)

        if self.bShowPW:
            self.hideTextBrowser()
        else:
            self.showTextBrowser()

        self.setUpdatesEnabled(True)
        self.update()

    def showTextBrowser(self):
        self.bShowPW = True
        if self.textBrowser == None:
            self.textBrowser = TextBrowser(self)
            #create the timer for flush textBrowser
            self.createTimerForRefreshTextBrowser()
            #text splitter add textbrowser
            self.textSplitter.addWidget(self.textBrowser)
            #sync the position of textedit to textbrowser
            self.textEdit.cursorPositionChanged.connect(self.cursorPosChanged)
        self.textBrowser.show()

    def hideTextBrowser(self):
        self.bShowPW = False
        self.timer.stop()
        self.textBrowser.hide()

    def createTimerForRefreshTextBrowser(self):
        if self.timer == None:
            self.timer = QTimer(self)
            self.timer.setSingleShot(False)
            self.timer.timeout.connect(self.fleshTextBrowser)
            self.timer.start(TimerInterval)
        else:
            self.timer.start()

    def fleshTextBrowser(self):
        if self.isTextChanged():
            self.setUpdatesEnabled(False)
            data = self.textEdit.toPlainText()
            self.textBrowser.setText(data)
            self.resetTextChangedFlag()
            #Avoid resync the textbrowser when user is inputting
            if self.isCursorPosChanged():
                self.syncTextBrowserPosition()
                self.resetCursorPosChangedFlag()
            self.setUpdatesEnabled(True)
        elif self.isCursorPosChanged():
            self.syncTextBrowserPosition()
            self.resetCursorPosChangedFlag()

    def syncTextBrowserPosition(self):
        browserSB = self.textBrowser.verticalScrollBar()
        maximum2 = browserSB.maximum()
        if maximum2 == 0:  #without scrollbar
            return

        minimum2 = browserSB.minimum()
        pageStep2 = browserSB.pageStep()

        #scrollbar area
        textSB = self.textEdit.verticalScrollBar()
        maximum = textSB.maximum()
        destPos = 0
        if maximum == 0:
            pos = self.textEdit.textCursor().position()
            length = len(self.textEdit.toPlainText())
            if length == 0:
                return
            destPos = int((maximum2 - minimum2 + pageStep2) *
                          float(pos / length) + minimum2 -
                          float(pageStep2 / 2))
        else:
            curSBPos = textSB.value()
            minimum = textSB.minimum()
            pageStep = textSB.pageStep()
            #cursor position
            cursorRect = self.textEdit.cursorRect()
            yPos = cursorRect.center().y()
            #viewport's height
            vpHeight = self.textEdit.viewport().height()
            destPos = int((maximum2 - minimum2 + pageStep2) * (
                (curSBPos + pageStep * float(yPos / vpHeight) - minimum2) /
                (maximum - minimum + pageStep)) + minimum2 -
                          float(pageStep2 / 2))

        #Ajust the result
        if destPos < minimum2:
            destPos = minimum2
        elif destPos > maximum2:
            destPos = maximum2
        browserSB.setValue(destPos)

    # main widget
    def updateWindowTitle(self):
        curFileName = getCurrentFileName()
        if curFileName != STR_NULL:
            self.setWindowTitle(curFileName)
        else:
            self.setWindowTitle(SoftWareName)

    def closeEvent(self, event):
        saveCurrentFile()
        event.accept()
Example #58
0
class ControllerWidget(QWidget):
    """
    Used to merge spectrum, table, TIC,
    error plot and sequenceIons widgets together.

    """
    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)
        self.mainlayout = QHBoxLayout(self)
        self.isAnnoOn = True
        self.clickedRT = None
        self.seleTableRT = None
        self.mzs = np.array([])
        self.ppm = np.array([])
        self.colors = np.array([])
        self.scanIDDict = {}
        self.curr_table_index = None
        self.filteredIonFragments = []
        self.peakAnnoData = None

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

    def loadFileMzML(self, file_path):
        self.isAnnoOn = False
        self.msexperimentWidget = QSplitter(Qt.Vertical)

        # data processing
        scans = self.readMS(file_path)

        # set Widgets
        self.spectrum_widget = SpectrumWidget()
        self.scan_widget = ScanTableWidget(scans)
        self.seqIons_widget = SequenceIonsWidget()
        self.error_widget = ErrorWidget()
        self.tic_widget = TICWidget()
        self.drawTic(scans)

        # connected signals
        self.scan_widget.sigScanClicked.connect(self.updateWidgetDataFromRow)
        self.tic_widget.sigRTClicked.connect(self.ticToTable)

        self.msexperimentWidget.addWidget(self.tic_widget)
        self.msexperimentWidget.addWidget(self.seqIons_widget)
        self.msexperimentWidget.addWidget(self.spectrum_widget)
        self.msexperimentWidget.addWidget(self.error_widget)
        self.msexperimentWidget.addWidget(self.scan_widget)
        self.mainlayout.addWidget(self.msexperimentWidget)

        # set widget sizes, where error plot is set smaller
        widget_height = self.msexperimentWidget.sizeHint().height()
        size_list = [
            widget_height, widget_height, widget_height, widget_height * 0.5,
            widget_height
        ]
        self.msexperimentWidget.setSizes(size_list)

        # default : first row selected.
        self.scan_widget.table_view.selectRow(0)

    def loadFileIdXML(self, file_path):
        prot_ids = []
        pep_ids = []
        pyopenms.IdXMLFile().load(file_path, prot_ids, pep_ids)
        Ions = {}

        # extract ID data from file
        for peptide_id in pep_ids:
            pep_mz = peptide_id.getMZ()
            pep_rt = peptide_id.getRT()

            for hit in peptide_id.getHits():
                pep_seq = str(hit.getSequence().toString())
                if "." in pep_seq:
                    pep_seq = pep_seq[3:-1]
                else:
                    pep_seq = pep_seq[2:-1]

                for anno in hit.getPeakAnnotations():
                    ion_charge = anno.charge
                    ion_mz = anno.mz
                    ion_label = anno.annotation

                    Ions[ion_label] = [ion_mz, ion_charge]

                self.scanIDDict[round(pep_rt, 3)] = {
                    "m/z": pep_mz,
                    "PepSeq": pep_seq,
                    "PepIons": Ions,
                }
                Ions = {}

        self.saveIdData()

    def saveIdData(self):
        # save ID data in table (correct rows) for later usage
        rows = self.scan_widget.table_model.rowCount(self.scan_widget)

        for row in range(0, rows - 1):
            tableRT = round(
                self.scan_widget.table_model.index(row, 2).data(), 3)
            if tableRT in self.scanIDDict:
                index_seq = self.scan_widget.table_model.index(row, 6)
                self.scan_widget.table_model.setData(
                    index_seq, self.scanIDDict[tableRT]["PepSeq"],
                    Qt.DisplayRole)

                index_ions = self.scan_widget.table_model.index(row, 7)
                # data needs to be a string, but reversible ->
                # using json.dumps()
                self.scan_widget.table_model.setData(
                    index_ions,
                    json.dumps(self.scanIDDict[tableRT]["PepIons"]),
                    Qt.DisplayRole,
                )

    def readMS(self, file_path):
        # read MzML files
        exp = pyopenms.MSExperiment()
        pyopenms.MzMLFile().load(file_path, exp)
        return exp

    def drawTic(self, scans):
        self.tic_widget.setTIC(scans.getTIC())

    def ticToTable(self, rt):
        # connect Tic info to table, and select specific row
        self.clickedRT = round(rt * 60, 3)
        if self.clickedRT != self.seleTableRT:
            self.scan_widget.table_view.selectRow(self.findClickedRT())

    def findClickedRT(self):  # find clicked RT in the scan table
        rows = self.scan_widget.table_model.rowCount(self.scan_widget)

        for row in range(0, rows - 1):
            if self.clickedRT == round(
                    self.scan_widget.table_model.index(row, 2).data(), 3):
                index = self.scan_widget.table_model.index(row, 2)
                try:
                    self.curr_table_index \
                        = self.scan_widget.proxy.mapFromSource(index)
                    # use proxy to get from filtered model index
                    return self.curr_table_index.row()
                except ValueError:
                    print("could not found ModelIndex of row")

    # for the future calculate ppm and add it to the table
    def errorData(self, ions_data):
        if ions_data not in "-":
            ions_data_dict = json.loads(ions_data)
            if ions_data_dict != {}:
                self.colors, self.mzs = self.filterColorsMZIons(ions_data_dict)
                mzs_size = len(self.mzs)
                self.ppm = np.random.randint(0, 3, size=mzs_size)
                self.error_widget.setMassErrors(
                    self.mzs, self.ppm,
                    self.colors)  # works for a static np.array
            else:
                self.error_widget.clear()
        else:
            self.error_widget.clear()

    def filterColorsMZIons(
        self, ions_data_dict
    ):  # create color/mz array by distinguishing between prefix & suffix ions
        self.peakAnnoData = ({})  # key is ion annotation (e.g. b2):
        # [mz, color distinguishing prefix, suffix]
        colors = []
        mzs = []
        col_red = (255, 0, 0)  # suffix
        col_blue = (0, 0, 255)  # prefix

        for fragData in self.filteredIonFragments:
            anno = fragData[0]
            if anno[0] in "abc":
                colors.append(col_blue)
                mzs.append(ions_data_dict[anno][0])
                self.peakAnnoData[fragData[1]] = [
                    ions_data_dict[anno][0], col_blue
                ]
            elif anno[0] in "xyz":
                colors.append(col_red)
                mzs.append(ions_data_dict[anno][0])
                self.peakAnnoData[fragData[1]] = [
                    ions_data_dict[anno][0], col_red
                ]
        return np.array(colors), np.array(mzs)

    def updateWidgetDataFromRow(
        self, index
    ):  # after clicking on a new row, update spectrum, error plot, peptideSeq
        # current row RT value
        self.seleTableRT = round(index.siblingAtColumn(2).data(), 3)

        # set new spectrum with setting that all peaks should be displayed
        self.spectrum_widget.setSpectrum(self.scan_widget.curr_spec,
                                         zoomToFullRange=True)

        # only draw sequence with given ions for MS2 and error plot
        if index.siblingAtColumn(0).data() == "MS2":
            self.drawSeqIons(
                index.siblingAtColumn(6).data(),
                index.siblingAtColumn(7).data())
            self.errorData(index.siblingAtColumn(7).data())
            if (self.peakAnnoData is not None
                ):  # peakAnnoData created with existing ions in errorData
                # (bc of coloring)
                self.spectrum_widget.setPeakAnnotations(
                    self.createPeakAnnotation())
                self.spectrum_widget.redrawPlot()
            else:
                self.spectrum_widget._clear_peak_annotations()
                self.spectrum_widget.redrawPlot()

        # otherwise delete old data
        elif index.siblingAtColumn(0).data() == "MS1":
            self.seqIons_widget.clear()
            self.error_widget.clear()
            self.peakAnnoData = None
            self.spectrum_widget._clear_peak_annotations()
            self.spectrum_widget.redrawPlot()

    def createPeakAnnotation(self):
        pStructList = []
        # for the future ->
        # check clashes like in the TIC widget and then add labels
        # (should be done in SpectrumWidget)
        for anno, data in self.peakAnnoData.items():
            mz, anno_color = data[0], data[1]
            index = self.find_nearest_Index(self.spectrum_widget._mzs, mz)
            pStructList.append(
                PeakAnnoStruct(
                    mz=self.spectrum_widget._mzs[index],
                    intensity=self.spectrum_widget._ints[index],
                    text_label=anno,
                    symbol=None,
                    symbol_color=anno_color,
                ))
        return pStructList

    def find_nearest_Index(self, array, value):
        array = np.asarray(array)
        idx = (np.abs(array - value)).argmin()
        return idx

    def drawSeqIons(self, seq, ions):  # generate provided peptide sequence
        seq = re.sub(r"\([^)]*\)", "",
                     seq)  # remove content in brackets -> easier usage

        # only draw sequence for M2 with peptide and ion data
        if seq not in "-" and ions not in "-":
            self.seqIons_widget.setPeptide(seq)
            # transform string data back to a dict
            ions_dict = json.loads(ions)
            if ions_dict != {}:
                self.suffix, self.prefix = self.filterIonsPrefixSuffixData(
                    ions_dict)
                self.seqIons_widget.setPrefix(self.prefix)
                self.seqIons_widget.setSuffix(self.suffix)
            else:  # no ions data
                self.prefix, self.suffix = {}, {}
                self.seqIons_widget.setPrefix(self.prefix)
                self.seqIons_widget.setSuffix(self.suffix)
                self.peakAnnoData = None
        else:
            self.seqIons_widget.clear()
            self.peakAnnoData = None

    def filterIonsPrefixSuffixData(
            self,
            ions):  # filter raw ion data and return suffix and prefix dicts
        suffix = {}
        prefix = {}

        ions_anno = list(ions.keys())
        # annotation(s) of raw ion data (used as key(s))
        self.filteredIonFragments = []

        for anno in ions_anno:
            if anno[1].isdigit() and anno[0] in "abcyxz":
                index, anno_short = self.filterAnnotationIon(anno)
                if ((index in suffix) and (anno[0] in "yxz") and
                    (anno_short
                     not in suffix[index])):  # avoid double annos e.g. y14
                    suffix[index].append(anno_short)
                elif ((index in prefix) and (anno[0] in "abc")
                      and (anno_short not in prefix[index])):
                    prefix[index].append(anno_short)
                elif anno[0] in "yxz":  # non existing keys
                    suffix[index] = [anno_short]
                elif anno[0] in "abc":  # non existing keys
                    prefix[index] = [anno_short]
        return suffix, prefix

    def filterAnnotationIon(self, fragment_anno):
        # filter from raw ion data annotation index
        # and filtered annotation name (e.g. y2)
        index = [s for s in re.findall(r"-?\d+\.?\d*", fragment_anno)][0]
        ion_anno = fragment_anno.split(index)[0] + index
        self.filteredIonFragments.append((fragment_anno, ion_anno))
        return int(index), ion_anno
Example #59
0
    def initUI(self):
        hbox = QHBoxLayout()

        # 프레임 설 : 위, 아래 통으로 하나 // 가운데는 왼쪽, 오른쪽 나누어짐
        # 상단에 배치할 프레임
        top = QFrame()
        top.setFrameShape(QFrame.Box)

        # 가운데 왼쪽에 배치할 프레임
        midleft = QFrame()
        midleft.setFrameShape(QFrame.StyledPanel)

        # 가운데 오른쪽에 배치할 프레임
        midright = QFrame()
        midright.setFrameShape(QFrame.Panel)

        # 아래에 배치할 프레임
        bottom = QFrame()
        bottom.setFrameShape(QFrame.WinPanel)
        bottom.setFrameShadow(QFrame.Sunken)

        # 쪼개지는 방향 정함
        splitter1 = QSplitter(Qt.Horizontal)  # 가로로 쪼개기!
        splitter1.addWidget(midleft)
        splitter1.addWidget(midright)

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

        hbox.addWidget(splitter2)
        self.setLayout(hbox)

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('QSplitter')
        self.show()
Example #60
0
class EmailViewerPageView(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.c = EmailViewerPageController()
        self.c.on_viewemail.connect(self.update_content)
        self.c.on_clearview.connect(self.clear_content)

        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)

        self.splitter = QSplitter()

        self._web_engine = QWebEngineView(self)
        self._web_engine.setMinimumWidth(330)
        self._web_engine.setSizePolicy(QSizePolicy.MinimumExpanding,
                                       QSizePolicy.Expanding)
        self.email_page = self._web_engine.page()
        self.splitter.addWidget(self._web_engine)

        attachment_model = AttachmentListModel()
        self.attachments = AttachmentsView(self)
        self.attachments.setMaximumWidth(300)
        self.attachments.set_model(attachment_model)
        self._attachments_collapsed = False
        self.splitter.addWidget(self.attachments)

        layout.addWidget(self.splitter)
        self.setLayout(layout)

    def resizeEvent(self, event):
        super().resizeEvent(event)
        # TODO: Fix the splitter not resizing when _web_engine gets smaller than minimumSize.
        #  Inspect sizes() for that, check if _web_engines size is less than minimumSize and
        #  somehow update the splitter's handle, it just has to be touched in order for it to resize
        #  to the proper size.
        #  !!! NOTE: First call to sizes returns [0, 0].
        page_size, attachments_size = self.splitter.sizes()
        if page_size == 0 and attachments_size == 0:
            return
        elif page_size < self._web_engine.minimumWidth(
        ) and not self._attachments_collapsed:
            self.splitter.setSizes((self.splitter.width(), 0))
            self._attachments_collapsed = True
        elif self._attachments_collapsed:
            splitter_width = self.splitter.width()
            size1 = self._web_engine.minimumWidth()
            size2 = self.attachments.sizeHint().width()
            if splitter_width > size1 + size2:
                self.splitter.setSizes((splitter_width - size2, size2))
                self._attachments_collapsed = False

    def update_content(self, body, attachments, error=None):
        if error:
            err_dialog = ErrorReportDialog(error)
            err_dialog.exec_()
            return

        self.attachments.clear_attachments()
        self.email_page.runJavaScript(
            f'document.open(); document.write(""); document.write(`{body}`); document.close();'
        )

        self.attachments.append_attachments(attachments)

    def clear_content(self, flag):
        self.attachments.clear_attachments()
        self.email_page.runJavaScript(
            'document.open(); document.write(""); document.close();')