def testBoolinSignal(self): b = QPushButton() b.setCheckable(True) self._clicked = False b.toggled[bool].connect(self.buttonCb) b.toggle() self.assert_(self._clicked)
def addPage(self, buttontext, widget): button = QPushButton(buttontext) button.setCheckable(True) button.setChecked(self.rightpane.count() == 0) self.buttongroup.addButton(button, self.rightpane.count()) self.groupbox.layout().addWidget(button) self.rightpane.addWidget(widget)
class ActualFakeActuator(object): def __init__(self, callback=None): self.callback = callback self.app = QApplication(sys.argv) self.vlayout = QVBoxLayout() self.button = QPushButton('light') self.button.pressed.connect(self._button_callback) self.button.setCheckable(True) self.button.setChecked(True) self.button.setStyleSheet('background-color: white') self.vlayout.addWidget(self.button) self.slider = QSlider() self.slider.setOrientation(Qt.Horizontal) self.vlayout.addWidget(self.slider) self.dial = QDial() self.dial.setNotchesVisible(True) self.dial.setWrapping(True) self.vlayout.addWidget(self.dial) self.quit = QPushButton('Quit') self.quit.clicked.connect(self.app.quit) self.vlayout.addWidget(self.quit) self.group = QGroupBox('Fake Actuator') self.group.setLayout(self.vlayout) def _button_callback(self): if self.button.isChecked(): self.button.setStyleSheet('background-color: red') else: self.button.setStyleSheet('background-color: white') def light_on(self): return self.button.isChecked() def toggle_light(self, on): self.button.setChecked(on) def volume(self): return self.slider.value() def set_volume(self, value): self.slider.setValue(value) def position(self): return self.dial.value() def set_position(self, value): self.dial.setValue(value) def run(self): self.group.show() self.app.exec_()
def testWithCppSlot(self): '''QMenuBar.addAction(id, object, slot)''' menubar = QMenuBar() widget = QPushButton() widget.setCheckable(True) widget.setChecked(False) action = menubar.addAction("Accounts", widget, SLOT("toggle()")) action.activate(QAction.Trigger) self.assert_(widget.isChecked())
def testBasic(self): '''QTest.mouseClick with QCheckBox''' button = QPushButton() button.setCheckable(True) button.setChecked(False) QTest.mouseClick(button, Qt.LeftButton) self.assert_(button.isChecked()) QTest.mouseClick(button, Qt.LeftButton) self.assertFalse(button.isChecked())
def setCanvas(self): ''' set widgets for a tab page - left side show image of current frame - right side show two plots: raw and rms - bot: button to edit triggers and slider to adjust video-emg offset ''' ######################## # set matplotlib plots # ######################## self.fig = Figure(dpi=70) self.canvas = FigureCanvas(self.fig) self.canvas.setParent(self.ui.mainFrame) self.axes = self.fig.add_subplot(211) self.axesRMS = self.fig.add_subplot(212) self.mpl_toolbar = NavigationToolbar2(self.canvas, self.ui.mainFrame) self.canvas.mpl_connect('draw_event', self.onDraw) #################################### # add button to matplotlib toolbar # #################################### redb = QPushButton('Edit Triggers') redb.setCheckable(True) self.mpl_toolbar.addWidget(redb) redb.clicked[bool].connect(self.toggleEditMode) # container for current frame of video layout = pq.GraphicsLayoutWidget() vb = layout.addViewBox() vb.setAspectLocked(True) self.ri = pq.ImageItem() vb.addItem(self.ri) # layout to organize elements grid = QGridLayout() wrapper = QWidget() vbox = QVBoxLayout(wrapper) splitter = QSplitter() vbox.addWidget(self.canvas) vbox.addWidget(self.mpl_toolbar) wrapper.setLayout(vbox) splitter.addWidget(layout) splitter.addWidget(wrapper) grid.addWidget(splitter) self.ri.show() layout.show() self.ui.mainFrame.setLayout(grid)
def __init__(self, p_def, p_direction="HOR"): """ 生成一个按钮组 :param p_def: [{id, name, type=None}] :return: None """ QWidget.__init__(self) # 定义 self.__definition = p_def # 按钮字典 self.__buttons = dict() # 设置方向 if "HOR" == p_direction: self.__layout = QHBoxLayout() else: self.__layout = QVBoxLayout() # 设置 layout self.setLayout(self.__layout) # 添加按钮 for t_def in self.__definition: _id = t_def["id"] _name = t_def["name"] _type = None if "type" not in t_def else t_def["type"] _button = QPushButton(_name) # Toggle button if _type is not None and "CHECK" == _type: _button.setCheckable(True) _button.clicked.connect(partial(self.sig_clicked.emit, _id)) self.__buttons["id"] = _button self.__layout.addWidget(_button) # 默认向右对齐 self.align_back() # 设置样式 self.setStyleSheet(get_theme("Buttons"))
class AddPresetDialog(QDialog): def __init__(self, parent=None): super(AddPresetDialog, self).__init__(parent) self.setWindowTitle(self.tr("Add IMAP Server Preset")) self.resize(388, 125) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setGeometry(QRect(184, 80, 181, 32)) self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setCenterButtons(False) self.save_btn = QPushButton("&Save") self.save_btn.setDefault(True) self.save_btn.setEnabled(False) self.cancel_btn = QPushButton(self.tr("&Cancel")) self.cancel_btn.setCheckable(True) self.cancel_btn.setAutoDefault(False) self.buttonBox.addButton(self.save_btn, QDialogButtonBox.AcceptRole) self.buttonBox.addButton(self.cancel_btn, QDialogButtonBox.RejectRole) self.preset_name_le = QLineEdit(self) self.preset_name_le.setGeometry(QRect(134, 12, 231, 20)) self.lb_name = QLabel(self) self.lb_name.setGeometry(QRect(14, 16, 58, 14)) self.lb_name.setText(self.tr("Name")) self.server_address_le = QLineEdit(self) self.server_address_le.setGeometry(QRect(134, 45, 231, 20)) self.lb_server = QLabel(self) self.lb_server.setGeometry(QRect(14, 48, 81, 16)) self.lb_server.setText(self.tr("IMAP Server")) self.lb_info = QLabel(self) self.lb_info.setGeometry(QRect(14, 90, 161, 16)) self.lb_info.setText(self.tr("(SSL is always on.)")) self.buttonBox.accepted.connect(self.act_save_preset) self.buttonBox.rejected.connect(self.reject) self.init_settings() self.settings.beginGroup("Server Presets") self.presetNameList = [] for preset in self.settings.allKeys(): self.presetNameList.append(preset) self.settings.endGroup() self.preset_name_le.textChanged.connect(self.check_preset_name_availability) self.server_address_le.textChanged.connect(self.check_server_address) # --------------------------------------------------------------------- def init_settings(self): QCoreApplication.setOrganizationName("erdinc.me") QCoreApplication.setOrganizationDomain("erdinc.me") QCoreApplication.setApplicationName("IMAPLinkParser") self.settings = QSettings() # self.settings.clear() # --------------------------------------------------------------------- @Slot() def act_save_preset(self): try: self.settings.beginGroup("Server Presets") self.settings.setValue(self.preset_name_le.text(), self.server_address_le.text()) self.settings.endGroup() except: self.reject() self.accept() # --------------------------------------------------------------------- @Slot(unicode) def check_preset_name_availability(self, text): if text in self.presetNameList: self.save_btn.setEnabled(False) self.lb_info.setText('<p style="color:red;">Preset name exists!') else: if self.server_address_le.text() and self.preset_name_le.text(): self.save_btn.setEnabled(True) self.lb_info.setText(self.tr("(SSL is always on.)")) else: self.save_btn.setEnabled(False) self.lb_info.setText(self.tr("(SSL is always on.)")) # --------------------------------------------------------------------- @Slot(unicode) def check_server_address(self): if self.server_address_le.text(): preset = self.preset_name_le.text() if preset and preset not in self.presetNameList: self.save_btn.setEnabled(True) else: self.save_btn.setEnabled(False)
class OptionsContainer(QWidget): def __init__(self,main_window): QWidget.__init__(self) self.main_window = main_window self.layout = QGridLayout() self.setLayout(self.layout) self.lr = numpy.zeros(2) self.fps = QSpinBox() self.fps.setValue(25) self.fps.setMinimum(1) self.fps.setMaximum(1000) self.layout.addWidget(QLabel("FPS:"),10,10) self.layout.addWidget(self.fps,10,11) self.capture_area_group = QButtonGroup() self.capture_area_fs = QRadioButton("Full Screen") self.connect(self.capture_area_fs, SIGNAL("clicked()"),self.capture_area_change) self.capture_area_fs.setChecked(True) self.capture_area_sa = QRadioButton("Selected Area") self.connect(self.capture_area_sa, SIGNAL("clicked()"),self.capture_area_change) self.capture_area_group.addButton(self.capture_area_fs) self.capture_area_group.addButton(self.capture_area_sa) self.capture_area_group.setExclusive(True) self.layout.addWidget(self.capture_area_fs,12,10) self.layout.addWidget(self.capture_area_sa,12,11) self.sa_group = QGroupBox() self.sa_grid = QGridLayout() self.sa_group.setLayout(self.sa_grid) self.sa_ul_bt = QPushButton("Select Upper Left") self.connect(self.sa_ul_bt, SIGNAL("clicked()"), self.select_ul) self.sa_lr_bt = QPushButton("Select Lower Right") self.connect(self.sa_lr_bt, SIGNAL("clicked()"), self.select_lr) self.sa_x = QSpinBox() self.sa_y = QSpinBox() self.sa_w = QSpinBox() self.sa_h = QSpinBox() for sb in [self.sa_h,self.sa_w,self.sa_x,self.sa_y]: sb.setMaximum(999999) sb.setMinimum(0) self.sa_grid.addWidget(self.sa_ul_bt,14,10,1,1) self.sa_grid.addWidget(self.sa_lr_bt,15,10,1,1) self.sa_grid.addWidget(QLabel("x"),14,11,1,1) self.sa_grid.addWidget(self.sa_x,14,12,1,1) self.sa_grid.addWidget(QLabel("y"),15,11,1,1) self.sa_grid.addWidget(self.sa_y,15,12,1,1) self.sa_grid.addWidget(QLabel("w"),16,11,1,1) self.sa_grid.addWidget(self.sa_w,16,12,1,1) self.sa_grid.addWidget(QLabel("h"),17,11,1,1) self.sa_grid.addWidget(self.sa_h,17,12,1,1) self.sa_show_bt = QPushButton("Show Area") self.sa_show_bt.setCheckable(True) self.connect(self.sa_show_bt, SIGNAL("clicked()"), self.show_selected_area) self.sa_grid.addWidget(self.sa_show_bt,18,10,1,10) self.sa_group.hide() self.layout.addWidget(self.sa_group,14,10,1,10) self.capture_delay = QSpinBox() self.capture_delay.setMinimum(0) self.capture_delay.setMaximum(10000) self.layout.addWidget(QLabel("Capture Delay"),18,10,1,1) self.layout.addWidget(self.capture_delay,18,11,1,1) self.capture_bt = QPushButton("Capture") self.stop_capture_bt = QPushButton("Stop") self.stop_capture_bt.hide() self.layout.addWidget(self.capture_bt,20,10,1,10) self.layout.addWidget(self.stop_capture_bt,30,10,1,10) self.ffmpeg_flags = QLineEdit() self.ffmpeg_flags.setText("-qscale 0 -vcodec mpeg4") self.layout.addWidget(QLabel("FFMPEG Flags:"),40,10) self.layout.addWidget(self.ffmpeg_flags,50,10,1,10) self.encode_bt = QPushButton("Encode Video") self.layout.addWidget(self.encode_bt,60,10,1,10) self.open_dir_bt = QPushButton("Open Directory") self.layout.addWidget(self.open_dir_bt,80,10,1,10) self.connect(self.open_dir_bt, SIGNAL("clicked()"),self.open_cwd) self.selected_area = SelectedArea() def show_selected_area(self): x = self.sa_x.value() y = self.sa_y.value() w = self.sa_w.value() h = self.sa_h.value() self.selected_area.setGeometry(x,y,w,h) self.selected_area.activateWindow() self.selected_area.raise_() if(self.sa_show_bt.isChecked()): self.selected_area.show() else:self.selected_area.hide() def select_ul(self): print "select_ul" self.clicked = False self.tw = TransWindow() self.tw.mouse_press = False self.tw.show() self.connect(self.tw, SIGNAL("mouse_press()"),self.set_ul) def select_lr(self): print "select_lr" self.clicked = False self.tw = TransWindow() self.tw.mouse_press = False self.tw.show() self.connect(self.tw, SIGNAL("mouse_press()"),self.set_lr) def set_ul(self): self.sa_x.setValue( self.tw.pos[0]) self.sa_y.setValue( self.tw.pos[1]) self.sa_w.setValue( self.lr[0] - self.sa_x.value()) self.sa_h.setValue( self.lr[1] - self.sa_y.value()) self.show_selected_area() def set_lr(self): self.lr = numpy.array([self.tw.pos[0],self.tw.pos[1]]) self.sa_w.setValue( self.tw.pos[0] - self.sa_x.value()) self.sa_h.setValue( self.tw.pos[1] - self.sa_y.value()) self.show_selected_area() def capture_area_change(self): print "capture_area_change" if(self.capture_area_fs.isChecked()): self.sa_group.hide() else: self.sa_group.show() self.adjustSize() self.main_window.adjustSize() def open_cwd(self): #will need to detect os and change accordingly os.system("open {}".format(os.getcwd()))
class InfoFrame( QFrame ): def __init__(self, parent = None, name = None, level=0, customValueGui = None ): self.name = name super(InfoFrame, self).__init__(parent) #interface methods go here.. their visibility needs to be connected to the expansion button self.methodElems = [] #level designates the value on the side of the name shown.. 0: top-level interface component self.level = level self.valueGuiElem = customValueGui # custom element to show within component #self.customValueGui = customValueGui self.initUi() def initUi(self): # button for interface expansion with name on it self.expButton = QPushButton(self.name, self) self.expButton.setCheckable(True) self.expButton.setChecked(False) #start unexpanded #level designates the value on the side of the name shown.. # 0: top-level interface component # 1: method component # 2: custom value component (pipeline components, practically) Need to provide valueGuiElem on contructor. if self.level == 0: # slider for switching interface activity state, 3 states: active, tentative, disabled self.valueGuiElem = ActivationSlider(self) elif self.level == 1: self.valueGuiElem = MethodValueLabel(self) else: if self.valueGuiElem == None: print "Warning: custom ui field empty, component level custom!" # connect the toggle signal to the expansion method self.expButton.toggled[bool].connect( self.showMethodElems ) lo = QHBoxLayout() lo.addSpacing( self.level * 15 ) lo.addWidget( self.expButton ) if self.valueGuiElem: lo.addWidget( self.valueGuiElem ) mainLayout = QVBoxLayout() mainLayout.addLayout(lo) self.setFrameStyle( QFrame.Box | QFrame.Raised ) self.setLayout( mainLayout ) def addGuiElem( self, elem ): self.methodElems.append( elem ) self.layout().addWidget( elem ) #self.expButton.toggled[bool].connect( elem.setVisible ) def showMethodElems(self, toggled ): if toggled: for child in self.methodElems: child.show() else: for child in self.methodElems: child.hide() # recursively displays, or hides, the child elements.. def showMethodElemsRecur(self, toggled ): for child in self.methodElems: if toggled: child.show() else: child.hide() if type( child ) == InfoFrame: child.showMethodElemsRecur(toggled)
def __init__(self, store): super(ItemSelector, self).__init__() self.setWindowTitle('Select Item Checkpoint') self.store = store items = self.store.get('/item') layout = QGridLayout() self.setLayout(layout) self.item_buttons = {} width = 5 label = QLabel('Selected Item') label.setAlignment(Qt.AlignHCenter) label.setStyleSheet('font-weight: bold;') layout.addWidget(label, 0, 0, 1, width) for (i, item) in enumerate(sorted(items)): parts = items[item]['name'].split(' ') + ['({})'.format(items[item]['location'])] lines = [''] for part in parts: if len(lines[-1]) > 10: lines.append('') lines[-1] += ' ' + part button = QPushButton('\n'.join([line.strip() for line in lines])) icon = QIcon(items[item].get('thumbnail', '')) if not icon.isNull(): button.setIcon(icon) button.setIconSize(QSize(64, 64)) button.setCheckable(True) button.clicked.connect(_call(self.select_item, item)) self.item_buttons[item] = button layout.addWidget(button, i // width + 1, i % width) self.select_item(self.store.get('/robot/selected_item')) self.box_buttons = {} label = QLabel('Selected Box') label.setAlignment(Qt.AlignHCenter) label.setStyleSheet('font-weight: bold;') layout.addWidget(label, 0, width + 1) for (i, box) in enumerate(sorted(self.store.get('/order'))): button = QPushButton(box) button.setCheckable(True) button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) button.clicked.connect(_call(self.select_box, box)) self.box_buttons[box] = button layout.addWidget(button, i + 1, width + 1) self.select_box(self.store.get('/robot/selected_box')) self.bin_buttons = {} label = QLabel('Selected Bin') label.setAlignment(Qt.AlignHCenter) label.setStyleSheet('font-weight: bold;') layout.addWidget(label, 0, width + 2) for (i, bin) in enumerate(sorted(self.store.get('/shelf/bin'))): button = QPushButton(bin) button.setCheckable(True) button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) button.clicked.connect(_call(self.select_bin, bin)) self.bin_buttons[bin] = button layout.addWidget(button, i + 1, width + 2) self.select_bin(self.store.get('/robot/selected_bin'))
class ProfileSelection(QDialog): ''' classdocs ''' removeProfile = Signal(Athlete_Model) profileSelected = Signal(Athlete_Model) profileUpdate_request = Signal(Athlete_Model, Athlete_Model) lastProfileDeleted = Signal() def __init__(self, athletesList): ''' Constructor ''' QDialog.__init__(self) self.setWindowTitle("Profile Selection") self.athletesList = athletesList self._initGUI() def _initGUI(self): topHLayout = QHBoxLayout() hLayout = QHBoxLayout() vLayout = QVBoxLayout() # Label greeterText = QLabel("Welcome to <b>Pushup app</b>." + \ "<br><br> Select a profile:") vLayout.addWidget(greeterText) # List self.list = QListWidget() self.list.setMinimumWidth(150) self.list.setSelectionMode(QAbstractItemView.SingleSelection) # SingleSelection is the default value, but I prefer to be sure self.list.itemSelectionChanged.connect(self._activateButtons) for athlete in self.athletesList: iconW = QIcon.fromTheme("user-available") # doens't work on Mac and Windows # http://qt-project.org/doc/qt-4.8/qicon.html#fromTheme listW = QListWidgetItem(iconW, athlete._name) listW.setData(Qt.UserRole, athlete) self.list.addItem(listW) topHLayout.addWidget(self.list) self.profileWidget = ProfileFormWidget() self.profileWidget.hide() topHLayout.addWidget(self.profileWidget) vLayout.addLayout(topHLayout) vLayout.addLayout(hLayout) # Buttons self.okBtn = QPushButton("Ok") self.okBtn.setDisabled(True) self.okBtn.setDefault(True) self.okBtn.clicked.connect(self._okButtonSlot) self.list.itemDoubleClicked.connect(self._okButtonSlot) cancelBtn = QPushButton("Cancel") cancelBtn.clicked.connect(self._cancelButtonSlot) self.editBtn = QPushButton("Edit") self.editBtn.setDisabled(True) self.editBtn.setCheckable(True) self.editBtn.clicked.connect(self._toggleProfileEdit) self.saveBtn = QPushButton("Save changes") # Saves the changes made on the profile self.saveBtn.hide() self.saveBtn.clicked.connect(self._saveButtonSlot) self.removeProfileBtn = QPushButton("Remove Profile") self.removeProfileBtn.setDisabled(True) self.removeProfileBtn.clicked.connect(self._removeProfile_Dialog) hLayout.addWidget(self.editBtn) hLayout.addWidget(self.removeProfileBtn) hLayout.addWidget(cancelBtn) hLayout.addWidget(self.okBtn) hLayout.addWidget(self.saveBtn) self.setLayout(vLayout) def getSelectedProfile(self): selectedListItem = self.list.selectedItems()[0] athleteProfile = selectedListItem.data(Qt.UserRole) return athleteProfile def updateList(self, athletes): self.list.clear() self.athletesList = athletes for athlete in self.athletesList: iconW = QIcon.fromTheme("user-available") # doens't work on Mac and Windows # http://qt-project.org/doc/qt-4.8/qicon.html#fromTheme listW = QListWidgetItem(iconW, athlete._name) listW.setData(Qt.UserRole, athlete) self.list.addItem(listW) def resetWidget(self): """ Resets the widget to the initial laoyout. Should be used only in specific cases """ self.editBtn.setChecked(False) self._toggleProfileEdit() def _removeProfile_Dialog(self): """Runs a prompt dialog. Ask the user if he really wants to remove the selected profile. """ confirmationDialog = QMessageBox() confirmationDialog.setText("Do you really want to remove the selected profile ?") confirmationDialog.setInformativeText("Profile deletion can not be undone") confirmationDialog.setIcon(QMessageBox.Question) confirmationDialog.setStandardButtons(QMessageBox.Yes | QMessageBox.No) confirmationDialog.accepted.connect(self._emitRemoveProfile) ret = confirmationDialog.exec_() if ret==QMessageBox.Yes: self._emitRemoveProfile() def _emitRemoveProfile(self): athlete = self.getSelectedProfile() rowToDelete = 0 for index, element in enumerate(self.athletesList): if element == athlete: rowToDelete = index self.list.takeItem(rowToDelete) self.athletesList.remove(athlete) self.removeProfile.emit(athlete) def _okButtonSlot(self): athlete = self.list.selectedItems()[0].data(Qt.UserRole) self.accept() # is it correct ? Maybe self.close() is better ? # Or should I redefine the accept() method ? #athleteProfile = self.getSelectedProfile() self.profileSelected.emit(athlete) def _cancelButtonSlot(self): if len(self.athletesList) == 0: self.lastProfileDeleted.emit() self.reject() def _saveButtonSlot(self): selectedProfile = self.getSelectedProfile() updatedProfile = self.profileWidget.getProfile() self.profileUpdate_request.emit(selectedProfile, updatedProfile) #self._toggleProfileEdit() def _toggleProfileEdit(self): if self.editBtn.isChecked(): self.profileWidget.setProfile(self.getSelectedProfile()) self.profileWidget.show() self.saveBtn.show() self.okBtn.hide() self.removeProfileBtn.hide() else: self.saveBtn.hide() self.profileWidget.hide() self.okBtn.show() self.removeProfileBtn.show() def _activateButtons(self): selectedItems = self.list.selectedItems() if len(selectedItems)!=0 : self.okBtn.setDisabled(False) self.removeProfileBtn.setDisabled(False) self.editBtn.setDisabled(False) else : self.okBtn.setDisabled(True) self.removeProfileBtn.setDisabled(True) self.editBtn.setDisabled(True)
class AVRProgrammerDialog(QtFixes.QDialog): def __init__(self): super(AVRProgrammerDialog, self).__init__(CWMainGUI.getInstance()) # self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint) self.avr = AVRProgrammer() self.setWindowTitle("ChipWhisperer-Lite AVR Programmer") layout = QVBoxLayout() layoutFW = QHBoxLayout() self.flashLocation = QtFixes.QLineEdit() flashFileButton = QPushButton("Find") flashFileButton.clicked.connect(self.findFlash) layoutFW.addWidget(QLabel("FLASH File")) layoutFW.addWidget(self.flashLocation) layoutFW.addWidget(flashFileButton) layout.addLayout(layoutFW) self.flashLocation.setText(QSettings().value("avr-flash-location")) # Add buttons readSigBut = QPushButton("Check Signature") readSigBut.clicked.connect(self.readSignature) verifyFlashBut = QPushButton("Verify FLASH") verifyFlashBut.clicked.connect(self.verifyFlash) verifyFlashBut.setEnabled(False) progFlashBut = QPushButton("Erase/Program/Verify FLASH") progFlashBut.clicked.connect(self.writeFlash) layoutBut = QHBoxLayout() layoutBut.addWidget(readSigBut) layoutBut.addWidget(verifyFlashBut) layoutBut.addWidget(progFlashBut) layout.addLayout(layoutBut) layoutFuse = QHBoxLayout() readFuseBut = QPushButton("Read Fuses") readFuseBut.clicked.connect(self.readFuses) writeFuseBut = QPushButton("Write Fuses") writeFuseBut.clicked.connect(self.writeFuses) self.lowfuseLine = QtFixes.QLineEdit("?") self.lowfuseLine.setMaxLength(2) self.lowfuseLine.setFixedWidth(25) self.highfuseLine = QtFixes.QLineEdit("?") self.highfuseLine.setMaxLength(2) self.highfuseLine.setFixedWidth(25) self.extfuseLine = QtFixes.QLineEdit("?") self.extfuseLine.setMaxLength(2) self.extfuseLine.setFixedWidth(25) # Don't allow use to change these fuses self.highfuseLine.setReadOnly(True) self.extfuseLine.setReadOnly(True) layoutFuse.addWidget(readFuseBut) layoutFuse.addWidget(QLabel("LOW:")) layoutFuse.addWidget(self.lowfuseLine) layoutFuse.addWidget(QLabel("HIGH:")) layoutFuse.addWidget(self.highfuseLine) layoutFuse.addWidget(QLabel("EXT:")) layoutFuse.addWidget(self.extfuseLine) layoutFuse.addWidget(writeFuseBut) layout.addLayout(layoutFuse) layoutExtra = QHBoxLayout() self.clockMode = QPushButton("Enable Slow Clock Mode") self.clockMode.setCheckable(True) self.clockMode.clicked.connect(self.toggleSlowClock) layoutExtra.addWidget(self.clockMode) layoutExtra.addStretch() layout.addLayout(layoutExtra) # Add status stuff self.statusLine = QPlainTextEdit() self.statusLine.setReadOnly(True) # self.statusLine.setFixedHeight(QFontMetrics(self.statusLine.font()).lineSpacing() * 5 + 10) layout.addWidget(self.statusLine) self.avr.newTextLog.connect(self.append) # Set dialog layout self.setLayout(layout) def append(self, text): self.statusLine.appendPlainText(text) def toggleSlowClock(self): if self.clockMode.isChecked(): self.avr.enableSlowClock(True) self.clockMode.setText("Disable Slow Clock Mode") else: self.avr.enableSlowClock(False) self.clockMode.setText("Enable Slow Clock Mode") def reject(self): #Ensure we disable slow-clock mode if self.clockMode.isChecked(): self.clockMode.setChecked(False) self.toggleSlowClock() #Release AVR self.avr.close() QDialog.reject(self) def findFlash(self): fname, _ = QFileDialog.getOpenFileName( self, 'Find FLASH File', QSettings().value("avr-flash-location"), '*.hex') if fname: self.flashLocation.setText(fname) QSettings().setValue("avr-flash-location", fname) def readSignature(self, close=True): self.avr.find() if close: self.avr.close() def readFuses(self): try: self.readSignature(close=False) self.statusLine.appendPlainText("Reading fuses") lfuse = self.avr.readFuse("low") hfuse = self.avr.readFuse("high") efuse = self.avr.readFuse("extended") self.statusLine.appendPlainText("OK: %02x %02x %02x" % (lfuse, hfuse, efuse)) self.lowfuseLine.setText("%02x" % lfuse) self.highfuseLine.setText("%02x" % hfuse) self.extfuseLine.setText("%02x" % efuse) except IOError: self.statusLine.appendPlainText("Reading fuses failed") self.lowfuseLine.setText("?") self.highfuseLine.setText("?") self.extfuseLine.setText("?") self.avr.close() def writeFuses(self): lfuse = int(self.lowfuseLine.text(), 16) # hfuse = int(self.highfuseLine.text(), 16) # efuse = int(self.extfuseLine.text(), 16) self.statusLine.appendPlainText( "Writing fuse: not only 'low' fuse is written, as hfuse/efuse can disable device\n" ) try: self.readSignature(close=False) self.avr.writeFuse("low", lfuse) # self.avr.writeFuse("high", hfuse) # self.avr.writeFuse("extended", efuse) # print("%x %x %x" % (lfuse, hfuse, efuse)) self.avr.close() except: self.avr.close() raise def verifyFlash(self): self.statusLine.appendPlainText("Verify not implemented") def writeFlash(self, erase=True, verify=True): self.avr.autoProgram(self.flashLocation.text(), erase, verify, self.statusLine.appendPlainText, QCoreApplication.processEvents) def setUSBInterface(self, iface): self.avr.setUSBInterface(iface)
class ImageViewer(QWidget): def __init__(self, filename=None, name=None, parent=None): super(ImageViewer, self).__init__(parent) self.imageRaw = np.zeros((200, 200, 200)) self.imageRGB = np.zeros((200, 200, 200, 3)) self.viewRange = [[100, 100], [100, 100], [100, 100]] self.zoomFactors = [3.0, 3.0, 3.0] self.iMin = 0 self.iMax = 1000 self.ijk = [0, 0, 0] self.name = 'untitled' self.initHbRL() self.mouseCursorCross = False ## Upper buttons self.upperRow = QHBoxLayout() self.drawRightHb = QPushButton('RightHb', self) self.drawLeftHb = QPushButton('LeftHb', self) self.drawRightHb.setCheckable(True) self.drawLeftHb.setCheckable(True) self.upperRow.addWidget(self.drawRightHb) self.upperRow.addWidget(self.drawLeftHb) QtCore.QObject.connect(self.drawRightHb, QtCore.SIGNAL('clicked()'), self.clickRightHb) QtCore.QObject.connect(self.drawLeftHb, QtCore.SIGNAL('clicked()'), self.clickLeftHb) ## View Layout self.scenes = [ MyGraphicsScene(self, 0), MyGraphicsScene(self, 1), MyGraphicsScene(self, 2) ] self.views = [ QGraphicsView(self.scenes[0]), QGraphicsView(self.scenes[1]), QGraphicsView(self.scenes[2]) ] self.sceneItems = [None, None, None] #Scene 4 view4 = QGridLayout() labelX = QLabel('X: ') labelY = QLabel('Y: ') labelZ = QLabel('Z: ') self.spin = [QSpinBox(), QSpinBox(), QSpinBox()] labelMinIntensity = QLabel('Min: ') labelMaxIntensity = QLabel('Max: ') labelZoom = QLabel('Zoom: ') self.spinMin = QSpinBox() self.spinMax = QSpinBox() self.spinZoom = QSpinBox() self.spinMin.setMaximum(10000) self.spinMax.setMaximum(10000) self.spinMin.setValue(self.iMin) self.spinMax.setValue(self.iMax) self.spinZoom.setValue(self.zoomFactors[0]) self.spinMin.setKeyboardTracking(False) self.spinMin.valueChanged.connect(self.setIntensity) self.spinMax.setKeyboardTracking(False) self.spinMax.valueChanged.connect(self.setIntensityMax) self.spinZoom.valueChanged.connect(self.setZoomFactor) self.spinZoom.setKeyboardTracking(False) labelAreaR = QLabel('Right: ') labelAreaL = QLabel('Left: ') self.labelAreaValueR = QLabel() self.labelAreaValueL = QLabel() view4.addWidget(labelX, 0, 0, 2, 1) view4.addWidget(labelY, 1, 0, 2, 1) view4.addWidget(labelZ, 2, 0, 2, 1) view4.addWidget(labelMinIntensity, 4, 0, 2, 1) view4.addWidget(labelMaxIntensity, 5, 0, 2, 1) view4.addWidget(labelZoom, 6, 0, 2, 1) view4.addWidget(labelAreaR, 7, 0) view4.addWidget(labelAreaL, 7, 2) view4.addWidget(self.spin[0], 0, 2, 2, 1) view4.addWidget(self.spin[1], 1, 2, 2, 1) view4.addWidget(self.spin[2], 2, 2, 2, 1) view4.addWidget(self.spinMin, 4, 2, 2, 1) view4.addWidget(self.spinMax, 5, 2, 2, 1) view4.addWidget(self.spinZoom, 6, 2, 2, 1) view4.addWidget(self.labelAreaValueR, 7, 1) view4.addWidget(self.labelAreaValueL, 7, 3) self.viewLayout = QGridLayout() self.viewLayout.addWidget(self.views[0], 0, 0) self.viewLayout.addWidget(self.views[1], 0, 1) self.viewLayout.addWidget(self.views[2], 1, 0) self.viewLayout.addLayout(view4, 1, 1) ## Lower self.lowerRow = QHBoxLayout() calculateButtonDown = QPushButton('calculateVolume', self) saveButtonDown = QPushButton('SaveHb', self) loadButtonDown = QPushButton('loadHb', self) savepngButtonDown = QPushButton('Save PNG', self) self.lowerRow.addWidget(calculateButtonDown) self.lowerRow.addWidget(saveButtonDown) self.lowerRow.addWidget(loadButtonDown) self.lowerRow.addWidget(savepngButtonDown) QtCore.QObject.connect(calculateButtonDown, QtCore.SIGNAL('clicked()'), self.getHbAreas) QtCore.QObject.connect(saveButtonDown, QtCore.SIGNAL('clicked()'), self.saveHb) QtCore.QObject.connect(loadButtonDown, QtCore.SIGNAL('clicked()'), self.loadHb) QtCore.QObject.connect(savepngButtonDown, QtCore.SIGNAL('clicked()'), self.saveCoronalSlice) ## Layout self.mainLayout = QVBoxLayout() self.mainLayout.addLayout(self.upperRow) self.mainLayout.addLayout(self.viewLayout) self.mainLayout.addLayout(self.lowerRow) self.setLayout(self.mainLayout) self.setWindowTitle("Image Viewer") self.resize(600, 700) self.show() if filename: self.loadNifti1(filename, name=name) def loadNifti1(self, filename, name=None): self.loadImage = LoadImage() self.loadImage.readNifti1(filename) if name is None: name = filename[:] if name[-7:] == '.nii.gz': name = name[:-7] elif name[-4:] == '.nii': name = name[:-4] for ch in ['/', '.', '~']: pos = name.find(ch) while pos > -1: name = '%s_%s' % (name[:pos], name[pos + 1:]) pos = name.find(ch) self.name = name self.imageRaw = self.loadImage.data self.spinMin.setMaximum(int(self.imageRaw.max() * 1.2)) self.spinMax.setMaximum(int(self.imageRaw.max() * 1.2)) #self.iMin = int(max(0, self.imageRaw.min()*1.2)) self.iMin = 0 self.iMax = int(self.imageRaw.max() * 0.8) self.spinMin.setValue(self.iMin) self.spinMax.setValue(self.iMax) self.imageRGB = convertImageRGB( resetIntensity(self.imageRaw, iMin=self.iMin, iMax=self.iMax)) self.setIJK() self.drawBaseImage() self.setSceneIJK() self.showSpinValue() self.setMouseCursor(True) def showSpinValue(self): self.spin[0].setMaximum(self.imageRaw.shape[0]) self.spin[1].setMaximum(self.imageRaw.shape[1]) self.spin[2].setMaximum(self.imageRaw.shape[2]) self.spin[0].setKeyboardTracking(False) self.spin[1].setKeyboardTracking(False) self.spin[2].setKeyboardTracking(False) self.spin[0].setValue(self.ijk[0]) self.spin[1].setValue(self.ijk[1]) self.spin[2].setValue(self.ijk[2]) self.spin[0].valueChanged.connect(self.resetI) self.spin[1].valueChanged.connect(self.resetJ) self.spin[2].valueChanged.connect(self.resetK) def resetI(self, i): self.ijk[0] = i self.drawBaseImage([0]) def resetJ(self, j): self.ijk[1] = j self.drawBaseImage([1]) self.labelAreaValueR.clear() self.labelAreaValueL.clear() def resetK(self, k): self.ijk[2] = k self.drawBaseImage([2]) def initHbRL(self): self.hbRight = { 'name': 'HbRight', 'color': 'red', 'images': [], 'points': [] } self.hbLeft = { 'name': 'HbLeft', 'color': 'blue', 'images': [], 'points': [] } def clickRightHb(self): if self.drawLeftHb.isChecked(): self.drawLeftHb.setChecked(False) def clickLeftHb(self): if self.drawRightHb.isChecked(): self.drawRightHb.setChecked(False) def saveHb(self, filename=None): if filename is None: filename = '%s_lawson_hb.csv' % self.name writeHb(filename, self.hbRight, self.hbLeft) with open(filename, 'a') as fout: volumes = self.getHbAreas() fout.write('%s,%s\n' % (volumes[0], volumes[1])) png_filename = filename[:-4] def saveCoronalSlice(self, filename=None): viewIndex = 1 if filename is None: filename = '%s_lawson_hb' % self.name filename += str('%03d.png' % self.ijk[viewIndex]) self.scenes[viewIndex].savePng(filename, 'PNG') def loadHb(self, filename=None): if filename is None: filename = '%s_lawson_hb.csv' % self.name self.initHbRL() readHb(filename, self.hbRight, self.hbLeft) def setMouseCursor(self, cross=False): if cross != self.mouseCursorCross: self.mouseCursorCross = cross if cross: #self.setCursor(QCursor(QtCore.Qt.CrossCursor)) self.setCursor(QtCore.Qt.CrossCursor) else: #self.setCursor(QCursor(QtCore.Qt.ArrowCursor)) self.setCursor(QtCore.Qt.ArrowCursor) def getZoomFactors(self): return self.zoomFactors def magZoomFactors(self, ratio): self.setZoomFactors([value + ratio for value in self.zoomFactors]) self.spinZoom.setValue(self.zoomFactors[0]) def setZoomFactors(self, zoomFactors): sceneRects = self.saveScene() self.zoomFactors = zoomFactors self.drawBaseImage() self.restoreScene(sceneRects) def setZoomFactor(self, zoomFactor): self.setZoomFactors([zoomFactor, zoomFactor, zoomFactor]) def getIntensity(self): return self.iMin, self.iMax def setIntensityMax(self, iMax): self.setIntensity(iMax=iMax) def setIntensity(self, iMin=None, iMax=None): if iMin: self.iMin = iMin if iMax: self.iMax = iMax self.imageRGB = convertImageRGB( resetIntensity(self.imageRaw, iMin=self.iMin, iMax=self.iMax)) self.drawBaseImage() def mousePressEventLeft(self, viewIndex, x, y): if viewIndex == 1: if self.drawRightHb.isChecked(): hbDict = self.hbRight labelAreaValue = self.labelAreaValueR elif self.drawLeftHb.isChecked(): hbDict = self.hbLeft labelAreaValue = self.labelAreaValueL else: self.resetIJK(viewIndex, x, y) return if not hbDict.has_key(self.ijk[viewIndex]): hbDict[self.ijk[viewIndex]] = HbRegionDraw() if hbDict[self.ijk[viewIndex]].insert == 4: for item in hbDict['images']: # lines self.scenes[viewIndex].removeItem(item) hbDict['images'] = [] item = hbDict['points'].pop(0) # last point self.scenes[viewIndex].removeItem(item) i, j = self.point2fijk(viewIndex, x, y) if not hbDict[self.ijk[viewIndex]].push((i, j)): item = hbDict['points'].pop(0) # last point self.scenes[viewIndex].removeItem(item) #self.scenes[viewIndex].removeItem(self.scenes[viewIndex].items()[0]) x_round, y_round = self.ij2point(viewIndex, i, j) hbDict['points'].insert( 0, self.scenes[viewIndex].addEllipse( x_round - 1, y_round - 1, 2, 2, pen=QPen(QColor(hbDict['color'])))) if hbDict[self.ijk[viewIndex]].insert >= 4: area = hbDict[self.ijk[viewIndex]].calculate_area( hbDict['name']) print ' %s %s: %s' % (self.ijk[viewIndex], hbDict['name'], area) self.drawHb(hbDict) #labelAreaValue.setText('%s: %3.2f' % (self.ijk[viewIndex], area)) labelAreaValue.setText('%3.2f' % (area)) else: self.resetIJK(viewIndex, x, y) def mousePressEventRight(self, viewIndex, x, y): if viewIndex == 1: if self.drawRightHb.isChecked(): hbDict = self.hbRight elif self.drawLeftHb.isChecked(): hbDict = self.hbLeft else: return if not hbDict.has_key(self.ijk[viewIndex]): return if hbDict[self.ijk[viewIndex]].insert == 4: for item in hbDict['images']: # lines self.scenes[viewIndex].removeItem(item) hbDict['images'] = [] #for item in self.scenes[viewIndex].items()[:3]: # lines # self.scenes[viewIndex].removeItem(item) if hbDict[self.ijk[viewIndex]].pop(): item = hbDict['points'].pop(0) # last point self.scenes[viewIndex].removeItem(item) #self.scenes[viewIndex].removeItem(self.scenes[viewIndex].items()[0]) def moveIJK(self, viewIndex, dx): self.ijk[viewIndex] += dx self.spin[viewIndex].setValue(self.ijk[viewIndex]) self.drawBaseImage([viewIndex]) self.labelAreaValueR.clear() self.labelAreaValueL.clear() def point2fijk(self, viewIndex, x, y): indexTable = [[1, 2], [0, 2], [0, 1]] xIndex = indexTable[viewIndex][0] yIndex = indexTable[viewIndex][1] ijkX = float(x) / self.zoomFactors[viewIndex] ijkY = self.imageRGB.shape[yIndex] - 1 - float( y) / self.zoomFactors[viewIndex] ijkX = np.round(ijkX * 2) / 2 ijkY = np.round(ijkY * 2) / 2 return (ijkX, ijkY) def point2fijk_flt(self, viewIndex, x, y): indexTable = [[1, 2], [0, 2], [0, 1]] xIndex = indexTable[viewIndex][0] yIndex = indexTable[viewIndex][1] ijkX = float(x) / self.zoomFactors[viewIndex] ijkY = self.imageRGB.shape[yIndex] - 1 - float( y) / self.zoomFactors[viewIndex] return (ijkX, ijkY) def point2ijk(self, viewIndex, x, y): indexTable = [[1, 2], [0, 2], [0, 1]] xIndex = indexTable[viewIndex][0] yIndex = indexTable[viewIndex][1] ijkX = int(x / self.zoomFactors[viewIndex]) ijkY = self.imageRGB.shape[yIndex] - 1 - int( y / self.zoomFactors[viewIndex]) return (ijkX, ijkY) def ij2point(self, viewIndex, i, j): indexTable = [[1, 2], [0, 2], [0, 1]] xIndex = indexTable[viewIndex][0] yIndex = indexTable[viewIndex][1] pointX = i * self.zoomFactors[viewIndex] pointY = (self.imageRGB.shape[yIndex] - 1 - j) * self.zoomFactors[viewIndex] return (pointX, pointY) def resetIJK(self, viewIndex, x, y): indexTable = [[1, 2], [0, 2], [0, 1]] xIndex = indexTable[viewIndex][0] yIndex = indexTable[viewIndex][1] self.ijk[xIndex] = int(x / self.zoomFactors[viewIndex]) self.ijk[yIndex] = self.imageRGB.shape[yIndex] - 1 - int( y / self.zoomFactors[viewIndex]) self.spin[xIndex].setValue(self.ijk[xIndex]) self.spin[yIndex].setValue(self.ijk[yIndex]) self.drawBaseImage(indexTable[viewIndex]) self.labelAreaValueR.clear() self.labelAreaValueL.clear() def saveScene(self): sceneRects = [0, 0, 0] for i in range(3): size = self.views[i].size().toTuple() x, y, _, _ = self.scenes[i].sceneRect().getRect() x += (size[0] - 10) / 2.0 y += (size[1] - 10) / 2.0 x /= self.zoomFactors[i] y /= self.zoomFactors[i] sceneRects[i] = [x, y] return sceneRects def restoreScene(self, sceneRects): for i in range(3): size = self.views[i].size().toTuple() x = sceneRects[i][0] * self.zoomFactors[i] y = sceneRects[i][1] * self.zoomFactors[i] self.scenes[i].setSceneRect(x - (size[0] - 10) / 2, y - (size[0] - 10) / 2, size[0] - 10, size[1] - 10) def setSceneIJK(self, viewIndex=(0, 1, 2)): for i in viewIndex: size = self.views[i].size().toTuple() xyCenter = [ self.ijk[tmp] * self.zoomFactors[i] for tmp in range(3) if tmp is not i ] self.scenes[i].setSceneRect(xyCenter[0] - size[0] / 2.0, xyCenter[1] - size[1] / 2.0, size[0] - 10, size[1] - 10) def setIJK(self, ijk='center'): if ijk == 'center': self.ijk = [ self.imageRGB.shape[0] / 2, self.imageRGB.shape[1] / 2, self.imageRGB.shape[2] / 2 ] else: self.ijk = ijk self.spin[0].setValue(self.ijk[0]) self.spin[1].setValue(self.ijk[1]) self.spin[2].setValue(self.ijk[2]) def get2D(self, plane): if plane == 0: return np.rot90(self.imageRGB[self.ijk[0], :, :, :]) elif plane == 1: return np.rot90(self.imageRGB[:, self.ijk[1], :, :]) elif plane == 2: return np.rot90(self.imageRGB[:, :, self.ijk[2], :]) def drawBaseImage(self, viewIndex=(0, 1, 2), eraseOthers=True): for i in viewIndex: imageArray3d = self.get2D(i) height, width, bytesPerComponent = imageArray3d.shape imageArray = imageArray3d.flatten() bytesPerLine = bytesPerComponent * width image = QImage(imageArray, width, height, bytesPerLine, QImage.Format_RGB888) #image = image.scaled( int(width*self.zoomFactors[i]), int(height*self.zoomFactors[i]), Qt.KeepAspectRatio, Qt.SmoothTransformation) image = image.scaled(int(width * self.zoomFactors[i]), int(height * self.zoomFactors[i]), QtCore.Qt.KeepAspectRatio) if self.sceneItems[i] is not None: #self.scenes[i].removeItem(self.sceneItems[i]) self.sceneItems[i].setPixmap(QPixmap.fromImage(image)) if False: items = self.scenes[i].items() for item in items: self.scenes[i].removeItem(item) self.sceneItems[i] = self.scenes[i].addPixmap( QPixmap.fromImage(image)) for item in items[1:]: self.scenes[i].additem(item) del items else: self.sceneItems[i] = self.scenes[i].addPixmap( QPixmap.fromImage(image)) if eraseOthers: for item in self.scenes[i].items(): if item != self.sceneItems[i]: self.scenes[i].removeItem(item) # TODO: where to put this self.drawHbPts(self.hbRight) self.drawHb(self.hbRight) self.drawHbPts(self.hbLeft) self.drawHb(self.hbLeft) def drawHbPts(self, hbDict): viewIndex = 1 if not hbDict.has_key(self.ijk[viewIndex]): return pts = [ self.ij2point(viewIndex, i, j) for (i, j) in hbDict[self.ijk[viewIndex]].get_points() ] for i in range(hbDict[self.ijk[viewIndex]].insert): hbDict['points'].insert( 0, self.scenes[viewIndex].addEllipse( pts[i][0] - 1, pts[i][1] - 1, 2, 2, pen=QPen(QColor(hbDict['color'])))) def drawHb(self, hbDict): viewIndex = 1 if not hbDict.has_key(self.ijk[viewIndex]): return if hbDict[self.ijk[viewIndex]].insert < 4: return a, b, c, d = [ self.ij2point(viewIndex, i, j) for (i, j) in hbDict[self.ijk[viewIndex]].get_points() ] cp = hbDict[self.ijk[viewIndex]].cp cp = self.ij2point(viewIndex, cp[0], cp[1]) vA = (a[0] - cp[0], a[1] - cp[1]) vB = (b[0] - cp[0], b[1] - cp[1]) vD = (d[0] - cp[0], d[1] - cp[1]) arcAD = QPainterPath() arcDB = QPainterPath() if hbDict['name'] == 'HbRight': sign = 1 startAngle = 0 else: sign = -1 startAngle = 180 angleADlad = sign * angleBw2Vectors(vA, vD) angleAD = 180 / np.pi * angleADlad if vD[0] * vD[0] + vD[1] * vD[1] >= vA[0] * vA[0] + vA[1] * vA[1]: rotD = (np.sqrt(vD[0] * vD[0] + vD[1] * vD[1]), 0) coefA = rotD[0] rotA = rotateVector(vA, angleADlad) coefB = np.sqrt(coefA * coefA / (coefA * coefA - rotA[0] * rotA[0]) * rotA[1] * rotA[1]) eccentricAnomalyAD = -180 / np.pi * np.arctan( coefA / coefB * np.tan(angleADlad)) arcAD.moveTo(cp[0] + sign * coefA, cp[1]) arcAD.arcTo(cp[0] - coefA, cp[1] - coefB, 2 * coefA, 2 * coefB, startAngle, eccentricAnomalyAD) else: rotA = (np.sqrt(vA[0] * vA[0] + vA[1] * vA[1]), 0) coefA = rotA[0] angleDAlad = sign * angleBw2Vectors(vD, vA) angleDA = 180 / np.pi * angleDAlad rotD = vD coefB = np.sqrt(coefA * coefA / (coefA * coefA - rotD[0] * rotD[0]) * rotD[1] * rotD[1]) eccentricAnomalyDA = 180 / np.pi * np.arctan( coefA / coefB * np.tan(angleDAlad)) arcAD.moveTo(cp[0] + sign * coefA, cp[1]) arcAD.arcTo(cp[0] - coefA, cp[1] - coefB, 2 * coefA, 2 * coefB, startAngle, eccentricAnomalyDA) angleAD = 0.0 if vD[0] * vD[0] + vD[1] * vD[1] >= vB[0] * vB[0] + vB[1] * vB[1]: rotD = (np.sqrt(vD[0] * vD[0] + vD[1] * vD[1]), 0) coefA = rotD[0] angleBDlad = sign * angleBw2Vectors(vD, vB) angleBD = 180 / np.pi * angleBDlad rotB = rotateVector(vB, angleADlad) coefB = np.sqrt(coefA * coefA / (coefA * coefA - rotB[0] * rotB[0]) * rotB[1] * rotB[1]) eccentricAnomalyDB = 180 / np.pi * np.arctan( coefA / coefB * np.tan(angleBDlad)) arcDB.moveTo(cp[0] + sign * coefA, cp[1]) arcDB.arcTo(cp[0] - coefA, cp[1] - coefB, 2 * coefA, 2 * coefB, startAngle, eccentricAnomalyDB) angleAB = 180 / np.pi * sign * angleBw2Vectors(vA, vD) else: rotB = (np.sqrt(vB[0] * vB[0] + vB[1] * vB[1]), 0) coefA = rotB[0] angleABlad = sign * angleBw2Vectors(vA, vB) angleAB = 180 / np.pi * angleABlad angleDBlad = sign * angleBw2Vectors(vD, vB) angleDB = 180 / np.pi * angleDBlad rotD = rotateVector(vD, angleABlad) coefB = np.sqrt(coefA * coefA / (coefA * coefA - rotD[0] * rotD[0]) * rotD[1] * rotD[1]) eccentricAnomalyDB = -180 / np.pi * np.arctan( coefA / coefB * np.tan(angleDBlad)) arcDB.moveTo(cp[0] + sign * coefA, cp[1]) arcDB.arcTo(cp[0] - coefA, cp[1] - coefB, 2 * coefA, 2 * coefB, startAngle, eccentricAnomalyDB) imgAC = self.scenes[viewIndex].addLine(a[0], a[1], cp[0], cp[1], pen=QPen(QColor( hbDict['color']))) imgBC = self.scenes[viewIndex].addLine(b[0], b[1], c[0], c[1], pen=QPen(QColor( hbDict['color']))) imgAD = self.scenes[viewIndex].addPath(arcAD, pen=QPen(QColor( hbDict['color']))) imgAD.setTransform(QTransform().translate( cp[0], cp[1]).rotate(-angleAD).translate(-cp[0], -cp[1])) imgDB = self.scenes[viewIndex].addPath(arcDB, pen=QPen(QColor( hbDict['color']))) imgDB.setTransform(QTransform().translate( cp[0], cp[1]).rotate(-angleAB).translate(-cp[0], -cp[1])) hbDict['images'] = [imgAD, imgDB, imgBC, imgAC] def getHbAreas(self): volumes = [] for hbDict in [self.hbRight, self.hbLeft]: keys = hbDict.keys() if not keys: volumes.append(0.0) continue print 'Calculate %s Volume...' % hbDict['name'] unit = self.loadImage.zooms[0] * self.loadImage.zooms[ 1] * self.loadImage.zooms[2] volume = 0.0 keys.sort() for key in keys: if type(key) == type(''): continue area = hbDict[key].area print ' %s: %s (voxel)' % (key, area) volume += area volume *= unit print 'volume = %s (mm^3)' % volume volumes.append(volume) return volumes
class MagnitudeNormalWidget(QWidget): """ QWidget for specifying vector by magnitude and Normal previous selected object is not loaded""" def __init__(self, vector, obj, parent=None): super(MagnitudeNormalWidget, self).__init__(parent) # for both py2 and py3 """ ui_path = os.path.join(os.path.dirname(__file__), "MagnitudeNormalWidget.ui") self.form = Gui.PySideUic.loadUi(ui_path) print(self.form.layout) print('type of self.form.inputVectorMag', type(self.form.inputVectorMag)) """ self.form = self self.inputVectorMag = _createInputField() self.labelMagnitude = QLabel('Magnitude') _magLayout = QHBoxLayout() _magLayout.addWidget(self.labelMagnitude) _magLayout.addWidget(self.inputVectorMag) self.buttonDirection = QPushButton( "select face or edge to add direction") self.buttonDirection.setCheckable(True) self.lineDirection = QLineEdit("Direction Shape Ref") self.checkReverse = QCheckBox("Reserve direction") self.labelVector = QLabel("Preview of vector value") _layout = QVBoxLayout() _layout.addLayout(_magLayout) _layout.addWidget(self.buttonDirection) _layout.addWidget(self.lineDirection) _layout.addWidget(self.checkReverse) _layout.addWidget(self.labelVector) self.setLayout(_layout) self.selecting_direction = False # add direction button status self.setVector(vector) if obj: self.obj = obj else: FreeCAD.Console.PrintError( "A FreeCAD DocumentObject derived object must provided for MagnitudeNormalWidget\n" ) self.form.inputVectorMag.valueChanged.connect( self.inputVectorMagChanged) self.form.lineDirection.textChanged.connect(self.lineDirectionChanged) self.form.buttonDirection.clicked.connect(self.buttonDirectionClicked) self.form.checkReverse.toggled.connect(self.checkReverseToggled) def updateUi(self): # set mag and preview label _m = self._magnitude * -1.0 if self._reversedDirection else self._magnitude self._vector = [v * _m for v in self._directionVector] self.form.labelVector.setText("Vector: " + str(self._vector)) pass def setVector(self, vector): self._vector = vector self._reversedDirection = False self._magnitude = (sum(v * v for v in vector)**0.5) if self._magnitude != 0: self._directionVector = [v / self._magnitude for v in vector] else: self._directionVector = [0, 0, 0] self.updateUi() def vector(self): _m = self._magnitude * -1.0 if self._reversedDirection else self._magnitude return [_m * v for v in self._directionVector] def buttonDirectionClicked(self): self.selecting_direction = not self.selecting_direction if self.selecting_direction: # If one object already selected, use it sels = FreeCADGui.Selection.getSelectionEx() if len(sels) == 1: sel = sels[0] if sel.HasSubObjects: if len(sel.SubElementNames) == 1: sub = sel.SubElementNames[0] self.selectDirection(sel.DocumentName, sel.ObjectName, sub) FreeCADGui.Selection.clearSelection() # start SelectionObserver and parse the function to add the References to the widget if self.selecting_direction: FreeCAD.Console.PrintMessage("Select face to define direction\n") FreeCADGui.Selection.addObserver(self) else: FreeCADGui.Selection.removeObserver(self) self.updateSelectionbuttonUI() def selectDirection(self, doc_name, obj_name, sub, selectedPoint=None): # This is the direction selection if not self.selecting_direction: # Shouldn't be here pass if FreeCADGui.activeDocument().Document.Name != self.obj.Document.Name: return selected_object = FreeCAD.getDocument(doc_name).getObject(obj_name) # On double click on a vertex of a solid sub is None and obj is the solid print('Selection: ' + selected_object.Shape.ShapeType + ' ' + selected_object.Name + GEOMETRY_REFERENCE_SEP + sub + " @ " + str(selectedPoint)) if hasattr(selected_object, "Shape") and sub: elt = selected_object.Shape.getElement(sub) if self.selecting_direction: if elt.ShapeType == 'Face': if CfdTools.isPlanar(elt): selection = (selected_object.Name, sub) self.form.lineDirection.setText( selection[0] + GEOMETRY_REFERENCE_SEP + selection[1]) # TODO: Display label, not name self._directionVector = elt.normalAt(0.5, 0.5) else: FreeCAD.Console.PrintMessage('Face must be planar\n') elif elt.ShapeType == 'Edge': self.form.lineDirection.setText(selected_object.Name + GEOMETRY_REFERENCE_SEP + sub) self._directionVector = self._getEdgeDirection(elt) else: FreeCAD.Console.PrintMessage( 'Only planar face and straight edge are supported as direction\n' ) self.selecting_direction = False # completed self.updateUi() def _getEdgeDirection(self, elt): v = elt.lastVertex().Point - elt.firstVertex().Point v_mag = sum([q * q for q in v])**0.5 if v_mag != 0: v = [q / v_mag for q in v] return v def updateSelectionbuttonUI(self): self.form.buttonDirection.setChecked(self.selecting_direction) def lineDirectionChanged(self, value): # soecify direc by directly setting QLineEdit with obj and subobj name selection = value.split(GEOMETRY_REFERENCE_SEP) # See if entered face actually exists and is planar try: selected_object = self.obj.Document.getObject(selection[0]) if hasattr(selected_object, "Shape"): elt = selected_object.Shape.getElement(selection[1]) if elt.ShapeType == 'Face': if CfdTools.isPlanar(elt): self._directionVector = elt.normalAt(0.5, 0.5) else: FreeCAD.Console.PrintMessage( value + " is not a valid, planar face\n") elif elt.ShapeType == 'Edge': self._directionVector = self._getEdgeDirection(elt) else: return self.updateUi() except SystemError: pass def inputVectorMagChanged(self, value): self._magnitude = value def checkReverseToggled(self, checked): self._reversedDirection = checked
class AVRProgrammerDialog(QtFixes.QDialog): def __init__(self): super(AVRProgrammerDialog, self).__init__(CWMainGUI.getInstance()) # self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint) self.avr = AVRProgrammer() self.setWindowTitle("ChipWhisperer-Lite AVR Programmer") layout = QVBoxLayout() layoutFW = QHBoxLayout() self.flashLocation = QtFixes.QLineEdit() flashFileButton = QPushButton("Find") flashFileButton.clicked.connect(self.findFlash) layoutFW.addWidget(QLabel("FLASH File")) layoutFW.addWidget(self.flashLocation) layoutFW.addWidget(flashFileButton) layout.addLayout(layoutFW) self.flashLocation.setText(QSettings().value("avr-flash-location")) # Add buttons readSigBut = QPushButton("Check Signature") readSigBut.clicked.connect(self.readSignature) verifyFlashBut = QPushButton("Verify FLASH") verifyFlashBut.clicked.connect(self.verifyFlash) verifyFlashBut.setEnabled(False) progFlashBut = QPushButton("Erase/Program/Verify FLASH") progFlashBut.clicked.connect(self.writeFlash) layoutBut = QHBoxLayout() layoutBut.addWidget(readSigBut) layoutBut.addWidget(verifyFlashBut) layoutBut.addWidget(progFlashBut) layout.addLayout(layoutBut) layoutFuse = QHBoxLayout() readFuseBut = QPushButton("Read Fuses") readFuseBut.clicked.connect(self.readFuses) writeFuseBut = QPushButton("Write Fuses") writeFuseBut.clicked.connect(self.writeFuses) self.lowfuseLine = QtFixes.QLineEdit("?") self.lowfuseLine.setMaxLength(2) self.lowfuseLine.setFixedWidth(25) self.highfuseLine = QtFixes.QLineEdit("?") self.highfuseLine.setMaxLength(2) self.highfuseLine.setFixedWidth(25) self.extfuseLine = QtFixes.QLineEdit("?") self.extfuseLine.setMaxLength(2) self.extfuseLine.setFixedWidth(25) # Don't allow use to change these fuses self.highfuseLine.setReadOnly(True) self.extfuseLine.setReadOnly(True) layoutFuse.addWidget(readFuseBut) layoutFuse.addWidget(QLabel("LOW:")) layoutFuse.addWidget(self.lowfuseLine) layoutFuse.addWidget(QLabel("HIGH:")) layoutFuse.addWidget(self.highfuseLine) layoutFuse.addWidget(QLabel("EXT:")) layoutFuse.addWidget(self.extfuseLine) layoutFuse.addWidget(writeFuseBut) layout.addLayout(layoutFuse) layoutExtra = QHBoxLayout() self.clockMode = QPushButton("Enable Slow Clock Mode") self.clockMode.setCheckable(True) self.clockMode.clicked.connect(self.toggleSlowClock) layoutExtra.addWidget(self.clockMode) layoutExtra.addStretch() layout.addLayout(layoutExtra) # Add status stuff self.statusLine = QPlainTextEdit() self.statusLine.setReadOnly(True) # self.statusLine.setFixedHeight(QFontMetrics(self.statusLine.font()).lineSpacing() * 5 + 10) self.statusLine.append = self.statusLine.appendPlainText layout.addWidget(self.statusLine) self.avr._logging = self.statusLine.append # Set dialog layout self.setLayout(layout) def toggleSlowClock(self): if self.clockMode.isChecked(): self.avr.avr.enableSlowClock(True) self.clockMode.setText("Disable Slow Clock Mode") else: self.avr.avr.enableSlowClock(False) self.clockMode.setText("Enable Slow Clock Mode") def reject(self): #Ensure we disable slow-clock mode if self.clockMode.isChecked(): self.clockMode.setChecked(False) self.toggleSlowClock() #Release AVR self.avr.close() QDialog.reject(self) def findFlash(self): fname, _ = QFileDialog.getOpenFileName(self, 'Find FLASH File', QSettings().value("avr-flash-location"), '*.hex') if fname: self.flashLocation.setText(fname) QSettings().setValue("avr-flash-location", fname) def readSignature(self, close=True): self.avr.find() if close: self.avr.close() def readFuses(self): try: self.readSignature(close=False) self.statusLine.append("Reading fuses") lfuse = self.avr.avr.readFuse("low") hfuse = self.avr.avr.readFuse("high") efuse = self.avr.avr.readFuse("extended") self.statusLine.append("OK: %02x %02x %02x" % (lfuse, hfuse, efuse)) self.lowfuseLine.setText("%02x" % lfuse) self.highfuseLine.setText("%02x" % hfuse) self.extfuseLine.setText("%02x" % efuse) except IOError: self.statusLine.append("Reading fuses failed") self.lowfuseLine.setText("?") self.highfuseLine.setText("?") self.extfuseLine.setText("?") self.avr.close() def writeFuses(self): lfuse = int(self.lowfuseLine.text(), 16) # hfuse = int(self.highfuseLine.text(), 16) # efuse = int(self.extfuseLine.text(), 16) self.statusLine.append("Writing fuse: not only 'low' fuse is written, as hfuse/efuse can disable device\n") try: self.readSignature(close=False) self.avr.avr.writeFuse("low", lfuse) # self.avr.avr.writeFuse("high", hfuse) # self.avr.avr.writeFuse("extended", efuse) # print("%x %x %x" % (lfuse, hfuse, efuse)) self.avr.close() except: self.avr.close() raise def verifyFlash(self): self.statusLine.append("Verify not implemented") def writeFlash(self, erase=True, verify=True): status = "FAILED" fname = self.flashLocation.text() self.statusLine.append("***Starting FLASH program process at %s***" % datetime.now().strftime('%H:%M:%S')) if (os.path.isfile(fname)): self.statusLine.append("File %s last changed on %s" % (fname, time.ctime(os.path.getmtime(fname)))) QCoreApplication.processEvents() try: self.statusLine.append("Entering Programming Mode") QCoreApplication.processEvents() self.readSignature(close=False) if erase: self.statusLine.append("Erasing Chip") QCoreApplication.processEvents() self.avr.erase() self.avr.close() self.readSignature(close=False) QCoreApplication.processEvents() self.avr.program(self.flashLocation.text(), memtype="flash", verify=verify) QCoreApplication.processEvents() self.statusLine.append("Exiting programming mode") self.avr.close() QCoreApplication.processEvents() status = "SUCCEEDED" except IOError as e: self.statusLine.append("FAILED: %s" % str(e)) try: self.avr.close() except IOError: pass else: self.statusLine.append("%s does not appear to be a file, check path" % fname) self.statusLine.append("***FLASH Program %s at %s***" % (status, datetime.now().strftime('%H:%M:%S'))) def setUSBInterface(self, iface): self.avr.setUSBInterface(iface)