예제 #1
0
def test():
    from qt import QWidget
    class W(QWidget):
        def __init__(self):

            QWidget.__init__(self)
    
    def create():
        global _list
        s = SampleControl()
        s.load('/home/ajole/wav/trance.wav')
        s.slotStart()
        s.slotSetZone(0, True)
        _list.append(s)
    
    import pkaudio
    from qt import QApplication, QPushButton, QObject, SIGNAL
    pkaudio.connect_to_host(startserver=0)
    a = QApplication([])

    w1 = SampleControl()
    w1.load('/home/ajole/wav/track.wav')
    w1.slotStart()
    w1.slotSetZone(0, True)

    b = QPushButton('create', None)
    QObject.connect(b,
                    SIGNAL('clicked()'),
                    create)
    b.show()
    a.setMainWidget(b)
    a.exec_loop()
예제 #2
0
class Window(QWidget):
    def __init__(self):

        QWidget.__init__(self)

        self.textBrowser = QTextBrowser(self)
        self.textBrowser.setTextFormat(QTextBrowser.LogText)
        self.lineEdit = QLineEdit(self)
        self.startButton = QPushButton(self.tr("Start"), self)
        self.stopButton = QPushButton(self.tr("Stop"), self)
        self.stopButton.setEnabled(False)

        self.connect(self.lineEdit, SIGNAL("returnPressed()"), self.startCommand)
        self.connect(self.startButton, SIGNAL("clicked()"), self.startCommand)
        self.connect(self.stopButton, SIGNAL("clicked()"), self.stopCommand)

 
        layout = QGridLayout(self, 2, 3)
        layout.setSpacing(8)
        layout.addMultiCellWidget(self.textBrowser, 0, 0, 0, 2)
        layout.addWidget(self.lineEdit, 1, 0)
        layout.addWidget(self.startButton, 1, 1)
        layout.addWidget(self.stopButton, 1, 2)
 
        self.process = QProcess()
        self.connect(self.process, SIGNAL("readyReadStdout()"), self.readOutput)
        self.connect(self.process, SIGNAL("readyReadStderr()"), self.readErrors)
        self.connect(self.process, SIGNAL("processExited()"), self.resetButtons)

    def startCommand(self):
        self.process.setArguments(QStringList.split(" ", self.lineEdit.text()))
        self.process.closeStdin()

        self.startButton.setEnabled(False)
        self.stopButton.setEnabled(True)
        self.textBrowser.clear()
        if not self.process.start():
            self.textBrowser.setText(
                QString("*** Failed to run %1 ***").arg(self.lineEdit.text())
                )
            self.resetButtons()
            return

 
    def stopCommand(self):
        self.resetButtons()
        self.process.tryTerminate()
        QTimer.singleShot(5000, self.process, SLOT("kill()"))

    def readOutput(self):

        self.textBrowser.append(QString(self.process.readStdout()))

    def readErrors(self):

        self.textBrowser.append("error: " + QString(self.process.readLineStderr()))

    def resetButtons(self):
        self.startButton.setEnabled(True)
        self.stopButton.setEnabled(False)
예제 #3
0
    def __init__(self):

        QWidget.__init__(self)

        self.textBrowser = QTextBrowser(self)
        self.textBrowser.setTextFormat(QTextBrowser.LogText)
        self.lineEdit = QLineEdit(self)
        self.startButton = QPushButton(self.tr("Start"), self)
        self.stopButton = QPushButton(self.tr("Stop"), self)
        self.stopButton.setEnabled(False)

        self.connect(self.lineEdit, SIGNAL("returnPressed()"), self.startCommand)
        self.connect(self.startButton, SIGNAL("clicked()"), self.startCommand)
        self.connect(self.stopButton, SIGNAL("clicked()"), self.stopCommand)
        layout = QGridLayout(self, 2, 3)
        layout.setSpacing(8)
        layout.addMultiCellWidget(self.textBrowser, 0, 0, 0, 2)
        layout.addWidget(self.lineEdit, 1, 0)
        layout.addWidget(self.startButton, 1, 1)
        layout.addWidget(self.stopButton, 1, 2)



        self.process = QProcess()
        self.connect(self.process, SIGNAL("readyReadStdout()"), self.readOutput)
        self.connect(self.process, SIGNAL("readyReadStderr()"), self.readErrors)
        self.connect(self.process, SIGNAL("processExited()"), self.resetButtons)
예제 #4
0
class ParamAdvancedWidget(QWidget):
    def __init__(self, phl_obj=None, parent=None):
        super(ParamAdvancedWidget, self).__init__()

        self.scrollable_widget = PhilWidget(phl_obj, parent=self)
        scrollArea = QScrollArea()
        scrollArea.setWidget(self.scrollable_widget)
        vbox = QVBoxLayout()

        search_label = QLabel("Search:")
        search_edit = QLineEdit()
        search_edit.setPlaceholderText("Type search here")
        search_edit.textChanged.connect(self.scrollable_widget.user_searching)
        self.search_next_button = QPushButton("Find next")
        self.search_next_button.setEnabled(False)

        hbox = QHBoxLayout()
        hbox.addWidget(search_label)
        hbox.addWidget(search_edit)
        hbox.addWidget(self.search_next_button)
        self.search_next_button.clicked.connect(self.scrollable_widget.find_next)
        vbox.addLayout(hbox)

        vbox.addWidget(scrollArea)
        self.setLayout(vbox)
예제 #5
0
    def __init__(self, interfazdato, cajadisponible):
        """Caja disponible son los elementos que aparecen a la izquierda en el selector"""
        #VARIABLES PUBLICAS
        QWidget.__init__(self, None, "selector", 0)

        image1 = QPixmap(IMAGE1DATA)
        image2 = QPixmap(IMAGE2DATA)

        selectorsimplelayout = QHBoxLayout(self, 11, 6, "WSelectorSimpleLayout")
        layout2 = QVBoxLayout(None, 0, 6, "layout2")
        widgetstack1 = QWidgetStack(self, "staaack")
        widgetstack1.addWidget(cajadisponible)
        widgetstack1.raiseWidget(cajadisponible)
        widgetstack1.setSizePolicy(QSizePolicy(\
                QSizePolicy.Expanding, QSizePolicy.Expanding, \
                0, 0, widgetstack1.sizePolicy().hasHeightForWidth()))
        self._cajadisponible = cajadisponible
        layout2.addWidget(widgetstack1)
        selectorsimplelayout.addLayout(layout2)
        
        layout1 = QVBoxLayout(None, 0, 6, "layout1")
        
        self.__pushbutton1 = QPushButton(self, "pushButton1")
        self.__pushbutton1.setMaximumSize(QSize(30, 30))
        self.__pushbutton1.setPixmap(image1)
        layout1.addWidget(self.__pushbutton1)
        spacer1 = QSpacerItem(30, 122, QSizePolicy.Minimum, QSizePolicy.Expanding)
        layout1.addItem(spacer1)
        
        self.__pushbutton2 = QPushButton(self,"pushButton2")
        self.__pushbutton2.setMaximumSize(QSize(30, 30))
        self.__pushbutton2.setPixmap(image2)
        self.__pushbutton2.setAccel("Del")
        layout1.addWidget(self.__pushbutton2)
        selectorsimplelayout.addLayout(layout1)
        
        layout3 = QVBoxLayout(None, 0, 6, "layout3")
        
        self._textlabel2 = QLabel(self, "textLabel2")
        layout3.addWidget(self._textlabel2)
        
        self._cajaseleccion = QListBox(self,"cajaseleccion")
        self._cajaseleccion.setMinimumSize(QSize(0, 60))
        layout3.addWidget(self._cajaseleccion)
        selectorsimplelayout.addLayout(layout3)
        self._cajaseleccion.setSizePolicy(QSizePolicy(\
                QSizePolicy.Expanding,QSizePolicy.Expanding, 0, 0, \
                self._cajaseleccion.sizePolicy().hasHeightForWidth()))
        
        self.setCaption("Form1")
        self._textlabel2.setText(u"Selección")
        
        self.resize(QSize(294, 240).expandedTo(self.minimumSizeHint()))
        self.clearWState(Qt.WState_Polished)
        self.__conexiones()
        #Miembros !qt

        self.seleccion = []
        self._dato = interfazdato
예제 #6
0
    def __init__(self, parent=None):
        super(ImportPage, self).__init__(parent=None)

        main_v_box = QVBoxLayout()

        label_font = QFont()
        sys_font_point_size = label_font.pointSize()
        label_font.setPointSize(sys_font_point_size + 2)
        step_label = QLabel(str("Import"))
        step_label.setFont(label_font)

        self.simple_lin = QLineEdit(self)
        self.simple_lin.textChanged.connect(self.update_command)

        self.x_spn_bx = QSpinBox()
        self.x_spn_bx.setMaximum(99999)
        self.x_spn_bx.setSpecialValueText(" ")
        self.y_spn_bx = QSpinBox()
        self.y_spn_bx.setMaximum(99999)
        self.y_spn_bx.setSpecialValueText(" ")

        self.x_spn_bx.valueChanged.connect(self.x_beam_changed)
        self.y_spn_bx.valueChanged.connect(self.y_beam_changed)

        self.chk_invert = QCheckBox("Invert rotation axis")
        self.chk_invert.stateChanged.connect(self.inv_rota_changed)

        self.opn_fil_btn = QPushButton(" \n Select file(s) \n ")

        main_path = get_main_path()

        self.opn_fil_btn.setIcon(QIcon(main_path + "/resources/import.png"))
        self.opn_fil_btn.setIconSize(QSize(80, 48))

        main_v_box.addWidget(step_label)
        main_v_box.addWidget(self.opn_fil_btn)
        main_v_box.addWidget(self.simple_lin)
        self.b_cetre_label = QLabel("\n\n Beam centre")
        main_v_box.addWidget(self.b_cetre_label)
        cent_hbox = QHBoxLayout()
        self.x_label = QLabel("    X: ")
        cent_hbox.addWidget(self.x_label)
        cent_hbox.addWidget(self.x_spn_bx)
        self.y_label = QLabel("    Y: ")
        cent_hbox.addWidget(self.y_label)
        cent_hbox.addWidget(self.y_spn_bx)
        #    cent_hbox.addWidget(QLabel(" \n "))
        cent_hbox.addStretch()
        main_v_box.addLayout(cent_hbox)
        main_v_box.addWidget(self.chk_invert)
        main_v_box.addStretch()

        self.opn_fil_btn.clicked.connect(self.open_files)

        self.defa_dir = str(os.getcwd())
        self.setLayout(main_v_box)
        # self.show()
        self.reset_par()
예제 #7
0
파일: scoring.py 프로젝트: zero804/kajongg
 def __init__(self, swappers):
     QMessageBox.__init__(self)
     decorateWindow(self, i18n("Swap Seats"))
     self.setText(
         i18n("By the rules, %1 and %2 should now exchange their seats. ",
              swappers[0].name, swappers[1].name))
     self.yesAnswer = QPushButton(i18n("&Exchange"))
     self.addButton(self.yesAnswer, QMessageBox.YesRole)
     self.noAnswer = QPushButton(i18n("&Keep seat"))
     self.addButton(self.noAnswer, QMessageBox.NoRole)
예제 #8
0
파일: humanclient.py 프로젝트: KDE/kajongg
 def keyPressEvent(self, event):
     """forward horizintal arrows to the hand board"""
     key = Board.mapChar2Arrow(event)
     if key in [Qt.Key_Left, Qt.Key_Right]:
         game = self.client.game
         if game and game.activePlayer == game.myself:
             game.myself.handBoard.keyPressEvent(event)
             self.setFocus()
             return
     QPushButton.keyPressEvent(self, event)
예제 #9
0
 def keyPressEvent(self, event):
     """forward horizintal arrows to the hand board"""
     key = Board.mapChar2Arrow(event)
     if key in [Qt.Key_Left, Qt.Key_Right]:
         game = self.client.game
         if game and game.activePlayer == game.myself:
             game.myself.handBoard.keyPressEvent(event)
             self.setFocus()
             return
     QPushButton.keyPressEvent(self, event)
예제 #10
0
 def setupFrameControlFrame(self):
   # TODO: initialize the slider based on the contents of the labels array
   self.frameSlider = ctk.ctkSliderWidget()
   self.frameLabel = QLabel('Current frame number')
   self.playButton = QPushButton('Play')
   self.playButton.toolTip = 'Iterate over multivolume frames'
   self.playButton.checkable = True
   frameControlHBox = QHBoxLayout()
   frameControlHBox.addWidget(self.frameLabel)
   frameControlHBox.addWidget(self.frameSlider)
   frameControlHBox.addWidget(self.playButton)
   self.inputFrameLayout.addRow(frameControlHBox)
예제 #11
0
 def setupPlottingFrame(self, parent=None):
   if not parent:
     parent = self.layout
   self.plottingFrameWidget = QWidget()
   self.plottingFrameLayout = QGridLayout()
   self.plottingFrameWidget.setLayout(self.plottingFrameLayout)
   self._multiVolumeIntensityChart = MultiVolumeIntensityChartView()
   self.popupChartButton = QPushButton("Undock chart")
   self.popupChartButton.setCheckable(True)
   self.plottingFrameLayout.addWidget(self._multiVolumeIntensityChart.chartView)
   self.plottingFrameLayout.addWidget(self.popupChartButton)
   parent.addWidget(self.plottingFrameWidget)
예제 #12
0
파일: gui_utils.py 프로젝트: luisodls/DUI
    def __init__(self):
        super(OuterCaller, self).__init__()

        v_box = QVBoxLayout()

        recip_lat_but = QPushButton("\n Open Reciprocal Lattice Viewer \n")
        recip_lat_but.clicked.connect(self.run_recip_dialg)
        v_box.addWidget(recip_lat_but)

        img_but = QPushButton("\n Open Image Viewer \n")
        img_but.clicked.connect(self.run_img_dialg)
        v_box.addWidget(img_but)

        self.diag = ExternalProcDialog(parent=self.window())
        self.setLayout(v_box)
예제 #13
0
 def setupUi(self):
     """layout the window"""
     decorateWindow(self, m18n('Customize rulesets'))
     self.setObjectName('Rulesets')
     hlayout = QHBoxLayout(self)
     v1layout = QVBoxLayout()
     self.v1widget = QWidget()
     v1layout = QVBoxLayout(self.v1widget)
     v2layout = QVBoxLayout()
     hlayout.addWidget(self.v1widget)
     hlayout.addLayout(v2layout)
     for widget in [self.v1widget, hlayout, v1layout, v2layout]:
         widget.setContentsMargins(0, 0, 0, 0)
     hlayout.setStretchFactor(self.v1widget, 10)
     self.btnCopy = QPushButton()
     self.btnRemove = QPushButton()
     self.btnCompare = QPushButton()
     self.btnClose = QPushButton()
     self.rulesetView = RuleTreeView(
         m18nc('kajongg',
               'Rule'),
         self.btnCopy,
         self.btnRemove,
         self.btnCompare)
     v1layout.addWidget(self.rulesetView)
     self.rulesetView.setWordWrap(True)
     self.rulesetView.setMouseTracking(True)
     spacerItem = QSpacerItem(
         20,
         20,
         QSizePolicy.Minimum,
         QSizePolicy.Expanding)
     v2layout.addWidget(self.btnCopy)
     v2layout.addWidget(self.btnRemove)
     v2layout.addWidget(self.btnCompare)
     self.btnCopy.clicked.connect(self.rulesetView.copyRow)
     self.btnRemove.clicked.connect(self.rulesetView.removeRow)
     self.btnCompare.clicked.connect(self.rulesetView.compareRow)
     self.btnClose.clicked.connect(self.hide)
     v2layout.addItem(spacerItem)
     v2layout.addWidget(self.btnClose)
     self.retranslateUi()
     StateSaver(self)
     self.show()
예제 #14
0
 def __init__(self, scene):
     QWidget.__init__(self)
     self.scene = scene
     decorateWindow(self, i18n('Scoring for this Hand'))
     self.nameLabels = [None] * 4
     self.spValues = [None] * 4
     self.windLabels = [None] * 4
     self.wonBoxes = [None] * 4
     self.detailsLayout = [None] * 4
     self.details = [None] * 4
     self.__tilePixMaps = []
     self.__meldPixMaps = []
     grid = QGridLayout(self)
     pGrid = QGridLayout()
     grid.addLayout(pGrid, 0, 0, 2, 1)
     pGrid.addWidget(QLabel(i18nc('kajongg', "Player")), 0, 0)
     pGrid.addWidget(QLabel(i18nc('kajongg', "Wind")), 0, 1)
     pGrid.addWidget(QLabel(i18nc('kajongg', 'Score')), 0, 2)
     pGrid.addWidget(QLabel(i18n("Winner")), 0, 3)
     self.detailTabs = QTabWidget()
     self.detailTabs.setDocumentMode(True)
     pGrid.addWidget(self.detailTabs, 0, 4, 8, 1)
     for idx in range(4):
         self.setupUiForPlayer(pGrid, idx)
     self.draw = QCheckBox(i18nc('kajongg', 'Draw'))
     self.draw.clicked.connect(self.wonChanged)
     btnPenalties = QPushButton(i18n("&Penalties"))
     btnPenalties.clicked.connect(self.penalty)
     self.btnSave = QPushButton(i18n('&Save Hand'))
     self.btnSave.clicked.connect(self.game.nextScoringHand)
     self.btnSave.setEnabled(False)
     self.setupUILastTileMeld(pGrid)
     pGrid.setRowStretch(87, 10)
     pGrid.addWidget(self.draw, 7, 3)
     self.cbLastTile.currentIndexChanged.connect(self.slotLastTile)
     self.cbLastMeld.currentIndexChanged.connect(self.slotInputChanged)
     btnBox = QHBoxLayout()
     btnBox.addWidget(btnPenalties)
     btnBox.addWidget(self.btnSave)
     pGrid.addLayout(btnBox, 8, 4)
     StateSaver(self)
     self.refresh()
예제 #15
0
    def set_ref(self, in_json_path, lin_num):
        my_box = QVBoxLayout()
        self.my_inner_table = ReindexTable(self)

        cwd_path = os.path.join(sys_arg.directory, "dui_files")
        full_json_path = os.path.join(cwd_path, in_json_path)

        self.my_inner_table.add_opts_lst(json_path=full_json_path)

        if self.my_inner_table.rec_col is not None:
            my_solu = self.my_inner_table.find_best_solu()
            self.my_inner_table.opt_clicked(my_solu, 0)

        recomd_str = "Select a bravais lattice to enforce: \n"
        try:
            recomd_str += "(best guess solution = row {})".format(
                self.my_inner_table.tmp_sel + 1)

        except BaseException as e:
            # Since we don't know exactly what this was supposed to be
            # - AttributeError? We don't know how to cleanly catch
            logger.error("Unknown exception catch caught. Was: %s", e)
            recomd_str += "(no best solution could be automatically determined)"

        bot_box = QHBoxLayout()
        bot_box.addWidget(QLabel(recomd_str))
        bot_box.addStretch()
        ok_but = QPushButton("     OK      ")
        ok_but.clicked.connect(self.my_inner_table.ok_clicked)
        bot_box.addWidget(ok_but)
        heather_text, v_heather_size = heather_text_from_lin(
            lin_num, full_json_path)
        my_box.addWidget(QLabel(heather_text))
        my_box.addWidget(self.my_inner_table)
        my_box.addLayout(bot_box)

        self.setLayout(my_box)

        n_col = self.my_inner_table.columnCount()
        tot_width = 80
        for col in range(n_col):
            loc_width = self.my_inner_table.columnWidth(col)
            tot_width += loc_width

        n_row = self.my_inner_table.rowCount()
        row_height = self.my_inner_table.rowHeight(1)
        tot_heght = int((float(n_row)) * float(row_height))
        tot_heght += int(
            (float(v_heather_size + 2)) * float(row_height * 0.62))

        self.resize(tot_width, tot_heght)
        # self.adjustSize()
        self.show()
 def SimpleButton(parent, title, handler, page=None, image=None):
     tabpage = parent.getPage(page)
     button = QPushButton(tabpage)
     if image:
         bi = QPixmap()
         bi.loadFromData(image, "PNG")
         button.setIconSet(QIconSet(bi))
         w = bi.width() + 3
         h = bi.height() + 3
         if w < 32:
             w = 32
         if h < 32:
             h = 32
         button.setMaximumSize(QSize(w, h))
     else:
         button.setText(title)
     QToolTip.add(button, title)
     parent.connect(button, SIGNAL("clicked()"), handler)
     button.show()
     p = ToolbarPlugin(parent)
     p.getWidget = lambda: button
    def setupFrameControlFrame(self):
        qSlicerMultiVolumeExplorerSimplifiedModuleWidget.setupFrameControlFrame(
            self)

        self.frameCopySelector = slicer.qMRMLNodeComboBox()
        self.frameCopySelector.setSizePolicy(QSizePolicy.Ignored,
                                             QSizePolicy.Preferred)
        self.frameCopySelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
        self.frameCopySelector.setMRMLScene(slicer.mrmlScene)
        self.frameCopySelector.addEnabled = 1
        self.frameCopySelector.enabled = 0
        # do not show "children" of vtkMRMLScalarVolumeNode
        self.frameCopySelector.hideChildNodeTypes = [
            "vtkMRMLDiffusionWeightedVolumeNode",
            "vtkMRMLDiffusionTensorVolumeNode", "vtkMRMLVectorVolumeNode"
        ]
        self.extractFrameCopy = False
        self.extractFrameCheckBox = QCheckBox('Enable copying while sliding')
        hbox = QHBoxLayout()
        hbox.addWidget(QLabel('Current frame copy'))
        hbox.addWidget(self.frameCopySelector)
        hbox.addWidget(self.extractFrameCheckBox)
        self.inputFrameLayout.addRow(hbox)

        self.currentFrameCopySelector = slicer.qMRMLNodeComboBox()
        self.currentFrameCopySelector.setSizePolicy(QSizePolicy.Ignored,
                                                    QSizePolicy.Preferred)
        self.currentFrameCopySelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
        self.currentFrameCopySelector.setMRMLScene(slicer.mrmlScene)
        self.currentFrameCopySelector.addEnabled = 0
        self.currentFrameCopySelector.enabled = 0

        self.currentFrameCopyButton = QPushButton('Copy frame')
        self.currentFrameCopyButton.toolTip = 'Copy currently selected frame'

        hbox2 = QHBoxLayout()
        hbox2.addWidget(QLabel('Current frame click-to-copy'))
        hbox2.addWidget(self.currentFrameCopySelector)
        hbox2.addWidget(self.currentFrameCopyButton)
        self.inputFrameLayout.addRow(hbox2)
  def setup(self):
    showPlusServerWidget = True
    if _platform == "linux" or _platform == "linux2" or _platform == "darwin": #linux or linux or OS X
      message = "Attention: You are running Slicer on Linux or OS X. Do you have PlusServer installed on the current OS?"
      result = QMessageBox.question(slicer.util.mainWindow(), 'ProstateTRUSNav', message,
                                     QMessageBox.Yes | QMessageBox.No)
      showPlusServerWidget = result == QMessageBox.Yes

    if _platform == "win32" or showPlusServerWidget:
      # Windows...
      plusServerCollapsibleButton = ctkCollapsibleButton()
      plusServerCollapsibleButton.text = "PlusServer"
      self.layout.addWidget(plusServerCollapsibleButton)
      self.configurationFileChooserButton = QPushButton(self.configurationFile)
      self.configurationFileChooserButton.connect('clicked()', self.onConfigFileSelected)
      self.runPlusServerButton = QPushButton("Run PlusServer")
      self.runPlusServerButton.setCheckable(True)
      self.runPlusServerButton.connect('clicked()', self.onRunPlusServerButtonClicked)

      self.serverFormLayout = QFormLayout(plusServerCollapsibleButton)

      self.serverExecutableChooserButton = QPushButton(self.serverExecutable)
      self.serverExecutableChooserButton.connect('clicked()', self.onServerExecutableSelected)

      hbox = QHBoxLayout()
      hbox.addWidget(self.serverExecutableChooserButton)
      self.serverFormLayout.addRow(hbox)

      hbox = QHBoxLayout()
      hbox.addWidget(self.configurationFileChooserButton)
      hbox.addWidget(self.runPlusServerButton)
      self.serverFormLayout.addRow(hbox)

    GuideletWidget.setup(self)

    # do specific setup here
    if _platform == "win32" or showPlusServerWidget:
      self.launchGuideletButton.setEnabled(False)
      self.checkExecutableAndArgument()
 def SimpleButton(parent, title, handler, page=None, image=None):
     tabpage = parent.getPage(page)
     button = QPushButton(tabpage)
     if image : 
         bi = QPixmap()
         bi.loadFromData(image, "PNG")
         button.setIconSet(QIconSet(bi))
         w = bi.width()+3
         h = bi.height()+3
         if w < 32:
             w = 32
         if h < 32:
             h = 32
         button.setMaximumSize(QSize(w, h))
     else:
         button.setText(title)
     QToolTip.add(button, title)
     parent.connect(button, SIGNAL("clicked()"), handler)
     button.show()
     p = ToolbarPlugin(parent)
     p.getWidget = lambda: button
예제 #20
0
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.btn1 = QPushButton("Click me", self)

        vbox = QVBoxLayout()
        vbox.addWidget(QLabel("A1"))
        vbox.addWidget(self.btn1)
        vbox.addWidget(QLabel("B2"))

        self.btn1.clicked.connect(self.doit)
        self.my_pop = None

        self.main_widget = QWidget(self)
        self.main_widget.setLayout(vbox)
        self.setCentralWidget(self.main_widget)
예제 #21
0
 def setupUi(self):
     """layout the window"""
     decorateWindow(self, i18n('Customize rulesets'))
     self.setObjectName('Rulesets')
     hlayout = QHBoxLayout(self)
     v1layout = QVBoxLayout()
     self.v1widget = QWidget()
     v1layout = QVBoxLayout(self.v1widget)
     v2layout = QVBoxLayout()
     hlayout.addWidget(self.v1widget)
     hlayout.addLayout(v2layout)
     for widget in [self.v1widget, hlayout, v1layout, v2layout]:
         widget.setContentsMargins(0, 0, 0, 0)
     hlayout.setStretchFactor(self.v1widget, 10)
     self.btnCopy = QPushButton()
     self.btnRemove = QPushButton()
     self.btnCompare = QPushButton()
     self.btnClose = QPushButton()
     self.rulesetView = RuleTreeView(
         i18ncE('kajongg',
                'Rule'),
         self.btnCopy,
         self.btnRemove,
         self.btnCompare)
     v1layout.addWidget(self.rulesetView)
     self.rulesetView.setWordWrap(True)
     self.rulesetView.setMouseTracking(True)
     spacerItem = QSpacerItem(
         20,
         20,
         QSizePolicy.Minimum,
         QSizePolicy.Expanding)
     v2layout.addWidget(self.btnCopy)
     v2layout.addWidget(self.btnRemove)
     v2layout.addWidget(self.btnCompare)
     self.btnCopy.clicked.connect(self.rulesetView.copyRow)
     self.btnRemove.clicked.connect(self.rulesetView.removeRow)
     self.btnCompare.clicked.connect(self.rulesetView.compareRow)
     self.btnClose.clicked.connect(self.hide)
     v2layout.addItem(spacerItem)
     v2layout.addWidget(self.btnClose)
     self.retranslateUi()
     StateSaver(self)
     self.show()
예제 #22
0
 def __init__(self, scene):
     QWidget.__init__(self)
     self.scene = scene
     decorateWindow(self, m18n("Scoring for this Hand"))
     self.nameLabels = [None] * 4
     self.spValues = [None] * 4
     self.windLabels = [None] * 4
     self.wonBoxes = [None] * 4
     self.detailsLayout = [None] * 4
     self.details = [None] * 4
     self.__tilePixMaps = []
     self.__meldPixMaps = []
     grid = QGridLayout(self)
     pGrid = QGridLayout()
     grid.addLayout(pGrid, 0, 0, 2, 1)
     pGrid.addWidget(QLabel(m18nc("kajongg", "Player")), 0, 0)
     pGrid.addWidget(QLabel(m18nc("kajongg", "Wind")), 0, 1)
     pGrid.addWidget(QLabel(m18nc("kajongg", "Score")), 0, 2)
     pGrid.addWidget(QLabel(m18n("Winner")), 0, 3)
     self.detailTabs = QTabWidget()
     self.detailTabs.setDocumentMode(True)
     pGrid.addWidget(self.detailTabs, 0, 4, 8, 1)
     for idx in range(4):
         self.setupUiForPlayer(pGrid, idx)
     self.draw = QCheckBox(m18nc("kajongg", "Draw"))
     self.draw.clicked.connect(self.wonChanged)
     btnPenalties = QPushButton(m18n("&Penalties"))
     btnPenalties.clicked.connect(self.penalty)
     self.btnSave = QPushButton(m18n("&Save Hand"))
     self.btnSave.clicked.connect(self.game.nextScoringHand)
     self.btnSave.setEnabled(False)
     self.setupUILastTileMeld(pGrid)
     pGrid.setRowStretch(87, 10)
     pGrid.addWidget(self.draw, 7, 3)
     self.cbLastTile.currentIndexChanged.connect(self.slotLastTile)
     self.cbLastMeld.currentIndexChanged.connect(self.slotInputChanged)
     btnBox = QHBoxLayout()
     btnBox.addWidget(btnPenalties)
     btnBox.addWidget(self.btnSave)
     pGrid.addLayout(btnBox, 8, 4)
     StateSaver(self)
     self.refresh()
예제 #23
0
파일: gui_utils.py 프로젝트: ndevenish/DUI
    def __init__(self, parent=None):
        super(ExternalProcDialog, self).__init__(parent)

        vbox = QVBoxLayout()
        label = QLabel(("Running a pop-up viewer ...\n\n"
                        "remember to close the viewer before\n"
                        "performing any other task"))
        label.setAlignment(Qt.AlignCenter)
        vbox.addWidget(label)

        kl_but = QPushButton("Close pop-up viewer")
        kl_but.clicked.connect(self.kill_my_proc)
        vbox.addWidget(kl_but)

        self.setLayout(vbox)
        self.setFixedSize(self.sizeHint())
        self.setModal(True)
        self.setWindowTitle("External Tool")

        self.my_process = None
예제 #24
0
    def __init__(self, parent=None):
        super(StopRunRetry, self).__init__()

        main_path = get_main_path()

        ctrl_box = QHBoxLayout()

        self.repeat_btn = QPushButton("\n Retry \n", self)

        re_try_icon_path = str(main_path + "/resources/re_try.png")
        re_try_grayed_path = str(main_path + "/resources/re_try_grayed.png")
        tmp_ico = QIcon()
        tmp_ico.addFile(re_try_icon_path, mode=QIcon.Normal)
        tmp_ico.addFile(re_try_grayed_path, mode=QIcon.Disabled)

        self.repeat_btn.setIcon(tmp_ico)
        self.repeat_btn.setIconSize(QSize(50, 38))
        ctrl_box.addWidget(self.repeat_btn)

        self.run_btn = QPushButton("\n  Run  \n", self)
        self.dials_logo_path = str(
            main_path + "/resources/DIALS_Logo_smaller_centred.png"
        )
        dials_grayed_path = str(
            main_path + "/resources/DIALS_Logo_smaller_centred_grayed.png"
        )
        tmp_ico = QIcon()
        tmp_ico.addFile(self.dials_logo_path, mode=QIcon.Normal)
        tmp_ico.addFile(dials_grayed_path, mode=QIcon.Disabled)

        self.run_btn.setIcon(tmp_ico)
        self.run_btn.setIconSize(QSize(50, 50))
        ctrl_box.addWidget(self.run_btn)

        self.stop_btn = QPushButton("\n  Stop  \n", self)
        stop_logo_path = str(main_path + "/resources/stop.png")
        stop_grayed_path = str(main_path + "/resources/stop_grayed.png")
        tmp_ico = QIcon()
        tmp_ico.addFile(stop_logo_path, mode=QIcon.Normal)
        tmp_ico.addFile(stop_grayed_path, mode=QIcon.Disabled)
        self.stop_btn.setIcon(tmp_ico)
        self.stop_btn.setIconSize(QSize(50, 38))
        ctrl_box.addWidget(self.stop_btn)

        self.setLayout(ctrl_box)
    def setup(self):
        showPlusServerWidget = True
        if _platform == "linux" or _platform == "linux2" or _platform == "darwin":  #linux or linux or OS X
            message = "Attention: You are running Slicer on Linux or OS X. Do you have PlusServer installed on the current OS?"
            result = QMessageBox.question(slicer.util.mainWindow(),
                                          'ProstateTRUSNav', message,
                                          QMessageBox.Yes | QMessageBox.No)
            showPlusServerWidget = result == QMessageBox.Yes

        if _platform == "win32" or showPlusServerWidget:
            # Windows...
            plusServerCollapsibleButton = ctkCollapsibleButton()
            plusServerCollapsibleButton.text = "PlusServer"
            self.layout.addWidget(plusServerCollapsibleButton)
            self.configurationFileChooserButton = QPushButton(
                self.configurationFile)
            self.configurationFileChooserButton.connect(
                'clicked()', self.onConfigFileSelected)
            self.runPlusServerButton = QPushButton("Run PlusServer")
            self.runPlusServerButton.setCheckable(True)
            self.runPlusServerButton.connect('clicked()',
                                             self.onRunPlusServerButtonClicked)

            self.serverFormLayout = QFormLayout(plusServerCollapsibleButton)

            self.serverExecutableChooserButton = QPushButton(
                self.serverExecutable)
            self.serverExecutableChooserButton.connect(
                'clicked()', self.onServerExecutableSelected)

            hbox = QHBoxLayout()
            hbox.addWidget(self.serverExecutableChooserButton)
            self.serverFormLayout.addRow(hbox)

            hbox = QHBoxLayout()
            hbox.addWidget(self.configurationFileChooserButton)
            hbox.addWidget(self.runPlusServerButton)
            self.serverFormLayout.addRow(hbox)

        GuideletWidget.setup(self)

        # do specific setup here
        if _platform == "win32" or showPlusServerWidget:
            self.launchGuideletButton.setEnabled(False)
            self.checkExecutableAndArgument()
  def setupFrameControlFrame(self):
    qSlicerMultiVolumeExplorerSimplifiedModuleWidget.setupFrameControlFrame(self)

    self.frameCopySelector = slicer.qMRMLNodeComboBox()
    self.frameCopySelector.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred)
    self.frameCopySelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
    self.frameCopySelector.setMRMLScene(slicer.mrmlScene)
    self.frameCopySelector.addEnabled = 1
    self.frameCopySelector.enabled = 0
    # do not show "children" of vtkMRMLScalarVolumeNode
    self.frameCopySelector.hideChildNodeTypes = ["vtkMRMLDiffusionWeightedVolumeNode",
                                                  "vtkMRMLDiffusionTensorVolumeNode",
                                                  "vtkMRMLVectorVolumeNode"]
    self.extractFrameCopy = False
    self.extractFrameCheckBox = QCheckBox('Enable copying while sliding')
    hbox = QHBoxLayout()
    hbox.addWidget(QLabel('Current frame copy'))
    hbox.addWidget(self.frameCopySelector)
    hbox.addWidget(self.extractFrameCheckBox)
    self.inputFrameLayout.addRow(hbox)

    self.currentFrameCopySelector = slicer.qMRMLNodeComboBox()
    self.currentFrameCopySelector.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred)
    self.currentFrameCopySelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
    self.currentFrameCopySelector.setMRMLScene(slicer.mrmlScene)
    self.currentFrameCopySelector.addEnabled = 0
    self.currentFrameCopySelector.enabled = 0

    self.currentFrameCopyButton = QPushButton('Copy frame')
    self.currentFrameCopyButton.toolTip = 'Copy currently selected frame'

    hbox2 = QHBoxLayout()
    hbox2.addWidget(QLabel('Current frame click-to-copy'))
    hbox2.addWidget(self.currentFrameCopySelector)
    hbox2.addWidget(self.currentFrameCopyButton)
    self.inputFrameLayout.addRow(hbox2)
예제 #27
0
class RulesetSelector(QWidget):

    """presents all available rulesets with previews"""

    def __init__(self, parent=None):
        super(RulesetSelector, self).__init__(parent)
        self.setContentsMargins(0, 0, 0, 0)
        self.setupUi()

    def setupUi(self):
        """layout the window"""
        decorateWindow(self, i18n('Customize rulesets'))
        self.setObjectName('Rulesets')
        hlayout = QHBoxLayout(self)
        v1layout = QVBoxLayout()
        self.v1widget = QWidget()
        v1layout = QVBoxLayout(self.v1widget)
        v2layout = QVBoxLayout()
        hlayout.addWidget(self.v1widget)
        hlayout.addLayout(v2layout)
        for widget in [self.v1widget, hlayout, v1layout, v2layout]:
            widget.setContentsMargins(0, 0, 0, 0)
        hlayout.setStretchFactor(self.v1widget, 10)
        self.btnCopy = QPushButton()
        self.btnRemove = QPushButton()
        self.btnCompare = QPushButton()
        self.btnClose = QPushButton()
        self.rulesetView = RuleTreeView(
            i18ncE('kajongg',
                   'Rule'),
            self.btnCopy,
            self.btnRemove,
            self.btnCompare)
        v1layout.addWidget(self.rulesetView)
        self.rulesetView.setWordWrap(True)
        self.rulesetView.setMouseTracking(True)
        spacerItem = QSpacerItem(
            20,
            20,
            QSizePolicy.Minimum,
            QSizePolicy.Expanding)
        v2layout.addWidget(self.btnCopy)
        v2layout.addWidget(self.btnRemove)
        v2layout.addWidget(self.btnCompare)
        self.btnCopy.clicked.connect(self.rulesetView.copyRow)
        self.btnRemove.clicked.connect(self.rulesetView.removeRow)
        self.btnCompare.clicked.connect(self.rulesetView.compareRow)
        self.btnClose.clicked.connect(self.hide)
        v2layout.addItem(spacerItem)
        v2layout.addWidget(self.btnClose)
        self.retranslateUi()
        StateSaver(self)
        self.show()

    def sizeHint(self):
        """we never want a horizontal scrollbar for player names,
        we always want to see them in full"""
        result = QWidget.sizeHint(self)
        available = Internal.app.desktop().availableGeometry()
        height = max(result.height(), available.height() * 2 // 3)
        width = max(result.width(), available.width() // 2)
        return QSize(width, height)

    def minimumSizeHint(self):
        """we never want a horizontal scrollbar for player names,
        we always want to see them in full"""
        return self.sizeHint()

    def showEvent(self, dummyEvent):
        """reload the rulesets"""
        self.refresh()

    def refresh(self):
        """retranslate and reload rulesets"""
        self.retranslateUi()
        self.rulesetView.rulesets = Ruleset.availableRulesets()

    def hideEvent(self, event):
        """close all differ dialogs"""
        for differ in self.rulesetView.differs:
            differ.hide()
            del differ
        QWidget.hideEvent(self, event)

    def retranslateUi(self):
        """translate to current language"""
        self.btnCopy.setText(i18n("C&opy"))
        self.btnCompare.setText(i18nc('Kajongg ruleset comparer', 'Co&mpare'))
        self.btnRemove.setText(i18n('&Remove'))
        self.btnClose.setText(i18n('&Close'))
class qSlicerMultiVolumeExplorerSimplifiedModuleWidget:

  def __init__(self, parent=None):
    logging.debug("qSlicerMultiVolumeExplorerSimplifiedModuleWidget:init() called")
    if not parent or not hasattr(parent, "layout"):
      self.parent = slicer.qMRMLWidget()
      self.parent.setLayout(QVBoxLayout())
    else:
      self.parent = parent

    self.layout = self.parent.layout()

    self._bgMultiVolumeNode = None
    self._fgMultiVolumeNode = None

    self.styleObserverTags = []
    self.sliceWidgetsPerStyle = {}

    self.chartPopupWindow = None
    self.chartPopupSize = QSize(600, 300)
    self.chartPopupPosition = QPoint(0,0)

  def hide(self):
    self.widget.hide()

  def show(self):
    self.widget.show()

  def setup(self):
    self.widget = QWidget()
    layout = QGridLayout()
    self.widget.setLayout(layout)
    self.layout.addWidget(self.widget)
    self.widget.show()
    self.layout = layout

    self.setupInputFrame()
    self.setupFrameControlFrame()
    self.setupAdditionalFrames()
    self.setupPlottingFrame()

    self.setFramesEnabled(False)

    self.timer = QTimer()
    self.timer.setInterval(50)

    self.setupConnections()

    # initialize slice observers (from DataProbe.py)
    # keep list of pairs: [observee,tag] so they can be removed easily
    self.styleObserverTags = []
    # keep a map of interactor styles to sliceWidgets so we can easily get sliceLogic
    self.sliceWidgetsPerStyle = {}
    self.refreshObservers()

  def setupInputFrame(self, parent=None):
    if not parent:
      parent = self.layout
    self.bgMultiVolumeSelector = slicer.qMRMLNodeComboBox()
    self.bgMultiVolumeSelector.nodeTypes = ['vtkMRMLMultiVolumeNode']
    self.bgMultiVolumeSelector.setMRMLScene(slicer.mrmlScene)
    self.bgMultiVolumeSelector.addEnabled = 0
    self._bgMultiVolumeSelectorLabel = QLabel('Input multivolume')
    inputFrameWidget = QWidget()
    self.inputFrameLayout = QFormLayout()
    inputFrameWidget.setLayout(self.inputFrameLayout)
    self.inputFrameLayout.addRow(self._bgMultiVolumeSelectorLabel, self.bgMultiVolumeSelector)
    parent.addWidget(inputFrameWidget)

  def setupFrameControlFrame(self):
    # TODO: initialize the slider based on the contents of the labels array
    self.frameSlider = ctk.ctkSliderWidget()
    self.frameLabel = QLabel('Current frame number')
    self.playButton = QPushButton('Play')
    self.playButton.toolTip = 'Iterate over multivolume frames'
    self.playButton.checkable = True
    frameControlHBox = QHBoxLayout()
    frameControlHBox.addWidget(self.frameLabel)
    frameControlHBox.addWidget(self.frameSlider)
    frameControlHBox.addWidget(self.playButton)
    self.inputFrameLayout.addRow(frameControlHBox)

  def setupAdditionalFrames(self):
    pass

  def setupPlottingFrame(self, parent=None):
    if not parent:
      parent = self.layout
    self.plottingFrameWidget = QWidget()
    self.plottingFrameLayout = QGridLayout()
    self.plottingFrameWidget.setLayout(self.plottingFrameLayout)
    self._multiVolumeIntensityChart = MultiVolumeIntensityChartView()
    self.popupChartButton = QPushButton("Undock chart")
    self.popupChartButton.setCheckable(True)
    self.plottingFrameLayout.addWidget(self._multiVolumeIntensityChart.chartView)
    self.plottingFrameLayout.addWidget(self.popupChartButton)
    parent.addWidget(self.plottingFrameWidget)

  def setupConnections(self):
    self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.onVCMRMLSceneChanged)
    self.bgMultiVolumeSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onBackgroundInputChanged)
    self.playButton.connect('toggled(bool)', self.onPlayButtonToggled)
    self.frameSlider.connect('valueChanged(double)', self.onSliderChanged)
    self.timer.connect('timeout()', self.goToNext)
    self.popupChartButton.connect('toggled(bool)', self.onDockChartViewToggled)

  def onDockChartViewToggled(self, checked):
    if checked:
      self.chartPopupWindow = QDialog()
      self.chartPopupWindow.setWindowFlags(PythonQt.QtCore.Qt.WindowStaysOnTopHint)
      layout = QGridLayout()
      self.chartPopupWindow.setLayout(layout)
      layout.addWidget(self._multiVolumeIntensityChart.chartView)
      layout.addWidget(self.popupChartButton)
      self.chartPopupWindow.finished.connect(self.dockChartView)
      self.chartPopupWindow.resize(self.chartPopupSize)
      self.chartPopupWindow.move(self.chartPopupPosition)
      self.chartPopupWindow.show()
      self.popupChartButton.setText("Dock chart")
      self._multiVolumeIntensityChart.chartView.show()
    else:
      self.chartPopupWindow.close()

  def dockChartView(self):
    self.chartPopupSize = self.chartPopupWindow.size
    self.chartPopupPosition = self.chartPopupWindow.pos
    self.plottingFrameLayout.addWidget(self._multiVolumeIntensityChart.chartView)
    self.plottingFrameLayout.addWidget(self.popupChartButton)
    self.popupChartButton.setText("Undock chart")
    self.popupChartButton.disconnect('toggled(bool)', self.onDockChartViewToggled)
    self.popupChartButton.checked = False
    self.popupChartButton.connect('toggled(bool)', self.onDockChartViewToggled)

  def onSliderChanged(self, frameId):
    if self._bgMultiVolumeNode is None:
      return
    newValue = int(frameId)
    self.setCurrentFrameNumber(newValue)

  def onVCMRMLSceneChanged(self, mrmlScene):
    logging.debug("qSlicerMultiVolumeExplorerSimplifiedModuleWidget:onVCMRMLSceneChanged")
    self.bgMultiVolumeSelector.setMRMLScene(slicer.mrmlScene)
    self.onBackgroundInputChanged()

  def refreshGUIForNewBackgroundImage(self):
    self._multiVolumeIntensityChart.reset()
    self.setFramesEnabled(True)
    if self._fgMultiVolumeNode and self._bgMultiVolumeNode:
      Helper.SetBgFgVolumes(self._bgMultiVolumeNode.GetID(), self._fgMultiVolumeNode.GetID())
    else:
      Helper.SetBgVolume(self._bgMultiVolumeNode.GetID())
    self.refreshFrameSlider()
    self._multiVolumeIntensityChart.bgMultiVolumeNode = self._bgMultiVolumeNode
    self.refreshObservers()

  def getBackgroundMultiVolumeNode(self):
    return self.bgMultiVolumeSelector.currentNode()

  def onBackgroundInputChanged(self):
    self._bgMultiVolumeNode = self.getBackgroundMultiVolumeNode()

    if self._bgMultiVolumeNode is not None:
      self.refreshGUIForNewBackgroundImage()
    else:
      self.setFramesEnabled(False)

  def onPlayButtonToggled(self, checked):
    if self._bgMultiVolumeNode is None:
      return
    if checked:
      self.timer.start()
      self.playButton.text = 'Stop'
    else:
      self.timer.stop()
      self.playButton.text = 'Play'

  def processEvent(self, observee, event):
    # logging.debug("processing event %s" % event)
    if self._bgMultiVolumeNode is None:
      return

    # TODO: use a timer to delay calculation and compress events
    if event == 'LeaveEvent':
      # reset all the readouts
      # TODO: reset the label text
      return

    if not self.sliceWidgetsPerStyle.has_key(observee):
      return

    interactor = observee.GetInteractor()
    self.createChart(self.sliceWidgetsPerStyle[observee], interactor.GetEventPosition())

  def createChart(self, sliceWidget, position):
    self._multiVolumeIntensityChart.createChart(sliceWidget, position)

  def setCurrentFrameNumber(self, frameNumber):
    mvDisplayNode = self._bgMultiVolumeNode.GetDisplayNode()
    mvDisplayNode.SetFrameComponent(frameNumber)

  def setFramesEnabled(self, enabled):
    pass

  def refreshObservers(self):
    """ When the layout changes, drop the observers from
    all the old widgets and create new observers for the
    newly created widgets"""
    self.removeObservers()
    # get new slice nodes
    layoutManager = slicer.app.layoutManager()
    sliceNodeCount = slicer.mrmlScene.GetNumberOfNodesByClass('vtkMRMLSliceNode')
    for nodeIndex in xrange(sliceNodeCount):
      # find the widget for each node in scene
      sliceNode = slicer.mrmlScene.GetNthNodeByClass(nodeIndex, 'vtkMRMLSliceNode')
      sliceWidget = layoutManager.sliceWidget(sliceNode.GetLayoutName())
      if sliceWidget:
        # add observers and keep track of tags
        style = sliceWidget.sliceView().interactorStyle()
        self.sliceWidgetsPerStyle[style] = sliceWidget
        events = ("MouseMoveEvent", "EnterEvent", "LeaveEvent")
        for event in events:
          tag = style.AddObserver(event, self.processEvent)
          self.styleObserverTags.append([style,tag])

  def removeObservers(self):
    for observee,tag in self.styleObserverTags:
      observee.RemoveObserver(tag)
    self.styleObserverTags = []
    self.sliceWidgetsPerStyle = {}

  def refreshFrameSlider(self):
    self.frameSlider.minimum = 0
    if not self._bgMultiVolumeNode:
      self.frameSlider.maximum = 0
      return
    nFrames = self._bgMultiVolumeNode.GetNumberOfFrames()
    self.frameSlider.maximum = nFrames - 1

  def goToNext(self):
    currentElement = self.frameSlider.value
    currentElement += 1
    if currentElement > self.frameSlider.maximum:
      currentElement = 0
    self.frameSlider.value = currentElement
예제 #29
0
class ImportPage(QWidget):

    update_command_lst_low_level = Signal(list)

    """
    This stacked widget basically helps the user to browse the input images
    path, there is no auto-generated GUI form Phil parameters in use withing
    this widget.
    """

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

        main_v_box = QVBoxLayout()

        label_font = QFont()
        sys_font_point_size = label_font.pointSize()
        label_font.setPointSize(sys_font_point_size + 2)
        step_label = QLabel(str("Import"))
        step_label.setFont(label_font)

        self.simple_lin = QLineEdit(self)
        self.simple_lin.textChanged.connect(self.update_command)

        self.x_spn_bx = QSpinBox()
        self.x_spn_bx.setMaximum(99999)
        self.x_spn_bx.setSpecialValueText(" ")
        self.y_spn_bx = QSpinBox()
        self.y_spn_bx.setMaximum(99999)
        self.y_spn_bx.setSpecialValueText(" ")

        self.x_spn_bx.valueChanged.connect(self.x_beam_changed)
        self.y_spn_bx.valueChanged.connect(self.y_beam_changed)

        self.chk_invert = QCheckBox("Invert rotation axis")
        self.chk_invert.stateChanged.connect(self.inv_rota_changed)

        self.opn_fil_btn = QPushButton(" \n Select file(s) \n ")

        main_path = get_main_path()

        self.opn_fil_btn.setIcon(QIcon(main_path + "/resources/import.png"))
        self.opn_fil_btn.setIconSize(QSize(80, 48))

        main_v_box.addWidget(step_label)
        main_v_box.addWidget(self.opn_fil_btn)
        main_v_box.addWidget(self.simple_lin)
        self.b_cetre_label = QLabel("\n\n Beam centre")
        main_v_box.addWidget(self.b_cetre_label)
        cent_hbox = QHBoxLayout()
        self.x_label = QLabel("    X: ")
        cent_hbox.addWidget(self.x_label)
        cent_hbox.addWidget(self.x_spn_bx)
        self.y_label = QLabel("    Y: ")
        cent_hbox.addWidget(self.y_label)
        cent_hbox.addWidget(self.y_spn_bx)
        #    cent_hbox.addWidget(QLabel(" \n "))
        cent_hbox.addStretch()
        main_v_box.addLayout(cent_hbox)
        main_v_box.addWidget(self.chk_invert)
        main_v_box.addStretch()

        self.opn_fil_btn.clicked.connect(self.open_files)

        self.defa_dir = str(os.getcwd())
        self.setLayout(main_v_box)
        # self.show()
        self.reset_par()

    def reset_par(self):
        logger.info("reset_par(ImportPage)")
        self.cmd_list = []
        self.simple_lin.setText(" ? ")
        self.x_spn_bx.setValue(0.0)
        self.y_spn_bx.setValue(0.0)
        self.chk_invert.setChecked(False)

        self.x_beam, self.y_beam = 0.0, 0.0
        self.path_file_str = ""
        self.second_half = ""
        self.third_half = ""

    def update_param_w_lst(self, lst_in):
        self.reset_par()
        logger.info("update_param_w_lst(ImportPage) \n lst: \n", lst_in)
        for singl_com in lst_in:
            if singl_com[0:1] == "/":
                self.path_file_str = str(singl_com)
                self.put_str_lin()

            if singl_com[0:12] == "image_range=":
                self.path_file_str += " "
                self.path_file_str += str(singl_com)
                self.put_str_lin()

            if singl_com == "invert_rotation_axis=True":
                self.chk_invert.setChecked(True)

            if singl_com[0:22] == "slow_fast_beam_centre=":
                yb_xb_str = singl_com[22:]
                yb_str, xb_str = yb_xb_str.split(",")
                yb = float(yb_str)
                xb = float(xb_str)
                self.y_spn_bx.setValue(yb)
                self.x_spn_bx.setValue(xb)

    def inv_rota_changed(self):
        if self.chk_invert.checkState():
            self.third_half = "invert_rotation_axis=True"

        else:
            self.third_half = ""

        self.put_str_lin()

    def x_beam_changed(self, value):
        self.x_beam = value
        self.build_second_half()

    def y_beam_changed(self, value):
        self.y_beam = value
        self.build_second_half()

    def build_second_half(self):
        if self.x_beam != 0.0 and self.y_beam != 0.0:
            self.second_half = (
                "slow_fast_beam_centre=" + str(self.y_beam) + "," + str(self.x_beam)
            )

        else:
            self.second_half = ""

        self.put_str_lin()

    def open_files(self):

        lst_file_path = QFileDialog.getOpenFileNames(
            self, "Open File(s)", self.defa_dir, "All Files (*.*)"
        )

        if len(lst_file_path) > 0:
            new_dir, new_command = get_import_run_string(lst_file_path)
            # logger.info("\n new_dir=", new_dir, ">>")
            # logger.info("\n new_command =", new_command, ">>")
            self.path_file_str = new_command
            self.defa_dir = new_dir
            self.put_str_lin()

    def put_str_lin(self):
        # logger.info("self.path_file_str =", self.path_file_str, ">>")
        self.cmd_list = [
            self.path_file_str,
            self.second_half.lstrip(),
            self.third_half.lstrip(),
        ]
        txt_lin = " ".join(self.cmd_list).rstrip()
        while "  " in txt_lin:
            txt_lin = txt_lin.replace("  ", " ")

        self.simple_lin.setText(txt_lin)

    def set_arg_obj(self, sys_arg_in):
        """Pass the system argument object to handle launch arguments."""
        if sys_arg_in.template is not None:
            str_arg = str(sys_arg_in.template)
            self.simple_lin.setText(str_arg)

    def update_command(self):
        self.command_lst = [["import"]]
        param_com = str(self.simple_lin.text())

        cmd_lst = param_com.split(" ")

        for single_com in cmd_lst:
            self.command_lst[0].append(single_com)

        self.update_command_lst_low_level.emit(self.command_lst[0])

    def gray_me_out(self):
        self.simple_lin.setEnabled(False)
        self.opn_fil_btn.setEnabled(False)
        self.x_spn_bx.setEnabled(False)
        self.y_spn_bx.setEnabled(False)
        self.x_label.setEnabled(False)
        self.y_label.setEnabled(False)
        self.b_cetre_label.setEnabled(False)
        self.chk_invert.setEnabled(False)

    def activate_me(self, cur_nod=None):
        self.simple_lin.setEnabled(True)
        self.opn_fil_btn.setEnabled(True)
        self.y_spn_bx.setEnabled(True)
        self.x_spn_bx.setEnabled(True)
        self.x_label.setEnabled(True)
        self.y_label.setEnabled(True)
        self.b_cetre_label.setEnabled(True)
        self.chk_invert.setEnabled(True)
  def setupPlotSettingsFrame(self):
    self.plotSettingsFrame = ctk.ctkCollapsibleButton()
    self.plotSettingsFrame.text = "Plotting Settings"
    self.plotSettingsFrame.collapsed = 1
    plotSettingsFrameLayout = QFormLayout(self.plotSettingsFrame)
    self.layout.addWidget(self.plotSettingsFrame)

    # label map for probing
    self.labelMapSelector = slicer.qMRMLNodeComboBox()
    self.labelMapSelector.nodeTypes = ['vtkMRMLLabelMapVolumeNode']
    self.labelMapSelector.toolTip = 'Label map to be probed'
    self.labelMapSelector.setMRMLScene(slicer.mrmlScene)
    self.labelMapSelector.addEnabled = 0
    self.chartButton = QPushButton('Chart')
    self.chartButton.setEnabled(False)

    hbox = QHBoxLayout()
    hbox.addWidget(QLabel('Probed label volume'))
    hbox.addWidget(self.labelMapSelector)
    hbox.addWidget(self.chartButton)
    plotSettingsFrameLayout.addRow(hbox)

    self.iCharting = QCheckBox('Interactive charting')
    self.iCharting.setChecked(True)
    plotSettingsFrameLayout.addRow(self.iCharting)

    self.iChartingMode = QButtonGroup()
    self.iChartingIntensity = QRadioButton('Signal intensity')
    self.iChartingIntensityFixedAxes = QRadioButton('Fixed range intensity')
    self.iChartingPercent = QRadioButton('Percentage change')
    self.iChartingIntensity.setChecked(1)
    self.iChartingMode.addButton(self.iChartingIntensity)
    self.iChartingMode.addButton(self.iChartingIntensityFixedAxes)
    self.iChartingMode.addButton(self.iChartingPercent)

    hbox = QHBoxLayout()
    self.plottingModeGroupBox = QGroupBox('Plotting mode:')
    plottingModeLayout = QVBoxLayout()
    self.plottingModeGroupBox.setLayout(plottingModeLayout)
    plottingModeLayout.addWidget(self.iChartingIntensity)
    plottingModeLayout.addWidget(self.iChartingIntensityFixedAxes)
    plottingModeLayout.addWidget(self.iChartingPercent)
    hbox.addWidget(self.plottingModeGroupBox)

    self.showLegendCheckBox = QCheckBox('Display legend')
    self.showLegendCheckBox.setChecked(0)
    self.xLogScaleCheckBox = QCheckBox('Use log scale for X axis')
    self.xLogScaleCheckBox.setChecked(0)
    self.yLogScaleCheckBox = QCheckBox('Use log scale for Y axis')
    self.yLogScaleCheckBox.setChecked(0)

    self.plotGeneralSettingsGroupBox = QGroupBox('General Plot options:')
    plotGeneralSettingsLayout = QVBoxLayout()
    self.plotGeneralSettingsGroupBox.setLayout(plotGeneralSettingsLayout)
    plotGeneralSettingsLayout.addWidget(self.showLegendCheckBox)
    plotGeneralSettingsLayout.addWidget(self.xLogScaleCheckBox)
    plotGeneralSettingsLayout.addWidget(self.yLogScaleCheckBox)
    hbox.addWidget(self.plotGeneralSettingsGroupBox)
    plotSettingsFrameLayout.addRow(hbox)

    self.nFramesBaselineCalculation = QSpinBox()
    self.nFramesBaselineCalculation.minimum = 1
    hbox = QHBoxLayout()
    hbox.addWidget(QLabel('Frame count(baseline calculation):'))
    hbox.addWidget(self.nFramesBaselineCalculation)
    plotSettingsFrameLayout.addRow(hbox)
예제 #31
0
# -*- coding: utf-8 -*-
import sys
from qt import QApplication, QPushButton

app=QApplication(sys.argv)
button=QPushButton(None)
button.setText(unicode("Merhaba Dünya"))
app.setMainWidget(button)
button.show()
app.exec_loop()
예제 #32
0
 def __init__(self, message, parent):
     QPushButton.__init__(self, parent)
     self.message = message
     self.client = parent.client
     self.setMinimumHeight(25)
     self.setText(message.buttonCaption())
class qSlicerMultiVolumeExplorerModuleWidget(qSlicerMultiVolumeExplorerSimplifiedModuleWidget):

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

  def setupAdditionalFrames(self):
    self.setupPlotSettingsFrame()

  def setupInputFrame(self, parent=None):
    self.inputFrame = ctk.ctkCollapsibleButton()
    self.inputFrame.text = "Input"
    self.inputFrame.collapsed = 0
    inputFrameCollapsibleLayout = QFormLayout(self.inputFrame)
    qSlicerMultiVolumeExplorerSimplifiedModuleWidget.setupInputFrame(self, parent=inputFrameCollapsibleLayout)
    self.layout.addWidget(self.inputFrame)

    self.fgMultiVolumeSelector = slicer.qMRMLNodeComboBox()
    self.fgMultiVolumeSelector.nodeTypes = ['vtkMRMLMultiVolumeNode']
    self.fgMultiVolumeSelector.setMRMLScene(slicer.mrmlScene)
    self.fgMultiVolumeSelector.addEnabled = 0
    self.fgMultiVolumeSelector.noneEnabled = 1
    self.fgMultiVolumeSelector.toolTip = "Secondary multivolume will be used for the secondary \
      plot in interactive charting. As an example, this can be used to overlay the \
      curve obtained by fitting a model to the data"
    self.inputFrameLayout.addRow(QLabel('Input secondary multivolume'), self.fgMultiVolumeSelector)

  def setupFrameControlFrame(self):
    qSlicerMultiVolumeExplorerSimplifiedModuleWidget.setupFrameControlFrame(self)

    self.frameCopySelector = slicer.qMRMLNodeComboBox()
    self.frameCopySelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
    self.frameCopySelector.setMRMLScene(slicer.mrmlScene)
    self.frameCopySelector.addEnabled = 1
    self.frameCopySelector.enabled = 0
    # do not show "children" of vtkMRMLScalarVolumeNode
    self.frameCopySelector.hideChildNodeTypes = ["vtkMRMLDiffusionWeightedVolumeNode",
                                                  "vtkMRMLDiffusionTensorVolumeNode",
                                                  "vtkMRMLVectorVolumeNode"]
    self.extractFrameCopy = False
    self.extractFrameCheckBox = QCheckBox('Enable copying')
    hbox = QHBoxLayout()
    hbox.addWidget(QLabel('Current frame copy'))
    hbox.addWidget(self.frameCopySelector)
    hbox.addWidget(self.extractFrameCheckBox)
    self.inputFrameLayout.addRow(hbox)

  def setupPlotSettingsFrame(self):
    self.plotSettingsFrame = ctk.ctkCollapsibleButton()
    self.plotSettingsFrame.text = "Plotting Settings"
    self.plotSettingsFrame.collapsed = 1
    plotSettingsFrameLayout = QFormLayout(self.plotSettingsFrame)
    self.layout.addWidget(self.plotSettingsFrame)

    # label map for probing
    self.labelMapSelector = slicer.qMRMLNodeComboBox()
    self.labelMapSelector.nodeTypes = ['vtkMRMLLabelMapVolumeNode']
    self.labelMapSelector.toolTip = 'Label map to be probed'
    self.labelMapSelector.setMRMLScene(slicer.mrmlScene)
    self.labelMapSelector.addEnabled = 0
    self.chartButton = QPushButton('Chart')
    self.chartButton.setEnabled(False)

    hbox = QHBoxLayout()
    hbox.addWidget(QLabel('Probed label volume'))
    hbox.addWidget(self.labelMapSelector)
    hbox.addWidget(self.chartButton)
    plotSettingsFrameLayout.addRow(hbox)

    self.iCharting = QCheckBox('Interactive charting')
    self.iCharting.setChecked(True)
    plotSettingsFrameLayout.addRow(self.iCharting)

    self.iChartingMode = QButtonGroup()
    self.iChartingIntensity = QRadioButton('Signal intensity')
    self.iChartingIntensityFixedAxes = QRadioButton('Fixed range intensity')
    self.iChartingPercent = QRadioButton('Percentage change')
    self.iChartingIntensity.setChecked(1)
    self.iChartingMode.addButton(self.iChartingIntensity)
    self.iChartingMode.addButton(self.iChartingIntensityFixedAxes)
    self.iChartingMode.addButton(self.iChartingPercent)

    hbox = QHBoxLayout()
    self.plottingModeGroupBox = QGroupBox('Plotting mode:')
    plottingModeLayout = QVBoxLayout()
    self.plottingModeGroupBox.setLayout(plottingModeLayout)
    plottingModeLayout.addWidget(self.iChartingIntensity)
    plottingModeLayout.addWidget(self.iChartingIntensityFixedAxes)
    plottingModeLayout.addWidget(self.iChartingPercent)
    hbox.addWidget(self.plottingModeGroupBox)

    self.showLegendCheckBox = QCheckBox('Display legend')
    self.showLegendCheckBox.setChecked(0)
    self.xLogScaleCheckBox = QCheckBox('Use log scale for X axis')
    self.xLogScaleCheckBox.setChecked(0)
    self.yLogScaleCheckBox = QCheckBox('Use log scale for Y axis')
    self.yLogScaleCheckBox.setChecked(0)

    self.plotGeneralSettingsGroupBox = QGroupBox('General Plot options:')
    plotGeneralSettingsLayout = QVBoxLayout()
    self.plotGeneralSettingsGroupBox.setLayout(plotGeneralSettingsLayout)
    plotGeneralSettingsLayout.addWidget(self.showLegendCheckBox)
    plotGeneralSettingsLayout.addWidget(self.xLogScaleCheckBox)
    plotGeneralSettingsLayout.addWidget(self.yLogScaleCheckBox)
    hbox.addWidget(self.plotGeneralSettingsGroupBox)
    plotSettingsFrameLayout.addRow(hbox)

    self.nFramesBaselineCalculation = QSpinBox()
    self.nFramesBaselineCalculation.minimum = 1
    hbox = QHBoxLayout()
    hbox.addWidget(QLabel('Frame count(baseline calculation):'))
    hbox.addWidget(self.nFramesBaselineCalculation)
    plotSettingsFrameLayout.addRow(hbox)

  def setupPlottingFrame(self, parent=None):
    self.plotFrame = ctk.ctkCollapsibleButton()
    self.plotFrame.text = "Plotting"
    self.plotFrame.collapsed = 0
    plotFrameLayout = QGridLayout(self.plotFrame)
    self.layout.addWidget(self.plotFrame)
    qSlicerMultiVolumeExplorerSimplifiedModuleWidget.setupPlottingFrame(self, parent=plotFrameLayout)

  def onDockChartViewToggled(self, checked):
    qSlicerMultiVolumeExplorerSimplifiedModuleWidget.onDockChartViewToggled(self, checked)
    if checked:
      self.layout.removeWidget(self.plotFrame)
      self.plotFrame.hide()

  def dockChartView(self):
    qSlicerMultiVolumeExplorerSimplifiedModuleWidget.dockChartView(self)
    self.layout.addWidget(self.plotFrame)
    self.plotFrame.show()

  def setFramesEnabled(self, enabled):
    qSlicerMultiVolumeExplorerSimplifiedModuleWidget.setFramesEnabled(self, enabled)
    self.plotSettingsFrame.setEnabled(enabled)
    self.plotFrame.setEnabled(enabled)
    self.plotFrame.collapsed = 0 if enabled else 1

  def setupConnections(self):
    qSlicerMultiVolumeExplorerSimplifiedModuleWidget.setupConnections(self)
    self.labelMapSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onLabelNodeChanged)
    self.chartButton.connect('clicked()', self.onLabeledChartRequested)
    self.xLogScaleCheckBox.connect('stateChanged(int)', self.onXLogScaleRequested)
    self.yLogScaleCheckBox.connect('stateChanged(int)', self.onYLogScaleRequested)
    self.nFramesBaselineCalculation.valueChanged.connect(self.onFrameCountBaselineCalculationChanged)
    self.iChartingMode.buttonClicked.connect(self.onChartingModeChanged)
    self.showLegendCheckBox.connect('stateChanged(int)', self.onShowLegendChanged)
    self.fgMultiVolumeSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onForegroundInputChanged)
    self.extractFrameCheckBox.connect('stateChanged(int)', self.onExtractFrameChanged)
    self.frameCopySelector.connect('mrmlSceneChanged(vtkMRMLScene*)', self.onVFMRMLSceneChanged)

  def onFrameCountBaselineCalculationChanged(self, value):
    self._multiVolumeIntensityChart.nFramesForBaselineCalculation = value

  def onChartingModeChanged(self, button):
    if button is self.iChartingIntensity:
      self._multiVolumeIntensityChart.activateSignalIntensityMode()
    elif button is self.iChartingIntensityFixedAxes:
      self._multiVolumeIntensityChart.activateFixedRangeIntensityMode()
    elif button is self.iChartingPercent:
      self._multiVolumeIntensityChart.activatePercentageChangeMode()

  def onShowLegendChanged(self, checked):
    self._multiVolumeIntensityChart.showLegend = True if checked == 2 else False

  def onXLogScaleRequested(self, checked):
    self._multiVolumeIntensityChart.showXLogScale = True if checked == 2 else False

  def onYLogScaleRequested(self, checked):
    self._multiVolumeIntensityChart.showYLogScale = True if checked == 2 else False

  def onLVMRMLSceneChanged(self, mrmlScene):
    self.labelMapSelector.setMRMLScene(slicer.mrmlScene)

  def onVFMRMLSceneChanged(self, mrmlScene):
    self.frameCopySelector.setMRMLScene(slicer.mrmlScene)

  def onLabelNodeChanged(self):
    labelNode = self.labelMapSelector.currentNode()
    self.chartButton.setEnabled(labelNode is not None and self._bgMultiVolumeNode is not None)

  def onForegroundInputChanged(self):
    logging.info("qSlicerMultiVolumeExplorerModuleWidget:ForegroundInputChanged")
    self._fgMultiVolumeNode = self.fgMultiVolumeSelector.currentNode()
    self._multiVolumeIntensityChart.fgMultiVolumeNode = self.fgMultiVolumeSelector.currentNode()
    self.refreshGUIForNewBackgroundImage()

  def onBackgroundInputChanged(self):
    qSlicerMultiVolumeExplorerSimplifiedModuleWidget.onBackgroundInputChanged(self)

    if self._bgMultiVolumeNode is not None:
      self.frameCopySelector.setCurrentNode(None)
      self.nFramesBaselineCalculation.maximum = self._bgMultiVolumeNode.GetNumberOfFrames()
    self.onLabelNodeChanged()

  '''
  If extract button is checked, will copy the current frame to the
  selected volume node on each event from frame slider
  '''
  def onExtractFrameChanged(self, checked):
    if checked:
      self.extractFrameCopy = True
      self.onSliderChanged(self.frameSlider.value)
    else:
      self.extractFrameCopy = False

  def onSliderChanged(self, frameId):
    qSlicerMultiVolumeExplorerSimplifiedModuleWidget.onSliderChanged(self, frameId)
    frameId = int(frameId)
    if self.extractFrameCopy:
      frameVolume = self.frameCopySelector.currentNode()
      frameVolumeCopy = Helper.extractFrame(frameVolume, self._bgMultiVolumeNode, frameId)
      if not frameVolume:
        self.frameCopySelector.setCurrentNode(frameVolumeCopy)
      frameName = '%s frame %d' % (self._bgMultiVolumeNode.GetName(), frameId)
      frameVolumeCopy.SetName(frameName)

  def onLabeledChartRequested(self):
    labelNode = self.labelMapSelector.currentNode()
    mvNode = self._bgMultiVolumeNode

    mvLabels = MultiVolumeIntensityChartView.getMultiVolumeLabels(self._bgMultiVolumeNode)

    chartViewNode = LabeledImageChartView(labelNode=labelNode,
                                           multiVolumeNode=mvNode,
                                           multiVolumeLabels=mvLabels,
                                           baselineFrames=self.nFramesBaselineCalculation,
                                           displayPercentageChange=self.iChartingPercent.checked)
    chartViewNode.requestChartCreation()

  def processEvent(self, observee, event):
    if not self.iCharting.checked:
      return
    qSlicerMultiVolumeExplorerSimplifiedModuleWidget.processEvent(self, observee, event)
    def setupPanel(self, parentWidget):
        logging.debug('ProstateTRUSNavUltrasound.setupPanel')

        self.connectorNode = self.guideletParent.connectorNode
        self.connectorNodeConnected = False

        collapsibleButton = ctkCollapsibleButton()
        collapsibleButton.setProperty('collapsedHeight', 20)
        setButtonStyle(collapsibleButton, 2.0)
        collapsibleButton.text = "Ultrasound"
        parentWidget.addWidget(collapsibleButton)

        ultrasoundLayout = QFormLayout(collapsibleButton)
        ultrasoundLayout.setContentsMargins(12, 4, 4, 4)
        ultrasoundLayout.setSpacing(4)

        self.connectDisconnectButton = QPushButton("Connect")
        self.connectDisconnectButton.setToolTip(
            "If clicked, connection OpenIGTLink")

        hbox = QHBoxLayout()
        hbox.addWidget(self.connectDisconnectButton)
        ultrasoundLayout.addRow(hbox)

        self.setupIcons()

        self.captureIDSelector = QComboBox()
        self.captureIDSelector.setToolTip("Pick capture device ID")
        self.captureIDSelector.setSizePolicy(QSizePolicy.Expanding,
                                             QSizePolicy.Expanding)

        self.volumeReconstructorIDSelector = QComboBox()
        self.volumeReconstructorIDSelector.setToolTip(
            "Pick volume reconstructor device ID")
        self.volumeReconstructorIDSelector.setSizePolicy(
            QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.startStopRecordingButton = QPushButton("  Start Recording")
        self.startStopRecordingButton.setCheckable(True)
        self.startStopRecordingButton.setIcon(self.recordIcon)
        self.startStopRecordingButton.setEnabled(False)
        self.startStopRecordingButton.setToolTip("If clicked, start recording")
        self.startStopRecordingButton.setSizePolicy(QSizePolicy.Expanding,
                                                    QSizePolicy.Expanding)

        recordParametersControlsLayout = QGridLayout()

        self.filenameLabel = self.createLabel("Filename:", visible=False)
        recordParametersControlsLayout.addWidget(self.filenameLabel, 1, 0)

        # Offline Reconstruction
        self.offlineReconstructButton = QPushButton("  Offline Reconstruction")
        self.offlineReconstructButton.setCheckable(True)
        self.offlineReconstructButton.setIcon(self.recordIcon)
        self.offlineReconstructButton.setEnabled(False)
        self.offlineReconstructButton.setToolTip(
            "If clicked, reconstruct recorded volume")
        self.offlineReconstructButton.setSizePolicy(QSizePolicy.Expanding,
                                                    QSizePolicy.Expanding)

        self.offlineVolumeToReconstructSelector = QComboBox()
        self.offlineVolumeToReconstructSelector.setEditable(True)
        self.offlineVolumeToReconstructSelector.setToolTip(
            "Pick/set volume to reconstruct")
        self.offlineVolumeToReconstructSelector.visible = False

        hbox = QHBoxLayout()
        hbox.addWidget(self.startStopRecordingButton)
        hbox.addWidget(self.offlineReconstructButton)
        ultrasoundLayout.addRow(hbox)

        # Scout scan (record and low resolution reconstruction) and live reconstruction
        # Scout scan part

        self.startStopScoutScanButton = QPushButton(
            "  Scout scan\n  Start recording")
        self.startStopScoutScanButton.setCheckable(True)
        self.startStopScoutScanButton.setIcon(self.recordIcon)
        self.startStopScoutScanButton.setToolTip("If clicked, start recording")
        self.startStopScoutScanButton.setEnabled(False)
        self.startStopScoutScanButton.setSizePolicy(QSizePolicy.Expanding,
                                                    QSizePolicy.Expanding)

        self.startStopLiveReconstructionButton = QPushButton(
            "  Start live reconstruction")
        self.startStopLiveReconstructionButton.setCheckable(True)
        self.startStopLiveReconstructionButton.setIcon(self.recordIcon)
        self.startStopLiveReconstructionButton.setToolTip(
            "If clicked, start live reconstruction")
        self.startStopLiveReconstructionButton.setEnabled(False)
        self.startStopLiveReconstructionButton.setSizePolicy(
            QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.displayRoiButton = QToolButton()
        self.displayRoiButton.setCheckable(True)
        self.displayRoiButton.setIcon(self.visibleOffIcon)
        self.displayRoiButton.setToolTip("If clicked, display ROI")

        hbox = QHBoxLayout()
        hbox.addWidget(self.startStopScoutScanButton)
        hbox.addWidget(self.startStopLiveReconstructionButton)
        # hbox.addWidget(self.displayRoiButton)
        ultrasoundLayout.addRow(hbox)

        self.snapshotTimer = QTimer()
        self.snapshotTimer.setSingleShot(True)

        self.onParameterSetSelected()

        return collapsibleButton
예제 #35
0
class SelectorElementosEstudio(QWidget):
    """Clase padre de los selectores. Los selectores permiten elegir una 
    o más variables, o una variable y un valor de esa variable, etc
    Las clases hijas deben suministrar cajadisponible,addelemento
    SelectorElementosEstudios tiene siempre una caja donde aparecen los resultados a la derecha, y provee los botones de adicion y sustracción de elementos
    """
    def __init__(self, interfazdato, cajadisponible):
        """Caja disponible son los elementos que aparecen a la izquierda en el selector"""
        #VARIABLES PUBLICAS
        QWidget.__init__(self, None, "selector", 0)

        image1 = QPixmap(IMAGE1DATA)
        image2 = QPixmap(IMAGE2DATA)

        selectorsimplelayout = QHBoxLayout(self, 11, 6, "WSelectorSimpleLayout")
        layout2 = QVBoxLayout(None, 0, 6, "layout2")
        widgetstack1 = QWidgetStack(self, "staaack")
        widgetstack1.addWidget(cajadisponible)
        widgetstack1.raiseWidget(cajadisponible)
        widgetstack1.setSizePolicy(QSizePolicy(\
                QSizePolicy.Expanding, QSizePolicy.Expanding, \
                0, 0, widgetstack1.sizePolicy().hasHeightForWidth()))
        self._cajadisponible = cajadisponible
        layout2.addWidget(widgetstack1)
        selectorsimplelayout.addLayout(layout2)
        
        layout1 = QVBoxLayout(None, 0, 6, "layout1")
        
        self.__pushbutton1 = QPushButton(self, "pushButton1")
        self.__pushbutton1.setMaximumSize(QSize(30, 30))
        self.__pushbutton1.setPixmap(image1)
        layout1.addWidget(self.__pushbutton1)
        spacer1 = QSpacerItem(30, 122, QSizePolicy.Minimum, QSizePolicy.Expanding)
        layout1.addItem(spacer1)
        
        self.__pushbutton2 = QPushButton(self,"pushButton2")
        self.__pushbutton2.setMaximumSize(QSize(30, 30))
        self.__pushbutton2.setPixmap(image2)
        self.__pushbutton2.setAccel("Del")
        layout1.addWidget(self.__pushbutton2)
        selectorsimplelayout.addLayout(layout1)
        
        layout3 = QVBoxLayout(None, 0, 6, "layout3")
        
        self._textlabel2 = QLabel(self, "textLabel2")
        layout3.addWidget(self._textlabel2)
        
        self._cajaseleccion = QListBox(self,"cajaseleccion")
        self._cajaseleccion.setMinimumSize(QSize(0, 60))
        layout3.addWidget(self._cajaseleccion)
        selectorsimplelayout.addLayout(layout3)
        self._cajaseleccion.setSizePolicy(QSizePolicy(\
                QSizePolicy.Expanding,QSizePolicy.Expanding, 0, 0, \
                self._cajaseleccion.sizePolicy().hasHeightForWidth()))
        
        self.setCaption("Form1")
        self._textlabel2.setText(u"Selección")
        
        self.resize(QSize(294, 240).expandedTo(self.minimumSizeHint()))
        self.clearWState(Qt.WState_Polished)
        self.__conexiones()
        #Miembros !qt

        self.seleccion = []
        self._dato = interfazdato

    def showEvent(self, event):
        """Redefinicion showEvent"""
        self._actualizar_cajas()
        QWidget.showEvent(self, event)

    def _actualizar_cajas(self):
        """Actualiza el contenido de las cajas"""
        self._cajaseleccion.clear()
        for valor in self.seleccion:
            self._cajaseleccion.insertItem(str(valor))
        self._actualizar_caja_disponible()


    def __conexiones(self):
        """Establece las conexiones entre elementos"""
        self.connect(self.__pushbutton1, SIGNAL("clicked()"), self._anadir_elemento)
        self.connect(self.__pushbutton2, SIGNAL("clicked()"), self.__borrar_elemento)


    def __borrar_elemento(self):
        """Borra el elemento seleccionado en lacaja de seleccion"""
        if self._cajaseleccion.currentText():
            del self.seleccion[self._cajaseleccion.currentItem()]
            self._actualizar_cajas()
    def setupPlotSettingsFrame(self):
        self.plotSettingsFrame = ctk.ctkCollapsibleButton()
        self.plotSettingsFrame.text = "Plotting Settings"
        self.plotSettingsFrame.collapsed = 1
        plotSettingsFrameLayout = QFormLayout(self.plotSettingsFrame)
        self.layout.addWidget(self.plotSettingsFrame)

        # label map for probing
        self.labelMapSelector = slicer.qMRMLNodeComboBox()
        self.labelMapSelector.nodeTypes = ['vtkMRMLLabelMapVolumeNode']
        self.labelMapSelector.toolTip = 'Label map to be probed'
        self.labelMapSelector.setMRMLScene(slicer.mrmlScene)
        self.labelMapSelector.addEnabled = 0
        self.chartButton = QPushButton('Chart')
        self.chartButton.setEnabled(False)

        hbox = QHBoxLayout()
        hbox.addWidget(QLabel('Probed label volume'))
        hbox.addWidget(self.labelMapSelector)
        hbox.addWidget(self.chartButton)
        plotSettingsFrameLayout.addRow(hbox)

        self.iCharting = QCheckBox('Interactive charting')
        self.iCharting.setChecked(True)
        plotSettingsFrameLayout.addRow(self.iCharting)

        self.iChartingMode = QButtonGroup()
        self.iChartingIntensity = QRadioButton('Signal intensity')
        self.iChartingIntensityFixedAxes = QRadioButton(
            'Fixed range intensity')
        self.iChartingPercent = QRadioButton('Percentage change')
        self.iChartingIntensity.setChecked(1)
        self.iChartingMode.addButton(self.iChartingIntensity)
        self.iChartingMode.addButton(self.iChartingIntensityFixedAxes)
        self.iChartingMode.addButton(self.iChartingPercent)

        hbox = QHBoxLayout()
        self.plottingModeGroupBox = QGroupBox('Plotting mode:')
        plottingModeLayout = QVBoxLayout()
        self.plottingModeGroupBox.setLayout(plottingModeLayout)
        plottingModeLayout.addWidget(self.iChartingIntensity)
        plottingModeLayout.addWidget(self.iChartingIntensityFixedAxes)
        plottingModeLayout.addWidget(self.iChartingPercent)
        hbox.addWidget(self.plottingModeGroupBox)

        self.showLegendCheckBox = QCheckBox('Display legend')
        self.showLegendCheckBox.setChecked(0)
        self.xLogScaleCheckBox = QCheckBox('Use log scale for X axis')
        self.xLogScaleCheckBox.setChecked(0)
        self.yLogScaleCheckBox = QCheckBox('Use log scale for Y axis')
        self.yLogScaleCheckBox.setChecked(0)

        self.plotGeneralSettingsGroupBox = QGroupBox('General Plot options:')
        plotGeneralSettingsLayout = QVBoxLayout()
        self.plotGeneralSettingsGroupBox.setLayout(plotGeneralSettingsLayout)
        plotGeneralSettingsLayout.addWidget(self.showLegendCheckBox)
        plotGeneralSettingsLayout.addWidget(self.xLogScaleCheckBox)
        plotGeneralSettingsLayout.addWidget(self.yLogScaleCheckBox)
        hbox.addWidget(self.plotGeneralSettingsGroupBox)
        plotSettingsFrameLayout.addRow(hbox)

        self.nFramesBaselineCalculation = QSpinBox()
        self.nFramesBaselineCalculation.minimum = 1
        hbox = QHBoxLayout()
        hbox.addWidget(QLabel('Frame count(baseline calculation):'))
        hbox.addWidget(self.nFramesBaselineCalculation)
        plotSettingsFrameLayout.addRow(hbox)
class ProstateTRUSNavWidget(GuideletWidget):

  DEFAULT_PLUSSERVER_CHOOSER_TEXT = "Choose PlusServer.exe"
  DEFAULT_CONFIGURATION_CHOOSER_TEXT = "Select Configuration"

  def __init__(self, parent = None):
    GuideletWidget.__init__(self, parent)
    self.plusServerProcess = None
    self.configurationFile = self.getSetting('ConfigurationFile', self.DEFAULT_CONFIGURATION_CHOOSER_TEXT)
    self.serverExecutable = self.getSetting('PlusServer', self.DEFAULT_PLUSSERVER_CHOOSER_TEXT)

  def cleanup(self):
    GuideletWidget.cleanup(self)
    if self.plusServerProcess:
      self.plusServerProcess.terminate()

  def setup(self):
    showPlusServerWidget = True
    if _platform == "linux" or _platform == "linux2" or _platform == "darwin": #linux or linux or OS X
      message = "Attention: You are running Slicer on Linux or OS X. Do you have PlusServer installed on the current OS?"
      result = QMessageBox.question(slicer.util.mainWindow(), 'ProstateTRUSNav', message,
                                     QMessageBox.Yes | QMessageBox.No)
      showPlusServerWidget = result == QMessageBox.Yes

    if _platform == "win32" or showPlusServerWidget:
      # Windows...
      plusServerCollapsibleButton = ctkCollapsibleButton()
      plusServerCollapsibleButton.text = "PlusServer"
      self.layout.addWidget(plusServerCollapsibleButton)
      self.configurationFileChooserButton = QPushButton(self.configurationFile)
      self.configurationFileChooserButton.connect('clicked()', self.onConfigFileSelected)
      self.runPlusServerButton = QPushButton("Run PlusServer")
      self.runPlusServerButton.setCheckable(True)
      self.runPlusServerButton.connect('clicked()', self.onRunPlusServerButtonClicked)

      self.serverFormLayout = QFormLayout(plusServerCollapsibleButton)

      self.serverExecutableChooserButton = QPushButton(self.serverExecutable)
      self.serverExecutableChooserButton.connect('clicked()', self.onServerExecutableSelected)

      hbox = QHBoxLayout()
      hbox.addWidget(self.serverExecutableChooserButton)
      self.serverFormLayout.addRow(hbox)

      hbox = QHBoxLayout()
      hbox.addWidget(self.configurationFileChooserButton)
      hbox.addWidget(self.runPlusServerButton)
      self.serverFormLayout.addRow(hbox)

    GuideletWidget.setup(self)

    # do specific setup here
    if _platform == "win32" or showPlusServerWidget:
      self.launchGuideletButton.setEnabled(False)
      self.checkExecutableAndArgument()

  def checkExecutableAndArgument(self):
    if os.path.exists(self.serverExecutable) and os.path.exists(self.configurationFile):
      self.runPlusServerButton.setEnabled(True)
    else:
      self.runPlusServerButton.setEnabled(False)

  def getSetting(self, settingName, defaultValue=""):
    settings = QSettings()
    value = settings.value(self.moduleName + '/' + settingName, defaultValue)
    return value if value is not None and value != "" else defaultValue

  def setSetting(self, settingName, value):
    settings = QSettings()
    settings.setValue(self.moduleName + '/'+ settingName, value)

  def addLauncherWidgets(self):
    GuideletWidget.addLauncherWidgets(self)
    # add launcher widget here

  def onServerExecutableSelected(self):
    executable = QFileDialog.getOpenFileName(self.parent, "PlusServer Executable",
                                                self.serverExecutable, "*.exe")
    if executable != "" and executable.find("PlusServer.exe"):
      self.serverExecutable = executable
      self.serverExecutableChooserButton.setText(executable)
      self.setSetting("PlusServer", executable)
    self.checkExecutableAndArgument()

  def onConfigFileSelected(self):
    self.configurationFile = QFileDialog.getOpenFileName(self.parent, "Choose Configuration File",
                                                            self.configurationFile, "*.xml")
    if self.configurationFile != "":
      self.configurationFileChooserButton.setText(os.path.split(self.configurationFile)[1])
      self.setSetting("ConfigurationFile", self.configurationFile)
    self.checkExecutableAndArgument()

  def onRunPlusServerButtonClicked(self):
    if self.runPlusServerButton.isChecked():
      command = [self.serverExecutable, "--config-file="+self.configurationFile]
      logging.info("Executing %s %s" % tuple(command))
      self.plusServerProcess = Popen([self.serverExecutable, "--config-file="+self.configurationFile])
      if self.plusServerProcess:
        self.runPlusServerButton.setText("Quit Plus Server")
        self.launchGuideletButton.setEnabled(True)
    else:
      if self.plusServerProcess:
        self.plusServerProcess.terminate()
        self.runPlusServerButton.setText("Run PlusServer")
        self.launchGuideletButton.setEnabled(False)

  def collectParameterList(self):
    parameterList = GuideletWidget.collectParameterList(self)
    if not parameterList:
      parameterList = dict()
    parameterList['OfflineVolumeToReconstruct'] = 0,
    return parameterList

  def createGuideletInstance(self, parameterList = None):
    return ProstateTRUSNavGuidelet(None, self.guideletLogic,  parameterList)

  def createGuideletLogic(self):
    return ProstateTRUSNavLogic()
class ProstateTRUSNavUltrasound(UltraSound):

    OFFLINE_VOLUME_FILENAME = "RecVol_Reference.mha"
    SCOUT_VOLUME_FILENAME = "ScoutScan.mha"
    LIVE_VOLUME_FILENAME = "LiveReconstructedVolume.mha"

    RECORDING_FILENAME = "Recording.mha"
    SCOUT_RECORDING_FILENAME = "ScoutScanRecording.mha"
    LIVE_RECORDING_FILENAME = LIVE_VOLUME_FILENAME

    SCOUT_VOLUME_NODE_NAME = "ScoutScan"
    OFFLINE_VOLUME_NODE_NAME = "RecVol_Reference"
    LIVE_VOLUME_NODE_NAME = "liveReconstruction"

    APPLY_HOLE_FILLING_FOR_SNAPSHOT = False
    SNAPSHOT_INTERVAL = 3
    OUTPUT_VOLUME_SPACING = 3
    LIVE_OUTPUT_VOLUME_SPACING = 1

    @property
    def roiNode(self):
        return self._roiNode

    @roiNode.setter
    def roiNode(self, node):
        self._roiNode = node
        if node is not None:
            self.startStopLiveReconstructionButton.setEnabled(True)
        else:
            self.startStopLiveReconstructionButton.setEnabled(False)

    def __init__(self, guideletParent):
        UltraSound.__init__(self, guideletParent)

        self.parameterNode = guideletParent.parameterNode
        self.parameterNodeObserver = None
        self._roiNode = None
        self.liveOutputSpacingValue = [
            self.LIVE_OUTPUT_VOLUME_SPACING, self.LIVE_OUTPUT_VOLUME_SPACING,
            self.LIVE_OUTPUT_VOLUME_SPACING
        ]
        self.outputSpacing = [
            self.OUTPUT_VOLUME_SPACING, self.OUTPUT_VOLUME_SPACING,
            self.OUTPUT_VOLUME_SPACING
        ]
        self.roiOrigin = None
        self.roiExtent = None
        self.defaultParameterNode = None
        self.logic = ProstateTRUSNavUltrasoundLogic()

    def setupPanel(self, parentWidget):
        logging.debug('ProstateTRUSNavUltrasound.setupPanel')

        self.connectorNode = self.guideletParent.connectorNode
        self.connectorNodeConnected = False

        collapsibleButton = ctkCollapsibleButton()
        collapsibleButton.setProperty('collapsedHeight', 20)
        setButtonStyle(collapsibleButton, 2.0)
        collapsibleButton.text = "Ultrasound"
        parentWidget.addWidget(collapsibleButton)

        ultrasoundLayout = QFormLayout(collapsibleButton)
        ultrasoundLayout.setContentsMargins(12, 4, 4, 4)
        ultrasoundLayout.setSpacing(4)

        self.connectDisconnectButton = QPushButton("Connect")
        self.connectDisconnectButton.setToolTip(
            "If clicked, connection OpenIGTLink")

        hbox = QHBoxLayout()
        hbox.addWidget(self.connectDisconnectButton)
        ultrasoundLayout.addRow(hbox)

        self.setupIcons()

        self.captureIDSelector = QComboBox()
        self.captureIDSelector.setToolTip("Pick capture device ID")
        self.captureIDSelector.setSizePolicy(QSizePolicy.Expanding,
                                             QSizePolicy.Expanding)

        self.volumeReconstructorIDSelector = QComboBox()
        self.volumeReconstructorIDSelector.setToolTip(
            "Pick volume reconstructor device ID")
        self.volumeReconstructorIDSelector.setSizePolicy(
            QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.startStopRecordingButton = QPushButton("  Start Recording")
        self.startStopRecordingButton.setCheckable(True)
        self.startStopRecordingButton.setIcon(self.recordIcon)
        self.startStopRecordingButton.setEnabled(False)
        self.startStopRecordingButton.setToolTip("If clicked, start recording")
        self.startStopRecordingButton.setSizePolicy(QSizePolicy.Expanding,
                                                    QSizePolicy.Expanding)

        recordParametersControlsLayout = QGridLayout()

        self.filenameLabel = self.createLabel("Filename:", visible=False)
        recordParametersControlsLayout.addWidget(self.filenameLabel, 1, 0)

        # Offline Reconstruction
        self.offlineReconstructButton = QPushButton("  Offline Reconstruction")
        self.offlineReconstructButton.setCheckable(True)
        self.offlineReconstructButton.setIcon(self.recordIcon)
        self.offlineReconstructButton.setEnabled(False)
        self.offlineReconstructButton.setToolTip(
            "If clicked, reconstruct recorded volume")
        self.offlineReconstructButton.setSizePolicy(QSizePolicy.Expanding,
                                                    QSizePolicy.Expanding)

        self.offlineVolumeToReconstructSelector = QComboBox()
        self.offlineVolumeToReconstructSelector.setEditable(True)
        self.offlineVolumeToReconstructSelector.setToolTip(
            "Pick/set volume to reconstruct")
        self.offlineVolumeToReconstructSelector.visible = False

        hbox = QHBoxLayout()
        hbox.addWidget(self.startStopRecordingButton)
        hbox.addWidget(self.offlineReconstructButton)
        ultrasoundLayout.addRow(hbox)

        # Scout scan (record and low resolution reconstruction) and live reconstruction
        # Scout scan part

        self.startStopScoutScanButton = QPushButton(
            "  Scout scan\n  Start recording")
        self.startStopScoutScanButton.setCheckable(True)
        self.startStopScoutScanButton.setIcon(self.recordIcon)
        self.startStopScoutScanButton.setToolTip("If clicked, start recording")
        self.startStopScoutScanButton.setEnabled(False)
        self.startStopScoutScanButton.setSizePolicy(QSizePolicy.Expanding,
                                                    QSizePolicy.Expanding)

        self.startStopLiveReconstructionButton = QPushButton(
            "  Start live reconstruction")
        self.startStopLiveReconstructionButton.setCheckable(True)
        self.startStopLiveReconstructionButton.setIcon(self.recordIcon)
        self.startStopLiveReconstructionButton.setToolTip(
            "If clicked, start live reconstruction")
        self.startStopLiveReconstructionButton.setEnabled(False)
        self.startStopLiveReconstructionButton.setSizePolicy(
            QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.displayRoiButton = QToolButton()
        self.displayRoiButton.setCheckable(True)
        self.displayRoiButton.setIcon(self.visibleOffIcon)
        self.displayRoiButton.setToolTip("If clicked, display ROI")

        hbox = QHBoxLayout()
        hbox.addWidget(self.startStopScoutScanButton)
        hbox.addWidget(self.startStopLiveReconstructionButton)
        # hbox.addWidget(self.displayRoiButton)
        ultrasoundLayout.addRow(hbox)

        self.snapshotTimer = QTimer()
        self.snapshotTimer.setSingleShot(True)

        self.onParameterSetSelected()

        return collapsibleButton

    def setupResliceDriver(self):
        layoutManager = slicer.app.layoutManager()
        # Show ultrasound in red view.
        redSlice = layoutManager.sliceWidget('Red')
        redSliceLogic = redSlice.sliceLogic()
        redSliceLogic.GetSliceCompositeNode().SetBackgroundVolumeID(
            self.liveUltrasoundNode_Reference.GetID())

        resliceLogic = slicer.modules.volumereslicedriver.logic()
        if resliceLogic:
            redNode = slicer.util.getNode('vtkMRMLSliceNodeRed')
            redNode.SetSliceResolutionMode(
                slicer.vtkMRMLSliceNode.SliceResolutionMatchVolumes)
            resliceLogic.SetDriverForSlice(
                self.liveUltrasoundNode_Reference.GetID(), redNode)
            resliceLogic.SetModeForSlice(
                6, redNode)  # Transverse mode, default for PLUS ultrasound.
        else:
            logging.warning('Logic not found for Volume Reslice Driver')

    def createCollapsibleButton(self, text, collapsed=False):
        collapsibleButton = ctkCollapsibleButton()
        collapsibleButton.text = text
        collapsibleButton.collapsed = collapsed
        return collapsibleButton

    def createLabel(self, text, visible=True):
        label = QLabel()
        label.setText(text)
        label.visible = visible
        return label

    def setupConnections(self):
        self.startStopRecordingButton.connect(
            'clicked(bool)', self.onStartStopRecordingButtonClicked)
        self.offlineReconstructButton.connect('clicked(bool)',
                                              self.onReconstVolume)
        self.startStopScoutScanButton.connect(
            'clicked(bool)', self.onStartStopScoutScanButtonClicked)
        self.startStopLiveReconstructionButton.connect(
            'clicked(bool)', self.onStartStopLiveReconstructionButtonClicked)
        self.displayRoiButton.connect('clicked(bool)',
                                      self.onDisplayRoiButtonClicked)
        self.captureIDSelector.connect('currentIndexChanged(QString)',
                                       self.updateParameterNodeFromGui)
        self.volumeReconstructorIDSelector.connect(
            'currentIndexChanged(QString)', self.updateParameterNodeFromGui)
        self.offlineVolumeToReconstructSelector.connect(
            'currentIndexChanged(int)', self.updateParameterNodeFromGui)
        self.displayRoiButton.connect('clicked(bool)',
                                      self.updateParameterNodeFromGui)
        self.snapshotTimer.timeout.connect(
            self.onRequestVolumeReconstructionSnapshot)
        self.connectDisconnectButton.connect(
            'clicked(bool)', self.onConnectDisconnectButtonClicked)

    def disconnect(self):
        self.startStopRecordingButton.disconnect(
            'clicked(bool)', self.onStartStopRecordingButtonClicked)
        self.offlineReconstructButton.disconnect('clicked(bool)',
                                                 self.onReconstVolume)
        self.startStopScoutScanButton.disconnect(
            'clicked(bool)', self.onStartStopScoutScanButtonClicked)
        self.startStopLiveReconstructionButton.disconnect(
            'clicked(bool)', self.onStartStopLiveReconstructionButtonClicked)
        self.displayRoiButton.disconnect('clicked(bool)',
                                         self.onDisplayRoiButtonClicked)
        self.captureIDSelector.disconnect('currentIndexChanged(QString)',
                                          self.updateParameterNodeFromGui)
        self.volumeReconstructorIDSelector.disconnect(
            'currentIndexChanged(QString)', self.updateParameterNodeFromGui)
        self.offlineVolumeToReconstructSelector.disconnect(
            'currentIndexChanged(int)', self.updateParameterNodeFromGui)
        self.displayRoiButton.disconnect('clicked(bool)',
                                         self.updateParameterNodeFromGui)
        self.snapshotTimer.timeout.disconnect(
            self.onRequestVolumeReconstructionSnapshot)
        self.connectDisconnectButton.disconnect(
            'clicked(bool)', self.onConnectDisconnectButtonClicked)

    def setupIcons(self):
        self.plusRemoteModuleDirectoryPath = slicer.modules.plusremote.path.replace(
            "PlusRemote.py", "")
        self.recordIcon = QIcon(self.plusRemoteModuleDirectoryPath +
                                '/Resources/Icons/icon_Record.png')
        self.stopIcon = QIcon(self.plusRemoteModuleDirectoryPath +
                              '/Resources/Icons/icon_Stop.png')
        self.waitIcon = QIcon(self.plusRemoteModuleDirectoryPath +
                              '/Resources/Icons/icon_Wait.png')
        self.visibleOffIcon = QIcon(":Icons\VisibleOff.png")
        self.visibleOnIcon = QIcon(":Icons\VisibleOn.png")

    def onParameterSetSelected(self):
        # Set up default values for new nodes
        if self.parameterNode:
            self.plusRemoteLogic.setDefaultParameters(self.parameterNode)
        self.updateGuiFromParameterNode()

    def updateGuiFromParameterNode(self):

        self.parameterVolumeList = {
            'OfflineVolumeToReconstruct':
            self.offlineVolumeToReconstructSelector
        }
        for parameter in self.parameterVolumeList:
            if self.parameterNode.GetParameter(parameter):
                self.parameterVolumeList[parameter].blockSignals(True)
            self.parameterVolumeList[parameter].blockSignals(False)

        if self.parameterNode.GetParameter('CaptureID'):
            self.captureIDSelector.blockSignals(True)
            for i in range(0, self.captureIDSelector.count):
                if self.parameterNode.GetParameter(
                        'CaptureID') == self.captureIDSelector.itemText(i):
                    self.captureIDSelector.setCurrentIndex(
                        int(self.parameterNode.GetParameter('CaptureIdIndex')))
            self.captureIDSelector.blockSignals(False)

        if self.parameterNode.GetParameter('VolumeReconstructor'):
            self.volumeReconstructorIDSelector.blockSignals(True)
            for i in range(0, self.volumeReconstructorIDSelector.count):
                if self.parameterNode.GetParameter(
                        'VolumeReconstructor'
                ) == self.volumeReconstructorIDSelector.itemText(i):
                    self.volumeReconstructorIDSelector.setCurrentIndex(
                        int(
                            self.parameterNode.GetParameter(
                                'VolumeReconstructorIndex')))
            self.volumeReconstructorIDSelector.blockSignals(False)

            self.roiNode = self.parameterNode.GetNthNodeReference('ROI', 0)

    def updateParameterNodeFromGui(self):
        #Update parameter node value to save when user change value in the interface
        if not self.parameterNode:
            return
        self.parametersList = {
            'CaptureID':
            self.captureIDSelector.currentText,
            'CaptureIdIndex':
            self.captureIDSelector.currentIndex,
            'VolumeReconstructor':
            self.volumeReconstructorIDSelector.currentText,
            'VolumeReconstructorIndex':
            self.volumeReconstructorIDSelector.currentIndex,
            'OfflineVolumeToReconstruct':
            self.offlineVolumeToReconstructSelector.currentIndex
        }
        for parameter in self.parametersList:
            self.parameterNode.SetParameter(
                parameter, str(self.parametersList[parameter]))
        if self.roiNode:
            roiNodeID = self.roiNode.GetID()
            self.parameterNode.SetNthNodeReferenceID('ROI', 0, roiNodeID)


#
# Connector observation and actions
#

    def onConnectorNodeConnected(self):
        logging.debug("ProstateTrusUltrasound:onConnectorNodeConnected")
        self.connectorNodeConnected = True
        self.captureIDSelector.setDisabled(False)
        self.volumeReconstructorIDSelector.setDisabled(False)
        self.plusRemoteLogic.getCaptureDeviceIds(
            self.connectorNode.GetID(),
            self.onGetCaptureDeviceCommandResponseReceived)
        self.plusRemoteLogic.getVolumeReconstructorDeviceIds(
            self.connectorNode.GetID(),
            self.onGetVolumeReconstructorDeviceCommandResponseReceived)
        self.connectDisconnectButton.setText("Disconnect")

    def onConnectorNodeDisconnected(self):
        logging.debug("ProstateTrusUltrasound:onConnectorNodeDisconnected")
        self.connectorNodeConnected = False
        self.startStopRecordingButton.setEnabled(False)
        self.startStopScoutScanButton.setEnabled(False)
        self.startStopLiveReconstructionButton.setEnabled(False)
        self.offlineReconstructButton.setEnabled(False)
        self.captureIDSelector.setDisabled(True)
        self.volumeReconstructorIDSelector.setDisabled(True)
        self.connectDisconnectButton.setText("Connect")

    def getLiveVolumeRecNode(self):
        liveVolumeRecNode = slicer.util.getNode(self.LIVE_VOLUME_NODE_NAME)
        return liveVolumeRecNode

    def getOfflineVolumeRecNode(self):
        offlineVolumeRecNode = slicer.util.getNode(
            self.OFFLINE_VOLUME_NODE_NAME)
        return offlineVolumeRecNode

    def getScoutVolumeNode(self):
        scoutScanVolumeNode = slicer.util.getNode(self.SCOUT_VOLUME_NODE_NAME)
        return scoutScanVolumeNode

    def onConnectDisconnectButtonClicked(self):
        if self.connectorNode.GetState(
        ) == slicer.vtkMRMLIGTLConnectorNode.STATE_CONNECTED:
            self.connectorNode.Stop()
        else:
            self.connectorNode.Start()

    def onStartStopRecordingButtonClicked(self):
        if self.startStopRecordingButton.isChecked():
            self.startStopRecordingButton.setText("  Stop Recording")
            self.startStopRecordingButton.setIcon(self.stopIcon)
            self.startStopRecordingButton.setToolTip(
                "If clicked, stop recording")
            self.onStartRecording(self.generateRecordingOutputFilename())
        else:
            self.startStopRecordingButton.setText("  Start Recording")
            self.startStopRecordingButton.setIcon(self.recordIcon)
            self.startStopRecordingButton.setToolTip(
                "If clicked, start recording")
            self.onStopRecording(self.onVolumeRecorded)

    def onStartStopScoutScanButtonClicked(self):
        if self.startStopScoutScanButton.isChecked():
            self.startStopScoutScanButton.setText(
                "  Scout Scan\n  Stop Recording and Reconstruct Recorded Volume"
            )
            self.startStopScoutScanButton.setIcon(self.stopIcon)
            self.startStopScoutScanButton.setToolTip(
                "If clicked, stop recording and reconstruct recorded volume")
            self.onStartRecording(self.generateScoutRecordingOutputFilename())
        else:
            self.onStopRecording(self.onScoutVolumeRecorded)

    def onStartStopLiveReconstructionButtonClicked(self):
        if self.startStopLiveReconstructionButton.isChecked():
            if self.roiNode:
                self.roiOrigin, self.roiExtent = self.logic.updateVolumeOriginAndExtentFromROI(
                    self.LIVE_OUTPUT_VOLUME_SPACING, self.roiNode)
            self.startStopLiveReconstructionButton.setText(
                "  Stop Live Reconstruction")
            self.startStopLiveReconstructionButton.setIcon(self.stopIcon)
            self.startStopLiveReconstructionButton.setToolTip(
                "If clicked, stop live reconstruction")
            self.onStartRecording(self.getLiveRecordingOutputFilename())
            self.onStartReconstruction()
        else:
            self.startStopLiveReconstructionButton.setText(
                "  Start Live Reconstruction")
            self.startStopLiveReconstructionButton.setIcon(self.recordIcon)
            self.startStopLiveReconstructionButton.setToolTip(
                "If clicked, start live reconstruction")
            self.onStopRecording(self.printCommandResponse)
            self.onStopReconstruction()

    def onDisplayRoiButtonClicked(self):
        if self.displayRoiButton.isChecked():
            self.displayRoiButton.setIcon(self.visibleOnIcon)
            self.displayRoiButton.setToolTip("If clicked, hide ROI")
            if self.roiNode:
                self.roiNode.SetDisplayVisibility(1)
        else:
            self.displayRoiButton.setIcon(self.visibleOffIcon)
            self.displayRoiButton.setToolTip("If clicked, display ROI")
            if self.roiNode:
                self.roiNode.SetDisplayVisibility(0)

    def generateRecordingOutputFilename(self):
        return self.plusRemoteLogic.addTimestampToFilename(
            self.RECORDING_FILENAME)

    def generateScoutRecordingOutputFilename(self):
        return self.plusRemoteLogic.addTimestampToFilename(
            self.SCOUT_RECORDING_FILENAME)

    def getLiveRecordingOutputFilename(self):
        return self.plusRemoteLogic.addTimestampToFilename(
            self.LIVE_RECORDING_FILENAME)

    def getLiveReconstructionOutputFilename(self):
        return self.plusRemoteLogic.addTimestampToFilename(
            self.LIVE_VOLUME_FILENAME)

    def onStartRecording(self, filename):
        self.plusRemoteLogic.startRecording(self.connectorNode.GetID(),
                                            self.captureIDSelector.currentText,
                                            filename,
                                            self.printCommandResponse)

    def onStopRecording(self, callback):
        self.plusRemoteLogic.stopRecording(self.connectorNode.GetID(),
                                           self.captureIDSelector.currentText,
                                           callback)

    def onStartReconstruction(self):
        if self.roiNode:
            self.roiOrigin, self.roiExtent = self.logic.updateVolumeOriginAndExtentFromROI(
                self.LIVE_OUTPUT_VOLUME_SPACING, self.roiNode)
        self.plusRemoteLogic.startVolumeReconstuction(
            self.connectorNode.GetID(),
            self.volumeReconstructorIDSelector.currentText,
            self.liveOutputSpacingValue, self.roiOrigin, self.roiExtent,
            self.printCommandResponse,
            self.getLiveReconstructionOutputFilename(),
            self.LIVE_VOLUME_NODE_NAME)
        # Set up timer for requesting snapshot
        self.snapshotTimer.start(self.SNAPSHOT_INTERVAL * 1000)

    def onStopReconstruction(self):
        self.snapshotTimer.stop()
        self.plusRemoteLogic.stopVolumeReconstruction(
            self.connectorNode.GetID(),
            self.volumeReconstructorIDSelector.currentText,
            self.onVolumeLiveReconstructed,
            self.getLiveReconstructionOutputFilename(),
            self.LIVE_VOLUME_NODE_NAME)

    def onReconstVolume(self):
        self.offlineReconstructButton.setIcon(self.waitIcon)
        self.offlineReconstructButton.setText(
            "  Offline Reconstruction in progress ...")
        self.offlineReconstructButton.setEnabled(False)
        self.plusRemoteLogic.reconstructRecorded(
            self.connectorNode.GetID(),
            self.volumeReconstructorIDSelector.currentText,
            self.offlineVolumeToReconstructSelector.currentText,
            self.outputSpacing, self.onVolumeReconstructed,
            self.OFFLINE_VOLUME_FILENAME, self.OFFLINE_VOLUME_NODE_NAME)

    def onScoutScanReconstVolume(self):
        self.startStopScoutScanButton.setIcon(self.waitIcon)
        self.startStopScoutScanButton.setText(
            "  Scout Scan\n  Reconstruction in progress ...")
        self.startStopScoutScanButton.setEnabled(False)
        self.plusRemoteLogic.reconstructRecorded(
            self.connectorNode.GetID(),
            self.volumeReconstructorIDSelector.currentText,
            self.lastScoutRecordingOutputFilename, self.outputSpacing,
            self.onScoutVolumeReconstructed, self.SCOUT_VOLUME_FILENAME,
            self.SCOUT_VOLUME_NODE_NAME)

    def onRequestVolumeReconstructionSnapshot(self, stopFlag=""):
        self.plusRemoteLogic.getVolumeReconstructionSnapshot(
            self.connectorNode.GetID(),
            self.volumeReconstructorIDSelector.currentText,
            self.LIVE_VOLUME_FILENAME, self.LIVE_VOLUME_NODE_NAME,
            self.APPLY_HOLE_FILLING_FOR_SNAPSHOT, self.onSnapshotAcquired)

    def executeCommandDelayed(self, method, delay=100):
        # Order of OpenIGTLink message receiving and processing is not guaranteed to be the same
        # therefore we wait a bit to make sure the image message is processed as well
        QTimer.singleShot(delay, method)

    def printCommandResponse(self, command, q):
        statusText = "Command {0} [{1}]: {2}\n".format(
            command.GetCommandName(), command.GetID(),
            command.StatusToString(command.GetStatus()))
        if command.GetResponseMessage():
            statusText = statusText + command.GetResponseMessage()
        elif command.GetResponseText():
            statusText = statusText + command.GetResponseText()
        logging.debug(statusText)

    def onGetCaptureDeviceCommandResponseReceived(self, command, q):
        self.printCommandResponse(command, q)
        if command.GetStatus() != command.CommandSuccess:
            return

        captureDeviceIdsListString = command.GetResponseMessage()
        if captureDeviceIdsListString:
            captureDevicesIdsList = captureDeviceIdsListString.split(",")
        else:
            captureDevicesIdsList = []

        for i in range(0, len(captureDevicesIdsList)):
            if self.captureIDSelector.findText(captureDevicesIdsList[i]) == -1:
                self.captureIDSelector.addItem(captureDevicesIdsList[i])

    def onGetVolumeReconstructorDeviceCommandResponseReceived(
            self, command, q):
        self.printCommandResponse(command, q)
        if command.GetStatus() != command.CommandSuccess:
            return

        volumeReconstructorDeviceIdsListString = command.GetResponseMessage()
        if volumeReconstructorDeviceIdsListString:
            volumeReconstructorDeviceIdsList = volumeReconstructorDeviceIdsListString.split(
                ",")
        else:
            volumeReconstructorDeviceIdsList = []

        self.volumeReconstructorIDSelector.clear()
        self.volumeReconstructorIDSelector.addItems(
            volumeReconstructorDeviceIdsList)
        self.startStopRecordingButton.setEnabled(True)
        self.offlineReconstructButton.setEnabled(True)
        self.startStopScoutScanButton.setEnabled(True)
        if self.roiNode:
            self.startStopLiveReconstructionButton.setEnabled(True)

    def onVolumeRecorded(self, command, q):
        self.printCommandResponse(command, q)
        self.offlineReconstructButton.setEnabled(True)

        volumeToReconstructFileName = os.path.basename(
            command.GetResponseMessage())
        self.offlineVolumeToReconstructSelector.insertItem(
            0, volumeToReconstructFileName)
        self.offlineVolumeToReconstructSelector.setCurrentIndex(0)

    def onScoutVolumeRecorded(self, command, q):
        self.printCommandResponse(command, q)
        self.offlineReconstructButton.setEnabled(True)

        if command.GetStatus() == command.CommandExpired:
            logging.fatal(
                "Scout Volume Recording: Timeout while waiting for volume reconstruction result"
            )
            return

        if command.GetStatus() == command.CommandSuccess:
            self.lastScoutRecordingOutputFilename = os.path.basename(
                command.GetResponseMessage())
            self.onScoutScanReconstVolume()

    def onVolumeReconstructed(self, command, q):
        self.printCommandResponse(command, q)

        self.offlineReconstructButton.setIcon(self.recordIcon)
        self.offlineReconstructButton.setText("Offline Reconstruction")
        self.offlineReconstructButton.setEnabled(True)
        self.offlineReconstructButton.setChecked(False)

        if command.GetStatus() == command.CommandExpired:
            # volume reconstruction command timed out
            logging.fatal(
                "Volume Reconstruction: Timeout while waiting for volume reconstruction result"
            )
            return

        if command.GetStatus() != command.CommandSuccess:
            logging.debug("Volume Reconstruction: " +
                          command.GetResponseMessage())
            return

        self.executeCommandDelayed(self.onVolumeReconstructedFinalize)

    def onVolumeReconstructedFinalize(self):
        applicationLogic = slicer.app.applicationLogic()
        applicationLogic.FitSliceToAll()
        self.guideletParent.showVolumeRendering(self.getOfflineVolumeRecNode())

    def onScoutVolumeReconstructed(self, command, q):
        self.printCommandResponse(command, q)

        if command.GetStatus() == command.CommandExpired:
            logging.fatal(
                "Scout Volume Reconstruction: Timeout while waiting for scout volume reconstruction result"
            )
            return

        self.startStopScoutScanButton.setIcon(self.recordIcon)
        self.startStopScoutScanButton.setText(
            "  Scout Scan\n  Start Recording")
        self.startStopScoutScanButton.setEnabled(True)

        if command.GetStatus() != command.CommandSuccess:
            logging.debug("Scout Volume Reconstruction: " +
                          command.GetResponseMessage())
            return

        self.executeCommandDelayed(self.onScoutVolumeReconstructedFinalize)

    def onScoutVolumeReconstructedFinalize(self):
        # Create and initialize ROI after scout scan because low resolution scout scan is used to set
        # a smaller ROI for the live high resolution reconstruction
        self.roiNode = self.logic.onRoiInitialization(
            self.SCOUT_VOLUME_NODE_NAME, self.roiNode)
        self.roiOrigin, self.roiExtent = self.logic.updateVolumeOriginAndExtentFromROI(
            self.LIVE_OUTPUT_VOLUME_SPACING, self.roiNode)
        scoutScanVolumeNode = self.getScoutVolumeNode()

        applicationLogic = slicer.app.applicationLogic()
        applicationLogic.FitSliceToAll()

        self.guideletParent.showVolumeRendering(scoutScanVolumeNode)

    def onSnapshotAcquired(self, command, q):
        self.printCommandResponse(command, q)

        if not self.startStopLiveReconstructionButton.isChecked():
            # live volume reconstruction is not active
            return

        self.executeCommandDelayed(self.onSnapshotAcquiredFinalize)

    def onSnapshotAcquiredFinalize(self):
        self.guideletParent.showVolumeRendering(self.getLiveVolumeRecNode())
        self.snapshotTimer.start(self.SNAPSHOT_INTERVAL * 1000)

    def onVolumeLiveReconstructed(self, command, q):
        self.printCommandResponse(command, q)

        if command.GetStatus() == command.CommandExpired:
            logging.fatal(
                "LIVE Volume Reconstruction: Failed to stop volume reconstruction"
            )
            return

        if command.GetStatus() != command.CommandSuccess:
            logging.debug("LIVE Volume Reconstruction " +
                          command.GetResponseMessage())
            return

        self.executeCommandDelayed(self.getLiveVolumeRecNode)

    def onVolumeLiveReconstructedFinalize(self):
        self.guideletParent.showVolumeRendering(self.getLiveVolumeRecNode())
예제 #39
0
파일: humanclient.py 프로젝트: KDE/kajongg
 def __init__(self, message, parent):
     QPushButton.__init__(self, parent)
     self.message = message
     self.client = parent.client
     self.setText(message.buttonCaption())
예제 #40
0
class ScoringDialog(QWidget):

    """a dialog for entering the scores"""

    # pylint: disable=too-many-instance-attributes

    def __init__(self, scene):
        QWidget.__init__(self)
        self.scene = scene
        decorateWindow(self, m18n("Scoring for this Hand"))
        self.nameLabels = [None] * 4
        self.spValues = [None] * 4
        self.windLabels = [None] * 4
        self.wonBoxes = [None] * 4
        self.detailsLayout = [None] * 4
        self.details = [None] * 4
        self.__tilePixMaps = []
        self.__meldPixMaps = []
        grid = QGridLayout(self)
        pGrid = QGridLayout()
        grid.addLayout(pGrid, 0, 0, 2, 1)
        pGrid.addWidget(QLabel(m18nc("kajongg", "Player")), 0, 0)
        pGrid.addWidget(QLabel(m18nc("kajongg", "Wind")), 0, 1)
        pGrid.addWidget(QLabel(m18nc("kajongg", "Score")), 0, 2)
        pGrid.addWidget(QLabel(m18n("Winner")), 0, 3)
        self.detailTabs = QTabWidget()
        self.detailTabs.setDocumentMode(True)
        pGrid.addWidget(self.detailTabs, 0, 4, 8, 1)
        for idx in range(4):
            self.setupUiForPlayer(pGrid, idx)
        self.draw = QCheckBox(m18nc("kajongg", "Draw"))
        self.draw.clicked.connect(self.wonChanged)
        btnPenalties = QPushButton(m18n("&Penalties"))
        btnPenalties.clicked.connect(self.penalty)
        self.btnSave = QPushButton(m18n("&Save Hand"))
        self.btnSave.clicked.connect(self.game.nextScoringHand)
        self.btnSave.setEnabled(False)
        self.setupUILastTileMeld(pGrid)
        pGrid.setRowStretch(87, 10)
        pGrid.addWidget(self.draw, 7, 3)
        self.cbLastTile.currentIndexChanged.connect(self.slotLastTile)
        self.cbLastMeld.currentIndexChanged.connect(self.slotInputChanged)
        btnBox = QHBoxLayout()
        btnBox.addWidget(btnPenalties)
        btnBox.addWidget(self.btnSave)
        pGrid.addLayout(btnBox, 8, 4)
        StateSaver(self)
        self.refresh()

    @property
    def game(self):
        """proxy"""
        return self.scene.game

    def setupUILastTileMeld(self, pGrid):
        """setup UI elements for last tile and last meld"""
        self.lblLastTile = QLabel(m18n("&Last Tile:"))
        self.cbLastTile = QComboBox()
        self.cbLastTile.setMinimumContentsLength(1)
        vpol = QSizePolicy()
        vpol.setHorizontalPolicy(QSizePolicy.Fixed)
        self.cbLastTile.setSizePolicy(vpol)
        self.cbLastTile.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLengthWithIcon)
        self.lblLastTile.setBuddy(self.cbLastTile)
        self.lblLastMeld = QLabel(m18n("L&ast Meld:"))
        self.prevLastTile = None
        self.cbLastMeld = QComboBox()
        self.cbLastMeld.setMinimumContentsLength(1)
        self.cbLastMeld.setSizePolicy(vpol)
        self.cbLastMeld.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLengthWithIcon)
        self.lblLastMeld.setBuddy(self.cbLastMeld)
        self.comboTilePairs = set()
        pGrid.setRowStretch(6, 5)
        pGrid.addWidget(self.lblLastTile, 7, 0, 1, 2)
        pGrid.addWidget(self.cbLastTile, 7, 2, 1, 1)
        pGrid.addWidget(self.lblLastMeld, 8, 0, 1, 2)
        pGrid.addWidget(self.cbLastMeld, 8, 2, 1, 2)

    def setupUiForPlayer(self, pGrid, idx):
        """setup UI elements for a player"""
        self.spValues[idx] = QSpinBox()
        self.nameLabels[idx] = QLabel()
        self.nameLabels[idx].setBuddy(self.spValues[idx])
        self.windLabels[idx] = WindLabel()
        pGrid.addWidget(self.nameLabels[idx], idx + 2, 0)
        pGrid.addWidget(self.windLabels[idx], idx + 2, 1)
        pGrid.addWidget(self.spValues[idx], idx + 2, 2)
        self.wonBoxes[idx] = QCheckBox("")
        pGrid.addWidget(self.wonBoxes[idx], idx + 2, 3)
        self.wonBoxes[idx].clicked.connect(self.wonChanged)
        self.spValues[idx].valueChanged.connect(self.slotInputChanged)
        detailTab = QWidget()
        self.detailTabs.addTab(detailTab, "")
        self.details[idx] = QWidget()
        detailTabLayout = QVBoxLayout(detailTab)
        detailTabLayout.addWidget(self.details[idx])
        detailTabLayout.addStretch()
        self.detailsLayout[idx] = QVBoxLayout(self.details[idx])

    def refresh(self):
        """reload game"""
        self.clear()
        game = self.game
        self.setVisible(game is not None and not game.finished())
        if game:
            for idx, player in enumerate(game.players):
                for child in self.details[idx].children():
                    if isinstance(child, RuleBox):
                        child.hide()
                        self.detailsLayout[idx].removeWidget(child)
                        del child
                if game:
                    self.spValues[idx].setRange(0, game.ruleset.limit or 99999)
                    self.nameLabels[idx].setText(player.localName)
                    self.windLabels[idx].wind = player.wind
                    self.windLabels[idx].roundsFinished = game.roundsFinished
                    self.detailTabs.setTabText(idx, player.localName)
                    player.manualRuleBoxes = [RuleBox(x) for x in game.ruleset.allRules if x.hasSelectable]
                    for ruleBox in player.manualRuleBoxes:
                        self.detailsLayout[idx].addWidget(ruleBox)
                        ruleBox.clicked.connect(self.slotInputChanged)
                player.refreshManualRules()

    def show(self):
        """only now compute content"""
        if self.game and not self.game.finished():
            self.slotInputChanged()
            QWidget.show(self)

    def penalty(self):
        """penalty button clicked"""
        dlg = PenaltyDialog(self.game)
        dlg.exec_()

    def slotLastTile(self):
        """called when the last tile changes"""
        newLastTile = self.computeLastTile()
        if not newLastTile:
            return
        if self.prevLastTile and self.prevLastTile.isExposed != newLastTile.isExposed:
            # state of last tile (concealed/exposed) changed:
            # for all checked boxes check if they still are applicable
            winner = self.game.winner
            if winner:
                for box in winner.manualRuleBoxes:
                    if box.isChecked():
                        box.setChecked(False)
                        if winner.hand.manualRuleMayApply(box.rule):
                            box.setChecked(True)
        self.prevLastTile = newLastTile
        self.fillLastMeldCombo()
        self.slotInputChanged()

    def computeLastTile(self):
        """returns the currently selected last tile"""
        idx = self.cbLastTile.currentIndex()
        if idx >= 0:
            return variantValue(self.cbLastTile.itemData(idx))

    def clickedPlayerIdx(self, checkbox):
        """the player whose box has been clicked"""
        for idx in range(4):
            if checkbox == self.wonBoxes[idx]:
                return idx
        assert False

    def wonChanged(self):
        """if a new winner has been defined, uncheck any previous winner"""
        newWinner = None
        if self.sender() != self.draw:
            clicked = self.clickedPlayerIdx(self.sender())
            if self.wonBoxes[clicked].isChecked():
                newWinner = self.game.players[clicked]
            else:
                newWinner = None
        self.game.winner = newWinner
        for idx in range(4):
            if newWinner != self.game.players[idx]:
                self.wonBoxes[idx].setChecked(False)
        if newWinner:
            self.draw.setChecked(False)
        self.fillLastTileCombo()
        self.slotInputChanged()

    def updateManualRules(self):
        """enable/disable them"""
        # if an exclusive rule has been activated, deactivate it for
        # all other players
        ruleBox = self.sender()
        if isinstance(ruleBox, RuleBox) and ruleBox.isChecked() and ruleBox.rule.exclusive():
            for idx, player in enumerate(self.game.players):
                if ruleBox.parentWidget() != self.details[idx]:
                    for pBox in player.manualRuleBoxes:
                        if pBox.rule.name == ruleBox.rule.name:
                            pBox.setChecked(False)
        try:
            newState = bool(self.game.winner.handBoard.uiTiles)
        except AttributeError:
            newState = False
        self.lblLastTile.setEnabled(newState)
        self.cbLastTile.setEnabled(newState)
        self.lblLastMeld.setEnabled(newState)
        self.cbLastMeld.setEnabled(newState)
        if self.game:
            for player in self.game.players:
                player.refreshManualRules(self.sender())

    def clear(self):
        """prepare for next hand"""
        if self.game:
            for idx, player in enumerate(self.game.players):
                self.spValues[idx].clear()
                self.spValues[idx].setValue(0)
                self.wonBoxes[idx].setChecked(False)
                player.payment = 0
                player.invalidateHand()
        for box in self.wonBoxes:
            box.setVisible(False)
        self.draw.setChecked(False)
        self.updateManualRules()

        if self.game is None:
            self.hide()
        else:
            for idx, player in enumerate(self.game.players):
                self.windLabels[idx].setPixmap(WINDPIXMAPS[(player.wind, player.wind == self.game.roundWind)])
            self.computeScores()
            self.spValues[0].setFocus()
            self.spValues[0].selectAll()

    def computeScores(self):
        """if tiles have been selected, compute their value"""
        # pylint: disable=too-many-branches
        # too many branches
        if not self.game:
            return
        if self.game.finished():
            self.hide()
            return
        for nameLabel, wonBox, spValue, player in zip(self.nameLabels, self.wonBoxes, self.spValues, self.game.players):
            with BlockSignals([spValue, wonBox]):
                # we do not want that change to call computeScores again
                if player.handBoard and player.handBoard.uiTiles:
                    spValue.setEnabled(False)
                    nameLabel.setBuddy(wonBox)
                    for _ in range(10):
                        prevTotal = player.handTotal
                        player.invalidateHand()
                        wonBox.setVisible(player.hand.won)
                        if not wonBox.isVisibleTo(self) and wonBox.isChecked():
                            wonBox.setChecked(False)
                            self.game.winner = None
                        elif prevTotal == player.handTotal:
                            break
                        player.refreshManualRules()
                    spValue.setValue(player.handTotal)
                else:
                    if not spValue.isEnabled():
                        spValue.clear()
                        spValue.setValue(0)
                        spValue.setEnabled(True)
                        nameLabel.setBuddy(spValue)
                    wonBox.setVisible(player.handTotal >= self.game.ruleset.minMJTotal())
                    if not wonBox.isVisibleTo(self) and wonBox.isChecked():
                        wonBox.setChecked(False)
                if not wonBox.isVisibleTo(self) and player is self.game.winner:
                    self.game.winner = None
        if Internal.scene.explainView:
            Internal.scene.explainView.refresh()

    def __lastMeldContent(self):
        """prepare content for lastmeld combo"""
        lastTiles = set()
        winnerTiles = []
        if self.game.winner and self.game.winner.handBoard:
            winnerTiles = self.game.winner.handBoard.uiTiles
            pairs = []
            for meld in self.game.winner.hand.melds:
                if len(meld) < 4:
                    pairs.extend(meld)
            for tile in winnerTiles:
                if tile.tile in pairs and not tile.isBonus:
                    lastTiles.add(tile.tile)
        return lastTiles, winnerTiles

    def __fillLastTileComboWith(self, lastTiles, winnerTiles):
        """fill last meld combo with prepared content"""
        self.comboTilePairs = lastTiles
        idx = self.cbLastTile.currentIndex()
        if idx < 0:
            idx = 0
        indexedTile = variantValue(self.cbLastTile.itemData(idx))
        restoredIdx = None
        self.cbLastTile.clear()
        if not winnerTiles:
            return
        pmSize = winnerTiles[0].board.tileset.faceSize
        pmSize = QSize(pmSize.width() * 0.5, pmSize.height() * 0.5)
        self.cbLastTile.setIconSize(pmSize)
        QPixmapCache.clear()
        self.__tilePixMaps = []
        shownTiles = set()
        for tile in winnerTiles:
            if tile.tile in lastTiles and tile.tile not in shownTiles:
                shownTiles.add(tile.tile)
                self.cbLastTile.addItem(QIcon(tile.pixmapFromSvg(pmSize, withBorders=False)), "", toQVariant(tile.tile))
                if indexedTile is tile.tile:
                    restoredIdx = self.cbLastTile.count() - 1
        if not restoredIdx and indexedTile:
            # try again, maybe the tile changed between concealed and exposed
            indexedTile = indexedTile.exposed
            for idx in range(self.cbLastTile.count()):
                if indexedTile is variantValue(self.cbLastTile.itemData(idx)).exposed:
                    restoredIdx = idx
                    break
        if not restoredIdx:
            restoredIdx = 0
        self.cbLastTile.setCurrentIndex(restoredIdx)
        self.prevLastTile = self.computeLastTile()

    def clearLastTileCombo(self):
        """as the name says"""
        self.comboTilePairs = None
        self.cbLastTile.clear()

    def fillLastTileCombo(self):
        """fill the drop down list with all possible tiles.
        If the drop down had content before try to preserve the
        current index. Even if the tile changed state meanwhile."""
        if self.game is None:
            return
        lastTiles, winnerTiles = self.__lastMeldContent()
        if self.comboTilePairs == lastTiles:
            return
        with BlockSignals(self.cbLastTile):
            # we only want to emit the changed signal once
            self.__fillLastTileComboWith(lastTiles, winnerTiles)
        self.cbLastTile.currentIndexChanged.emit(0)

    def __fillLastMeldComboWith(self, winnerMelds, indexedMeld, lastTile):
        """fill last meld combo with prepared content"""
        winner = self.game.winner
        faceWidth = winner.handBoard.tileset.faceSize.width() * 0.5
        faceHeight = winner.handBoard.tileset.faceSize.height() * 0.5
        restoredIdx = None
        for meld in winnerMelds:
            pixMap = QPixmap(faceWidth * len(meld), faceHeight)
            pixMap.fill(Qt.transparent)
            self.__meldPixMaps.append(pixMap)
            painter = QPainter(pixMap)
            for element in meld:
                painter.drawPixmap(
                    0,
                    0,
                    winner.handBoard.tilesByElement(element)[0].pixmapFromSvg(
                        QSize(faceWidth, faceHeight), withBorders=False
                    ),
                )
                painter.translate(QPointF(faceWidth, 0.0))
            self.cbLastMeld.addItem(QIcon(pixMap), "", toQVariant(str(meld)))
            if indexedMeld == str(meld):
                restoredIdx = self.cbLastMeld.count() - 1
        if not restoredIdx and indexedMeld:
            # try again, maybe the meld changed between concealed and exposed
            indexedMeld = indexedMeld.lower()
            for idx in range(self.cbLastMeld.count()):
                meldContent = str(variantValue(self.cbLastMeld.itemData(idx)))
                if indexedMeld == meldContent.lower():
                    restoredIdx = idx
                    if lastTile not in meldContent:
                        lastTile = lastTile.swapped
                        assert lastTile in meldContent
                        with BlockSignals(self.cbLastTile):  # we want to continue right here
                            idx = self.cbLastTile.findData(toQVariant(lastTile))
                            self.cbLastTile.setCurrentIndex(idx)
                    break
        if not restoredIdx:
            restoredIdx = 0
        self.cbLastMeld.setCurrentIndex(restoredIdx)
        self.cbLastMeld.setIconSize(QSize(faceWidth * 3, faceHeight))

    def fillLastMeldCombo(self):
        """fill the drop down list with all possible melds.
        If the drop down had content before try to preserve the
        current index. Even if the meld changed state meanwhile."""
        with BlockSignals(self.cbLastMeld):  # we only want to emit the changed signal once
            showCombo = False
            idx = self.cbLastMeld.currentIndex()
            if idx < 0:
                idx = 0
            indexedMeld = str(variantValue(self.cbLastMeld.itemData(idx)))
            self.cbLastMeld.clear()
            self.__meldPixMaps = []
            if not self.game.winner:
                return
            if self.cbLastTile.count() == 0:
                return
            lastTile = Internal.scene.computeLastTile()
            winnerMelds = [m for m in self.game.winner.hand.melds if len(m) < 4 and lastTile in m]
            assert len(winnerMelds), "lastTile %s missing in %s" % (lastTile, self.game.winner.hand.melds)
            if len(winnerMelds) == 1:
                self.cbLastMeld.addItem(QIcon(), "", toQVariant(str(winnerMelds[0])))
                self.cbLastMeld.setCurrentIndex(0)
                return
            showCombo = True
            self.__fillLastMeldComboWith(winnerMelds, indexedMeld, lastTile)
            self.lblLastMeld.setVisible(showCombo)
            self.cbLastMeld.setVisible(showCombo)
        self.cbLastMeld.currentIndexChanged.emit(0)

    def slotInputChanged(self):
        """some input fields changed: update"""
        for player in self.game.players:
            player.invalidateHand()
        self.updateManualRules()
        self.computeScores()
        self.validate()
        for player in self.game.players:
            self.game.wall.decoratePlayer(player)
        Internal.mainWindow.updateGUI()

    def validate(self):
        """update the status of the OK button"""
        game = self.game
        if game:
            valid = True
            if game.winner and game.winner.handTotal < game.ruleset.minMJTotal():
                valid = False
            elif not game.winner and not self.draw.isChecked():
                valid = False
            self.btnSave.setEnabled(valid)
예제 #41
0
class ScoringDialog(QWidget):
    """a dialog for entering the scores"""

    # pylint: disable=too-many-instance-attributes

    def __init__(self, scene):
        QWidget.__init__(self)
        self.scene = scene
        decorateWindow(self, i18n('Scoring for this Hand'))
        self.nameLabels = [None] * 4
        self.spValues = [None] * 4
        self.windLabels = [None] * 4
        self.wonBoxes = [None] * 4
        self.detailsLayout = [None] * 4
        self.details = [None] * 4
        self.__tilePixMaps = []
        self.__meldPixMaps = []
        grid = QGridLayout(self)
        pGrid = QGridLayout()
        grid.addLayout(pGrid, 0, 0, 2, 1)
        pGrid.addWidget(QLabel(i18nc('kajongg', "Player")), 0, 0)
        pGrid.addWidget(QLabel(i18nc('kajongg', "Wind")), 0, 1)
        pGrid.addWidget(QLabel(i18nc('kajongg', 'Score')), 0, 2)
        pGrid.addWidget(QLabel(i18n("Winner")), 0, 3)
        self.detailTabs = QTabWidget()
        self.detailTabs.setDocumentMode(True)
        pGrid.addWidget(self.detailTabs, 0, 4, 8, 1)
        for idx in range(4):
            self.setupUiForPlayer(pGrid, idx)
        self.draw = QCheckBox(i18nc('kajongg', 'Draw'))
        self.draw.clicked.connect(self.wonChanged)
        btnPenalties = QPushButton(i18n("&Penalties"))
        btnPenalties.clicked.connect(self.penalty)
        self.btnSave = QPushButton(i18n('&Save Hand'))
        self.btnSave.clicked.connect(self.game.nextScoringHand)
        self.btnSave.setEnabled(False)
        self.setupUILastTileMeld(pGrid)
        pGrid.setRowStretch(87, 10)
        pGrid.addWidget(self.draw, 7, 3)
        self.cbLastTile.currentIndexChanged.connect(self.slotLastTile)
        self.cbLastMeld.currentIndexChanged.connect(self.slotInputChanged)
        btnBox = QHBoxLayout()
        btnBox.addWidget(btnPenalties)
        btnBox.addWidget(self.btnSave)
        pGrid.addLayout(btnBox, 8, 4)
        StateSaver(self)
        self.refresh()

    @property
    def game(self):
        """proxy"""
        return self.scene.game

    def setupUILastTileMeld(self, pGrid):
        """setup UI elements for last tile and last meld"""
        self.lblLastTile = QLabel(i18n('&Last Tile:'))
        self.cbLastTile = QComboBox()
        self.cbLastTile.setMinimumContentsLength(1)
        vpol = QSizePolicy()
        vpol.setHorizontalPolicy(QSizePolicy.Fixed)
        self.cbLastTile.setSizePolicy(vpol)
        self.cbLastTile.setSizeAdjustPolicy(
            QComboBox.AdjustToMinimumContentsLengthWithIcon)
        self.lblLastTile.setBuddy(self.cbLastTile)
        self.lblLastMeld = QLabel(i18n('L&ast Meld:'))
        self.prevLastTile = None
        self.cbLastMeld = QComboBox()
        self.cbLastMeld.setMinimumContentsLength(1)
        self.cbLastMeld.setSizePolicy(vpol)
        self.cbLastMeld.setSizeAdjustPolicy(
            QComboBox.AdjustToMinimumContentsLengthWithIcon)
        self.lblLastMeld.setBuddy(self.cbLastMeld)
        self.comboTilePairs = set()
        pGrid.setRowStretch(6, 5)
        pGrid.addWidget(self.lblLastTile, 7, 0, 1, 2)
        pGrid.addWidget(self.cbLastTile, 7, 2, 1, 1)
        pGrid.addWidget(self.lblLastMeld, 8, 0, 1, 2)
        pGrid.addWidget(self.cbLastMeld, 8, 2, 1, 2)

    def setupUiForPlayer(self, pGrid, idx):
        """setup UI elements for a player"""
        self.spValues[idx] = QSpinBox()
        self.nameLabels[idx] = QLabel()
        self.nameLabels[idx].setBuddy(self.spValues[idx])
        self.windLabels[idx] = WindLabel()
        pGrid.addWidget(self.nameLabels[idx], idx + 2, 0)
        pGrid.addWidget(self.windLabels[idx], idx + 2, 1)
        pGrid.addWidget(self.spValues[idx], idx + 2, 2)
        self.wonBoxes[idx] = QCheckBox("")
        pGrid.addWidget(self.wonBoxes[idx], idx + 2, 3)
        self.wonBoxes[idx].clicked.connect(self.wonChanged)
        self.spValues[idx].valueChanged.connect(self.slotInputChanged)
        detailTab = QWidget()
        self.detailTabs.addTab(detailTab, '')
        self.details[idx] = QWidget()
        detailTabLayout = QVBoxLayout(detailTab)
        detailTabLayout.addWidget(self.details[idx])
        detailTabLayout.addStretch()
        self.detailsLayout[idx] = QVBoxLayout(self.details[idx])

    def refresh(self):
        """reload game"""
        self.clear()
        game = self.game
        self.setVisible(game is not None and not game.finished())
        if game:
            for idx, player in enumerate(game.players):
                for child in self.details[idx].children():
                    if isinstance(child, RuleBox):
                        child.hide()
                        self.detailsLayout[idx].removeWidget(child)
                        del child
                if game:
                    self.spValues[idx].setRange(0, game.ruleset.limit or 99999)
                    self.nameLabels[idx].setText(player.localName)
                    self.refreshWindLabels()
                    self.detailTabs.setTabText(idx, player.localName)
                    player.manualRuleBoxes = [
                        RuleBox(x) for x in game.ruleset.allRules
                        if x.hasSelectable
                    ]
                    for ruleBox in player.manualRuleBoxes:
                        self.detailsLayout[idx].addWidget(ruleBox)
                        ruleBox.clicked.connect(self.slotInputChanged)
                player.refreshManualRules()

    def show(self):
        """only now compute content"""
        if self.game and not self.game.finished():
            self.slotInputChanged()
            QWidget.show(self)

    def penalty(self):
        """penalty button clicked"""
        dlg = PenaltyDialog(self.game)
        dlg.exec_()

    def slotLastTile(self):
        """called when the last tile changes"""
        newLastTile = self.computeLastTile()
        if not newLastTile:
            return
        if self.prevLastTile and self.prevLastTile.isExposed != newLastTile.isExposed:
            # state of last tile (concealed/exposed) changed:
            # for all checked boxes check if they still are applicable
            winner = self.game.winner
            if winner:
                for box in winner.manualRuleBoxes:
                    if box.isChecked():
                        box.setChecked(False)
                        if winner.hand.manualRuleMayApply(box.rule):
                            box.setChecked(True)
        self.prevLastTile = newLastTile
        self.fillLastMeldCombo()
        self.slotInputChanged()

    def computeLastTile(self):
        """returns the currently selected last tile"""
        idx = self.cbLastTile.currentIndex()
        if idx >= 0:
            return self.cbLastTile.itemData(idx)

    def clickedPlayerIdx(self, checkbox):
        """the player whose box has been clicked"""
        for idx in range(4):
            if checkbox == self.wonBoxes[idx]:
                return idx
        assert False

    def wonChanged(self):
        """if a new winner has been defined, uncheck any previous winner"""
        newWinner = None
        if self.sender() != self.draw:
            clicked = self.clickedPlayerIdx(self.sender())
            if self.wonBoxes[clicked].isChecked():
                newWinner = self.game.players[clicked]
            else:
                newWinner = None
        self.game.winner = newWinner
        for idx in range(4):
            if newWinner != self.game.players[idx]:
                self.wonBoxes[idx].setChecked(False)
        if newWinner:
            self.draw.setChecked(False)
        self.fillLastTileCombo()
        self.slotInputChanged()

    def updateManualRules(self):
        """enable/disable them"""
        # if an exclusive rule has been activated, deactivate it for
        # all other players
        ruleBox = self.sender()
        if isinstance(
                ruleBox,
                RuleBox) and ruleBox.isChecked() and ruleBox.rule.exclusive():
            for idx, player in enumerate(self.game.players):
                if ruleBox.parentWidget() != self.details[idx]:
                    for pBox in player.manualRuleBoxes:
                        if pBox.rule.name == ruleBox.rule.name:
                            pBox.setChecked(False)
        try:
            newState = bool(self.game.winner.handBoard.uiTiles)
        except AttributeError:
            newState = False
        self.lblLastTile.setEnabled(newState)
        self.cbLastTile.setEnabled(newState)
        self.lblLastMeld.setEnabled(newState)
        self.cbLastMeld.setEnabled(newState)
        if self.game:
            for player in self.game.players:
                player.refreshManualRules(self.sender())

    def clear(self):
        """prepare for next hand"""
        if self.game:
            for idx, player in enumerate(self.game.players):
                self.spValues[idx].clear()
                self.spValues[idx].setValue(0)
                self.wonBoxes[idx].setChecked(False)
                player.payment = 0
                player.invalidateHand()
        for box in self.wonBoxes:
            box.setVisible(False)
        self.draw.setChecked(False)
        self.updateManualRules()

        if self.game is None:
            self.hide()
        else:
            self.refreshWindLabels()
            self.computeScores()
            self.spValues[0].setFocus()
            self.spValues[0].selectAll()

    def refreshWindLabels(self):
        """update their wind and prevailing"""
        for idx, player in enumerate(self.game.players):
            self.windLabels[idx].wind = player.wind
            self.windLabels[idx].roundsFinished = self.game.roundsFinished

    def computeScores(self):
        """if tiles have been selected, compute their value"""
        # pylint: disable=too-many-branches
        # too many branches
        if not self.game:
            return
        if self.game.finished():
            self.hide()
            return
        for nameLabel, wonBox, spValue, player in zip(self.nameLabels,
                                                      self.wonBoxes,
                                                      self.spValues,
                                                      self.game.players):
            with BlockSignals([spValue, wonBox]):
                # we do not want that change to call computeScores again
                if player.handBoard and player.handBoard.uiTiles:
                    spValue.setEnabled(False)
                    nameLabel.setBuddy(wonBox)
                    for _ in range(10):
                        prevTotal = player.handTotal
                        player.invalidateHand()
                        wonBox.setVisible(player.hand.won)
                        if not wonBox.isVisibleTo(self) and wonBox.isChecked():
                            wonBox.setChecked(False)
                            self.game.winner = None
                        elif prevTotal == player.handTotal:
                            break
                        player.refreshManualRules()
                    spValue.setValue(player.handTotal)
                else:
                    if not spValue.isEnabled():
                        spValue.clear()
                        spValue.setValue(0)
                        spValue.setEnabled(True)
                        nameLabel.setBuddy(spValue)
                    wonBox.setVisible(
                        player.handTotal >= self.game.ruleset.minMJTotal())
                    if not wonBox.isVisibleTo(self) and wonBox.isChecked():
                        wonBox.setChecked(False)
                if not wonBox.isVisibleTo(self) and player is self.game.winner:
                    self.game.winner = None
        if Internal.scene.explainView:
            Internal.scene.explainView.refresh()

    def __lastMeldContent(self):
        """prepare content for lastmeld combo"""
        lastTiles = set()
        winnerTiles = []
        if self.game.winner and self.game.winner.handBoard:
            winnerTiles = self.game.winner.handBoard.uiTiles
            pairs = []
            for meld in self.game.winner.hand.melds:
                if len(meld) < 4:
                    pairs.extend(meld)
            for tile in winnerTiles:
                if tile.tile in pairs and not tile.isBonus:
                    lastTiles.add(tile.tile)
        return lastTiles, winnerTiles

    def __fillLastTileComboWith(self, lastTiles, winnerTiles):
        """fill last meld combo with prepared content"""
        self.comboTilePairs = lastTiles
        idx = self.cbLastTile.currentIndex()
        if idx < 0:
            idx = 0
        indexedTile = self.cbLastTile.itemData(idx)
        restoredIdx = None
        self.cbLastTile.clear()
        if not winnerTiles:
            return
        pmSize = winnerTiles[0].board.tileset.faceSize
        pmSize = QSize(pmSize.width() * 0.5, pmSize.height() * 0.5)
        self.cbLastTile.setIconSize(pmSize)
        QPixmapCache.clear()
        self.__tilePixMaps = []
        shownTiles = set()
        for tile in winnerTiles:
            if tile.tile in lastTiles and tile.tile not in shownTiles:
                shownTiles.add(tile.tile)
                self.cbLastTile.addItem(
                    QIcon(tile.pixmapFromSvg(pmSize, withBorders=False)), '',
                    tile.tile)
                if indexedTile is tile.tile:
                    restoredIdx = self.cbLastTile.count() - 1
        if not restoredIdx and indexedTile:
            # try again, maybe the tile changed between concealed and exposed
            indexedTile = indexedTile.exposed
            for idx in range(self.cbLastTile.count()):
                if indexedTile is self.cbLastTile.itemData(idx).exposed:
                    restoredIdx = idx
                    break
        if not restoredIdx:
            restoredIdx = 0
        self.cbLastTile.setCurrentIndex(restoredIdx)
        self.prevLastTile = self.computeLastTile()

    def clearLastTileCombo(self):
        """as the name says"""
        self.comboTilePairs = None
        self.cbLastTile.clear()

    def fillLastTileCombo(self):
        """fill the drop down list with all possible tiles.
        If the drop down had content before try to preserve the
        current index. Even if the tile changed state meanwhile."""
        if self.game is None:
            return
        lastTiles, winnerTiles = self.__lastMeldContent()
        if self.comboTilePairs == lastTiles:
            return
        with BlockSignals(self.cbLastTile):
            # we only want to emit the changed signal once
            self.__fillLastTileComboWith(lastTiles, winnerTiles)
        self.cbLastTile.currentIndexChanged.emit(0)

    def __fillLastMeldComboWith(self, winnerMelds, indexedMeld, lastTile):
        """fill last meld combo with prepared content"""
        winner = self.game.winner
        faceWidth = winner.handBoard.tileset.faceSize.width() * 0.5
        faceHeight = winner.handBoard.tileset.faceSize.height() * 0.5
        restoredIdx = None
        for meld in winnerMelds:
            pixMap = QPixmap(faceWidth * len(meld), faceHeight)
            pixMap.fill(Qt.transparent)
            self.__meldPixMaps.append(pixMap)
            painter = QPainter(pixMap)
            for element in meld:
                painter.drawPixmap(
                    0, 0,
                    winner.handBoard.tilesByElement(element)[0].pixmapFromSvg(
                        QSize(faceWidth, faceHeight), withBorders=False))
                painter.translate(QPointF(faceWidth, 0.0))
            self.cbLastMeld.addItem(QIcon(pixMap), '', str(meld))
            if indexedMeld == str(meld):
                restoredIdx = self.cbLastMeld.count() - 1
        if not restoredIdx and indexedMeld:
            # try again, maybe the meld changed between concealed and exposed
            indexedMeld = indexedMeld.lower()
            for idx in range(self.cbLastMeld.count()):
                meldContent = str(self.cbLastMeld.itemData(idx))
                if indexedMeld == meldContent.lower():
                    restoredIdx = idx
                    if lastTile not in meldContent:
                        lastTile = lastTile.swapped
                        assert lastTile in meldContent
                        with BlockSignals(self.cbLastTile
                                          ):  # we want to continue right here
                            idx = self.cbLastTile.findData(lastTile)
                            self.cbLastTile.setCurrentIndex(idx)
                    break
        if not restoredIdx:
            restoredIdx = 0
        self.cbLastMeld.setCurrentIndex(restoredIdx)
        self.cbLastMeld.setIconSize(QSize(faceWidth * 3, faceHeight))

    def fillLastMeldCombo(self):
        """fill the drop down list with all possible melds.
        If the drop down had content before try to preserve the
        current index. Even if the meld changed state meanwhile."""
        with BlockSignals(self.cbLastMeld
                          ):  # we only want to emit the changed signal once
            showCombo = False
            idx = self.cbLastMeld.currentIndex()
            if idx < 0:
                idx = 0
            indexedMeld = str(self.cbLastMeld.itemData(idx))
            self.cbLastMeld.clear()
            self.__meldPixMaps = []
            if not self.game.winner:
                return
            if self.cbLastTile.count() == 0:
                return
            lastTile = Internal.scene.computeLastTile()
            winnerMelds = [
                m for m in self.game.winner.hand.melds
                if len(m) < 4 and lastTile in m
            ]
            assert len(winnerMelds), 'lastTile %s missing in %s' % (
                lastTile, self.game.winner.hand.melds)
            if len(winnerMelds) == 1:
                self.cbLastMeld.addItem(QIcon(), '', str(winnerMelds[0]))
                self.cbLastMeld.setCurrentIndex(0)
                return
            showCombo = True
            self.__fillLastMeldComboWith(winnerMelds, indexedMeld, lastTile)
            self.lblLastMeld.setVisible(showCombo)
            self.cbLastMeld.setVisible(showCombo)
        self.cbLastMeld.currentIndexChanged.emit(0)

    def slotInputChanged(self):
        """some input fields changed: update"""
        for player in self.game.players:
            player.invalidateHand()
        self.updateManualRules()
        self.computeScores()
        self.validate()
        for player in self.game.players:
            player.showInfo()
        Internal.mainWindow.updateGUI()

    def validate(self):
        """update the status of the OK button"""
        game = self.game
        if game:
            valid = True
            if game.winner and game.winner.handTotal < game.ruleset.minMJTotal(
            ):
                valid = False
            elif not game.winner and not self.draw.isChecked():
                valid = False
            self.btnSave.setEnabled(valid)
예제 #42
0
class RulesetSelector(QWidget):

    """presents all available rulesets with previews"""

    def __init__(self, parent=None):
        super(RulesetSelector, self).__init__(parent)
        self.setContentsMargins(0, 0, 0, 0)
        self.setupUi()

    def setupUi(self):
        """layout the window"""
        decorateWindow(self, m18n('Customize rulesets'))
        self.setObjectName('Rulesets')
        hlayout = QHBoxLayout(self)
        v1layout = QVBoxLayout()
        self.v1widget = QWidget()
        v1layout = QVBoxLayout(self.v1widget)
        v2layout = QVBoxLayout()
        hlayout.addWidget(self.v1widget)
        hlayout.addLayout(v2layout)
        for widget in [self.v1widget, hlayout, v1layout, v2layout]:
            widget.setContentsMargins(0, 0, 0, 0)
        hlayout.setStretchFactor(self.v1widget, 10)
        self.btnCopy = QPushButton()
        self.btnRemove = QPushButton()
        self.btnCompare = QPushButton()
        self.btnClose = QPushButton()
        self.rulesetView = RuleTreeView(
            m18nc('kajongg',
                  'Rule'),
            self.btnCopy,
            self.btnRemove,
            self.btnCompare)
        v1layout.addWidget(self.rulesetView)
        self.rulesetView.setWordWrap(True)
        self.rulesetView.setMouseTracking(True)
        spacerItem = QSpacerItem(
            20,
            20,
            QSizePolicy.Minimum,
            QSizePolicy.Expanding)
        v2layout.addWidget(self.btnCopy)
        v2layout.addWidget(self.btnRemove)
        v2layout.addWidget(self.btnCompare)
        self.btnCopy.clicked.connect(self.rulesetView.copyRow)
        self.btnRemove.clicked.connect(self.rulesetView.removeRow)
        self.btnCompare.clicked.connect(self.rulesetView.compareRow)
        self.btnClose.clicked.connect(self.hide)
        v2layout.addItem(spacerItem)
        v2layout.addWidget(self.btnClose)
        self.retranslateUi()
        StateSaver(self)
        self.show()

    def sizeHint(self):
        """we never want a horizontal scrollbar for player names,
        we always want to see them in full"""
        result = QWidget.sizeHint(self)
        available = KApplication.kApplication().desktop().availableGeometry()
        height = max(result.height(), available.height() * 2 // 3)
        width = max(result.width(), available.width() // 2)
        return QSize(width, height)

    def minimumSizeHint(self):
        """we never want a horizontal scrollbar for player names,
        we always want to see them in full"""
        return self.sizeHint()

    def showEvent(self, dummyEvent):
        """reload the rulesets"""
        self.refresh()

    def refresh(self):
        """retranslate and reload rulesets"""
        self.retranslateUi()
        self.rulesetView.rulesets = Ruleset.availableRulesets()

    def hideEvent(self, event):
        """close all differ dialogs"""
        for differ in self.rulesetView.differs:
            differ.hide()
            del differ
        QWidget.hideEvent(self, event)

    def retranslateUi(self):
        """translate to current language"""
        self.btnCopy.setText(m18n("Copy"))
        self.btnCompare.setText(m18nc('Kajongg ruleset comparer', 'Compare'))
        self.btnRemove.setText(m18n("Remove"))
        self.btnClose.setText(m18n('Close'))
  def setupPanel(self, parentWidget):
    logging.debug('ProstateTRUSNavUltrasound.setupPanel')

    self.connectorNode = self.guideletParent.connectorNode
    self.connectorNodeConnected = False

    collapsibleButton = ctkCollapsibleButton()
    collapsibleButton.setProperty('collapsedHeight', 20)
    setButtonStyle(collapsibleButton, 2.0)
    collapsibleButton.text = "Ultrasound"
    parentWidget.addWidget(collapsibleButton)

    ultrasoundLayout = QFormLayout(collapsibleButton)
    ultrasoundLayout.setContentsMargins(12,4,4,4)
    ultrasoundLayout.setSpacing(4)

    self.connectDisconnectButton = QPushButton("Connect")
    self.connectDisconnectButton.setToolTip("If clicked, connection OpenIGTLink")

    hbox = QHBoxLayout()
    hbox.addWidget(self.connectDisconnectButton)
    ultrasoundLayout.addRow(hbox)

    self.setupIcons()

    self.captureIDSelector = QComboBox()
    self.captureIDSelector.setToolTip("Pick capture device ID")
    self.captureIDSelector.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

    self.volumeReconstructorIDSelector = QComboBox()
    self.volumeReconstructorIDSelector.setToolTip( "Pick volume reconstructor device ID" )
    self.volumeReconstructorIDSelector.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

    self.startStopRecordingButton = QPushButton("  Start Recording")
    self.startStopRecordingButton.setCheckable(True)
    self.startStopRecordingButton.setIcon(self.recordIcon)
    self.startStopRecordingButton.setEnabled(False)
    self.startStopRecordingButton.setToolTip("If clicked, start recording")
    self.startStopRecordingButton.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

    recordParametersControlsLayout = QGridLayout()

    self.filenameLabel = self.createLabel("Filename:", visible=False)
    recordParametersControlsLayout.addWidget(self.filenameLabel, 1, 0)

     # Offline Reconstruction
    self.offlineReconstructButton = QPushButton("  Offline Reconstruction")
    self.offlineReconstructButton.setCheckable(True)
    self.offlineReconstructButton.setIcon(self.recordIcon)
    self.offlineReconstructButton.setEnabled(False)
    self.offlineReconstructButton.setToolTip("If clicked, reconstruct recorded volume")
    self.offlineReconstructButton.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

    self.offlineVolumeToReconstructSelector = QComboBox()
    self.offlineVolumeToReconstructSelector.setEditable(True)
    self.offlineVolumeToReconstructSelector.setToolTip( "Pick/set volume to reconstruct" )
    self.offlineVolumeToReconstructSelector.visible = False

    hbox = QHBoxLayout()
    hbox.addWidget(self.startStopRecordingButton)
    hbox.addWidget(self.offlineReconstructButton)
    ultrasoundLayout.addRow(hbox)

    # Scout scan (record and low resolution reconstruction) and live reconstruction
    # Scout scan part

    self.startStopScoutScanButton = QPushButton("  Scout scan\n  Start recording")
    self.startStopScoutScanButton.setCheckable(True)
    self.startStopScoutScanButton.setIcon(self.recordIcon)
    self.startStopScoutScanButton.setToolTip("If clicked, start recording")
    self.startStopScoutScanButton.setEnabled(False)
    self.startStopScoutScanButton.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

    self.startStopLiveReconstructionButton = QPushButton("  Start live reconstruction")
    self.startStopLiveReconstructionButton.setCheckable(True)
    self.startStopLiveReconstructionButton.setIcon(self.recordIcon)
    self.startStopLiveReconstructionButton.setToolTip("If clicked, start live reconstruction")
    self.startStopLiveReconstructionButton.setEnabled(False)
    self.startStopLiveReconstructionButton.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

    self.displayRoiButton = QToolButton()
    self.displayRoiButton.setCheckable(True)
    self.displayRoiButton.setIcon(self.visibleOffIcon)
    self.displayRoiButton.setToolTip("If clicked, display ROI")

    hbox = QHBoxLayout()
    hbox.addWidget(self.startStopScoutScanButton)
    hbox.addWidget(self.startStopLiveReconstructionButton)
    # hbox.addWidget(self.displayRoiButton)
    ultrasoundLayout.addRow(hbox)

    self.snapshotTimer = QTimer()
    self.snapshotTimer.setSingleShot(True)

    self.onParameterSetSelected()

    return collapsibleButton
class ProstateTRUSNavWidget(GuideletWidget):

    DEFAULT_PLUSSERVER_CHOOSER_TEXT = "Choose PlusServer.exe"
    DEFAULT_CONFIGURATION_CHOOSER_TEXT = "Select Configuration"

    def __init__(self, parent=None):
        GuideletWidget.__init__(self, parent)
        self.plusServerProcess = None
        self.configurationFile = self.getSetting(
            'ConfigurationFile', self.DEFAULT_CONFIGURATION_CHOOSER_TEXT)
        self.serverExecutable = self.getSetting(
            'PlusServer', self.DEFAULT_PLUSSERVER_CHOOSER_TEXT)

    def cleanup(self):
        GuideletWidget.cleanup(self)
        if self.plusServerProcess:
            self.plusServerProcess.terminate()

    def setup(self):
        showPlusServerWidget = True
        if _platform == "linux" or _platform == "linux2" or _platform == "darwin":  #linux or linux or OS X
            message = "Attention: You are running Slicer on Linux or OS X. Do you have PlusServer installed on the current OS?"
            result = QMessageBox.question(slicer.util.mainWindow(),
                                          'ProstateTRUSNav', message,
                                          QMessageBox.Yes | QMessageBox.No)
            showPlusServerWidget = result == QMessageBox.Yes

        if _platform == "win32" or showPlusServerWidget:
            # Windows...
            plusServerCollapsibleButton = ctkCollapsibleButton()
            plusServerCollapsibleButton.text = "PlusServer"
            self.layout.addWidget(plusServerCollapsibleButton)
            self.configurationFileChooserButton = QPushButton(
                self.configurationFile)
            self.configurationFileChooserButton.connect(
                'clicked()', self.onConfigFileSelected)
            self.runPlusServerButton = QPushButton("Run PlusServer")
            self.runPlusServerButton.setCheckable(True)
            self.runPlusServerButton.connect('clicked()',
                                             self.onRunPlusServerButtonClicked)

            self.serverFormLayout = QFormLayout(plusServerCollapsibleButton)

            self.serverExecutableChooserButton = QPushButton(
                self.serverExecutable)
            self.serverExecutableChooserButton.connect(
                'clicked()', self.onServerExecutableSelected)

            hbox = QHBoxLayout()
            hbox.addWidget(self.serverExecutableChooserButton)
            self.serverFormLayout.addRow(hbox)

            hbox = QHBoxLayout()
            hbox.addWidget(self.configurationFileChooserButton)
            hbox.addWidget(self.runPlusServerButton)
            self.serverFormLayout.addRow(hbox)

        GuideletWidget.setup(self)

        # do specific setup here
        if _platform == "win32" or showPlusServerWidget:
            self.launchGuideletButton.setEnabled(False)
            self.checkExecutableAndArgument()

    def checkExecutableAndArgument(self):
        if os.path.exists(self.serverExecutable) and os.path.exists(
                self.configurationFile):
            self.runPlusServerButton.setEnabled(True)
        else:
            self.runPlusServerButton.setEnabled(False)

    def getSetting(self, settingName, defaultValue=""):
        settings = QSettings()
        value = settings.value(self.moduleName + '/' + settingName,
                               defaultValue)
        return value if value is not None and value != "" else defaultValue

    def setSetting(self, settingName, value):
        settings = QSettings()
        settings.setValue(self.moduleName + '/' + settingName, value)

    def addLauncherWidgets(self):
        GuideletWidget.addLauncherWidgets(self)
        # add launcher widget here

    def onServerExecutableSelected(self):
        executable = QFileDialog.getOpenFileName(self.parent,
                                                 "PlusServer Executable",
                                                 self.serverExecutable,
                                                 "*.exe")
        if executable != "" and executable.find("PlusServer.exe"):
            self.serverExecutable = executable
            self.serverExecutableChooserButton.setText(executable)
            self.setSetting("PlusServer", executable)
        self.checkExecutableAndArgument()

    def onConfigFileSelected(self):
        self.configurationFile = QFileDialog.getOpenFileName(
            self.parent, "Choose Configuration File", self.configurationFile,
            "*.xml")
        if self.configurationFile != "":
            self.configurationFileChooserButton.setText(
                os.path.split(self.configurationFile)[1])
            self.setSetting("ConfigurationFile", self.configurationFile)
        self.checkExecutableAndArgument()

    def onRunPlusServerButtonClicked(self):
        if self.runPlusServerButton.isChecked():
            command = [
                self.serverExecutable,
                "--config-file=" + self.configurationFile
            ]
            logging.info("Executing %s %s" % tuple(command))
            self.plusServerProcess = Popen([
                self.serverExecutable,
                "--config-file=" + self.configurationFile
            ])
            if self.plusServerProcess:
                self.runPlusServerButton.setText("Quit Plus Server")
                self.launchGuideletButton.setEnabled(True)
        else:
            if self.plusServerProcess:
                self.plusServerProcess.terminate()
                self.runPlusServerButton.setText("Run PlusServer")
                self.launchGuideletButton.setEnabled(False)

    def collectParameterList(self):
        parameterList = GuideletWidget.collectParameterList(self)
        if not parameterList:
            parameterList = dict()
        parameterList['OfflineVolumeToReconstruct'] = 0,
        return parameterList

    def createGuideletInstance(self, parameterList=None):
        return ProstateTRUSNavGuidelet(None, self.guideletLogic, parameterList)

    def createGuideletLogic(self):
        return ProstateTRUSNavLogic()
class qSlicerMultiVolumeExplorerModuleWidget(
        qSlicerMultiVolumeExplorerSimplifiedModuleWidget):
    def __init__(self, parent=None):
        qSlicerMultiVolumeExplorerSimplifiedModuleWidget.__init__(self, parent)

    def setupAdditionalFrames(self):
        self.setupPlotSettingsFrame()

    def setupInputFrame(self, parent=None):
        self.inputFrame = ctk.ctkCollapsibleButton()
        self.inputFrame.text = "Input"
        self.inputFrame.collapsed = 0
        inputFrameCollapsibleLayout = QFormLayout(self.inputFrame)
        qSlicerMultiVolumeExplorerSimplifiedModuleWidget.setupInputFrame(
            self, parent=inputFrameCollapsibleLayout)
        self.layout.addWidget(self.inputFrame)

        self.fgMultiVolumeSelector = slicer.qMRMLNodeComboBox()
        self.fgMultiVolumeSelector.nodeTypes = ['vtkMRMLMultiVolumeNode']
        self.fgMultiVolumeSelector.setMRMLScene(slicer.mrmlScene)
        self.fgMultiVolumeSelector.addEnabled = 0
        self.fgMultiVolumeSelector.noneEnabled = 1
        self.fgMultiVolumeSelector.toolTip = "Secondary multivolume will be used for the secondary \
      plot in interactive charting. As an example, this can be used to overlay the \
      curve obtained by fitting a model to the data"

        self.inputFrameLayout.addRow(QLabel('Input secondary multivolume'),
                                     self.fgMultiVolumeSelector)

    def setupFrameControlFrame(self):
        qSlicerMultiVolumeExplorerSimplifiedModuleWidget.setupFrameControlFrame(
            self)

        self.frameCopySelector = slicer.qMRMLNodeComboBox()
        self.frameCopySelector.setSizePolicy(QSizePolicy.Ignored,
                                             QSizePolicy.Preferred)
        self.frameCopySelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
        self.frameCopySelector.setMRMLScene(slicer.mrmlScene)
        self.frameCopySelector.addEnabled = 1
        self.frameCopySelector.enabled = 0
        # do not show "children" of vtkMRMLScalarVolumeNode
        self.frameCopySelector.hideChildNodeTypes = [
            "vtkMRMLDiffusionWeightedVolumeNode",
            "vtkMRMLDiffusionTensorVolumeNode", "vtkMRMLVectorVolumeNode"
        ]
        self.extractFrameCopy = False
        self.extractFrameCheckBox = QCheckBox('Enable copying')
        hbox = QHBoxLayout()
        hbox.addWidget(QLabel('Current frame copy'))
        hbox.addWidget(self.frameCopySelector)
        hbox.addWidget(self.extractFrameCheckBox)
        self.inputFrameLayout.addRow(hbox)

    def setupPlotSettingsFrame(self):
        self.plotSettingsFrame = ctk.ctkCollapsibleButton()
        self.plotSettingsFrame.text = "Plotting Settings"
        self.plotSettingsFrame.collapsed = 1
        plotSettingsFrameLayout = QFormLayout(self.plotSettingsFrame)
        self.layout.addWidget(self.plotSettingsFrame)

        # label map for probing
        self.labelMapSelector = slicer.qMRMLNodeComboBox()
        self.labelMapSelector.nodeTypes = ['vtkMRMLLabelMapVolumeNode']
        self.labelMapSelector.toolTip = 'Label map to be probed'
        self.labelMapSelector.setMRMLScene(slicer.mrmlScene)
        self.labelMapSelector.addEnabled = 0
        self.chartButton = QPushButton('Chart')
        self.chartButton.setEnabled(False)

        hbox = QHBoxLayout()
        hbox.addWidget(QLabel('Probed label volume'))
        hbox.addWidget(self.labelMapSelector)
        hbox.addWidget(self.chartButton)
        plotSettingsFrameLayout.addRow(hbox)

        self.iCharting = QCheckBox('Interactive charting')
        self.iCharting.setChecked(True)
        plotSettingsFrameLayout.addRow(self.iCharting)

        self.iChartingMode = QButtonGroup()
        self.iChartingIntensity = QRadioButton('Signal intensity')
        self.iChartingIntensityFixedAxes = QRadioButton(
            'Fixed range intensity')
        self.iChartingPercent = QRadioButton('Percentage change')
        self.iChartingIntensity.setChecked(1)
        self.iChartingMode.addButton(self.iChartingIntensity)
        self.iChartingMode.addButton(self.iChartingIntensityFixedAxes)
        self.iChartingMode.addButton(self.iChartingPercent)

        hbox = QHBoxLayout()
        self.plottingModeGroupBox = QGroupBox('Plotting mode:')
        plottingModeLayout = QVBoxLayout()
        self.plottingModeGroupBox.setLayout(plottingModeLayout)
        plottingModeLayout.addWidget(self.iChartingIntensity)
        plottingModeLayout.addWidget(self.iChartingIntensityFixedAxes)
        plottingModeLayout.addWidget(self.iChartingPercent)
        hbox.addWidget(self.plottingModeGroupBox)

        self.showLegendCheckBox = QCheckBox('Display legend')
        self.showLegendCheckBox.setChecked(0)
        self.xLogScaleCheckBox = QCheckBox('Use log scale for X axis')
        self.xLogScaleCheckBox.setChecked(0)
        self.yLogScaleCheckBox = QCheckBox('Use log scale for Y axis')
        self.yLogScaleCheckBox.setChecked(0)

        self.plotGeneralSettingsGroupBox = QGroupBox('General Plot options:')
        plotGeneralSettingsLayout = QVBoxLayout()
        self.plotGeneralSettingsGroupBox.setLayout(plotGeneralSettingsLayout)
        plotGeneralSettingsLayout.addWidget(self.showLegendCheckBox)
        plotGeneralSettingsLayout.addWidget(self.xLogScaleCheckBox)
        plotGeneralSettingsLayout.addWidget(self.yLogScaleCheckBox)
        hbox.addWidget(self.plotGeneralSettingsGroupBox)
        plotSettingsFrameLayout.addRow(hbox)

        self.nFramesBaselineCalculation = QSpinBox()
        self.nFramesBaselineCalculation.minimum = 1
        hbox = QHBoxLayout()
        hbox.addWidget(QLabel('Frame count(baseline calculation):'))
        hbox.addWidget(self.nFramesBaselineCalculation)
        plotSettingsFrameLayout.addRow(hbox)

    def setupPlottingFrame(self, parent=None):
        self.plotFrame = ctk.ctkCollapsibleButton()
        self.plotFrame.text = "Plotting"
        self.plotFrame.collapsed = 0
        plotFrameLayout = QGridLayout(self.plotFrame)
        self.layout.addWidget(self.plotFrame)
        qSlicerMultiVolumeExplorerSimplifiedModuleWidget.setupPlottingFrame(
            self, parent=plotFrameLayout)

    def onDockChartViewToggled(self, checked):
        qSlicerMultiVolumeExplorerSimplifiedModuleWidget.onDockChartViewToggled(
            self, checked)
        if checked:
            self.layout.removeWidget(self.plotFrame)
            self.plotFrame.hide()

    def dockChartView(self):
        qSlicerMultiVolumeExplorerSimplifiedModuleWidget.dockChartView(self)
        self.layout.addWidget(self.plotFrame)
        self.plotFrame.show()

    def setFramesEnabled(self, enabled):
        qSlicerMultiVolumeExplorerSimplifiedModuleWidget.setFramesEnabled(
            self, enabled)
        self.plotSettingsFrame.setEnabled(enabled)
        self.plotFrame.setEnabled(enabled)
        self.plotFrame.collapsed = 0 if enabled else 1

    def setupConnections(self):
        qSlicerMultiVolumeExplorerSimplifiedModuleWidget.setupConnections(self)
        self.labelMapSelector.connect('currentNodeChanged(vtkMRMLNode*)',
                                      self.onLabelNodeChanged)
        self.chartButton.connect('clicked()', self.onLabeledChartRequested)
        self.xLogScaleCheckBox.connect('stateChanged(int)',
                                       self.onXLogScaleRequested)
        self.yLogScaleCheckBox.connect('stateChanged(int)',
                                       self.onYLogScaleRequested)
        self.nFramesBaselineCalculation.valueChanged.connect(
            self.onFrameCountBaselineCalculationChanged)
        self.iChartingMode.buttonClicked.connect(self.onChartingModeChanged)
        self.showLegendCheckBox.connect('stateChanged(int)',
                                        self.onShowLegendChanged)
        self.fgMultiVolumeSelector.connect('currentNodeChanged(vtkMRMLNode*)',
                                           self.onForegroundInputChanged)
        self.extractFrameCheckBox.connect('stateChanged(int)',
                                          self.onExtractFrameChanged)
        self.frameCopySelector.connect('mrmlSceneChanged(vtkMRMLScene*)',
                                       self.onVFMRMLSceneChanged)

    def onFrameCountBaselineCalculationChanged(self, value):
        self._multiVolumeIntensityChart.nFramesForBaselineCalculation = value

    def onChartingModeChanged(self, button):
        if button is self.iChartingIntensity:
            self._multiVolumeIntensityChart.activateSignalIntensityMode()
        elif button is self.iChartingIntensityFixedAxes:
            self._multiVolumeIntensityChart.activateFixedRangeIntensityMode()
        elif button is self.iChartingPercent:
            self._multiVolumeIntensityChart.activatePercentageChangeMode()

    def onShowLegendChanged(self, checked):
        self._multiVolumeIntensityChart.showLegend = True if checked == 2 else False

    def onXLogScaleRequested(self, checked):
        self._multiVolumeIntensityChart.showXLogScale = True if checked == 2 else False

    def onYLogScaleRequested(self, checked):
        self._multiVolumeIntensityChart.showYLogScale = True if checked == 2 else False

    def onLVMRMLSceneChanged(self, mrmlScene):
        self.labelMapSelector.setMRMLScene(slicer.mrmlScene)

    def onVFMRMLSceneChanged(self, mrmlScene):
        self.frameCopySelector.setMRMLScene(slicer.mrmlScene)

    def onLabelNodeChanged(self):
        labelNode = self.labelMapSelector.currentNode()
        self.chartButton.setEnabled(labelNode is not None
                                    and self._bgMultiVolumeNode is not None)

    def onForegroundInputChanged(self):
        logging.info(
            "qSlicerMultiVolumeExplorerModuleWidget:ForegroundInputChanged")
        self._fgMultiVolumeNode = self.fgMultiVolumeSelector.currentNode()
        self._multiVolumeIntensityChart.fgMultiVolumeNode = self.fgMultiVolumeSelector.currentNode(
        )
        self.refreshGUIForNewBackgroundImage()

    def onBackgroundInputChanged(self):
        qSlicerMultiVolumeExplorerSimplifiedModuleWidget.onBackgroundInputChanged(
            self)

        if self._bgMultiVolumeNode is not None:
            self.frameCopySelector.setCurrentNode(None)
            self.nFramesBaselineCalculation.maximum = self._bgMultiVolumeNode.GetNumberOfFrames(
            )
        self.onLabelNodeChanged()

    '''
  If extract button is checked, will copy the current frame to the
  selected volume node on each event from frame slider
  '''

    def onExtractFrameChanged(self, checked):
        if checked:
            self.extractFrameCopy = True
            self.onSliderChanged(self.frameSlider.value)
        else:
            self.extractFrameCopy = False

    def onSliderChanged(self, frameId):
        qSlicerMultiVolumeExplorerSimplifiedModuleWidget.onSliderChanged(
            self, frameId)
        frameId = int(frameId)
        if self.extractFrameCopy:
            frameVolume = self.frameCopySelector.currentNode()
            frameVolumeCopy = Helper.extractFrame(frameVolume,
                                                  self._bgMultiVolumeNode,
                                                  frameId)
            if not frameVolume:
                self.frameCopySelector.setCurrentNode(frameVolumeCopy)
            frameName = '%s frame %d' % (self._bgMultiVolumeNode.GetName(),
                                         frameId)
            frameVolumeCopy.SetName(frameName)

    def onLabeledChartRequested(self):
        labelNode = self.labelMapSelector.currentNode()
        mvNode = self._bgMultiVolumeNode

        mvLabels = MultiVolumeIntensityChartView.getMultiVolumeLabels(
            self._bgMultiVolumeNode)

        chartViewNode = LabeledImageChartView(
            labelNode=labelNode,
            multiVolumeNode=mvNode,
            multiVolumeLabels=mvLabels,
            baselineFrames=self.nFramesBaselineCalculation,
            displayPercentageChange=self.iChartingPercent.checked)
        chartViewNode.requestChartCreation()

    def processEvent(self, observee, event):
        if not self.iCharting.checked:
            return
        qSlicerMultiVolumeExplorerSimplifiedModuleWidget.processEvent(
            self, observee, event)
예제 #46
0
import sys
from qt import QApplication, QPushButton

app=QApplication(sys.argv)
button=QPushButton(None)
button.setText("Hello World")
app.setMainWidget(button)
button.show()
app.exec_loop()
class qSlicerMultiVolumeExplorerSimplifiedModuleWidget:
    def __init__(self, parent=None):
        logging.debug(
            "qSlicerMultiVolumeExplorerSimplifiedModuleWidget:init() called")
        if not parent or not hasattr(parent, "layout"):
            self.parent = slicer.qMRMLWidget()
            self.parent.setLayout(QVBoxLayout())
        else:
            self.parent = parent

        self.layout = self.parent.layout()

        self._bgMultiVolumeNode = None
        self._fgMultiVolumeNode = None

        self.styleObserverTags = []
        self.sliceWidgetsPerStyle = {}

        self.chartPopupWindow = None
        self.chartPopupSize = QSize(600, 300)
        self.chartPopupPosition = QPoint(0, 0)

    def hide(self):
        self.widget.hide()

    def show(self):
        self.widget.show()

    def setup(self):
        self.widget = QWidget()
        layout = QGridLayout()
        self.widget.setLayout(layout)
        self.layout.addWidget(self.widget)
        self.widget.show()
        self.layout = layout

        self.setupInputFrame()
        self.setupFrameControlFrame()
        self.setupAdditionalFrames()
        self.setupPlottingFrame()

        self.setFramesEnabled(False)

        self.timer = QTimer()
        self.timer.setInterval(50)

        self.setupConnections()

        # initialize slice observers (from DataProbe.py)
        # keep list of pairs: [observee,tag] so they can be removed easily
        self.styleObserverTags = []
        # keep a map of interactor styles to sliceWidgets so we can easily get sliceLogic
        self.sliceWidgetsPerStyle = {}
        self.refreshObservers()

    def setupInputFrame(self, parent=None):
        if not parent:
            parent = self.layout
        self.bgMultiVolumeSelector = slicer.qMRMLNodeComboBox()
        self.bgMultiVolumeSelector.nodeTypes = ['vtkMRMLMultiVolumeNode']
        self.bgMultiVolumeSelector.setMRMLScene(slicer.mrmlScene)
        self.bgMultiVolumeSelector.addEnabled = 0
        self._bgMultiVolumeSelectorLabel = QLabel('Input multivolume')
        inputFrameWidget = QWidget()
        self.inputFrameLayout = QFormLayout()
        inputFrameWidget.setLayout(self.inputFrameLayout)
        self.inputFrameLayout.addRow(self._bgMultiVolumeSelectorLabel,
                                     self.bgMultiVolumeSelector)
        parent.addWidget(inputFrameWidget)

    def setupFrameControlFrame(self):
        # TODO: initialize the slider based on the contents of the labels array
        self.frameSlider = ctk.ctkSliderWidget()
        self.frameSlider.setSizePolicy(QSizePolicy.Ignored,
                                       QSizePolicy.Preferred)
        self.frameLabel = QLabel('Current frame number')
        self.playButton = QPushButton('Play')
        self.playButton.toolTip = 'Iterate over multivolume frames'
        self.playButton.checkable = True
        frameControlHBox = QHBoxLayout()
        frameControlHBox.addWidget(self.frameLabel)
        frameControlHBox.addWidget(self.frameSlider)
        frameControlHBox.addWidget(self.playButton)
        self.inputFrameLayout.addRow(frameControlHBox)

    def setupAdditionalFrames(self):
        pass

    def setupPlottingFrame(self, parent=None):
        if not parent:
            parent = self.layout
        self.plottingFrameWidget = QWidget()
        self.plottingFrameLayout = QGridLayout()
        self.plottingFrameWidget.setLayout(self.plottingFrameLayout)
        self._multiVolumeIntensityChart = MultiVolumeIntensityChartView()
        self.popupChartButton = QPushButton("Undock chart")
        self.popupChartButton.setCheckable(True)
        self.plottingFrameLayout.addWidget(
            self._multiVolumeIntensityChart.chartView)
        self.plottingFrameLayout.addWidget(self.popupChartButton)
        parent.addWidget(self.plottingFrameWidget)

    def setupConnections(self):
        self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                            self.onVCMRMLSceneChanged)
        self.bgMultiVolumeSelector.connect('currentNodeChanged(vtkMRMLNode*)',
                                           self.onBackgroundInputChanged)
        self.playButton.connect('toggled(bool)', self.onPlayButtonToggled)
        self.frameSlider.connect('valueChanged(double)', self.onSliderChanged)
        self.timer.connect('timeout()', self.goToNext)
        self.popupChartButton.connect('toggled(bool)',
                                      self.onDockChartViewToggled)

    def onDockChartViewToggled(self, checked):
        if checked:
            self.chartPopupWindow = QDialog()
            self.chartPopupWindow.setWindowFlags(
                PythonQt.QtCore.Qt.WindowStaysOnTopHint)
            layout = QGridLayout()
            self.chartPopupWindow.setLayout(layout)
            layout.addWidget(self._multiVolumeIntensityChart.chartView)
            layout.addWidget(self.popupChartButton)
            self.chartPopupWindow.finished.connect(self.dockChartView)
            self.chartPopupWindow.resize(self.chartPopupSize)
            self.chartPopupWindow.move(self.chartPopupPosition)
            self.chartPopupWindow.show()
            self.popupChartButton.setText("Dock chart")
            self._multiVolumeIntensityChart.chartView.show()
        else:
            self.chartPopupWindow.close()

    def dockChartView(self):
        self.chartPopupSize = self.chartPopupWindow.size
        self.chartPopupPosition = self.chartPopupWindow.pos
        self.plottingFrameLayout.addWidget(
            self._multiVolumeIntensityChart.chartView)
        self.plottingFrameLayout.addWidget(self.popupChartButton)
        self.popupChartButton.setText("Undock chart")
        self.popupChartButton.disconnect('toggled(bool)',
                                         self.onDockChartViewToggled)
        self.popupChartButton.checked = False
        self.popupChartButton.connect('toggled(bool)',
                                      self.onDockChartViewToggled)

    def onSliderChanged(self, frameId):
        if self._bgMultiVolumeNode is None:
            return
        newValue = int(frameId)
        self.setCurrentFrameNumber(newValue)

    def onVCMRMLSceneChanged(self, mrmlScene):
        logging.debug(
            "qSlicerMultiVolumeExplorerSimplifiedModuleWidget:onVCMRMLSceneChanged"
        )
        self.bgMultiVolumeSelector.setMRMLScene(slicer.mrmlScene)
        self.onBackgroundInputChanged()

    def refreshGUIForNewBackgroundImage(self):
        self._multiVolumeIntensityChart.reset()
        self.setFramesEnabled(True)
        if self._fgMultiVolumeNode and self._bgMultiVolumeNode:
            Helper.SetBgFgVolumes(self._bgMultiVolumeNode.GetID(),
                                  self._fgMultiVolumeNode.GetID())
        else:
            Helper.SetBgVolume(self._bgMultiVolumeNode.GetID())
        self.refreshFrameSlider()
        self._multiVolumeIntensityChart.bgMultiVolumeNode = self._bgMultiVolumeNode
        self.refreshObservers()

    def getBackgroundMultiVolumeNode(self):
        return self.bgMultiVolumeSelector.currentNode()

    def onBackgroundInputChanged(self):
        self._bgMultiVolumeNode = self.getBackgroundMultiVolumeNode()

        if self._bgMultiVolumeNode is not None:
            self.refreshGUIForNewBackgroundImage()
        else:
            self.setFramesEnabled(False)

    def onPlayButtonToggled(self, checked):
        if self._bgMultiVolumeNode is None:
            return
        if checked:
            self.timer.start()
            self.playButton.text = 'Stop'
        else:
            self.timer.stop()
            self.playButton.text = 'Play'

    def processEvent(self, observee, event):
        # logging.debug("processing event %s" % event)
        if self._bgMultiVolumeNode is None:
            return

        # TODO: use a timer to delay calculation and compress events
        if event == 'LeaveEvent':
            # reset all the readouts
            # TODO: reset the label text
            return

        if not self.sliceWidgetsPerStyle.has_key(observee):
            return

        interactor = observee.GetInteractor()
        self.createChart(self.sliceWidgetsPerStyle[observee],
                         interactor.GetEventPosition())

    def createChart(self, sliceWidget, position):
        self._multiVolumeIntensityChart.createChart(sliceWidget, position)

    def setCurrentFrameNumber(self, frameNumber):
        mvDisplayNode = self._bgMultiVolumeNode.GetDisplayNode()
        mvDisplayNode.SetFrameComponent(frameNumber)

    def setFramesEnabled(self, enabled):
        pass

    def refreshObservers(self):
        """ When the layout changes, drop the observers from
    all the old widgets and create new observers for the
    newly created widgets"""
        self.removeObservers()
        # get new slice nodes
        layoutManager = slicer.app.layoutManager()
        sliceNodeCount = slicer.mrmlScene.GetNumberOfNodesByClass(
            'vtkMRMLSliceNode')
        for nodeIndex in xrange(sliceNodeCount):
            # find the widget for each node in scene
            sliceNode = slicer.mrmlScene.GetNthNodeByClass(
                nodeIndex, 'vtkMRMLSliceNode')
            sliceWidget = layoutManager.sliceWidget(sliceNode.GetLayoutName())
            if sliceWidget:
                # add observers and keep track of tags
                style = sliceWidget.sliceView().interactorStyle()
                self.sliceWidgetsPerStyle[style] = sliceWidget
                events = ("MouseMoveEvent", "EnterEvent", "LeaveEvent")
                for event in events:
                    tag = style.AddObserver(event, self.processEvent)
                    self.styleObserverTags.append([style, tag])

    def removeObservers(self):
        for observee, tag in self.styleObserverTags:
            observee.RemoveObserver(tag)
        self.styleObserverTags = []
        self.sliceWidgetsPerStyle = {}

    def refreshFrameSlider(self):
        self.frameSlider.minimum = 0
        if not self._bgMultiVolumeNode:
            self.frameSlider.maximum = 0
            return
        nFrames = self._bgMultiVolumeNode.GetNumberOfFrames()
        self.frameSlider.maximum = nFrames - 1

    def goToNext(self):
        currentElement = self.frameSlider.value
        currentElement += 1
        if currentElement > self.frameSlider.maximum:
            currentElement = 0
        self.frameSlider.value = currentElement
class ProstateTRUSNavUltrasound(UltraSound):

  OFFLINE_VOLUME_FILENAME = "RecVol_Reference.mha"
  SCOUT_VOLUME_FILENAME = "ScoutScan.mha"
  LIVE_VOLUME_FILENAME = "LiveReconstructedVolume.mha"

  RECORDING_FILENAME = "Recording.mha"
  SCOUT_RECORDING_FILENAME = "ScoutScanRecording.mha"
  LIVE_RECORDING_FILENAME = LIVE_VOLUME_FILENAME

  SCOUT_VOLUME_NODE_NAME = "ScoutScan"
  OFFLINE_VOLUME_NODE_NAME = "RecVol_Reference"
  LIVE_VOLUME_NODE_NAME = "liveReconstruction"

  APPLY_HOLE_FILLING_FOR_SNAPSHOT = False
  SNAPSHOT_INTERVAL = 3
  OUTPUT_VOLUME_SPACING = 3
  LIVE_OUTPUT_VOLUME_SPACING = 1

  @property
  def roiNode(self):
    return self._roiNode

  @roiNode.setter
  def roiNode(self, node):
    self._roiNode=node
    if node is not None:
      self.startStopLiveReconstructionButton.setEnabled(True)
    else:
      self.startStopLiveReconstructionButton.setEnabled(False)

  def __init__(self, guideletParent):
    UltraSound.__init__(self, guideletParent)

    self.parameterNode = guideletParent.parameterNode
    self.parameterNodeObserver = None
    self._roiNode = None
    self.liveOutputSpacingValue = [self.LIVE_OUTPUT_VOLUME_SPACING, self.LIVE_OUTPUT_VOLUME_SPACING,
                                   self.LIVE_OUTPUT_VOLUME_SPACING]
    self.outputSpacing = [self.OUTPUT_VOLUME_SPACING, self.OUTPUT_VOLUME_SPACING, self.OUTPUT_VOLUME_SPACING]
    self.roiOrigin = None
    self.roiExtent = None
    self.defaultParameterNode = None
    self.logic = ProstateTRUSNavUltrasoundLogic()

  def setupPanel(self, parentWidget):
    logging.debug('ProstateTRUSNavUltrasound.setupPanel')

    self.connectorNode = self.guideletParent.connectorNode
    self.connectorNodeConnected = False

    collapsibleButton = ctkCollapsibleButton()
    collapsibleButton.setProperty('collapsedHeight', 20)
    setButtonStyle(collapsibleButton, 2.0)
    collapsibleButton.text = "Ultrasound"
    parentWidget.addWidget(collapsibleButton)

    ultrasoundLayout = QFormLayout(collapsibleButton)
    ultrasoundLayout.setContentsMargins(12,4,4,4)
    ultrasoundLayout.setSpacing(4)

    self.connectDisconnectButton = QPushButton("Connect")
    self.connectDisconnectButton.setToolTip("If clicked, connection OpenIGTLink")

    hbox = QHBoxLayout()
    hbox.addWidget(self.connectDisconnectButton)
    ultrasoundLayout.addRow(hbox)

    self.setupIcons()

    self.captureIDSelector = QComboBox()
    self.captureIDSelector.setToolTip("Pick capture device ID")
    self.captureIDSelector.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

    self.volumeReconstructorIDSelector = QComboBox()
    self.volumeReconstructorIDSelector.setToolTip( "Pick volume reconstructor device ID" )
    self.volumeReconstructorIDSelector.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

    self.startStopRecordingButton = QPushButton("  Start Recording")
    self.startStopRecordingButton.setCheckable(True)
    self.startStopRecordingButton.setIcon(self.recordIcon)
    self.startStopRecordingButton.setEnabled(False)
    self.startStopRecordingButton.setToolTip("If clicked, start recording")
    self.startStopRecordingButton.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

    recordParametersControlsLayout = QGridLayout()

    self.filenameLabel = self.createLabel("Filename:", visible=False)
    recordParametersControlsLayout.addWidget(self.filenameLabel, 1, 0)

     # Offline Reconstruction
    self.offlineReconstructButton = QPushButton("  Offline Reconstruction")
    self.offlineReconstructButton.setCheckable(True)
    self.offlineReconstructButton.setIcon(self.recordIcon)
    self.offlineReconstructButton.setEnabled(False)
    self.offlineReconstructButton.setToolTip("If clicked, reconstruct recorded volume")
    self.offlineReconstructButton.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

    self.offlineVolumeToReconstructSelector = QComboBox()
    self.offlineVolumeToReconstructSelector.setEditable(True)
    self.offlineVolumeToReconstructSelector.setToolTip( "Pick/set volume to reconstruct" )
    self.offlineVolumeToReconstructSelector.visible = False

    hbox = QHBoxLayout()
    hbox.addWidget(self.startStopRecordingButton)
    hbox.addWidget(self.offlineReconstructButton)
    ultrasoundLayout.addRow(hbox)

    # Scout scan (record and low resolution reconstruction) and live reconstruction
    # Scout scan part

    self.startStopScoutScanButton = QPushButton("  Scout scan\n  Start recording")
    self.startStopScoutScanButton.setCheckable(True)
    self.startStopScoutScanButton.setIcon(self.recordIcon)
    self.startStopScoutScanButton.setToolTip("If clicked, start recording")
    self.startStopScoutScanButton.setEnabled(False)
    self.startStopScoutScanButton.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

    self.startStopLiveReconstructionButton = QPushButton("  Start live reconstruction")
    self.startStopLiveReconstructionButton.setCheckable(True)
    self.startStopLiveReconstructionButton.setIcon(self.recordIcon)
    self.startStopLiveReconstructionButton.setToolTip("If clicked, start live reconstruction")
    self.startStopLiveReconstructionButton.setEnabled(False)
    self.startStopLiveReconstructionButton.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

    self.displayRoiButton = QToolButton()
    self.displayRoiButton.setCheckable(True)
    self.displayRoiButton.setIcon(self.visibleOffIcon)
    self.displayRoiButton.setToolTip("If clicked, display ROI")

    hbox = QHBoxLayout()
    hbox.addWidget(self.startStopScoutScanButton)
    hbox.addWidget(self.startStopLiveReconstructionButton)
    # hbox.addWidget(self.displayRoiButton)
    ultrasoundLayout.addRow(hbox)

    self.snapshotTimer = QTimer()
    self.snapshotTimer.setSingleShot(True)

    self.onParameterSetSelected()

    return collapsibleButton

  def setupResliceDriver(self):
    layoutManager = slicer.app.layoutManager()
    # Show ultrasound in red view.
    redSlice = layoutManager.sliceWidget('Red')
    redSliceLogic = redSlice.sliceLogic()
    redSliceLogic.GetSliceCompositeNode().SetBackgroundVolumeID(self.liveUltrasoundNode_Reference.GetID())

    resliceLogic = slicer.modules.volumereslicedriver.logic()
    if resliceLogic:
      redNode = slicer.util.getNode('vtkMRMLSliceNodeRed')
      redNode.SetSliceResolutionMode(slicer.vtkMRMLSliceNode.SliceResolutionMatchVolumes)
      resliceLogic.SetDriverForSlice(self.liveUltrasoundNode_Reference.GetID(), redNode)
      resliceLogic.SetModeForSlice(6, redNode) # Transverse mode, default for PLUS ultrasound.
    else:
      logging.warning('Logic not found for Volume Reslice Driver')

  def createCollapsibleButton(self, text, collapsed=False):
    collapsibleButton = ctkCollapsibleButton()
    collapsibleButton.text = text
    collapsibleButton.collapsed = collapsed
    return collapsibleButton

  def createLabel(self, text, visible=True):
    label = QLabel()
    label.setText(text)
    label.visible = visible
    return label

  def setupConnections(self):
    self.startStopRecordingButton.connect('clicked(bool)', self.onStartStopRecordingButtonClicked)
    self.offlineReconstructButton.connect('clicked(bool)', self.onReconstVolume)
    self.startStopScoutScanButton.connect('clicked(bool)', self.onStartStopScoutScanButtonClicked)
    self.startStopLiveReconstructionButton.connect('clicked(bool)', self.onStartStopLiveReconstructionButtonClicked)
    self.displayRoiButton.connect('clicked(bool)', self.onDisplayRoiButtonClicked)
    self.captureIDSelector.connect('currentIndexChanged(QString)', self.updateParameterNodeFromGui)
    self.volumeReconstructorIDSelector.connect('currentIndexChanged(QString)', self.updateParameterNodeFromGui)
    self.offlineVolumeToReconstructSelector.connect('currentIndexChanged(int)', self.updateParameterNodeFromGui)
    self.displayRoiButton.connect('clicked(bool)', self.updateParameterNodeFromGui)
    self.snapshotTimer.timeout.connect(self.onRequestVolumeReconstructionSnapshot)
    self.connectDisconnectButton.connect('clicked(bool)', self.onConnectDisconnectButtonClicked)

  def disconnect(self):
    self.startStopRecordingButton.disconnect('clicked(bool)', self.onStartStopRecordingButtonClicked)
    self.offlineReconstructButton.disconnect('clicked(bool)', self.onReconstVolume)
    self.startStopScoutScanButton.disconnect('clicked(bool)', self.onStartStopScoutScanButtonClicked)
    self.startStopLiveReconstructionButton.disconnect('clicked(bool)', self.onStartStopLiveReconstructionButtonClicked)
    self.displayRoiButton.disconnect('clicked(bool)', self.onDisplayRoiButtonClicked)
    self.captureIDSelector.disconnect('currentIndexChanged(QString)', self.updateParameterNodeFromGui)
    self.volumeReconstructorIDSelector.disconnect('currentIndexChanged(QString)', self.updateParameterNodeFromGui)
    self.offlineVolumeToReconstructSelector.disconnect('currentIndexChanged(int)', self.updateParameterNodeFromGui)
    self.displayRoiButton.disconnect('clicked(bool)', self.updateParameterNodeFromGui)
    self.snapshotTimer.timeout.disconnect(self.onRequestVolumeReconstructionSnapshot)
    self.connectDisconnectButton.disconnect('clicked(bool)', self.onConnectDisconnectButtonClicked)

  def setupIcons(self):
    self.plusRemoteModuleDirectoryPath = slicer.modules.plusremote.path.replace("PlusRemote.py", "")
    self.recordIcon = QIcon(self.plusRemoteModuleDirectoryPath + '/Resources/Icons/icon_Record.png')
    self.stopIcon = QIcon(self.plusRemoteModuleDirectoryPath + '/Resources/Icons/icon_Stop.png')
    self.waitIcon = QIcon(self.plusRemoteModuleDirectoryPath + '/Resources/Icons/icon_Wait.png')
    self.visibleOffIcon = QIcon(":Icons\VisibleOff.png")
    self.visibleOnIcon = QIcon(":Icons\VisibleOn.png")

  def onParameterSetSelected(self):
    # Set up default values for new nodes
    if self.parameterNode:
      self.plusRemoteLogic.setDefaultParameters(self.parameterNode)
    self.updateGuiFromParameterNode()

  def updateGuiFromParameterNode(self):

    self.parameterVolumeList = {'OfflineVolumeToReconstruct': self.offlineVolumeToReconstructSelector}
    for parameter in self.parameterVolumeList:
      if self.parameterNode.GetParameter(parameter):
        self.parameterVolumeList[parameter].blockSignals(True)
      self.parameterVolumeList[parameter].blockSignals(False)

    if self.parameterNode.GetParameter('CaptureID'):
      self.captureIDSelector.blockSignals(True)
      for i in range(0, self.captureIDSelector.count):
        if self.parameterNode.GetParameter('CaptureID') == self.captureIDSelector.itemText(i):
          self.captureIDSelector.setCurrentIndex(int(self.parameterNode.GetParameter('CaptureIdIndex')))
      self.captureIDSelector.blockSignals(False)

    if self.parameterNode.GetParameter('VolumeReconstructor'):
      self.volumeReconstructorIDSelector.blockSignals(True)
      for i in range(0, self.volumeReconstructorIDSelector.count):
        if self.parameterNode.GetParameter('VolumeReconstructor') == self.volumeReconstructorIDSelector.itemText(i):
          self.volumeReconstructorIDSelector.setCurrentIndex(int(self.parameterNode.GetParameter('VolumeReconstructorIndex')))
      self.volumeReconstructorIDSelector.blockSignals(False)

      self.roiNode = self.parameterNode.GetNthNodeReference('ROI', 0)

  def updateParameterNodeFromGui(self):
    #Update parameter node value to save when user change value in the interface
    if not self.parameterNode:
      return
    self.parametersList = {'CaptureID': self.captureIDSelector.currentText,
                           'CaptureIdIndex': self.captureIDSelector.currentIndex,
                           'VolumeReconstructor': self.volumeReconstructorIDSelector.currentText,
                           'VolumeReconstructorIndex': self.volumeReconstructorIDSelector.currentIndex,
                           'OfflineVolumeToReconstruct': self.offlineVolumeToReconstructSelector.currentIndex}
    for parameter in self.parametersList:
      self.parameterNode.SetParameter(parameter, str(self.parametersList[parameter]))
    if self.roiNode:
      roiNodeID = self.roiNode.GetID()
      self.parameterNode.SetNthNodeReferenceID('ROI', 0, roiNodeID)

#
# Connector observation and actions
#

  def onConnectorNodeConnected(self):
    logging.debug("ProstateTrusUltrasound:onConnectorNodeConnected")
    self.connectorNodeConnected = True
    self.captureIDSelector.setDisabled(False)
    self.volumeReconstructorIDSelector.setDisabled(False)
    self.plusRemoteLogic.getCaptureDeviceIds(self.connectorNode.GetID(),
                                   self.onGetCaptureDeviceCommandResponseReceived)
    self.plusRemoteLogic.getVolumeReconstructorDeviceIds(self.connectorNode.GetID(),
                                               self.onGetVolumeReconstructorDeviceCommandResponseReceived)
    self.connectDisconnectButton.setText("Disconnect")

  def onConnectorNodeDisconnected(self):
    logging.debug("ProstateTrusUltrasound:onConnectorNodeDisconnected")
    self.connectorNodeConnected = False
    self.startStopRecordingButton.setEnabled(False)
    self.startStopScoutScanButton.setEnabled(False)
    self.startStopLiveReconstructionButton.setEnabled(False)
    self.offlineReconstructButton.setEnabled(False)
    self.captureIDSelector.setDisabled(True)
    self.volumeReconstructorIDSelector.setDisabled(True)
    self.connectDisconnectButton.setText("Connect")

  def getLiveVolumeRecNode(self):
    liveVolumeRecNode = slicer.util.getNode(self.LIVE_VOLUME_NODE_NAME)
    return liveVolumeRecNode

  def getOfflineVolumeRecNode(self):
    offlineVolumeRecNode = slicer.util.getNode(self.OFFLINE_VOLUME_NODE_NAME)
    return offlineVolumeRecNode

  def getScoutVolumeNode(self):
    scoutScanVolumeNode = slicer.util.getNode(self.SCOUT_VOLUME_NODE_NAME)
    return scoutScanVolumeNode

  def onConnectDisconnectButtonClicked(self):
    if self.connectorNode.GetState() == slicer.vtkMRMLIGTLConnectorNode.STATE_CONNECTED:
      self.connectorNode.Stop()
    else:
      self.connectorNode.Start()

  def onStartStopRecordingButtonClicked(self):
    if self.startStopRecordingButton.isChecked():
      self.startStopRecordingButton.setText("  Stop Recording")
      self.startStopRecordingButton.setIcon(self.stopIcon)
      self.startStopRecordingButton.setToolTip( "If clicked, stop recording" )
      self.onStartRecording(self.generateRecordingOutputFilename())
    else:
      self.startStopRecordingButton.setText("  Start Recording")
      self.startStopRecordingButton.setIcon(self.recordIcon)
      self.startStopRecordingButton.setToolTip( "If clicked, start recording" )
      self.onStopRecording(self.onVolumeRecorded)

  def onStartStopScoutScanButtonClicked(self):
    if self.startStopScoutScanButton.isChecked():
      self.startStopScoutScanButton.setText("  Scout Scan\n  Stop Recording and Reconstruct Recorded Volume")
      self.startStopScoutScanButton.setIcon(self.stopIcon)
      self.startStopScoutScanButton.setToolTip( "If clicked, stop recording and reconstruct recorded volume" )
      self.onStartRecording(self.generateScoutRecordingOutputFilename())
    else:
      self.onStopRecording(self.onScoutVolumeRecorded)

  def onStartStopLiveReconstructionButtonClicked(self):
    if self.startStopLiveReconstructionButton.isChecked():
      if self.roiNode:
        self.roiOrigin, self.roiExtent = self.logic.updateVolumeOriginAndExtentFromROI(self.LIVE_OUTPUT_VOLUME_SPACING,
                                                                                       self.roiNode)
      self.startStopLiveReconstructionButton.setText("  Stop Live Reconstruction")
      self.startStopLiveReconstructionButton.setIcon(self.stopIcon)
      self.startStopLiveReconstructionButton.setToolTip( "If clicked, stop live reconstruction" )
      self.onStartRecording(self.getLiveRecordingOutputFilename())
      self.onStartReconstruction()
    else:
      self.startStopLiveReconstructionButton.setText("  Start Live Reconstruction")
      self.startStopLiveReconstructionButton.setIcon(self.recordIcon)
      self.startStopLiveReconstructionButton.setToolTip( "If clicked, start live reconstruction" )
      self.onStopRecording(self.printCommandResponse)
      self.onStopReconstruction()

  def onDisplayRoiButtonClicked(self):
    if self.displayRoiButton.isChecked():
      self.displayRoiButton.setIcon(self.visibleOnIcon)
      self.displayRoiButton.setToolTip("If clicked, hide ROI")
      if self.roiNode:
        self.roiNode.SetDisplayVisibility(1)
    else:
      self.displayRoiButton.setIcon(self.visibleOffIcon)
      self.displayRoiButton.setToolTip("If clicked, display ROI")
      if self.roiNode:
        self.roiNode.SetDisplayVisibility(0)

  def generateRecordingOutputFilename(self):
    return self.plusRemoteLogic.addTimestampToFilename(self.RECORDING_FILENAME)

  def generateScoutRecordingOutputFilename(self):
    return self.plusRemoteLogic.addTimestampToFilename(self.SCOUT_RECORDING_FILENAME)

  def getLiveRecordingOutputFilename(self):
    return self.plusRemoteLogic.addTimestampToFilename(self.LIVE_RECORDING_FILENAME)

  def getLiveReconstructionOutputFilename(self):
    return self.plusRemoteLogic.addTimestampToFilename(self.LIVE_VOLUME_FILENAME)

  def onStartRecording(self, filename):
    self.plusRemoteLogic.startRecording(self.connectorNode.GetID(), self.captureIDSelector.currentText,
                                        filename, self.printCommandResponse)

  def onStopRecording(self, callback):
    self.plusRemoteLogic.stopRecording(self.connectorNode.GetID(), self.captureIDSelector.currentText, callback)

  def onStartReconstruction(self):
    if self.roiNode:
      self.roiOrigin, self.roiExtent = self.logic.updateVolumeOriginAndExtentFromROI(self.LIVE_OUTPUT_VOLUME_SPACING,
                                                                                     self.roiNode)
    self.plusRemoteLogic.startVolumeReconstuction(self.connectorNode.GetID(),
                                                   self.volumeReconstructorIDSelector.currentText,
                                                   self.liveOutputSpacingValue, self.roiOrigin,
                                                   self.roiExtent, self.printCommandResponse,
                                                   self.getLiveReconstructionOutputFilename(), self.LIVE_VOLUME_NODE_NAME)
    # Set up timer for requesting snapshot
    self.snapshotTimer.start(self.SNAPSHOT_INTERVAL*1000)

  def onStopReconstruction(self):
    self.snapshotTimer.stop()
    self.plusRemoteLogic.stopVolumeReconstruction(self.connectorNode.GetID(),
                                                  self.volumeReconstructorIDSelector.currentText,
                                                  self.onVolumeLiveReconstructed,
                                                  self.getLiveReconstructionOutputFilename(),
                                                  self.LIVE_VOLUME_NODE_NAME)

  def onReconstVolume(self):
    self.offlineReconstructButton.setIcon(self.waitIcon)
    self.offlineReconstructButton.setText("  Offline Reconstruction in progress ...")
    self.offlineReconstructButton.setEnabled(False)
    self.plusRemoteLogic.reconstructRecorded(self.connectorNode.GetID(), self.volumeReconstructorIDSelector.currentText,
                                             self.offlineVolumeToReconstructSelector.currentText, self.outputSpacing,
                                             self.onVolumeReconstructed, self.OFFLINE_VOLUME_FILENAME,
                                             self.OFFLINE_VOLUME_NODE_NAME)

  def onScoutScanReconstVolume(self):
    self.startStopScoutScanButton.setIcon(self.waitIcon)
    self.startStopScoutScanButton.setText("  Scout Scan\n  Reconstruction in progress ...")
    self.startStopScoutScanButton.setEnabled(False)
    self.plusRemoteLogic.reconstructRecorded(self.connectorNode.GetID(), self.volumeReconstructorIDSelector.currentText,
                                             self.lastScoutRecordingOutputFilename, self.outputSpacing,
                                             self.onScoutVolumeReconstructed, self.SCOUT_VOLUME_FILENAME,
                                             self.SCOUT_VOLUME_NODE_NAME)

  def onRequestVolumeReconstructionSnapshot(self, stopFlag = ""):
    self.plusRemoteLogic.getVolumeReconstructionSnapshot(self.connectorNode.GetID(),
                                                         self.volumeReconstructorIDSelector.currentText,
                                                         self.LIVE_VOLUME_FILENAME,
                                                         self.LIVE_VOLUME_NODE_NAME,
                                                         self.APPLY_HOLE_FILLING_FOR_SNAPSHOT, self.onSnapshotAcquired)

  def executeCommandDelayed(self, method, delay=100):
    # Order of OpenIGTLink message receiving and processing is not guaranteed to be the same
    # therefore we wait a bit to make sure the image message is processed as well
    QTimer.singleShot(delay, method)

  def printCommandResponse(self, command, q):
    statusText = "Command {0} [{1}]: {2}\n".format(command.GetCommandName(), command.GetID(),
                                                   command.StatusToString(command.GetStatus()))
    if command.GetResponseMessage():
      statusText = statusText + command.GetResponseMessage()
    elif command.GetResponseText():
      statusText = statusText + command.GetResponseText()
    logging.debug(statusText)

  def onGetCaptureDeviceCommandResponseReceived(self, command, q):
    self.printCommandResponse(command, q)
    if command.GetStatus() != command.CommandSuccess:
      return

    captureDeviceIdsListString = command.GetResponseMessage()
    if captureDeviceIdsListString:
      captureDevicesIdsList = captureDeviceIdsListString.split(",")
    else:
      captureDevicesIdsList = []

    for i in range(0,len(captureDevicesIdsList)):
      if self.captureIDSelector.findText(captureDevicesIdsList[i]) == -1:
        self.captureIDSelector.addItem(captureDevicesIdsList[i])

  def onGetVolumeReconstructorDeviceCommandResponseReceived(self, command, q):
    self.printCommandResponse(command, q)
    if command.GetStatus() != command.CommandSuccess:
      return

    volumeReconstructorDeviceIdsListString = command.GetResponseMessage()
    if volumeReconstructorDeviceIdsListString:
      volumeReconstructorDeviceIdsList = volumeReconstructorDeviceIdsListString.split(",")
    else:
      volumeReconstructorDeviceIdsList = []

    self.volumeReconstructorIDSelector.clear()
    self.volumeReconstructorIDSelector.addItems(volumeReconstructorDeviceIdsList)
    self.startStopRecordingButton.setEnabled(True)
    self.offlineReconstructButton.setEnabled(True)
    self.startStopScoutScanButton.setEnabled(True)
    if self.roiNode:
      self.startStopLiveReconstructionButton.setEnabled(True)

  def onVolumeRecorded(self, command, q):
    self.printCommandResponse(command, q)
    self.offlineReconstructButton.setEnabled(True)

    volumeToReconstructFileName = os.path.basename(command.GetResponseMessage())
    self.offlineVolumeToReconstructSelector.insertItem(0,volumeToReconstructFileName)
    self.offlineVolumeToReconstructSelector.setCurrentIndex(0)

  def onScoutVolumeRecorded(self, command, q):
    self.printCommandResponse(command,q)
    self.offlineReconstructButton.setEnabled(True)

    if command.GetStatus() == command.CommandExpired:
      logging.fatal("Scout Volume Recording: Timeout while waiting for volume reconstruction result")
      return

    if command.GetStatus() == command.CommandSuccess:
      self.lastScoutRecordingOutputFilename = os.path.basename(command.GetResponseMessage())
      self.onScoutScanReconstVolume()

  def onVolumeReconstructed(self, command, q):
    self.printCommandResponse(command,q)

    self.offlineReconstructButton.setIcon(self.recordIcon)
    self.offlineReconstructButton.setText("Offline Reconstruction")
    self.offlineReconstructButton.setEnabled(True)
    self.offlineReconstructButton.setChecked(False)

    if command.GetStatus() == command.CommandExpired:
      # volume reconstruction command timed out
      logging.fatal("Volume Reconstruction: Timeout while waiting for volume reconstruction result")
      return

    if command.GetStatus() != command.CommandSuccess:
      logging.debug("Volume Reconstruction: " + command.GetResponseMessage())
      return

    self.executeCommandDelayed(self.onVolumeReconstructedFinalize)

  def onVolumeReconstructedFinalize(self):
    applicationLogic = slicer.app.applicationLogic()
    applicationLogic.FitSliceToAll()
    self.guideletParent.showVolumeRendering(self.getOfflineVolumeRecNode())

  def onScoutVolumeReconstructed(self, command, q):
    self.printCommandResponse(command,q)

    if command.GetStatus() == command.CommandExpired:
      logging.fatal("Scout Volume Reconstruction: Timeout while waiting for scout volume reconstruction result")
      return

    self.startStopScoutScanButton.setIcon(self.recordIcon)
    self.startStopScoutScanButton.setText("  Scout Scan\n  Start Recording")
    self.startStopScoutScanButton.setEnabled(True)

    if command.GetStatus() != command.CommandSuccess:
      logging.debug("Scout Volume Reconstruction: " + command.GetResponseMessage())
      return

    self.executeCommandDelayed(self.onScoutVolumeReconstructedFinalize)

  def onScoutVolumeReconstructedFinalize(self):
    # Create and initialize ROI after scout scan because low resolution scout scan is used to set
    # a smaller ROI for the live high resolution reconstruction
    self.roiNode = self.logic.onRoiInitialization(self.SCOUT_VOLUME_NODE_NAME, self.roiNode)
    self.roiOrigin, self.roiExtent = self.logic.updateVolumeOriginAndExtentFromROI(self.LIVE_OUTPUT_VOLUME_SPACING,
                                                                                   self.roiNode)
    scoutScanVolumeNode = self.getScoutVolumeNode()

    applicationLogic = slicer.app.applicationLogic()
    applicationLogic.FitSliceToAll()

    self.guideletParent.showVolumeRendering(scoutScanVolumeNode)

  def onSnapshotAcquired(self, command, q):
    self.printCommandResponse(command,q)

    if not self.startStopLiveReconstructionButton.isChecked():
      # live volume reconstruction is not active
      return

    self.executeCommandDelayed(self.onSnapshotAcquiredFinalize)

  def onSnapshotAcquiredFinalize(self):
    self.guideletParent.showVolumeRendering(self.getLiveVolumeRecNode())
    self.snapshotTimer.start(self.SNAPSHOT_INTERVAL*1000)

  def onVolumeLiveReconstructed(self, command, q):
    self.printCommandResponse(command,q)

    if command.GetStatus() == command.CommandExpired:
      logging.fatal("LIVE Volume Reconstruction: Failed to stop volume reconstruction")
      return

    if command.GetStatus() != command.CommandSuccess:
      logging.debug("LIVE Volume Reconstruction " + command.GetResponseMessage())
      return

    self.executeCommandDelayed(self.getLiveVolumeRecNode)

  def onVolumeLiveReconstructedFinalize(self):
    self.guideletParent.showVolumeRendering(self.getLiveVolumeRecNode())