class SensitivitySlider(QWidget): def __init__(self, obj = None, parent = None): QWidget.__init__(self, parent) if obj is None : return self.layout = QVBoxLayout() self.sensitivityLabel = QLabel() self.layout.addWidget(self.sensitivityLabel) self.sensitivitySlider = QSlider() self.sensitivitySlider.setRange(0, 200) self.sensitivitySlider.setSingleStep(1) self.sensitivitySlider.setOrientation(Qt.Horizontal) self.sensitivitySlider.valueChanged[int].connect(self.sensitivityDisplay) self.layout.addWidget(self.sensitivitySlider) self.setLayout(self.layout) if obj.config().hasKey("Sensitivity") : data_ = obj.config().readEntry("Sensitivity") value, state = data_.toInt() if not state : value = 100 else : value = 100 self.sensitivitySlider.setValue(value) def sensitivityDisplay(self, i = 100): if i<100 : s = 2 + int(float(100-i)/33) self.sensitivityLabel.setText('<b><u>Sensitivity of sliders</u>: 1/%s</b>' % s) else : s = 1 + int(float(i-100)/25) self.sensitivityLabel.setText('<b><u>Sensitivity of sliders</u>: %i</b>' % s)
class LinearPoti(PluginBase): qtcb_position = pyqtSignal(int) def __init__(self, ipcon, uid): PluginBase.__init__(self, ipcon, uid) self.lp = bricklet_linear_poti.LinearPoti(self.uid) self.ipcon.add_device(self.lp) self.version = ".".join(map(str, self.lp.get_version()[1])) self.qtcb_position.connect(self.cb_position) self.lp.register_callback(self.lp.CALLBACK_POSITION, self.qtcb_position.emit) self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, 100) self.position_label = PositionLabel("Position: ") self.current_value = 0 plot_list = [["", Qt.red, self.get_current_value]] self.plot_widget = PlotWidget("Position", plot_list) layout_h = QHBoxLayout() layout_h.addStretch() layout_h.addWidget(self.position_label) layout_h.addWidget(self.slider) layout_h.addStretch() layout = QVBoxLayout(self) layout.addLayout(layout_h) layout.addWidget(self.plot_widget) def start(self): try: self.cb_position(self.lp.get_position()) self.lp.set_position_callback_period(20) except ip_connection.Error: return self.plot_widget.stop = False def stop(self): try: self.lp.set_position_callback_period(0) except ip_connection.Error: pass self.plot_widget.stop = True @staticmethod def has_name(name): return "Linear Poti Bricklet" in name def get_current_value(self): return self.current_value def cb_position(self, position): self.current_value = position self.slider.setValue(position) self.position_label.setText(str(position))
class Slider(QWidget): def __init__(self, caption, default_value, minimum_value=1, maximum_value=60, single_step=1, page_step=6, caption_size=None, unit='', time=False, tooltip=''): QWidget.__init__(self) self.value = default_value self.unit = unit self.time = time description = QLabel(caption) description.setWordWrap(True) description.setToolTip(tooltip) if caption_size: description.setMaximumWidth(caption_size) self.slider = QSlider(Qt.Horizontal) self.slider.setMaximum(maximum_value) self.slider.setMinimum(minimum_value) self.slider.setSingleStep(single_step) self.slider.setPageStep(page_step) self.slider.setToolTip(tooltip) #self.slider.setTickInterval(2) #self.slider.setTickPosition(QSlider.TicksBelow) self.slider.valueChanged.connect(self.__on_change) self.value_label = QLabel() hbox = QHBoxLayout() hbox.addWidget(description) hbox.addWidget(self.slider) hbox.addWidget(self.value_label) hbox.setMargin(0) self.setLayout(hbox) self.setContentsMargins(5, 0, 5, 0) self.slider.setValue(self.value) self.__on_change(self.value) def __on_change(self, value): # FIXME: Fill with spaces to reach the maximum length self.value = value unit = self.unit if self.time: minutes = timedelta(minutes=self.value) date = datetime(1, 1, 1) + minutes text = "%02dh %02dm" % (date.hour, date.minute) else: text = "%s %s" % (self.value, self.unit) self.value_label.setText(text) def get_value(self): return int(self.slider.value())
def add_slider(self, label, description, minimum, maximum, value, slider_moved_func, parent, tick_interval=1, single_step=1, slider_scale_factor=1, int_values=False): # make layout to hold slider and textbox control_layout = QHBoxLayout() slider_label = label + "_slider" textbox_label = label + "_textbox" # make slider & add to layout slider = QSlider(Qt.Horizontal) slider.setObjectName(label) slider.setFocusPolicy(Qt.StrongFocus) slider.setTickPosition(QSlider.TicksBothSides) slider.setTickInterval(tick_interval) slider.setSingleStep(single_step) slider.setMinimum(minimum) slider.setMaximum(maximum) slider.setValue(value) control_layout.addWidget(slider) # make textbox & add to layout textbox = QLineEdit() textbox.setObjectName(label) textbox.setFixedWidth(40) textbox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) textbox.returnPressed.connect( self.controller.update_crop_params_from_gui) self.update_textbox_from_slider(slider, textbox, slider_scale_factor, int_values) control_layout.addWidget(textbox) # connect slider to set textbox text & update params slider.sliderMoved.connect(lambda: self.update_textbox_from_slider( slider, textbox, slider_scale_factor, int_values)) slider.sliderMoved.connect(slider_moved_func) slider.sliderPressed.connect(lambda: self.slider_pressed(slider)) slider.sliderReleased.connect(lambda: self.slider_released(slider)) # connect textbox to textbox.editingFinished.connect( lambda: self.update_slider_from_textbox(slider, textbox, slider_scale_factor)) textbox.editingFinished.connect(slider_moved_func) # add row to form layout parent.addRow(description, control_layout) # add to list of controls self.crop_param_controls[-1][slider_label] = slider self.crop_param_controls[-1][textbox_label] = textbox
def add_parameter(self, name, parameter_data, parameter_change): layout = self.frm_parameters.layout() qtitle = QLabel(parameter_data[3]) qslider = QSlider(Qt.Horizontal) qmin = QLabel(str(parameter_data[0])) qmax = QLabel(str(parameter_data[1])) qvalue = QLabel(str(parameter_data[2])) qslider.setRange(parameter_data[0], parameter_data[1]) qslider.setValue(parameter_data[2]) qtitle.setAlignment(Qt.AlignHCenter) qvalue.setAlignment(Qt.AlignHCenter) pos = layout.rowCount() layout.addWidget(qtitle, pos, 0, 1, 3) layout.addWidget(qmin, pos + 1, 0, 1, 1) layout.addWidget(qslider, pos + 1, 1, 1, 1) layout.addWidget(qmax, pos + 1, 2, 1, 1) layout.addWidget(qvalue, pos + 2, 0, 1, 3) def value_changed(value): v = parameter_change(name, value) qvalue.setNum(v) qslider.valueChanged.connect(value_changed) qslider.setTracking(True) self.parameters[name] = qslider
class IntelligentSlider(QWidget): ''' A slider that adds a 'name' attribute and calls a callback with 'name' as an argument to the registerd callback. This allows you to create large groups of sliders in a loop, but still keep track of the individual events It also prints a label below the slider. The range of the slider is hardcoded from zero - 1000, but it supports a conversion factor so you can scale the results''' def __init__(self, name, a, b, callback): QWidget.__init__(self) self.name = name self.callback = callback self.a = a self.b = b self.manually_triggered = False self.slider = QSlider() self.slider.setRange(0, 1000) self.slider.setValue(500) self.slider.valueChanged.connect(self.slider_changed) self.name_label = QLabel() self.name_label.setText(self.name) self.name_label.setAlignment(QtCore.Qt.AlignCenter) self.value_label = QLabel() self.value_label.setText('%2.2f' % (self.slider.value() * self.a + self.b)) self.value_label.setAlignment(QtCore.Qt.AlignCenter) self.layout = QGridLayout(self) self.layout.addWidget(self.name_label, 0, 0) self.layout.addWidget(self.slider, 1, 0, QtCore.Qt.AlignHCenter) self.layout.addWidget(self.value_label, 2, 0) # bind this to the valueChanged signal of the slider def slider_changed(self, val): val = self.val() self.value_label.setText(str(val)[:4]) if not self.manually_triggered: self.callback(self.name, val) def set_conv_fac(self, a, b): self.a = a self.b = b def set_value(self, val): self.manually_triggered = True self.slider.setValue(int((val - self.b) / self.a)) self.value_label.setText('%2.2f' % val) self.manually_triggered = False def val(self): return self.slider.value() * self.a + self.b
class LinearPoti(PluginBase): qtcb_position = pyqtSignal(int) def __init__(self, ipcon, uid, version): PluginBase.__init__(self, ipcon, uid, 'Linear Poti Bricklet', version) self.lp = BrickletLinearPoti(uid, ipcon) self.qtcb_position.connect(self.cb_position) self.lp.register_callback(self.lp.CALLBACK_POSITION, self.qtcb_position.emit) self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, 100) self.position_label = PositionLabel('Position: ') self.current_value = None plot_list = [['', Qt.red, self.get_current_value]] self.plot_widget = PlotWidget('Position', plot_list) layout_h = QHBoxLayout() layout_h.addStretch() layout_h.addWidget(self.position_label) layout_h.addWidget(self.slider) layout_h.addStretch() layout = QVBoxLayout(self) layout.addLayout(layout_h) layout.addWidget(self.plot_widget) def start(self): async_call(self.lp.get_position, None, self.cb_position, self.increase_error_count) async_call(self.lp.set_position_callback_period, 20, None, self.increase_error_count) self.plot_widget.stop = False def stop(self): async_call(self.lp.set_position_callback_period, 0, None, self.increase_error_count) self.plot_widget.stop = True def get_url_part(self): return 'linear_poti' @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletLinearPoti.DEVICE_IDENTIFIER def get_current_value(self): return self.current_value def cb_position(self, position): self.current_value = position self.slider.setValue(position) self.position_label.setText(str(position))
class LinearPoti(PluginBase): def __init__(self, *args): PluginBase.__init__(self, BrickletLinearPoti, *args) self.lp = self.device self.cbe_position = CallbackEmulator(self.lp.get_position, self.cb_position, self.increase_error_count) self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, 100) self.position_label = PositionLabel('Position: ') self.current_value = None plot_list = [['', Qt.red, self.get_current_value]] self.plot_widget = PlotWidget('Position', plot_list) layout_h = QHBoxLayout() layout_h.addStretch() layout_h.addWidget(self.position_label) layout_h.addWidget(self.slider) layout_h.addStretch() layout = QVBoxLayout(self) layout.addLayout(layout_h) layout.addWidget(self.plot_widget) def start(self): async_call(self.lp.get_position, None, self.cb_position, self.increase_error_count) self.cbe_position.set_period(25) self.plot_widget.stop = False def stop(self): self.cbe_position.set_period(0) self.plot_widget.stop = True def destroy(self): pass def get_url_part(self): return 'linear_poti' @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletLinearPoti.DEVICE_IDENTIFIER def get_current_value(self): return self.current_value def cb_position(self, position): self.current_value = position self.slider.setValue(position) self.position_label.setText(str(position))
class MusicView(preferences.Group): def __init__(self, page): super(MusicView, self).__init__(page) layout = QGridLayout() self.setLayout(layout) self.magnifierSizeLabel = QLabel() self.magnifierSizeSlider = QSlider(Qt.Horizontal, valueChanged=self.changed) self.magnifierSizeSlider.setSingleStep(50) self.magnifierSizeSlider.setRange(*popplerview.MagnifierSettings.sizeRange) self.magnifierSizeSpinBox = QSpinBox() self.magnifierSizeSpinBox.setRange(*popplerview.MagnifierSettings.sizeRange) self.magnifierSizeSpinBox.valueChanged.connect(self.magnifierSizeSlider.setValue) self.magnifierSizeSlider.valueChanged.connect(self.magnifierSizeSpinBox.setValue) layout.addWidget(self.magnifierSizeLabel, 0, 0) layout.addWidget(self.magnifierSizeSlider, 0, 1) layout.addWidget(self.magnifierSizeSpinBox, 0, 2) self.magnifierScaleLabel = QLabel() self.magnifierScaleSlider = QSlider(Qt.Horizontal, valueChanged=self.changed) self.magnifierScaleSlider.setSingleStep(50) self.magnifierScaleSlider.setRange(*popplerview.MagnifierSettings.scaleRange) self.magnifierScaleSpinBox = QSpinBox() self.magnifierScaleSpinBox.setRange(*popplerview.MagnifierSettings.scaleRange) self.magnifierScaleSpinBox.valueChanged.connect(self.magnifierScaleSlider.setValue) self.magnifierScaleSlider.valueChanged.connect(self.magnifierScaleSpinBox.setValue) layout.addWidget(self.magnifierScaleLabel, 1, 0) layout.addWidget(self.magnifierScaleSlider, 1, 1) layout.addWidget(self.magnifierScaleSpinBox, 1, 2) app.translateUI(self) def translateUI(self): self.setTitle(_("Music View")) self.magnifierSizeLabel.setText(_("Magnifier Size:")) self.magnifierSizeLabel.setToolTip(_( "Size of the magnifier glass (Ctrl+Click in the Music View).")) # L10N: as in "400 pixels", appended after number in spinbox, note the leading space self.magnifierSizeSpinBox.setSuffix(_(" pixels")) self.magnifierScaleLabel.setText(_("Magnifier Scale:")) self.magnifierScaleLabel.setToolTip(_( "Magnification of the magnifier.")) self.magnifierScaleSpinBox.setSuffix(_("percent unit sign", "%")) def loadSettings(self): s = popplerview.MagnifierSettings.load() self.magnifierSizeSlider.setValue(s.size) self.magnifierScaleSlider.setValue(s.scale) def saveSettings(self): s = popplerview.MagnifierSettings() s.size = self.magnifierSizeSlider.value() s.scale = self.magnifierScaleSlider.value() s.save()
def metronome(): import os, sys, time from PyQt4.QtCore import SIGNAL from PyQt4.QtGui import QApplication, QPushButton, QSlider, QWidget from PyQt4.QtGui import QHBoxLayout import scsynth import synths app = QApplication(sys.argv) server = scsynth.server.start(verbose=True) #server = scsynth.server.connect() engine = Engine(server, app) server.sendMsg('/dumpOSC', 1) engine.tempoclock.set_tempo(120) SYNTHDEF_PATH = os.path.join(os.path.expanduser('~'), '.pksampler', 'synthdefs') SYNTHDEFS = ('JASStereoSamplePlayer.scsyndef', 'JASSine.scsyndef', ) for fname in SYNTHDEFS: engine.server.sendMsg('/d_load', os.path.join(SYNTHDEF_PATH, fname)) CLICK = '/Users/patrick/.pksampler/clicks/click_1.wav' engine.loader.load(CLICK) time.sleep(.1) notes = [scsynth.Note(i, i+16, 69) for i in (0, )] pattern = scsynth.Pattern(notes) pattern.beats = 1 stream = engine.register(synths.Sine(), pattern) stream.loop(True) engine.start() widget = QWidget() Layout = QHBoxLayout(widget) widget.resize(100, 250) widget.show() def set_tempo(value): engine.tempoclock.set_tempo(value) slider = QSlider(widget) slider.setRange(100, 180) slider.setValue(140) QObject.connect(slider, SIGNAL('valueChanged(int)'), set_tempo) Layout.addWidget(slider) button = QPushButton('quit', widget) QObject.connect(button, SIGNAL('clicked()'), app.quit) Layout.addWidget(button) app.exec_() engine.stop()
def _addSlider(self, v, cnt): control = QSlider(Qt.Horizontal) control.setMinimumWidth(172) control.setFocusPolicy(Qt.StrongFocus) control.setMaximum(v.max * 160) control.setMinimum(v.min * 160) control.setValue(v.value * 160) control.tag = cnt if self.styleName == "mac": control.setAttribute(Qt.WA_MacMiniSize, True) self.layout.addWidget(control, cnt, 1) self.connect(control, SIGNAL("valueChanged(int)"), self.numberChanged_)
class LinearPoti(PluginBase): def __init__(self, *args): PluginBase.__init__(self, BrickletLinearPoti, *args) self.lp = self.device self.cbe_position = CallbackEmulator(self.lp.get_position, self.cb_position, self.increase_error_count) self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, 100) self.slider.setMinimumWidth(200) self.current_position = None plots = [('Position', Qt.red, lambda: self.current_position, str)] self.plot_widget = PlotWidget('Position', plots, extra_key_widgets=[self.slider], curve_motion_granularity=40, update_interval=0.025) layout = QVBoxLayout(self) layout.addWidget(self.plot_widget) def start(self): async_call(self.lp.get_position, None, self.cb_position, self.increase_error_count) self.cbe_position.set_period(25) self.plot_widget.stop = False def stop(self): self.cbe_position.set_period(0) self.plot_widget.stop = True def destroy(self): pass @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletLinearPoti.DEVICE_IDENTIFIER def cb_position(self, position): self.current_position = position self.slider.setValue(position)
def __init__(self): QWidget.__init__(self) self.resize(400, 100) self.setWindowTitle('Control Duty Cycle of PWM0') sl = QSlider(Qt.Horizontal) sl.setMinimum(0) sl.setMaximum(255) sl.setValue(128) sl.valueChanged.connect(self.set_pwm) layout = QVBoxLayout() layout.addWidget(sl) self.setLayout(layout) self.init_pwm()
def __init__(self): QWidget.__init__(self) self.resize(400, 100) self.setWindowTitle('Control Duty Cycle of PWM0') sl = QSlider(Qt.Horizontal) sl.setMinimum(0) sl.setMaximum(65535) sl.setValue(0) sl.valueChanged.connect(self.set_pwm) layout = QVBoxLayout() layout.addWidget(sl) self.setLayout(layout) self.init_pwm()
class LinearPoti(PluginBase): def __init__(self, *args): PluginBase.__init__(self, BrickletLinearPoti, *args) self.lp = self.device self.cbe_position = CallbackEmulator(self.lp.get_position, self.cb_position, self.increase_error_count) self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, 100) self.slider.setMinimumWidth(200) self.current_position = None plots = [('Position', Qt.red, lambda: self.current_position, str)] self.plot_widget = PlotWidget('Position', plots, extra_key_widgets=[self.slider], curve_motion_granularity=40, update_interval=0.025) layout = QVBoxLayout(self) layout.addWidget(self.plot_widget) def start(self): async_call(self.lp.get_position, None, self.cb_position, self.increase_error_count) self.cbe_position.set_period(25) self.plot_widget.stop = False def stop(self): self.cbe_position.set_period(0) self.plot_widget.stop = True def destroy(self): pass def get_url_part(self): return 'linear_poti' @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletLinearPoti.DEVICE_IDENTIFIER def cb_position(self, position): self.current_position = position self.slider.setValue(position)
class LabelControlItems(QWidget): def __init__(self): super(LabelControlItems, self).__init__() nlabels = 5 self.combobox_labels = QComboBox() self.label_label = QLabel("Label: ") self.label_text = QLabel("Text: ") self.text_label = QLineEdit("Label1") self.button_label = QPushButton("On/Off") self.scale_labelsize = QSlider(Qt.Horizontal) self.label_labelsize = QLabel("Label Size") self.scale_labelsize.setMinimum(1) self.scale_labelsize.setValue(20) self.button_label.setCheckable(True) for i in range(nlabels): self.combobox_labels.addItem("Label"+str(i+1)) layout = QGridLayout() layout.addWidget(self.label_label,0,0) layout.addWidget(self.combobox_labels,1,0) layout.addWidget(self.label_text,0,1) layout.addWidget(self.text_label,1,1) layout.addWidget(self.button_label,1,2) layout.addWidget(self.label_labelsize,0,3) layout.addWidget(self.scale_labelsize,1,3) for col, stretch in enumerate((5,5,5,5)): layout.setColumnStretch(col, stretch) layout.setMargin(5) layout.setHorizontalSpacing(5) layout.setVerticalSpacing(0) self.setLayout(layout)
class MainWindow(QMainWindow): def __init__(self, *args): QMainWindow.__init__(self, *args) self.d_plot = Plot(self) self.setCentralWidget(self.d_plot) self.toolBar = QToolBar(self) self.btnPrint = QToolButton(self.toolBar) self.btnPrint.setText("Print") self.btnPrint.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.toolBar.addWidget(self.btnPrint) #self.btnPrint.clicked.connect(self.d_plot.printPlot() ) self.toolBar.addSeparator() self.toolBar.addWidget(QLabel("Color Map ")) self.mapBox = QComboBox(self.toolBar) self.mapBox.addItem("RGB") self.mapBox.addItem("Indexed Colors") self.mapBox.addItem("Hue") self.mapBox.addItem("Alpha") self.mapBox.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.toolBar.addWidget(self.mapBox) self.mapBox.currentIndexChanged['int'].connect(self.d_plot.setColorMap) self.toolBar.addWidget(QLabel(" Opacity ")) self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, 255) self.slider.setValue(255) self.slider.valueChanged['int'].connect(self.d_plot.setAlpha) self.toolBar.addWidget(self.slider) self.toolBar.addWidget(QLabel(" ")) self.btnSpectrogram = QCheckBox("Spectrogram", self.toolBar) self.toolBar.addWidget(self.btnSpectrogram) self.btnSpectrogram.toggled['bool'].connect( self.d_plot.showSpectrogram) self.btnContour = QCheckBox("Contour", self.toolBar) self.toolBar.addWidget(self.btnContour) #self.btnContour.toggled['bool'](self.d_plot.showContour ) self.addToolBar(self.toolBar) self.btnSpectrogram.setChecked(True) self.btnContour.setChecked(False)
class QCustomSlider(QWidget): def __init__(self, sliderOrientation=None): super(QCustomSlider, self).__init__() self._slider = QSlider(sliderOrientation) self.setLayout(QVBoxLayout()) self._labelTicksWidget = QWidget(self) self._labelTicksWidget.setLayout(QHBoxLayout()) self._labelTicksWidget.layout().setContentsMargins(0, 0, 0, 0) self.layout().addWidget(self._slider) self.layout().addWidget(self._labelTicksWidget) def setTickLabels(self, listWithLabels): lengthOfList = len(listWithLabels) for index, label in enumerate(listWithLabels): label = QLabel(str(label)) label.setContentsMargins(0, 0, 0, 0) if index > lengthOfList/3: label.setAlignment(QtCore.Qt.AlignCenter) if index > 2*lengthOfList/3: label.setAlignment(QtCore.Qt.AlignRight) self._labelTicksWidget.layout().addWidget(label) def setRange(self, mini, maxi): self._slider.setRange(mini, maxi) def setPageStep(self, value): self._slider.setPageStep(value) def setTickInterval(self, value): self._slider.setTickInterval(value) def setTickPosition(self, position): self._slider.setTickPosition(position) def setValue(self, value): self._slider.setValue(value) def onValueChangedCall(self, function): self._slider.valueChanged.connect(function)
def create_slider(slider_type, slider_range, slider_default): # Horizontal Slider if slider_type == SLDR_TYPE_HSlider: slider = QSlider(Qt.Horizontal) # Vertical Slider elif slider_type == SLDR_TYPE_VSlider: slider = QSlider(Qt.Vertical) # Dial elif slider_type == SLDR_TYPE_Dial: slider = QDial() # Horizontal Scrollbar elif slider_type == SLDR_TYPE_HScrollbar: slider = QScrollBar(Qt.Horizontal) # Vertical Scrollbar elif slider_type == SLDR_TYPE_VScrollbar: slider = QScrollbar(Qt.Vertical) else: raise TypeError("Invalid slider type") slider.setRange(slider_range[0], slider_range[1]) slider.setValue(slider_default) return slider
class SpinSlider(QWidget): "Boite de spin + curseur avec sauvegarde de la dernière valeur sélectionnée" def __init__(self, debut, fin, defaut, optionConfig=None, parent=None): QWidget.__init__(self) self.spin = QSpinBox() self.slider = QSlider(Qt.Horizontal) self.spin.setRange(debut, fin) self.slider.setRange(debut, fin) valeur = None if optionConfig: self.config = parent.config self.idSection = parent.idSection self.optionConfig = optionConfig try : valeur = self.config.get(self.idSection, self.optionConfig) except: valeur = defaut self.config.set(self.idSection, self.optionConfig, valeur) erreur = False if valeur: try: valeur = int(valeur) except ValueError: erreur = True if not erreur and debut <= valeur <= fin: self.spin.setValue(valeur) self.slider.setValue(valeur) else: self.spin.setValue(defaut) self.slider.setValue(defaut) if optionConfig: self.connect(self.spin, SIGNAL("valueChanged(int)"), self.sauveConfig) self.connect(self.spin, SIGNAL("valueChanged(int)"), self.slider, SLOT("setValue(int)")) self.connect(self.slider, SIGNAL("valueChanged(int)"), self.spin, SLOT("setValue(int)")) self.connect(self.spin, SIGNAL("valueChanged(int)"), self.changed) hbox = QHBoxLayout(self) hbox.addWidget(self.spin) hbox.addWidget(self.slider) hbox.setMargin(0) # pour un meilleur alignement dans un grid def changed(self, i): self.emit(SIGNAL("valueChanged(int)"), i) def sauveConfig(self, i): self.config.set(self.idSection, self.optionConfig, str(i)) def value(self): return self.spin.value() def setValue(self, i): self.spin.setValue(i) self.slider.setValue(i)
class LightingControlItems(QWidget): def __init__(self): super(LightingControlItems, self).__init__() self.button_shade = QPushButton('Shade On/Off') self.button_interpolation = QPushButton('Interpolation: Linear/NN ') self.button_gradientopacity = QPushButton('Gradient Opacity On/Off') for comp in (self.button_shade, self.button_interpolation, self.button_gradientopacity): comp.setCheckable(True) self.slider_ambient = QSlider(Qt.Horizontal) self.slider_diffuse = QSlider(Qt.Horizontal) self.slider_specular = QSlider(Qt.Horizontal) self.slider_keylightintensity = QSlider(Qt.Horizontal) self.slider_ambient.setValue(100.0) self.slider_diffuse.setValue(100.0) self.slider_keylightintensity.setValue(20) for comp in (self.button_shade, self.button_interpolation, self.button_gradientopacity, self.slider_ambient, self.slider_diffuse, self.slider_specular, self.slider_keylightintensity): comp.setEnabled(False) self.label_ambient = QLabel('Ambient: 1.0') self.label_diffuse = QLabel('Diffuse: 1.0') self.label_specular = QLabel('Specular: 0.0') self.label_keylightintensity = QLabel('Key Light Intensity: 4.0') layout = QGridLayout() for ind, comp in enumerate( (self.label_ambient, self.label_diffuse, self.label_specular, self.label_keylightintensity)): layout.addWidget(comp, 0, ind) for ind, comp in enumerate( (self.slider_ambient, self.slider_diffuse, self.slider_specular, self.slider_keylightintensity)): layout.addWidget(comp, 1, ind) layout.addWidget(self.button_interpolation, 0, ind + 1) layout.addWidget(self.button_gradientopacity, 1, ind + 1) layout.addWidget(self.button_shade, 1, ind + 2) layout.setMargin(5) layout.setVerticalSpacing(0) self.setLayout(layout)
class LightingControlItems(QWidget): def __init__(self): super(LightingControlItems, self).__init__() self.button_shade = QPushButton('Shade On/Off') self.button_interpolation = QPushButton('Interpolation: Linear/NN ') self.button_gradientopacity = QPushButton('Gradient Opacity On/Off') for comp in (self.button_shade, self.button_interpolation, self.button_gradientopacity): comp.setCheckable(True) self.slider_ambient = QSlider(Qt.Horizontal) self.slider_diffuse = QSlider(Qt.Horizontal) self.slider_specular = QSlider(Qt.Horizontal) self.slider_keylightintensity = QSlider(Qt.Horizontal) self.slider_ambient.setValue(100.0) self.slider_diffuse.setValue(100.0) self.slider_keylightintensity.setValue(20) for comp in (self.button_shade, self.button_interpolation, self.button_gradientopacity, self.slider_ambient, self.slider_diffuse, self.slider_specular, self.slider_keylightintensity): comp.setEnabled(False) self.label_ambient = QLabel('Ambient: 1.0') self.label_diffuse = QLabel('Diffuse: 1.0') self.label_specular = QLabel('Specular: 0.0') self.label_keylightintensity = QLabel('Key Light Intensity: 4.0') layout = QGridLayout() for ind, comp in enumerate((self.label_ambient, self.label_diffuse, self.label_specular, self.label_keylightintensity)): layout.addWidget(comp,0,ind) for ind, comp in enumerate((self.slider_ambient, self.slider_diffuse, self.slider_specular, self.slider_keylightintensity)): layout.addWidget(comp,1,ind) layout.addWidget(self.button_interpolation,0,ind+1) layout.addWidget(self.button_gradientopacity,1,ind+1) layout.addWidget(self.button_shade,1,ind+2) layout.setMargin(5) layout.setVerticalSpacing(0) self.setLayout(layout)
class SpinAndSliderWidget(QWidget): """this combinate a spin box and a slider in log scale""" sigChanged = pyqtSignal() def __init__( self, parent=None, value=1., limits=[0.001, 1000], orientation=Qt.Horizontal, ): QWidget.__init__(self, parent) self._val = None self.limits = limits if orientation == Qt.Horizontal: self.mainlayout = QHBoxLayout() else: self.mainlayout = QVBoxLayout() self.setLayout(self.mainlayout) #~ self.spinbox = QDoubleSpinBox(decimals = 4, singleStep = .1, #~ minimum = self.limits[0], maximum = self.limits[1]) self.spinbox = pg.SpinBox(decimals=4, singleStep=.1, minimum=self.limits[0], maximum=self.limits[1]) self.mainlayout.addWidget(self.spinbox) self.slider = QSlider(Qt.Horizontal, minimum=0, maximum=100) self.mainlayout.addWidget(self.slider) self.slider.setMinimumWidth(20) self.spinbox.valueChanged.connect(self.spinbox_changed) self.slider.valueChanged.connect(self.slider_changed) self.setValue(value) def value(self): return self._val def setValue(self, val): self._val = val self.spinbox.valueChanged.disconnect(self.spinbox_changed) self.spinbox.setValue(val) self.spinbox.valueChanged.connect(self.spinbox_changed) self.slider.valueChanged.disconnect(self.slider_changed) self.slider.setValue(self.to_log(val)) self.slider.valueChanged.connect(self.slider_changed) def to_log(self, val): min, max = self.limits return int((np.log10(val) - np.log10(min)) / (np.log10(max) - np.log10(min)) * 100) def from_log(self, val): min, max = self.limits return 10**((val / 100.) * (np.log10(max) - np.log10(min)) + np.log10(min)) def slider_changed(self, val): self._val = self.from_log(val) self.spinbox.valueChanged.disconnect(self.spinbox_changed) self.spinbox.setValue(self._val) self.spinbox.valueChanged.connect(self.spinbox_changed) self.sigChanged.emit() def spinbox_changed(self, val): self._val = val self.slider.valueChanged.disconnect(self.slider_changed) self.slider.setValue(self.to_log(self._val)) self.slider.valueChanged.connect(self.slider_changed) self.sigChanged.emit() def updateDisplayLabel(self, value=None): if value is None: value = self.param.value() opts = self.param.opts if value is None: text = '' else: text = '{}'.format(self._val) self.displayLabel.setText(text)
class QTSeedEditor(QDialog): """ DICOM viewer. """ @staticmethod def get_line(mode='h'): line = QFrame() if mode == 'h': line.setFrameStyle(QFrame.HLine) elif mode == 'v': line.setFrameStyle(QFrame.VLine) line.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding) return line def initUI(self, shape, vscale, height=600, mode='seed'): """ Initialize UI. Parameters ---------- shape : (int, int, int) Shape of data matrix. vscale : (float, float, float) Voxel scaling. height : int Maximal slice height in pixels. mode : str Editor mode. """ # picture grid = height / float(shape[1] * vscale[1]) mgrid = (grid * vscale[0], grid * vscale[1]) self.slice_box = SliceBox(shape[:-1], mgrid, mode) self.slice_box.setScrollFun(self.scrollSlices) self.connect(self.slice_box, SIGNAL('focus_slider'), self.focusSliceSlider) # sliders self.allow_select_slice = True self.n_slices = shape[2] self.slider = QSlider(Qt.Vertical) self.slider.label = QLabel() self.slider.label.setText('Slice: %d / %d' % (self.actual_slice, self.n_slices)) self.slider.setRange(1, self.n_slices) self.slider.valueChanged.connect(self.sliderSelectSlice) self.slider.setValue(self.actual_slice) self.slider_cw = {} self.slider_cw['c'] = QSlider(Qt.Horizontal) self.slider_cw['c'].valueChanged.connect(self.changeC) self.slider_cw['c'].label = QLabel() self.slider_cw['w'] = QSlider(Qt.Horizontal) self.slider_cw['w'].valueChanged.connect(self.changeW) self.slider_cw['w'].label = QLabel() self.view_label = QLabel('View size: %d x %d' % self.img_aview.shape[:-1]) self.voxel_label = QLabel('Voxel size [mm]:\n %.2f x %.2f x %.2f'\ % tuple(self.voxel_size[np.array(self.act_transposition)])) combo_view_options = VIEW_TABLE.keys() combo_view = QComboBox(self) combo_view.activated[str].connect(self.setView) combo_view.addItems(combo_view_options) # buttons self.btn_quit = QPushButton("Return", self) self.btn_quit.clicked.connect(self.quit) combo_dmask = QComboBox(self) combo_dmask.activated.connect(self.changeMask) self.mask_points_tab, aux = self.init_draw_mask(DRAW_MASK, mgrid) for icon, label in aux: combo_dmask.addItem(icon, label) self.slice_box.setMaskPoints(self.mask_points_tab[combo_dmask.currentIndex()]) self.status_bar = QStatusBar() vopts = [] vmenu = [] appmenu = [] if mode == 'seed' and self.mode_fun is not None: btn_recalc = QPushButton("Recalculate", self) btn_recalc.clicked.connect(self.recalculate) appmenu.append(QLabel('<b>Segmentation mode</b><br><br><br>' + 'Select the region of interest<br>' + 'using the mouse buttons:<br><br>' + ' <i>left</i> - inner region<br>' + ' <i>right</i> - outer region<br><br>')) appmenu.append(btn_recalc) appmenu.append(QLabel()) self.volume_label = QLabel('Volume:\n unknown') appmenu.append(self.volume_label) # Set middle pencil as default (M. Jirik) combo_dmask.setCurrentIndex(1) self.slice_box.setMaskPoints( self.mask_points_tab[combo_dmask.currentIndex()]) # -----mjirik---end------ if mode == 'seed' or mode == 'crop'\ or mode == 'mask' or mode == 'draw': btn_del = QPushButton("Delete Seeds", self) btn_del.clicked.connect(self.deleteSliceSeeds) vmenu.append(None) vmenu.append(btn_del) combo_contour_options = ['fill', 'contours', 'off'] combo_contour = QComboBox(self) combo_contour.activated[str].connect(self.changeContourMode) combo_contour.addItems(combo_contour_options) self.changeContourMode(combo_contour_options[combo_contour.currentIndex()]) vopts.append(QLabel('Selection mode:')) vopts.append(combo_contour) if mode == 'mask': btn_recalc_mask = QPushButton("Recalculate mask", self) btn_recalc_mask.clicked.connect(self.updateMaskRegion_btn) btn_all = QPushButton("Select all", self) btn_all.clicked.connect(self.maskSelectAll) btn_reset = QPushButton("Reset selection", self) btn_reset.clicked.connect(self.resetSelection) btn_reset_seads = QPushButton("Reset seads", self) btn_reset_seads.clicked.connect(self.resetSeads) btn_add = QPushButton("Add selection", self) btn_add.clicked.connect(self.maskAddSelection) btn_rem = QPushButton("Remove selection", self) btn_rem.clicked.connect(self.maskRemoveSelection) btn_mask = QPushButton("Mask region", self) btn_mask.clicked.connect(self.maskRegion) appmenu.append(QLabel('<b>Mask mode</b><br><br><br>' + 'Select the region to mask<br>' + 'using the left mouse button<br><br>')) appmenu.append(self.get_line('h')) appmenu.append(btn_recalc_mask) appmenu.append(btn_all) appmenu.append(btn_reset) appmenu.append(btn_reset_seads) appmenu.append(self.get_line('h')) appmenu.append(btn_add) appmenu.append(btn_rem) appmenu.append(self.get_line('h')) appmenu.append(btn_mask) appmenu.append(self.get_line('h')) self.mask_qhull = None if mode == 'crop': btn_crop = QPushButton("Crop", self) btn_crop.clicked.connect(self.crop) appmenu.append(QLabel('<b>Crop mode</b><br><br><br>' + 'Select the crop region<br>' + 'using the left mouse button<br><br>')) appmenu.append(btn_crop) if mode == 'draw': appmenu.append(QLabel('<b>Manual segmentation<br> mode</b><br><br><br>' + 'Mark the region of interest<br>' + 'using the mouse buttons:<br><br>' + ' <i>left</i> - draw<br>' + ' <i>right</i> - erase<br>' + ' <i>middle</i> - vol. erase<br><br>')) btn_reset = QPushButton("Reset", self) btn_reset.clicked.connect(self.resetSliceDraw) vmenu.append(None) vmenu.append(btn_reset) combo_erase_options = ['inside', 'outside'] combo_erase = QComboBox(self) combo_erase.activated[str].connect(self.changeEraseMode) combo_erase.addItems(combo_erase_options) self.changeEraseMode(combo_erase_options[combo_erase.currentIndex()]) vopts.append(QLabel('Volume erase mode:')) vopts.append(combo_erase) hbox = QHBoxLayout() vbox = QVBoxLayout() vbox_left = QVBoxLayout() vbox_app = QVBoxLayout() hbox.addWidget(self.slice_box) hbox.addWidget(self.slider) vbox_left.addWidget(self.slider.label) vbox_left.addWidget(self.view_label) vbox_left.addWidget(self.voxel_label) vbox_left.addWidget(QLabel()) vbox_left.addWidget(QLabel('View plane:')) vbox_left.addWidget(combo_view) vbox_left.addWidget(self.get_line()) vbox_left.addWidget(self.slider_cw['c'].label) vbox_left.addWidget(self.slider_cw['c']) vbox_left.addWidget(self.slider_cw['w'].label) vbox_left.addWidget(self.slider_cw['w']) vbox_left.addWidget(self.get_line()) vbox_left.addWidget(QLabel('Drawing mask:')) vbox_left.addWidget(combo_dmask) for ii in vopts: vbox_left.addWidget(ii) for ii in vmenu: if ii is None: vbox_left.addStretch(1) else: vbox_left.addWidget(ii) for ii in appmenu: if ii is None: vbox_app.addStretch(1) else: vbox_app.addWidget(ii) vbox_app.addStretch(1) vbox_app.addWidget(self.btn_quit) hbox.addLayout(vbox_left) hbox.addWidget(self.get_line('v')) hbox.addLayout(vbox_app) vbox.addLayout(hbox) vbox.addWidget(self.status_bar) self.my_layout = vbox self.setLayout(vbox) self.setWindowTitle('Segmentation Editor') self.show() def __init__(self, img, viewPositions=None, seeds=None, contours=None, mode='seed', modeFun=None, voxelSize=[1,1,1], volume_unit='mm3'): """ Initiate Editor Parameters ---------- img : array DICOM data matrix. actualSlice : int Index of actual slice. seeds : array Seeds, user defined regions of interest. contours : array Computed segmentation. mode : str Editor modes: 'seed' - seed editor 'crop' - manual crop 'draw' - drawing 'mask' - mask region modeFun : fun Mode function invoked by user button. voxelSize : tuple of float voxel size [mm] volume_unit : allow select output volume in mililiters or mm3 [mm, ml] """ QDialog.__init__(self) self.mode = mode self.mode_fun = modeFun self.actual_view = 'axial' self.act_transposition = VIEW_TABLE[self.actual_view] self.img = img self.img_aview = self.img.transpose(self.act_transposition) self.volume_unit = volume_unit self.last_view_position = {} for jj, ii in enumerate(VIEW_TABLE.iterkeys()): if viewPositions is None: viewpos = img.shape[VIEW_TABLE[ii][-1]] / 2 else: viewpos = viewPositions[jj] self.last_view_position[ii] =\ img.shape[VIEW_TABLE[ii][-1]] - viewpos - 1 self.actual_slice = self.last_view_position[self.actual_view] # set contours self.contours = contours if self.contours is None: self.contours_aview = None else: self.contours_aview = self.contours.transpose(self.act_transposition) # masked data - has information about which data were removed # 1 == enabled, 0 == deleted # How to return: # editorDialog.exec_() # masked_data = editorDialog.masked self.masked = np.ones(self.img.shape, np.int8) self.voxel_size = np.squeeze(np.asarray(voxelSize)) self.voxel_scale = self.voxel_size / float(np.min(self.voxel_size)) self.voxel_volume = np.prod(voxelSize) # set seeds if seeds is None: self.seeds = np.zeros(self.img.shape, np.int8) else: self.seeds = seeds self.seeds_aview = self.seeds.transpose(self.act_transposition) self.seeds_modified = False self.initUI(self.img_aview.shape, self.voxel_scale[np.array(self.act_transposition)], 600, mode) if mode == 'draw': self.seeds_orig = self.seeds.copy() self.slice_box.setEraseFun(self.eraseVolume) # set view window values C/W lb = np.min(img) self.img_min_val = lb ub = np.max(img) dul = np.double(ub) - np.double(lb) self.cw_range = {'c': [lb, ub], 'w': [1, dul]} self.slider_cw['c'].setRange(lb, ub) self.slider_cw['w'].setRange(1, dul) self.changeC(lb + dul / 2) self.changeW(dul) self.offset = np.zeros((3,), dtype=np.int16) def showStatus(self, msg): self.status_bar.showMessage(QString(msg)) QApplication.processEvents() def init_draw_mask(self, draw_mask, grid): mask_points = [] mask_iconlabel = [] for mask, label in draw_mask: w, h = mask.shape xx, yy = mask.nonzero() mask_points.append((xx - w/2, yy - h/2)) img = QImage(w, h, QImage.Format_ARGB32) img.fill(qRgba(255, 255, 255, 0)) for ii in range(xx.shape[0]): img.setPixel(xx[ii], yy[ii], qRgba(0, 0, 0, 255)) img = img.scaled(QSize(w * grid[0], h * grid[1])) icon = QIcon(QPixmap.fromImage(img)) mask_iconlabel.append((icon, label)) return mask_points, mask_iconlabel def saveSliceSeeds(self): aux = self.slice_box.getSliceSeeds() if aux is not None: self.seeds_aview[...,self.actual_slice] = aux self.seeds_modified = True else: self.seeds_modified = False def updateMaskRegion_btn(self): self.saveSliceSeeds() self.updateMaskRegion() def updateMaskRegion(self): crp = self.getCropBounds(return_nzs=True) if crp is not None: off, cri, nzs = crp if nzs[0].shape[0] <=5: self.showStatus("Not enough points (need >= 5)!") else: points = np.transpose(nzs) hull = Delaunay(points) X, Y, Z = np.mgrid[cri[0], cri[1], cri[2]] grid = np.vstack([X.ravel(), Y.ravel(), Z.ravel()]).T simplex = hull.find_simplex(grid) fill = grid[simplex >=0,:] fill = (fill[:,0], fill[:,1], fill[:,2]) if self.contours is None or self.contours_old is None: self.contours = np.zeros(self.img.shape, np.int8) self.contours_old = self.contours.copy() else: self.contours[self.contours != 2] = 0 self.contours[fill] = 1 self.contours_aview = self.contours.transpose(self.act_transposition) self.selectSlice(self.actual_slice) def maskRegion(self): self.masked[self.contours == 0] = 0 self.img[self.contours != 2] = self.img_min_val self.contours.fill(0) self.contours_old = self.contours.copy() self.seeds.fill(0) self.selectSlice(self.actual_slice) def maskAddSelection(self): self.updateMaskRegion() if self.contours is None: return self.contours[self.contours == 1] = 2 self.contours_old = self.contours.copy() self.seeds.fill(0) self.selectSlice(self.actual_slice) def maskRemoveSelection(self): self.updateMaskRegion() if self.contours is None: return self.contours[self.contours == 1] = 0 self.contours_old = self.contours.copy() self.seeds.fill(0) self.selectSlice(self.actual_slice) def maskSelectAll(self): self.updateMaskRegion() self.seeds[0][0][0] = 1 self.seeds[0][0][-1] = 1 self.seeds[0][-1][0] = 1 self.seeds[0][-1][-1] = 1 self.seeds[-1][0][0] = 1 self.seeds[-1][0][-1] = 1 self.seeds[-1][-1][0] = 1 self.seeds[-1][-1][-1] = 1 self.updateMaskRegion() self.selectSlice(self.actual_slice) def resetSelection(self): self.updateMaskRegion() if self.contours is None: return self.contours.fill(0) self.contours_old = self.contours.copy() self.seeds.fill(0) self.selectSlice(self.actual_slice) def resetSeads(self): self.seeds.fill(0) if self.contours is not None: self.contours = self.contours_old.copy() self.contours_aview = self.contours.transpose(self.act_transposition) self.updateMaskRegion() self.selectSlice(self.actual_slice) def updateCropBounds(self): crp = self.getCropBounds() if crp is not None: _, cri = crp self.contours = np.zeros(self.img.shape, np.int8) self.contours[cri].fill(1) self.contours_aview = self.contours.transpose(self.act_transposition) def focusSliceSlider(self): self.slider.setFocus(True) def sliderSelectSlice(self, value): self.selectSlice(self.n_slices - value) def scrollSlices(self, inc): if abs(inc) > 0: new = self.actual_slice + inc self.selectSlice(new) def selectSlice(self, value, force=False): if not(self.allow_select_slice): return if (value < 0) or (value >= self.n_slices): return if (value != self.actual_slice) or force: self.saveSliceSeeds() if self.seeds_modified: if self.mode == 'crop': self.updateCropBounds() elif self.mode == 'mask': self.updateMaskRegion() if self.contours is None: contours = None else: contours = self.contours_aview[...,value] slider_val = self.n_slices - value self.slider.setValue(slider_val) self.slider.label.setText('Slice: %d / %d' % (slider_val, self.n_slices)) self.slice_box.setSlice(self.img_aview[...,value], self.seeds_aview[...,value], contours) self.actual_slice = value def getSeeds(self): return self.seeds def getImg(self): return self.img def getOffset(self): return self.offset * self.voxel_size def getSeedsVal(self, label): return self.img[self.seeds==label] def getContours(self): return self.contours def setContours(self, contours): self.contours = contours self.contours_aview = self.contours.transpose(self.act_transposition) self.selectSlice(self.actual_slice) def changeCW(self, value, key): rg = self.cw_range[key] if (value < rg[0]) or (value > rg[1]): return if (value != self.slice_box.getCW()[key]): self.slider_cw[key].setValue(value) self.slider_cw[key].label.setText('%s: %d' % (key.upper(), value)) self.slice_box.setCW(value, key) self.slice_box.updateSliceCW(self.img_aview[...,self.actual_slice]) def changeC(self, value): self.changeCW(value, 'c') def changeW(self, value): self.changeCW(value, 'w') def setView(self, value): self.last_view_position[self.actual_view] = self.actual_slice # save seeds self.saveSliceSeeds() if self.seeds_modified: if self.mode == 'crop': self.updateCropBounds() elif self.mode == 'mask': self.updateMaskRegion() key = str(value) self.actual_view = key self.actual_slice = self.last_view_position[key] self.act_transposition = VIEW_TABLE[key] self.img_aview = self.img.transpose(self.act_transposition) self.seeds_aview = self.seeds.transpose(self.act_transposition) if self.contours is not None: self.contours_aview = self.contours.transpose(self.act_transposition) contours = self.contours_aview[...,self.actual_slice] else: contours = None vscale = self.voxel_scale[np.array(self.act_transposition)] height = self.slice_box.height() grid = height / float(self.img_aview.shape[1] * vscale[1]) # width = (self.img_aview.shape[0] * vscale[0])[0] # if width > 800: # height = 400 # grid = height / float(self.img_aview.shape[1] * vscale[1]) mgrid = (grid * vscale[0], grid * vscale[1]) self.slice_box.resizeSlice(new_slice_size=self.img_aview.shape[:-1], new_grid=mgrid) self.slice_box.setSlice(self.img_aview[...,self.actual_slice], self.seeds_aview[...,self.actual_slice], contours) self.allow_select_slice = False self.n_slices = self.img_aview.shape[2] slider_val = self.n_slices - self.actual_slice self.slider.setRange(1, self.n_slices) self.slider.setValue(slider_val) self.allow_select_slice = True self.slider.label.setText('Slice: %d / %d' % (slider_val, self.n_slices)) self.view_label.setText('View size: %d x %d' % self.img_aview.shape[:-1]) self.adjustSize() self.adjustSize() def changeMask(self, val): self.slice_box.setMaskPoints(self.mask_points_tab[val]) def changeContourMode(self, val): self.slice_box.contour_mode = str(val) self.slice_box.updateSlice() def changeEraseMode(self, val): self.slice_box.erase_mode = str(val) def eraseVolume(self, pos, mode): self.showStatus("Processing...") xyz = np.array(pos + (self.actual_slice,)) p = np.zeros_like(xyz) p[np.array(self.act_transposition)] = xyz p = tuple(p) if self.seeds[p] > 0: if mode == 'inside': erase_reg(self.seeds, p, val=0) elif mode == 'outside': erase_reg(self.seeds, p, val=-1) idxs = np.where(self.seeds < 0) self.seeds.fill(0) self.seeds[idxs] = 1 if self.contours is None: contours = None else: contours = self.contours_aview[...,self.actual_slice] self.slice_box.setSlice(self.img_aview[...,self.actual_slice], self.seeds_aview[...,self.actual_slice], contours) self.showStatus("Done") def cropUpdate(self, img): for ii in VIEW_TABLE.iterkeys(): self.last_view_position[ii] = 0 self.actual_slice = 0 self.img = img self.img_aview = self.img.transpose(self.act_transposition) self.contours = None self.contours_aview = None self.seeds = np.zeros(self.img.shape, np.int8) self.seeds_aview = self.seeds.transpose(self.act_transposition) self.seeds_modified = False vscale = self.voxel_scale[np.array(self.act_transposition)] height = self.slice_box.height() grid = height / float(self.img_aview.shape[1] * vscale[1]) mgrid = (grid * vscale[0], grid * vscale[1]) self.slice_box.resizeSlice(new_slice_size=self.img_aview.shape[:-1], new_grid=mgrid) self.slice_box.setSlice(self.img_aview[...,self.actual_slice], self.seeds_aview[...,self.actual_slice], None) self.allow_select_slice = False self.n_slices = self.img_aview.shape[2] self.slider.setValue(self.actual_slice + 1) self.slider.setRange(1, self.n_slices) self.allow_select_slice = True self.slider.label.setText('Slice: %d / %d' % (self.actual_slice + 1, self.n_slices)) self.view_label.setText('View size: %d x %d' % self.img_aview.shape[:-1]) def getCropBounds(self, return_nzs=False, flat=False): nzs = self.seeds.nonzero() cri = [] flag = True for ii in range(3): if nzs[ii].shape[0] == 0: flag = False break smin, smax = np.min(nzs[ii]), np.max(nzs[ii]) if not(flat): if smin == smax: flag = False break cri.append((smin, smax)) if flag: cri = np.array(cri) out = [] offset = [] for jj, ii in enumerate(cri): out.append(slice(ii[0], ii[1] + 1)) offset.append(ii[0]) if return_nzs: return np.array(offset), tuple(out), nzs else: return np.array(offset), tuple(out) else: return None def crop(self): self.showStatus("Processing...") crp = self.getCropBounds() if crp is not None: offset, cri = crp crop = self.img[cri] self.img = np.ascontiguousarray(crop) self.offset += offset self.showStatus('Done') else: self.showStatus('Region not selected!') self.cropUpdate(self.img) def recalculate(self, event): self.saveSliceSeeds() if np.abs(np.min(self.seeds) - np.max(self.seeds)) < 2: self.showStatus('Inner and outer regions not defined!') return self.showStatus("Processing...") self.mode_fun(self) self.selectSlice(self.actual_slice) self.updateVolume() self.showStatus("Done") def deleteSliceSeeds(self, event): self.seeds_aview[...,self.actual_slice] = 0 self.slice_box.setSlice(seeds=self.seeds_aview[...,self.actual_slice]) self.slice_box.updateSlice() def resetSliceDraw(self, event): seeds_orig_aview = self.seeds_orig.transpose(self.act_transposition) self.seeds_aview[...,self.actual_slice] = seeds_orig_aview[...,self.actual_slice] self.slice_box.setSlice(seeds=self.seeds_aview[...,self.actual_slice]) self.slice_box.updateSlice() def quit(self, event): self.close() def updateVolume(self): text = 'Volume:\n unknown' if self.voxel_volume is not None: if self.mode == 'draw': vd = self.seeds else: vd = self.contours if vd is not None: nzs = vd.nonzero() nn = nzs[0].shape[0] if self.volume_unit == 'ml': text = 'Volume [ml]:\n %.2f' %\ (nn * self.voxel_volume / 1000) else: text = 'Volume [mm3]:\n %.2e' % (nn * self.voxel_volume) self.volume_label.setText(text) def getROI(self): crp = self.getCropBounds() if crp is not None: _, cri = crp else: cri = [] for jj, ii in enumerate(self.img.shape): off = self.offset[jj] cri.append(slice(off, off + ii)) return cri
class MainWindow(QWidget): def __init__(self): QWidget.__init__(self, None) # initiate timer self.timer = QTimer() self.timer.timeout.connect(self.reload) # layout id gridbox-like self.box = QGridLayout() self.resize(800, 800) self.setLayout(self.box) # Create two labels and a button self.vertLabel = QLabel("Radolan Data Window", self) self.timeLabel = QLabel("Time", self) self.sliderLabel = QLabel("00:00", self) # File Dialog self.dlg = QFileDialog() self.dlg.setFileMode(QFileDialog.Directory) self.dlg.setOption(QFileDialog.ShowDirsOnly, True) # Canvas self.canvas = None self.cbar = CBarCanvas() # Sliders self.slider = QSlider(Qt.Horizontal) self.slider.setMinimum(1) self.slider.setMaximum(100) self.slider.setTickInterval(1) self.slider.setSingleStep(1) self.slider.valueChanged.connect(self.slider_moved) self.cHighSlider = QSlider(Qt.Horizontal) self.cHighSlider.setMinimum(0) self.cHighSlider.setMaximum(4096) self.cHighSlider.setTickInterval(1) self.cHighSlider.setSingleStep(1) self.cHighSlider.setValue(4096) self.cHighSlider.valueChanged.connect(self.cHighSlider_moved) self.cHighLabel = QLabel("Upper Limit:") self.cHighValue = QLabel("4096") # Load Button self.loadButton = QPushButton("Open Directory") self.loadButton.clicked.connect(self.button_clicked) # Text Output Widget self.attrWidget = TextWidget() self.attrWidget.setVisible(False) self.createButtons() # grid parameters self.c1 = 0 self.c2 = 10 # add Widgets to Layout self.box.addWidget(self.loadButton, 0, self.c1, 1, 11) self.box.addWidget(self.dlg, 1, self.c1, 3, 11) self.box.addWidget(self.attrWidget, 1, self.c1, 3, -1) self.box.addWidget(self.vertLabel, 6, self.c1, 1, 10) self.box.addWidget(self.cbar.native, 5, self.c2, 10, 1) self.box.addWidget(self.timeLabel, 4, self.c1, 1, 10) self.box.addWidget(self.playPauseButton, 4, self.c1 + 1, 1, 1) self.box.addWidget(self.cHighLabel, 4, self.c1 + 4, 1, 1) self.box.addWidget(self.cHighValue, 4, self.c1 + 5, 1, 1) self.box.addWidget(self.cHighSlider, 4, self.c1 + 6, 1, 4) self.box.addWidget(self.sliderLabel, 5, self.c1, 1, 1) self.box.addWidget(self.slider, 5, self.c1 + 1, 1, 9) self.show() # connect Filedialog self.dlg.fileSelected.connect(self.folder_selected) def folder_selected(self, folder): if not self.canvas: self.canvas = Canvas() self.box.addWidget(self.canvas.native, 7, self.c1, -1, 10) inname = "/raa*" self.canvas.flist = sorted(glob.glob(str(folder) + inname)) self.canvas.frames = len(self.canvas.flist) self.slider.setMaximum(self.canvas.frames) self.attrWidget.setVisible(True) self.slider.setValue(1) self.slider_moved(1) def button_clicked(self): self.attrWidget.setVisible(False) self.dlg.setVisible(True) # loop continuously through data def reload(self): if self.slider.value() == self.slider.maximum(): self.slider.setValue(1) else: self.slider.setValue(self.slider.value() + 1) # changing upper limit def cHighSlider_moved(self, position): clow, chigh = self.canvas.image.clim self.canvas.image.clim = (clow, position) self.cHighValue.setText(str(position)) # slide through data def slider_moved(self, position): self.canvas.actualFrame = position - 1 self.canvas.data, self.canvas.attrs = read_RADOLAN_composite(self.canvas.flist[self.canvas.actualFrame], missing=0) # adapt color limits if self.canvas.data.dtype == 'uint8': self.cHighSlider.setMaximum(255) else: self.cHighSlider.setMaximum(4096) # change and update self.canvas.update() self.sliderLabel.setText(self.canvas.attrs['datetime'].strftime("%H:%M")) self.attrWidget.radolanVersion.setText(self.canvas.attrs['radolanversion']) self.attrWidget.dateTime.setText(self.canvas.attrs['datetime'].strftime("%Y-%m-%d")) self.attrWidget.productType.setText(self.canvas.attrs['producttype'].upper()) # start/stop capability def playpause(self): if self.playPauseButton.toolTip() == 'Play': self.playPauseButton.setToolTip("Pause") self.timer.start() self.playPauseButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPause)) else: self.playPauseButton.setToolTip("Play") self.timer.stop() self.playPauseButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) # create play/pause Button def createButtons(self): iconSize = QSize(18, 18) self.playPauseButton = QToolButton() self.playPauseButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.playPauseButton.setIconSize(iconSize) self.playPauseButton.setToolTip("Play") self.playPauseButton.clicked.connect(self.playpause)
class Widget(QWidget): def __init__(self, dockwidget): super(Widget, self).__init__(dockwidget) self._document = None self._fileSelector = QComboBox(editable=True, insertPolicy=QComboBox.NoInsert) widgets.drag.ComboDrag(self._fileSelector).role = Qt.UserRole self._fileSelector.lineEdit().setReadOnly(True) self._fileSelector.lineEdit().setFocusPolicy(Qt.NoFocus) self._stopButton = QToolButton() self._playButton = QToolButton() self._timeSlider = QSlider(Qt.Horizontal, tracking=False, singleStep=500, pageStep=5000, invertedControls=True) self._display = Display() self._tempoFactor = QSlider(Qt.Vertical, minimum=-50, maximum=50, singleStep=1, pageStep=5) grid = QGridLayout(spacing=0) self.setLayout(grid) grid.addWidget(self._fileSelector, 0, 0, 1, 3) grid.addWidget(self._stopButton, 1, 0) grid.addWidget(self._playButton, 1, 1) grid.addWidget(self._timeSlider, 1, 2) grid.addWidget(self._display, 2, 0, 1, 3) grid.addWidget(self._tempoFactor, 0, 3, 3, 1) # size policy of combo p = self._fileSelector.sizePolicy() p.setHorizontalPolicy(QSizePolicy.Ignored) self._fileSelector.setSizePolicy(p) # size policy of combo popup p = self._fileSelector.view().sizePolicy() p.setHorizontalPolicy(QSizePolicy.MinimumExpanding) self._fileSelector.view().setSizePolicy(p) self._player = player.Player() self._outputCloseTimer = QTimer(interval=60000, singleShot=True, timeout=self.closeOutput) self._timeSliderTicker = QTimer(interval=200, timeout=self.updateTimeSlider) self._fileSelector.activated[int].connect(self.slotFileSelected) self._tempoFactor.valueChanged.connect(self.slotTempoChanged) self._timeSlider.valueChanged.connect(self.slotTimeSliderChanged) self._timeSlider.sliderMoved.connect(self.slotTimeSliderMoved) self._player.beat.connect(self.updateDisplayBeat) self._player.time.connect(self.updateDisplayTime) self._player.stateChanged.connect(self.slotPlayerStateChanged) self.slotPlayerStateChanged(False) dockwidget.mainwindow().currentDocumentChanged.connect( self.loadResults) app.documentLoaded.connect(self.slotUpdatedFiles) app.jobFinished.connect(self.slotUpdatedFiles) app.aboutToQuit.connect(self.stop) midihub.aboutToRestart.connect(self.slotAboutToRestart) midihub.settingsChanged.connect(self.clearMidiSettings, -100) midihub.settingsChanged.connect(self.readMidiSettings) app.documentClosed.connect(self.slotDocumentClosed) app.translateUI(self) self.readMidiSettings() d = dockwidget.mainwindow().currentDocument() if d: self.loadResults(d) def translateUI(self): self._tempoFactor.setToolTip(_("Tempo")) def slotAboutToRestart(self): self.stop() self._player.set_output(None) def clearMidiSettings(self): """Called first when settings are changed.""" self.stop() self._outputCloseTimer.stop() self._player.set_output(None) def readMidiSettings(self): """Called after clearMidiSettings(), and on first init.""" pass def openOutput(self): """Called when playing starts. Ensures an output port is opened.""" self._outputCloseTimer.stop() if not self._player.output(): p = QSettings().value("midi/player/output_port", midihub.default_output(), type("")) o = midihub.output_by_name(p) if o: self._player.set_output(output.Output(o)) def closeOutput(self): """Called when the output close timer fires. Closes the output.""" self._player.set_output(None) def slotPlayerStateChanged(self, playing): ac = self.parentWidget().actionCollection # setDefaultAction also adds the action for b in self._stopButton, self._playButton: while b.actions(): b.removeAction(b.actions()[0]) if playing: self._timeSliderTicker.start() self._stopButton.setDefaultAction(ac.midi_stop) self._playButton.setDefaultAction(ac.midi_pause) else: self._timeSliderTicker.stop() self.updateTimeSlider() self._stopButton.setDefaultAction(ac.midi_restart) self._playButton.setDefaultAction(ac.midi_play) # close the output if the preference is set if QSettings().value("midi/close_outputs", False, bool): self._outputCloseTimer.start() def play(self): """Starts the MIDI player, opening an output if necessary.""" if not self._player.is_playing() and not self._player.has_events(): self.restart() self.openOutput() if not self._player.output(): self._display.statusMessage(_("No output found!")) self._player.start() def stop(self): """Stops the MIDI player.""" self._player.stop() def restart(self): """Restarts the MIDI player. If another file is in the file selector, or the file was updated, the new file is loaded. """ self._player.seek(0) self.updateTimeSlider() self._display.reset() if self._document: files = midifiles.MidiFiles.instance(self._document) index = self._fileSelector.currentIndex() if files and (files.song(index) is not self._player.song()): self.loadSong(index) def slotTempoChanged(self, value): """Called when the user drags the tempo.""" # convert -50 to 50 to 0.5 to 2.0 factor = 2**(value / 50.0) self._player.set_tempo_factor(factor) self._display.setTempo("{0}%".format(int(factor * 100))) def slotTimeSliderChanged(self, value): self._player.seek(value) self._display.setTime(value) if self._player.song(): self._display.setBeat(*self._player.song().beat(value)[1:]) def slotTimeSliderMoved(self, value): self._display.setTime(value) if self._player.song(): self._display.setBeat(*self._player.song().beat(value)[1:]) def updateTimeSlider(self): if not self._timeSlider.isSliderDown(): with qutil.signalsBlocked(self._timeSlider): self._timeSlider.setMaximum(self._player.total_time()) self._timeSlider.setValue(self._player.current_time()) def updateDisplayBeat(self, measnum, beat, num, den): if not self._timeSlider.isSliderDown(): self._display.setBeat(measnum, beat, num, den) def updateDisplayTime(self, time): if not self._timeSlider.isSliderDown(): self._display.setTime(time) def slotUpdatedFiles(self, document): """Called when there are new MIDI files.""" if document == self.parentWidget().mainwindow().currentDocument(): self.loadResults(document) def loadResults(self, document): self._document = document files = midifiles.MidiFiles.instance(document) self._fileSelector.setModel(files.model()) if files: self._fileSelector.setCurrentIndex(files.current) if not self._player.is_playing(): self.loadSong(files.current) def loadSong(self, index): files = midifiles.MidiFiles.instance(self._document) self._player.set_song(files.song(index)) m, s = divmod(self._player.total_time() // 1000, 60) name = self._fileSelector.currentText() self.updateTimeSlider() self._display.reset() self._display.statusMessage(_("midi lcd screen", "LOADED"), name, _("midi lcd screen", "TOTAL"), "{0}:{1:02}".format(m, s)) def slotFileSelected(self, index): if self._document: self._player.stop() files = midifiles.MidiFiles.instance(self._document) if files: files.current = index self.restart() def slotDocumentClosed(self, document): if document == self._document: self._document = None self._fileSelector.clear() self._player.stop() self._player.clear() self.updateTimeSlider() self._display.reset()
class FitParam(object): def __init__(self, name, value, mini, maxi, logscale=False, steps=5000, format='%.3f', size_offset=0, unit=''): self.name = name self.value = value self.min = mini if logscale == False else max(1e-120, mini) self.max = maxi self.logscale = logscale self.steps = steps self.format = format self.unit = unit self.prefix_label = None self.lineedit = None self.unit_label = None self.slider = None self.button = None self._widgets = [] self._size_offset = size_offset self._refresh_callback = None self.dataset = FitParamDataSet(title=_("Curve fitting parameter")) def copy(self): """Return a copy of this fitparam""" return self.__class__(self.name, self.value, self.min, self.max, self.logscale, self.steps, self.format, self._size_offset, self.unit) def create_widgets(self, parent, refresh_callback): self._refresh_callback = refresh_callback self.prefix_label = QLabel() font = self.prefix_label.font() font.setPointSize(font.pointSize() + self._size_offset) self.prefix_label.setFont(font) self.button = QPushButton() self.button.setIcon(get_icon('settings.png')) self.button.setToolTip( _("Edit '%s' fit parameter properties") % self.name) QObject.connect(self.button, SIGNAL('clicked()'), lambda: self.edit_param(parent)) self.lineedit = QLineEdit() QObject.connect(self.lineedit, SIGNAL('editingFinished()'), self.line_editing_finished) self.unit_label = QLabel(self.unit) self.slider = QSlider() self.slider.setOrientation(Qt.Horizontal) self.slider.setRange(0, self.steps - 1) QObject.connect(self.slider, SIGNAL("valueChanged(int)"), self.slider_value_changed) self.update(refresh=False) self.add_widgets([ self.prefix_label, self.lineedit, self.unit_label, self.slider, self.button ]) def add_widgets(self, widgets): self._widgets += widgets def get_widgets(self): return self._widgets def set_scale(self, state): self.logscale = state > 0 self.update_slider_value() def set_text(self, fmt=None): style = "<span style=\'color: #444444\'><b>%s</b></span>" self.prefix_label.setText(style % self.name) if self.value is None: value_str = '' else: if fmt is None: fmt = self.format value_str = fmt % self.value self.lineedit.setText(value_str) self.lineedit.setDisabled(self.value == self.min and self.max == self.min) def line_editing_finished(self): try: self.value = float(self.lineedit.text()) except ValueError: self.set_text() self.update_slider_value() self._refresh_callback() def slider_value_changed(self, int_value): if self.logscale: #~ total_delta = np.log10(1+self.max-self.min) #~ self.value = self.min+10**(total_delta*int_value/(self.steps-1))-1 #~ total_delta = np.log10(self.max)-np.log10(self.min) ratio = int_value / (self.steps - 1) self.value = self.max**ratio * self.min**(1 - ratio) else: total_delta = self.max - self.min self.value = self.min + total_delta * int_value / (self.steps - 1) self.set_text() self._refresh_callback() def update_slider_value(self): from numpy import isnan, isinf if (self.value is None or self.min is None or self.max is None): self.slider.setEnabled(False) if self.slider.parent() and self.slider.parent().isVisible(): self.slider.show() elif self.value == self.min and self.max == self.min: self.slider.hide() else: self.slider.setEnabled(True) if self.slider.parent() and self.slider.parent().isVisible(): self.slider.show() if self.logscale: value_delta = max([np.log10(self.value / self.min), 0.]) total_delta = np.log10(self.max / self.min) if not isnan(self.steps * value_delta / total_delta): intval = int(self.steps * value_delta / total_delta) else: intval = int(self.min) else: value_delta = self.value - self.min total_delta = self.max - self.min intval = int(self.steps * value_delta / total_delta) self.slider.blockSignals(True) print intval print sys.stdout.flush() self.slider.setValue(intval) self.slider.blockSignals(False) def edit_param(self, parent): update_dataset(self.dataset, self) if self.dataset.edit(parent=parent): restore_dataset(self.dataset, self) if self.value > self.max: self.max = self.value if self.value < self.min: self.min = self.value self.update(True) def update(self, refresh=True): self.unit_label.setText(self.unit) self.slider.setRange(0, self.steps - 1) self.update_slider_value() self.set_text() if refresh: self._refresh_callback()
class MainWin(QMainWindow): def __init__(self, mx, spurs, fef, parent=None, plot_lib='mpl'): QMainWindow.__init__(self, parent) self.mx = mx self.spurset = spurs self.fef = fef if plot_lib == 'qwt': from chart.qwtchart import qwtchart as chart elif plot_lib == 'mpl': from chart.mplchart import mplchart as chart elif plot_lib == 'pg': from chart.pyqtgraphchart import pyqtgraphchart as chart else: raise NotImplementedError self.chart = chart(self.spurset, self.fef, self) self.create_menu_bar() self.create_main_frame() self.hookup() def hookup(self): # connect all the objects that are supposed to be watching each other # for changes and updates. self.mx.register(self.chart.draw_spurs) self.spurset.register(self.chart.draw_spurs) self.chart.picker_watch(self.fef) self.fef.register(self.chart.draw_fef) self.chart.draw_spurs(self.spurset) self.chart.draw_fef(self.fef) def IF_slide(self, i): """ callback method for the IF selection slider""" self.IFtextbox.setText(str(i)) self.mx.IF = i def about(self): msg = ''' A frequency-planing tool based on the method of spur distances. (A reference to the article will go here) For more info, view the README included with this program. Patrick Yeon, 2012''' QMessageBox.about(self, 'Spur Distance Chart', msg.strip()) def mxtypecb(self, i): """ callback method for mixer configuration selection combobox""" self.mx.m, self.mx.n = [(-1, 1), (1, -1), (1,1)][i] # trigger anything watching the mixer self.mx.update_watchers() def create_main_frame(self): self.main_frame = QWidget() # Looking at the main frame as two columns. On the left there is the # chart and the IF control. In the right column we'll have range # settings, mixer settings, and maybe other stuff that comes up? self.IFtextbox = QLineEdit() self.IFtextbox.setMinimumWidth(6) self.IFtextbox.setText(str(self.spurset.mixer.IF)) # TODO link up the textbox so that it can also be input self.IFslider = QSlider(Qt.Horizontal) # TODO I'd really like some form of slider that doesn't actually limit # the user. Also, if IFtextbox could modify the IF, that'd be nice. self.IFslider.setRange(int(self.mx.IF * 0.1), (self.mx.IF * 5)) self.IFslider.setValue(self.mx.IF) self.IFslider.setTracking(True) self.IFslider.setTickPosition(QSlider.TicksAbove) step = max(1, int(0.01 * self.mx.IF)) self.IFslider.setSingleStep(step) self.IFslider.setPageStep(step * 10) self.IFcid = self.connect(self.IFslider, SIGNAL('valueChanged(int)'), self.IF_slide) IFbar = QHBoxLayout() IFbar.addWidget(QLabel('IF')) IFbar.addWidget(self.IFtextbox) IFbar.addWidget(self.IFslider) IFbar.addStretch() leftcol = QVBoxLayout() leftcol.addWidget(self.chart.plot) leftcol.addLayout(IFbar) # left column done. Now the right-hand side rangebox = QVBoxLayout() for (prop, name, f) in [(spurset.RFmin, 'RFmin', self.spurset.RFmin), (spurset.RFmax, 'RFmax', self.spurset.RFmax), (spurset.dspan, 'dspan', self.spurset.dspan)]: rangebox.addLayout(Fbar(self.spurset, prop, name, f, 0, 10000)) autocb = QCheckBox('Auto') # Disable it, won't be implemented for release # but leave it there, to nag me into doing it. autocb.setDisabled(True) rangebox.addWidget(autocb) # a line to report the front-end filter's limits fefstat = QHBoxLayout() fefstat.addWidget(QLabel('Filter Range: ')) fefrange = QLabel('%d - %d' % (self.fef.start, self.fef.stop)) # TODO not sure about the lambda here. Feels like if I give it time, # I'll sort out a sensible overall connection scheme. self.fef.register(lambda o: fefrange.setText('%d - %d' % (self.fef.start, self.fef.stop))) fefstat.addWidget(fefrange) # mixer high/low-side injection picker mxbar = QHBoxLayout() mxbar.addWidget(QLabel('IF = ')) mxtype = QComboBox() mxtype.addItem('LO - RF') mxtype.addItem('RF - LO') mxtype.addItem('RF + LO') # TODO this is ugly mxtype.setCurrentIndex([(-1, 1), (1, -1), (1,1)].index((self.mx.m, self.mx.n))) self.mxtypecid = self.connect(mxtype, SIGNAL('currentIndexChanged(int)'), self.mxtypecb) mxbar.addWidget(mxtype) # alright, the actual column proper in the layout vbar = QVBoxLayout() vbar.addLayout(rangebox) vbar.addLayout(fefstat) vbar.addLayout(mxbar) legend = self.chart.legend() vbar.addWidget(legend) # need to let the legend stretch so that everything fits in it vbar.setStretchFactor(legend, 1) vbar.addStretch() hbox = QHBoxLayout() hbox.addLayout(leftcol) hbox.addLayout(vbar) # make sure the legend doesn't stretch so far horizontally that the # chart suffers considerable loss of space. hbox.setStretchFactor(leftcol, 5) hbox.setStretchFactor(vbar, 1) self.main_frame.setLayout(hbox) self.setCentralWidget(self.main_frame) def create_menu_bar(self): filemenu = self.menuBar().addMenu('&File') close = QAction('&Quit', self) close.setShortcut('Ctrl+W') self.connect(close, SIGNAL('triggered()'), self.close) filemenu.addAction(close) helpmenu = self.menuBar().addMenu('&Help') about = QAction('&About', self) about.setShortcut('F1') self.connect(about, SIGNAL('triggered()'), self.about) helpmenu.addAction(about)
class CMainWindow(QFrame): def __init__(self): QMainWindow.__init__(self) layout = QGridLayout(self) layout.setMargin(2) btnFiles = QPushButton(u'Файлы', self) btnVideo = QPushButton(u'Видео', self) btnPlay = QPushButton(u'Play/Pause', self) btnStop = QPushButton(u'Stop', self) btnMute = QPushButton(u'Mute', self) btnMute.setCheckable(True) btnMainMenu = QPushButton(u'Main', self) self.sldVolume = QSlider(Qt.Vertical, self) self.sldPosition = QSlider(Qt.Horizontal, self) self.layMain = QStackedLayout() btnFiles.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) btnVideo.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) btnPlay.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) btnStop.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) btnMute.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) btnMainMenu.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.sldVolume.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) self.sldPosition.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) layout.addWidget(btnFiles, 0, 0) layout.addWidget(btnVideo, 0, 1) layout.addWidget(btnPlay, 0, 3) layout.addWidget(btnStop, 0, 4) layout.addWidget(btnMute, 0, 5) layout.addWidget(btnMainMenu, 2, 5) layout.addWidget(self.sldVolume, 1, 5) layout.addWidget(self.sldPosition, 2, 0, 1, 5) layout.addLayout(self.layMain, 1, 0, 1, 5) fileBrowser = CFileBrowser(self) self.videoWidget = QWidget(self) self.exitMenu = CExitMenu(self) self.mplayer = MPlayerControl(self, self.videoWidget) fileBrowser.chosen.connect(self.startPlay) btnFiles.clicked.connect(lambda: self.selectMode(0)) btnVideo.clicked.connect(lambda: self.selectMode(1)) btnMainMenu.clicked.connect(lambda: self.selectMode(2)) self.sldPosition.valueChanged.connect(self.mplayer.seek) self.sldVolume.valueChanged.connect(self.mplayer.setvol) btnMute.clicked.connect(lambda: self.mplayer.mute(btnMute.isChecked())) btnPlay.clicked.connect(self.mplayer.play) btnStop.clicked.connect(self.mplayer.stop) self.sldVolume.setValue(QtGui.qApp.settings['volume']) self.mplayer.percent_position.connect(self.on_mplayer_position) self.layMain.addWidget(fileBrowser) self.layMain.addWidget(self.videoWidget) self.layMain.addWidget(self.exitMenu) @pyqtSlot(int) def on_mplayer_position(self, pos): self.sldPosition.blockSignals(True) self.sldPosition.setValue(pos) self.sldPosition.blockSignals(False) @pyqtSlot(int) def selectMode(self, mode): self.layMain.setCurrentIndex(mode) @pyqtSlot(str) def startPlay(self, path): self.selectMode(1) self.mplayer.play(path) def closeEvent(self, event): self.mplayer.quit() QFrame.closeEvent(self, event)
class MyMainWindow(QMainWindow): ' Main Window ' def __init__(self, parent=None): super(MyMainWindow, self).__init__(parent) self.statusBar().showMessage(__doc__) self.setWindowTitle(__doc__) self.setMinimumSize(250, 280) self.setMaximumSize(300, 300) self.resize(250, 290) self.setWindowIcon(QIcon.fromTheme("face-monkey")) self.setStyleSheet('''QWidget { color: rgba( 0, 255, 255, 255 ); background-color: #323232; font-family: 'Ubuntu Light'; font-size: 14px; } QToolTip { border: 1px solid black; background-color: #ffa02f; background-image: None; padding: 1px; border-radius: 3px; opacity: 100; } QWidget:item:hover { background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #ca0619 ); color: #000000; } QWidget:item:selected { background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a ); } QWidget:disabled { color: #404040; background-color: #323232; } QWidget:focus { background-image: None; border: 2px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a ); } QPushButton { background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #565656, stop: 0.1 #525252, stop: 0.5 #4e4e4e, stop: 0.9 #4a4a4a, stop: 1 #464646 ); border-width: 1px; border-color: #1e1e1e; border-style: solid; border-radius: 6; padding: 3px; font-size: 12px; padding-left: 5px; padding-right: 5px; background-image: None; } QPushButton:pressed { background-image: None; background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2d2d2d, stop: 0.1 #2b2b2b, stop: 0.5 #292929, stop: 0.9 #282828, stop: 1 #252525 ); } QComboBox { background-image: None; selection-background-color: #ffaa00; background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #565656, stop: 0.1 #525252, stop: 0.5 #4e4e4e, stop: 0.9 #4a4a4a, stop: 1 #464646 ); border-style: solid; border: 1px solid #1e1e1e; border-radius: 5; } QComboBox:hover, QPushButton:hover { background-image: url(.bg.png); border: 2px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a ); } QComboBox:on { padding-top: 3px; padding-left: 4px; background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2d2d2d, stop: 0.1 #2b2b2b, stop: 0.5 #292929, stop: 0.9 #282828, stop: 1 #252525 ); selection-background-color: #ffaa00; background-image: None; } QComboBox QAbstractItemView { background-image: None; border: 2px solid darkgray; selection-background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a ); } QComboBox::drop-down { subcontrol-origin: padding; subcontrol-position: top right; width: 15px; border-left-width: 0px; border-left-color: darkgray; border-left-style: solid; border-top-right-radius: 3px; border-bottom-right-radius: 3px; background-image: None; } QComboBox::down-arrow { background-image: None; } QSlider { border-width: 2px; border-color: #1e1e1e; border-style: solid; padding: 3px; font-size: 8px; padding-left: 5px; padding-right: 5px; width: 25px; border-radius: 5px; } QSlider::sub-page:vertical { background: red; border: none; width: 25px; } QSlider::add-page:vertical { background: green; border: none; width: 25px; } QSlider::handle:vertical { background-color: QLinearGradient(spread:pad, x1:0, y1:0, x2:1, y2:0.273, stop:0 rgba(0, 0, 0, 255), stop:1 rgba(150, 255, 255, 255) ); width: 10px; height: 25px; border: 1px solid grey; text-align: center; border-top-left-radius: 2px; border-bottom-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius 2px; margin-left: 2px; margin-right: 2px; } QSlider::handle:vertical:hover { border: 2px solid #ffaa00; margin-left: 2px; margin-right: 2px; } QSlider::sub-page:vertical:disabled { background: #bbb; border-color: #999; } QSlider::add-page:vertical:disabled { background: #eee; border-color: #999; } QSlider::handle:vertical:disabled { background: #eee; border: 1px solid #aaa; border-radius: 4px; } ''') self.label1 = QLabel(self) self.label1.setText('Use Debug') self.label1.setGeometry(QtCore.QRect(25, 25, 125, 25)) self.slider1 = QSlider(self) self.slider1.setGeometry(QtCore.QRect(150, 25, 25, 25)) self.slider1.setTickInterval(1) self.slider1.setCursor(QCursor(QtCore.Qt.OpenHandCursor)) self.slider1.TickPosition(QSlider.TicksBothSides) self.slider1.setRange(0, 1) self.slider1.setValue(1) self.sli1lbl = QLabel(str(self.slider1.value()), self.slider1) self.sli1lbl.move(9, 5) self.sli1lbl.setAutoFillBackground(False) self.slider1.valueChanged.connect( lambda: self.sli1lbl.setText(str(self.slider1.value()))) self.slider1.sliderPressed.connect( lambda: self.slider1.setCursor(QCursor(QtCore.Qt.ClosedHandCursor))) self.slider1.sliderReleased.connect( lambda: self.slider1.setCursor(QCursor(QtCore.Qt.OpenHandCursor))) self.label2 = QLabel(self) self.label2.setText('Make Executable') self.label2.setGeometry(QtCore.QRect(25, 75, 125, 25)) self.slider2 = QSlider(self) self.slider2.setGeometry(QtCore.QRect(150, 75, 25, 25)) self.slider2.setTickInterval(1) self.slider2.setCursor(QCursor(QtCore.Qt.OpenHandCursor)) self.slider2.TickPosition(QSlider.TicksBothSides) self.slider2.setRange(0, 1) self.slider2.setValue(1) self.sli2lbl = QLabel(str(self.slider2.value()), self.slider2) self.sli2lbl.move(9, 5) self.sli2lbl.setAutoFillBackground(False) self.slider2.valueChanged.connect( lambda: self.sli2lbl.setText(str(self.slider2.value()))) self.slider2.sliderPressed.connect( lambda: self.slider2.setCursor(QCursor(QtCore.Qt.ClosedHandCursor))) self.slider2.sliderReleased.connect( lambda: self.slider2.setCursor(QCursor(QtCore.Qt.OpenHandCursor))) self.label3 = QLabel(self) self.label3.setText('Relative Imports') self.label3.setGeometry(QtCore.QRect(25, 125, 125, 25)) self.slider3 = QSlider(self) self.slider3.setGeometry(QtCore.QRect(150, 125, 25, 25)) self.slider3.setTickInterval(1) self.slider3.setCursor(QCursor(QtCore.Qt.OpenHandCursor)) self.slider3.TickPosition(QSlider.TicksBothSides) self.slider3.setRange(0, 1) self.slider3.setValue(0) self.sli3lbl = QLabel(str(self.slider3.value()), self.slider3) self.sli3lbl.move(9, 5) self.sli3lbl.setAutoFillBackground(False) self.slider3.valueChanged.connect( lambda: self.sli3lbl.setText(str(self.slider3.value()))) self.slider3.sliderPressed.connect( lambda: self.slider3.setCursor(QCursor(QtCore.Qt.ClosedHandCursor))) self.slider3.sliderReleased.connect( lambda: self.slider3.setCursor(QCursor(QtCore.Qt.OpenHandCursor))) self.label4 = QLabel(self) self.label4.setText('Indent Spaces') self.label4.setGeometry(QtCore.QRect(25, 175, 125, 25)) self.combo1 = QComboBox(self) self.combo1.setCursor(QCursor(QtCore.Qt.PointingHandCursor)) self.combo1.addItems(['4', '0', '2', '6', '8']) self.combo1.setGeometry(QtCore.QRect(150, 175, 50, 25)) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setGeometry(QtCore.QRect(25, 225, 200, 32)) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons( QDialogButtonBox.Ok | QDialogButtonBox.Cancel | QDialogButtonBox.Close | QDialogButtonBox.Help) self.buttonBox.setCenterButtons(False) self.buttonBox.helpRequested.connect(lambda: QMessageBox.about( self, __doc__, str(__doc__ + ', ' + ',\nversion ' + __version__ + '(' + __license__ + '),\nby ' + __author__ + ', ' + __email__))) self.buttonBox.accepted.connect(self.run) self.buttonBox.rejected.connect(self.close) palette = self.palette() palette.setBrush(QPalette.Base, Qt.transparent) self.setPalette(palette) self.setAttribute(Qt.WA_OpaquePaintEvent, False) def run(self): 'Run the actual conversion.' # Ask the User for the source .ui file as input filein = str(QFileDialog.getOpenFileName( self, __doc__, path.expanduser("~"), 'UI(*.ui)')).strip() # Parse Value of Slider1 as the Debug flag parameter if self.slider1.value() == 0: arg1 = '' else: arg1 = '--debug ' # Parse Value of Slider2 as the Execute flag parameter if self.slider2.value() == 0: arg2 = '' else: arg2 = '--execute ' # Parse Value of Slider3 as the relative imports flag parameter if self.slider3.value() == 0: arg3 = '' else: arg3 = '--from-imports ' # debug #print(arg1, arg2, arg3, str(self.combo1.currentText())) # run the subprocesses subprocess.Popen( 'nice --adjustment=19 pyuic4 ' + arg1 + arg2 + arg3 + '--indent=' + str(self.combo1.currentText()) + ' --output=' + str(filein).lower().replace('.ui', '.py') + ' ' + filein + ' && chmod -v +x ' + str(filein).lower().replace('.ui', '.py'), shell=True) def paintEvent(self, event): ' Paint semi-transparent background ' painter = QPainter(self) painter.fillRect(event.rect(), Qt.transparent) painter.setPen(Qt.NoPen) painter.setBrush(QColor(0, 0, 0)) painter.setOpacity(0.75) painter.drawRoundedRect(self.rect(), 75, 50) painter.end()
def setValue(self, val): QSlider.setValue(self, val * 100)
class LinearPoti(PluginBase): qtcb_position = pyqtSignal(int) def __init__(self, ipcon, uid): PluginBase.__init__(self, ipcon, uid) self.lp = bricklet_linear_poti.LinearPoti(self.uid) self.ipcon.add_device(self.lp) self.version = '.'.join(map(str, self.lp.get_version()[1])) self.qtcb_position.connect(self.cb_position) self.lp.register_callback(self.lp.CALLBACK_POSITION, self.qtcb_position.emit) self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, 100) self.position_label = PositionLabel('Position: ') self.current_value = 0 plot_list = [['', Qt.red, self.get_current_value]] self.plot_widget = PlotWidget('Position', plot_list) layout_h = QHBoxLayout() layout_h.addStretch() layout_h.addWidget(self.position_label) layout_h.addWidget(self.slider) layout_h.addStretch() layout = QVBoxLayout(self) layout.addLayout(layout_h) layout.addWidget(self.plot_widget) def start(self): try: self.cb_position(self.lp.get_position()) self.lp.set_position_callback_period(20) except ip_connection.Error: return self.plot_widget.stop = False def stop(self): try: self.lp.set_position_callback_period(0) except ip_connection.Error: pass self.plot_widget.stop = True @staticmethod def has_name(name): return 'Linear Poti Bricklet' in name def get_current_value(self): return self.current_value def cb_position(self, position): self.current_value = position self.slider.setValue(position) self.position_label.setText(str(position))
class EditGeometryProperties(PyDialog): force = True def __init__(self, data, win_parent=None): """ +------------------+ | Edit Actor Props | +------------------+------+ | Name1 | | Name2 | | Name3 | | Name4 | | | | Active_Name main | | Color box | | Line_Width 2 | | Point_Size 2 | | Bar_Scale 2 | | Opacity 0.5 | | Show/Hide | | | | Apply OK Cancel | +-------------------------+ """ PyDialog.__init__(self, data, win_parent) self.set_font_size(data['font_size']) del self.out_data['font_size'] self.setWindowTitle('Edit Geometry Properties') self.allow_update = True #default #self.win_parent = win_parent #self.out_data = data self.keys = sorted(data.keys()) self.keys = data.keys() keys = self.keys nrows = len(keys) self.active_key = 'main' #keys[0] items = keys header_labels = ['Groups'] table_model = Model(items, header_labels, self) view = CustomQTableView(self) #Call your custom QTableView here view.setModel(table_model) if qt_version == 4: view.horizontalHeader().setResizeMode(QtGui.QHeaderView.Stretch) self.table = view actor_obj = data[self.active_key] name = actor_obj.name line_width = actor_obj.line_width point_size = actor_obj.point_size bar_scale = actor_obj.bar_scale opacity = actor_obj.opacity color = actor_obj.color show = actor_obj.is_visible self.representation = actor_obj.representation # table header = self.table.horizontalHeader() header.setStretchLastSection(True) self._default_is_apply = False self.name = QLabel("Name:") self.name_edit = QLineEdit(str(name)) self.name_edit.setDisabled(True) self.color = QLabel("Color:") self.color_edit = QPushButton() #self.color_edit.setFlat(True) color = self.out_data[self.active_key].color qcolor = QtGui.QColor() qcolor.setRgb(*color) #print('color =%s' % str(color)) palette = QtGui.QPalette( self.color_edit.palette()) # make a copy of the palette #palette.setColor(QtGui.QPalette.Active, QtGui.QPalette.Base, \ #qcolor) palette.setColor(QtGui.QPalette.Background, QtGui.QColor('blue')) # ButtonText self.color_edit.setPalette(palette) self.color_edit.setStyleSheet("QPushButton {" "background-color: rgb(%s, %s, %s);" % tuple(color) + #"border:1px solid rgb(255, 170, 255); " "}") self.use_slider = True self.is_opacity_edit_active = False self.is_opacity_edit_slider_active = False self.is_line_width_edit_active = False self.is_line_width_edit_slider_active = False self.is_point_size_edit_active = False self.is_point_size_edit_slider_active = False self.is_bar_scale_edit_active = False self.is_bar_scale_edit_slider_active = False self.opacity = QLabel("Opacity:") self.opacity_edit = QDoubleSpinBox(self) self.opacity_edit.setRange(0.1, 1.0) self.opacity_edit.setDecimals(1) self.opacity_edit.setSingleStep(0.1) self.opacity_edit.setValue(opacity) if self.use_slider: self.opacity_slider_edit = QSlider(QtCore.Qt.Horizontal) self.opacity_slider_edit.setRange(1, 10) self.opacity_slider_edit.setValue(opacity * 10) self.opacity_slider_edit.setTickInterval(1) self.opacity_slider_edit.setTickPosition(QSlider.TicksBelow) self.line_width = QLabel("Line Width:") self.line_width_edit = QSpinBox(self) self.line_width_edit.setRange(1, 15) self.line_width_edit.setSingleStep(1) self.line_width_edit.setValue(line_width) if self.use_slider: self.line_width_slider_edit = QSlider(QtCore.Qt.Horizontal) self.line_width_slider_edit.setRange(1, 15) self.line_width_slider_edit.setValue(line_width) self.line_width_slider_edit.setTickInterval(1) self.line_width_slider_edit.setTickPosition(QSlider.TicksBelow) if self.representation in ['point', 'surface']: self.line_width.setEnabled(False) self.line_width_edit.setEnabled(False) self.line_width_slider_edit.setEnabled(False) self.point_size = QLabel("Point Size:") self.point_size_edit = QSpinBox(self) self.point_size_edit.setRange(1, 15) self.point_size_edit.setSingleStep(1) self.point_size_edit.setValue(point_size) self.point_size.setVisible(False) self.point_size_edit.setVisible(False) if self.use_slider: self.point_size_slider_edit = QSlider(QtCore.Qt.Horizontal) self.point_size_slider_edit.setRange(1, 15) self.point_size_slider_edit.setValue(point_size) self.point_size_slider_edit.setTickInterval(1) self.point_size_slider_edit.setTickPosition(QSlider.TicksBelow) self.point_size_slider_edit.setVisible(False) if self.representation in ['wire', 'surface']: self.point_size.setEnabled(False) self.point_size_edit.setEnabled(False) if self.use_slider: self.point_size_slider_edit.setEnabled(False) self.bar_scale = QLabel("Bar Scale:") self.bar_scale_edit = QDoubleSpinBox(self) #self.bar_scale_edit.setRange(0.01, 1.0) # was 0.1 #self.bar_scale_edit.setRange(0.05, 5.0) self.bar_scale_edit.setDecimals(1) #self.bar_scale_edit.setSingleStep(bar_scale / 10.) self.bar_scale_edit.setSingleStep(0.1) self.bar_scale_edit.setValue(bar_scale) #if self.use_slider: #self.bar_scale_slider_edit = QSlider(QtCore.Qt.Horizontal) #self.bar_scale_slider_edit.setRange(1, 100) # 1/0.05 = 100/5.0 #self.bar_scale_slider_edit.setValue(opacity * 0.05) #self.bar_scale_slider_edit.setTickInterval(10) #self.bar_scale_slider_edit.setTickPosition(QSlider.TicksBelow) if self.representation != 'bar': self.bar_scale.setEnabled(False) self.bar_scale_edit.setEnabled(False) self.bar_scale.setVisible(False) self.bar_scale_edit.setVisible(False) #self.bar_scale_slider_edit.setVisible(False) #self.bar_scale_slider_edit.setEnabled(False) # show/hide self.checkbox_show = QCheckBox("Show") self.checkbox_hide = QCheckBox("Hide") self.checkbox_show.setChecked(show) self.checkbox_hide.setChecked(not show) if name == 'main': self.color.setEnabled(False) self.color_edit.setEnabled(False) self.point_size.setEnabled(False) self.point_size_edit.setEnabled(False) if self.use_slider: self.point_size_slider_edit.setEnabled(False) self.cancel_button = QPushButton("Close") self.create_layout() self.set_connections() def on_update_geometry_properties_window(self, data): """Not Implemented""" return #new_keys = sorted(data.keys()) #if self.active_key in new_keys: #i = new_keys.index(self.active_key) #else: #i = 0 #self.table.update_data(new_keys) #self.out_data = data #self.update_active_key(i) def update_active_key(self, index): """ Parameters ---------- index : PyQt4.QtCore.QModelIndex the index of the list Internal Parameters ------------------- name : str the name of obj obj : CoordProperties, AltGeometry the storage object for things like line_width, point_size, etc. """ if qt_version == 4: name = str(index.data().toString()) else: name = str(index.data()) print('name = %r' % name) #i = self.keys.index(self.active_key) self.active_key = name self.name_edit.setText(name) obj = self.out_data[name] if isinstance(obj, CoordProperties): opacity = 1.0 representation = 'coord' is_visible = obj.is_visible elif isinstance(obj, AltGeometry): line_width = obj.line_width point_size = obj.point_size bar_scale = obj.bar_scale opacity = obj.opacity representation = obj.representation is_visible = obj.is_visible self.color_edit.setStyleSheet( "QPushButton {" "background-color: rgb(%s, %s, %s);" % tuple(obj.color) + #"border:1px solid rgb(255, 170, 255); " "}") self.allow_update = False self.force = False self.line_width_edit.setValue(line_width) self.point_size_edit.setValue(point_size) self.bar_scale_edit.setValue(bar_scale) self.force = True self.allow_update = True else: raise NotImplementedError(obj) allowed_representations = [ 'main', 'surface', 'coord', 'toggle', 'wire', 'point', 'bar' ] if self.representation != representation: self.representation = representation if representation not in allowed_representations: msg = 'name=%r; representation=%r is invalid\nrepresentations=%r' % ( name, representation, allowed_representations) if self.representation == 'coord': self.color.setVisible(False) self.color_edit.setVisible(False) self.line_width.setVisible(False) self.line_width_edit.setVisible(False) self.point_size.setVisible(False) self.point_size_edit.setVisible(False) self.bar_scale.setVisible(False) self.bar_scale_edit.setVisible(False) self.opacity.setVisible(False) self.opacity_edit.setVisible(False) if self.use_slider: self.opacity_slider_edit.setVisible(False) self.point_size_slider_edit.setVisible(False) self.line_width_slider_edit.setVisible(False) #self.bar_scale_slider_edit.setVisible(False) else: self.color.setVisible(True) self.color_edit.setVisible(True) self.line_width.setVisible(True) self.line_width_edit.setVisible(True) self.point_size.setVisible(True) self.point_size_edit.setVisible(True) self.bar_scale.setVisible(True) #self.bar_scale_edit.setVisible(True) self.opacity.setVisible(True) self.opacity_edit.setVisible(True) if self.use_slider: self.opacity_slider_edit.setVisible(True) self.line_width_slider_edit.setVisible(True) self.point_size_slider_edit.setVisible(True) #self.bar_scale_slider_edit.setVisible(True) if name == 'main': self.color.setEnabled(False) self.color_edit.setEnabled(False) self.point_size.setEnabled(False) self.point_size_edit.setEnabled(False) self.line_width.setEnabled(True) self.line_width_edit.setEnabled(True) self.bar_scale.setEnabled(False) self.bar_scale_edit.setEnabled(False) show_points = False show_line_width = True show_bar_scale = False if self.use_slider: self.line_width_slider_edit.setEnabled(True) #self.bar_scale_slider_edit.setVisible(False) else: self.color.setEnabled(True) self.color_edit.setEnabled(True) show_points = False if self.representation in ['point', 'wire+point']: show_points = True show_line_width = False if self.representation in ['wire', 'wire+point', 'bar']: show_line_width = True if representation == 'bar': show_bar_scale = True else: show_bar_scale = False #self.bar_scale_button.setVisible(show_bar_scale) #self.bar_scale_edit.setSingleStep(bar_scale / 10.) #if self.use_slider: #self.bar_scale_slider_edit.setEnabled(False) self.point_size.setEnabled(show_points) self.point_size_edit.setEnabled(show_points) self.point_size.setVisible(show_points) self.point_size_edit.setVisible(show_points) self.line_width.setEnabled(show_line_width) self.line_width_edit.setEnabled(show_line_width) self.bar_scale.setEnabled(show_bar_scale) self.bar_scale_edit.setEnabled(show_bar_scale) self.bar_scale.setVisible(show_bar_scale) self.bar_scale_edit.setVisible(show_bar_scale) if self.use_slider: self.point_size_slider_edit.setEnabled(show_points) self.point_size_slider_edit.setVisible(show_points) self.line_width_slider_edit.setEnabled(show_line_width) #if self.representation in ['wire', 'surface']: self.opacity_edit.setValue(opacity) #if self.use_slider: #self.opacity_slider_edit.setValue(opacity*10) self.checkbox_show.setChecked(is_visible) self.checkbox_hide.setChecked(not is_visible) passed = self.on_validate() #self.on_apply(force=True) # TODO: was turned on...do I want this??? #self.allow_update = True #def on_name_select(self): #print('on_name_select') #return def create_layout(self): ok_cancel_box = QHBoxLayout() ok_cancel_box.addWidget(self.cancel_button) grid = QGridLayout() irow = 0 grid.addWidget(self.name, irow, 0) grid.addWidget(self.name_edit, irow, 1) irow += 1 grid.addWidget(self.color, irow, 0) grid.addWidget(self.color_edit, irow, 1) irow += 1 grid.addWidget(self.opacity, irow, 0) if self.use_slider: grid.addWidget(self.opacity_edit, irow, 2) grid.addWidget(self.opacity_slider_edit, irow, 1) else: grid.addWidget(self.opacity_edit, irow, 1) irow += 1 grid.addWidget(self.line_width, irow, 0) if self.use_slider: grid.addWidget(self.line_width_edit, irow, 2) grid.addWidget(self.line_width_slider_edit, irow, 1) else: grid.addWidget(self.line_width_edit, irow, 1) irow += 1 grid.addWidget(self.point_size, irow, 0) if self.use_slider: grid.addWidget(self.point_size_edit, irow, 2) grid.addWidget(self.point_size_slider_edit, irow, 1) else: grid.addWidget(self.point_size_edit, irow, 1) irow += 1 grid.addWidget(self.bar_scale, irow, 0) if self.use_slider and 0: grid.addWidget(self.bar_scale_edit, irow, 2) grid.addWidget(self.bar_scale_slider_edit, irow, 1) else: grid.addWidget(self.bar_scale_edit, irow, 1) irow += 1 checkboxs = QButtonGroup(self) checkboxs.addButton(self.checkbox_show) checkboxs.addButton(self.checkbox_hide) vbox = QVBoxLayout() vbox.addWidget(self.table) vbox.addLayout(grid) if 0: vbox.addWidget(self.checkbox_show) vbox.addWidget(self.checkbox_hide) else: vbox1 = QVBoxLayout() vbox1.addWidget(self.checkbox_show) vbox1.addWidget(self.checkbox_hide) vbox.addLayout(vbox1) vbox.addStretch() #vbox.addWidget(self.check_apply) vbox.addLayout(ok_cancel_box) self.setLayout(vbox) def set_connections(self): self.opacity_edit.valueChanged.connect(self.on_opacity) self.line_width_edit.valueChanged.connect(self.on_line_width) self.point_size_edit.valueChanged.connect(self.on_point_size) self.bar_scale_edit.valueChanged.connect(self.on_bar_scale) if self.use_slider: self.opacity_slider_edit.valueChanged.connect( self.on_opacity_slider) self.line_width_slider_edit.valueChanged.connect( self.on_line_width_slider) self.point_size_slider_edit.valueChanged.connect( self.on_point_size_slider) #self.bar_scale_slider_edit.valueChanged.connect(self.on_bar_scale_slider) # self.connect(self.opacity_edit, QtCore.SIGNAL('clicked()'), self.on_opacity) # self.connect(self.line_width, QtCore.SIGNAL('clicked()'), self.on_line_width) # self.connect(self.point_size, QtCore.SIGNAL('clicked()'), self.on_point_size) if qt_version == 4: self.connect(self, QtCore.SIGNAL('triggered()'), self.closeEvent) self.color_edit.clicked.connect(self.on_color) self.checkbox_show.clicked.connect(self.on_show) self.checkbox_hide.clicked.connect(self.on_hide) self.cancel_button.clicked.connect(self.on_cancel) # closeEvent def keyPressEvent(self, event): if event.key() == QtCore.Qt.Key_Escape: self.close() def closeEvent(self, event): self.on_cancel() def on_color(self): """called when the user clicks on the color box""" name = self.active_key obj = self.out_data[name] rgb_color_ints = obj.color msg = name col = QColorDialog.getColor(QtGui.QColor(*rgb_color_ints), self, "Choose a %s color" % msg) if col.isValid(): color_float = col.getRgbF()[:3] obj.color = color_float color_int = [int(colori * 255) for colori in color_float] self.color_edit.setStyleSheet( "QPushButton {" "background-color: rgb(%s, %s, %s);" % tuple(color_int) + #"border:1px solid rgb(255, 170, 255); " "}") self.on_apply(force=self.force) #print(self.allow_update) def on_show(self): """shows the actor""" name = self.active_key is_checked = self.checkbox_show.isChecked() self.out_data[name].is_visible = is_checked self.on_apply(force=self.force) def on_hide(self): """hides the actor""" name = self.active_key is_checked = self.checkbox_hide.isChecked() self.out_data[name].is_visible = not is_checked self.on_apply(force=self.force) def on_line_width(self): """increases/decreases the wireframe (for solid bodies) or the bar thickness""" self.is_line_width_edit_active = True name = self.active_key line_width = self.line_width_edit.value() self.out_data[name].line_width = line_width if not self.is_line_width_edit_slider_active: if self.use_slider: self.line_width_slider_edit.setValue(line_width) self.is_line_width_edit_active = False self.on_apply(force=self.force) self.is_line_width_edit_active = False def on_line_width_slider(self): """increases/decreases the wireframe (for solid bodies) or the bar thickness""" self.is_line_width_edit_slider_active = True #name = self.active_key line_width = self.line_width_slider_edit.value() if not self.is_line_width_edit_active: self.line_width_edit.setValue(line_width) self.is_line_width_edit_slider_active = False def on_point_size(self): """increases/decreases the point size""" self.is_point_size_edit_active = True name = self.active_key point_size = self.point_size_edit.value() self.out_data[name].point_size = point_size if not self.is_point_size_edit_slider_active: if self.use_slider: self.point_size_slider_edit.setValue(point_size) self.is_point_size_edit_active = False self.on_apply(force=self.force) self.is_point_size_edit_active = False def on_point_size_slider(self): """increases/decreases the point size""" self.is_point_size_edit_slider_active = True name = self.active_key point_size = self.point_size_slider_edit.value() if not self.is_point_size_edit_active: self.point_size_edit.setValue(point_size) self.is_point_size_edit_slider_active = False def on_bar_scale(self): """ Vectors start at some xyz coordinate and can increase in length. Increases/decreases the length scale factor. """ self.is_bar_scale_edit_active = True name = self.active_key float_bar_scale = self.bar_scale_edit.value() self.out_data[name].bar_scale = float_bar_scale if not self.is_bar_scale_edit_slider_active: int_bar_scale = int(round(float_bar_scale * 20, 0)) #if self.use_slider: #self.bar_scale_slider_edit.setValue(int_bar_scale) self.is_bar_scale_edit_active = False self.on_apply(force=self.force) self.is_bar_scale_edit_active = False def on_bar_scale_slider(self): """ Vectors start at some xyz coordinate and can increase in length. Increases/decreases the length scale factor. """ self.is_bar_scale_edit_slider_active = True name = self.active_key int_bar_scale = self.bar_scale_slider_edit.value() if not self.is_bar_scale_edit_active: float_bar_scale = int_bar_scale / 20. self.bar_scale_edit.setValue(float_bar_scale) self.is_bar_scale_edit_slider_active = False def on_opacity(self): """ opacity = 1.0 (solid/opaque) opacity = 0.0 (invisible) """ self.is_opacity_edit_active = True name = self.active_key float_opacity = self.opacity_edit.value() self.out_data[name].opacity = float_opacity if not self.is_opacity_edit_slider_active: int_opacity = int(round(float_opacity * 10, 0)) if self.use_slider: self.opacity_slider_edit.setValue(int_opacity) self.is_opacity_edit_active = False self.on_apply(force=self.force) self.is_opacity_edit_active = False def on_opacity_slider(self): """ opacity = 1.0 (solid/opaque) opacity = 0.0 (invisible) """ self.is_opacity_edit_slider_active = True name = self.active_key int_opacity = self.opacity_slider_edit.value() if not self.is_opacity_edit_active: float_opacity = int_opacity / 10. self.opacity_edit.setValue(float_opacity) self.is_opacity_edit_slider_active = False #def on_axis(self, text): ##print(self.combo_axis.itemText()) #self._axis = str(text) #self.plane.setText('Point on %s? Plane:' % self._axis) #self.point_a.setText('Point on %s Axis:' % self._axis) #self.point_b.setText('Point on %s%s Plane:' % (self._axis, self._plane)) #def on_plane(self, text): #self._plane = str(text) #self.point_b.setText('Point on %s%s Plane:' % (self._axis, self._plane)) #def _on_float(self, field): #try: #eval_float_from_string(field.text()) #field.setStyleSheet("QLineEdit{background: white;}") #except ValueError: #field.setStyleSheet("QLineEdit{background: red;}") #def on_default_name(self): #self.name_edit.setText(str(self._default_name)) #self.name_edit.setStyleSheet("QLineEdit{background: white;}") #def check_float(self, cell): #text = cell.text() #try: #value = eval_float_from_string(text) #cell.setStyleSheet("QLineEdit{background: white;}") #return value, True #except ValueError: #cell.setStyleSheet("QLineEdit{background: red;}") #return None, False #def check_name(self, cell): #text = str(cell.text()).strip() #if len(text): #cell.setStyleSheet("QLineEdit{background: white;}") #return text, True #else: #cell.setStyleSheet("QLineEdit{background: red;}") #return None, False def on_validate(self): self.out_data['clicked_ok'] = True self.out_data['clicked_cancel'] = False old_obj = self.out_data[self.active_key] old_obj.line_width = self.line_width_edit.value() old_obj.point_size = self.point_size_edit.value() old_obj.bar_scale = self.bar_scale_edit.value() old_obj.opacity = self.opacity_edit.value() #old_obj.color = self.color_edit old_obj.is_visible = self.checkbox_show.isChecked() return True #name_value, flag0 = self.check_name(self.name_edit) #ox_value, flag1 = self.check_float(self.transparency_edit) #if flag0 and flag1: #self.out_data['clicked_ok'] = True #return True #return False def on_apply(self, force=False): passed = self.on_validate() #print("passed=%s force=%s allow=%s" % (passed, force, self.allow_update)) if (passed or force) and self.allow_update and hasattr( self.win_parent, 'on_update_geometry_properties'): #print('obj = %s' % self.out_data[self.active_key]) self.win_parent.on_update_geometry_properties(self.out_data, name=self.active_key) return passed def on_cancel(self): passed = self.on_apply(force=True) if passed: self.close()
class MyMainWindow(QMainWindow): ' Main Window ' def __init__(self, parent=None): ' Initialize QWidget inside MyMainWindow ' super(MyMainWindow, self).__init__(parent) self.statusBar().showMessage(__doc__.title()) self.setWindowTitle(__doc__) self.setMinimumSize(600, 800) self.setMaximumSize(2048, 1024) self.resize(1024, 800) self.setWindowIcon(QIcon.fromTheme("face-monkey")) if not A11Y: self.setStyleSheet('''QWidget{color:#fff;font-family:Oxygen} QWidget:item:hover, QWidget:item:selected { background-color: cyan; color: #000 } QWidget:disabled { color: #404040; background-color: #323232 } QWidget:focus { border: 1px solid cyan } QPushButton { background-color: gray; padding: 3px; border: 1px solid gray; border-radius: 9px; margin: 0;font-size: 12px; padding-left: 5px; padding-right: 5px } QLineEdit, QTextEdit { background-color: #4a4a4a; border: 1px solid gray; border-radius: 0; font-size: 12px; } QPushButton:pressed { background-color: #323232 } QComboBox { background-color: #4a4a4a; padding-left: 9px; border: 1px solid gray; border-radius: 5px; } QComboBox:pressed { background-color: gray } QComboBox QAbstractItemView, QMenu { border: 1px solid #4a4a4a; background:grey; selection-background-color: cyan; selection-color: #000; } QSlider { padding: 3px; font-size: 8px; padding-left: 2px; padding-right: 2px; border: 5px solid #1e1e1e } QSlider::sub-page:vertical { background-color: QLinearGradient(spread:pad, x1:0, y1:0, x2:1, y2:0.27, stop:0 rgba(255, 0, 0, 255), stop:1 rgba(50, 0, 0, 200)); border: 4px solid #1e1e1e; border-radius: 5px } QSlider::add-page:vertical { background-color: QLinearGradient(spread:pad, x1:0, y1:0, x2:1, y2:0.27, stop:0 rgba(0, 255, 0, 255), stop:1 rgba(0, 99, 0, 255)); border: 4px solid #1e1e1e; border-radius: 5px; } QSlider::handle:vertical { background-color: QLinearGradient(spread:pad, x1:0, y1:0, x2:1, y2:0.273, stop:0 rgba(0, 0, 0, 255), stop:1 gray); height: 5px; border: 1px dotted #fff; text-align: center; border-top-left-radius: 2px; border-bottom-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius 2px; margin-left: 2px; margin-right: 2px; } QSlider::handle:vertical:hover { border: 1px solid cyan } QSlider::sub-page:vertical:disabled { background: #bbb; border-color: #999; } QSlider::add-page:vertical:disabled { background: #eee; border-color: #999; } QSlider::handle:vertical:disabled { background: #eee; border: 1px solid #aaa; border-radius: 4px; } QToolBar, QStatusBar, QDockWidget::title{background-color:#323232;} QToolBar::handle, QToolBar::handle:vertical, QToolBar::handle:horizontal { border: 1px solid gray; border-radius: 9px; width: 19px; height: 19px; margin: 0.5px } QGroupBox { border: 1px solid gray; border-radius: 9px; padding-top: 9px; } QStatusBar, QToolBar::separator:horizontal, QToolBar::separator:vertical {color:gray} QScrollBar:vertical{ background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #212121,stop: 1.0 #323232); width: 10px; } QScrollBar:horizontal{ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #212121,stop: 1.0 #323232); height: 10px; } QScrollBar::handle:vertical{ padding: 2px; min-height: 50px; background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #585858,stop: 1.0 #404040); border-radius: 5px; border: 1px solid #191919; } QScrollBar::handle:horizontal{ padding: 2px; min-width: 50px; background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #585858,stop: 1.0 #404040); border-radius: 5px; border: 1px solid #191919; } QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical, QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal, QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal { background: none; border: none; } QDockWidget::close-button, QDockWidget::float-button { border: 1px solid gray; border-radius: 3px; background: darkgray; }''') self.process = QProcess() self.process.readyReadStandardOutput.connect(self.read_output) self.process.readyReadStandardError.connect(self.read_errors) self.process.finished.connect(self._process_finished) self.process.error.connect(self._process_finished) self.group0, self.group1 = QGroupBox("Options"), QGroupBox("Paths") self.group2 = QGroupBox("Nodes") self.group3 = QGroupBox("Python Code") self.group4, self.group5 = QGroupBox("Logs"), QGroupBox("Backend") g0grid, g1vlay = QGridLayout(self.group0), QVBoxLayout(self.group1) g5vlay = QVBoxLayout(self.group5) self.treeview_nodes, self.textedit_source = QTextEdit(), QTextEdit() self.dock1, self.dock2 = QDockWidget(), QDockWidget() self.output, self.dock3 = QTextEdit(), QDockWidget() self.treeview_nodes.setAutoFormatting(QTextEdit.AutoAll) self.treeview_nodes.setWordWrapMode(QTextOption.NoWrap) self.dock1.setWidget(self.treeview_nodes) self.dock2.setWidget(self.textedit_source) self.dock3.setWidget(self.output) self.dock1.setWindowTitle("Tree") self.dock2.setWindowTitle("Sources") self.dock3.setWindowTitle("STDOutput") featur = QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetFloatable self.dock1.setFeatures(featur) self.dock2.setFeatures(featur) self.dock3.setFeatures(featur) QVBoxLayout(self.group2).addWidget(self.dock1) QVBoxLayout(self.group3).addWidget(self.dock2) QVBoxLayout(self.group4).addWidget(self.dock3) self.slider1, self.slider2 = QSlider(), QSlider() g0grid.addWidget(self.slider1, 0, 0) g0grid.addWidget(QLabel('Use Debug'), 0, 1) self.slider2.setValue(1) g0grid.addWidget(self.slider2, 1, 0) g0grid.addWidget(QLabel('Use verbose'), 1, 1) self.slider3, self.slider4 = QSlider(), QSlider() self.slider3.setValue(1) g0grid.addWidget(self.slider3, 2, 0) g0grid.addWidget(QLabel('Show compiling progress'), 2, 1) self.slider4.setValue(1) g0grid.addWidget(self.slider4, 3, 0) g0grid.addWidget(QLabel('Show Scons building debug'), 3, 1) self.slider5, self.slider6 = QSlider(), QSlider() g0grid.addWidget(self.slider5, 4, 0) g0grid.addWidget(QLabel('Keep debug unstriped binary'), 4, 1) g0grid.addWidget(self.slider6, 5, 0) g0grid.addWidget(QLabel('Traced execution outputs'), 5, 1) self.slider7, self.slider8 = QSlider(), QSlider() self.slider7.setValue(1) g0grid.addWidget(self.slider7, 6, 0) g0grid.addWidget(QLabel('Remove the build folder'), 6, 1) g0grid.addWidget(self.slider8, 7, 0) g0grid.addWidget(QLabel('No Python Optimizations'), 7, 1) self.slider9, self.slider10 = QSlider(), QSlider() g0grid.addWidget(self.slider9, 8, 0) g0grid.addWidget(QLabel('No Statements line numbers'), 8, 1) g0grid.addWidget(self.slider10, 9, 0) g0grid.addWidget(QLabel('Execute the output binary'), 9, 1) self.slider11, self.slider12 = QSlider(), QSlider() g0grid.addWidget(self.slider11, 10, 0) g0grid.addWidget(QLabel('Warning detected implicit exceptions'), 10, 1) g0grid.addWidget(self.slider12, 11, 0) g0grid.addWidget(QLabel('Keep the PYTHONPATH, do not Reset it'), 11, 1) self.slider13 = QSlider() g0grid.addWidget(self.slider13, 12, 0) g0grid.addWidget(QLabel('Enhance compile, CPython incompatible'), 12, 1) self.slider1a, self.slider2a = QSlider(), QSlider() g0grid.addWidget(self.slider1a, 0, 2) g0grid.addWidget(QLabel('Descendent Recursive Compile'), 0, 3) self.slider2a.setValue(1) g0grid.addWidget(self.slider2a, 1, 2) g0grid.addWidget(QLabel('Force non recursive compile'), 1, 3) self.slider3a, self.slider4a = QSlider(), QSlider() g0grid.addWidget(self.slider3a, 2, 2) g0grid.addWidget(QLabel('STD Lib Recursive Compile'), 2, 3) g0grid.addWidget(self.slider4a, 3, 2) g0grid.addWidget(QLabel('Enforce the use of Clang'), 3, 3) self.slider5a, self.slider6a = QSlider(), QSlider() self.slider5a.setValue(1) g0grid.addWidget(self.slider5a, 4, 2) g0grid.addWidget(QLabel('Use G++ link time optimizations'), 4, 3) g0grid.addWidget(self.slider6a, 5, 2) g0grid.addWidget(QLabel('Disable the console window'), 5, 3) self.slider7a, self.slider8a = QSlider(), QSlider() g0grid.addWidget(self.slider7a, 6, 2) g0grid.addWidget(QLabel('Force compile for MS Windows'), 6, 3) g0grid.addWidget(self.slider8a, 7, 2) g0grid.addWidget(QLabel('Use Python Debug versions'), 7, 3) self.slider9a, self.slider10a = QSlider(), QSlider() self.slider9a.setValue(1) g0grid.addWidget(self.slider9a, 8, 2) g0grid.addWidget(QLabel('Create standalone executable'), 8, 3) g0grid.addWidget(self.slider10a, 9, 2) g0grid.addWidget(QLabel('Enable Standalone mode build'), 9, 3) self.slider11a, self.slider12a = QSlider(), QSlider() g0grid.addWidget(self.slider11a, 10, 2) g0grid.addWidget(QLabel('Make module executable instead of app'), 10, 3) g0grid.addWidget(self.slider12a, 11, 2) g0grid.addWidget(QLabel('No froze module of stdlib as bytecode'), 11, 3) self.slider13a = QSlider() g0grid.addWidget(self.slider13a, 12, 2) g0grid.addWidget(QLabel('Force use of MinGW on MS Windows'), 12, 3) for each_widget in (self.slider1, self.slider2, self.slider3, self.slider4, self.slider5, self.slider6, self.slider7, self.slider8, self.slider9, self.slider10, self.slider11, self.slider12, self.slider13, self.slider1a, self.slider2a, self.slider3a, self.slider4a, self.slider5a, self.slider6a, self.slider7a, self.slider8a, self.slider9a, self.slider10a, self.slider11a, self.slider12a, self.slider13a): each_widget.setRange(0, 1) each_widget.setCursor(QCursor(Qt.OpenHandCursor)) each_widget.setTickInterval(1) each_widget.TickPosition(QSlider.TicksBothSides) self.combo1 = QComboBox() self.combo1.addItems(('2.7', '2.6', '3.2', '3.3')) g5vlay.addWidget(QLabel('Python Version')) g5vlay.addWidget(self.combo1) self.combo2 = QComboBox() self.combo2.addItems(('Default', 'Low', 'High')) g5vlay.addWidget(QLabel('CPU priority')) g5vlay.addWidget(self.combo2) self.combo3 = QComboBox() self.combo3.addItems(('1', '2', '3', '4', '5', '6', '7', '8', '9')) g5vlay.addWidget(QLabel('MultiProcessing Workers')) g5vlay.addWidget(self.combo3) self.outdir = QLineEdit() self.outdir.setStyleSheet("QLineEdit{margin-left:25px}") self.clearButton = QToolButton(self.outdir) self.clearButton.setIcon(QIcon.fromTheme("edit-clear")) self.clearButton.setIconSize(QSize(25, 25)) self.clearButton.setStyleSheet("QToolButton{border:none}") self.clearButton.hide() self.clearButton.clicked.connect(self.outdir.clear) self.outdir.textChanged.connect( lambda: self.clearButton.setVisible(True)) self.clearButton.clicked.connect( lambda: self.clearButton.setVisible(False)) self.outdir.setPlaceholderText('Output Directory') if path.isfile('.nuitka-output-dir.txt'): self.outdir.setText(open('.nuitka-output-dir.txt', 'r').read()) else: self.outdir.setText(path.expanduser("~")) self.completer, self.dirs = QCompleter(self), QDirModel(self) self.dirs.setFilter(QDir.Dirs | QDir.NoDotAndDotDot) self.completer.setModel(self.dirs) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.setCompletionMode(QCompleter.PopupCompletion) self.completer.popup().setStyleSheet( """border:1px solid #4a4a4a;background:grey; selection-background-color:cyan;selection-color:#000""") self.completer.popup().setVerticalScrollBarPolicy( Qt.ScrollBarAlwaysOff) self.outdir.setCompleter(self.completer) self.btn1 = QPushButton(QIcon.fromTheme("document-open"), 'Open' if IS_WIN else '') self.btn1.clicked.connect( lambda: open('.nuitka-output-dir.txt', 'w').write( str( QFileDialog.getExistingDirectory( None, 'Open Output Directory', path.expanduser("~"))))) self.btn1.released.connect(lambda: self.outdir.setText( open('.nuitka-output-dir.txt', 'r').read())) g1vlay.addWidget(QLabel('Output Directory')) g1vlay.addWidget(self.outdir) g1vlay.addWidget(self.btn1) self.target = QLineEdit() self.target.setStyleSheet("QLineEdit{margin-left:25px}") self.clearButton2 = QToolButton(self.target) self.clearButton2.setIcon(QIcon.fromTheme("edit-clear")) self.clearButton2.setIconSize(QSize(25, 25)) self.clearButton2.setStyleSheet("QToolButton{border:none}") self.clearButton2.hide() self.clearButton2.clicked.connect(self.target.clear) self.target.textChanged.connect( lambda: self.clearButton2.setVisible(True)) self.clearButton2.clicked.connect( lambda: self.clearButton2.setVisible(False)) self.target.setPlaceholderText('Target Python App to Binary Compile') self.target.setCompleter(self.completer) self.btn2 = QPushButton(QIcon.fromTheme("document-open"), 'Open' if IS_WIN else '') self.btn2.clicked.connect(lambda: self.target.setText( str( QFileDialog.getOpenFileName( None, "Open", path.expanduser("~"), ';;'.join([ '{}(*.{})'.format(e.upper(), e) for e in ('py', 'pyw', '*') ]))))) g1vlay.addWidget(QLabel('Input File')) g1vlay.addWidget(self.target) g1vlay.addWidget(self.btn2) self.icon, self.icon_label = QLineEdit(), QLabel('Icon File') self.icon.setStyleSheet("QLineEdit{margin-left:25px}") self.clearButton3 = QToolButton(self.icon) self.clearButton3.setIcon(QIcon.fromTheme("edit-clear")) self.clearButton3.setIconSize(QSize(25, 25)) self.clearButton3.setStyleSheet("QToolButton{border:none}") self.clearButton3.hide() self.clearButton3.clicked.connect(self.icon.clear) self.icon.textChanged.connect( lambda: self.clearButton3.setVisible(True)) self.clearButton3.clicked.connect( lambda: self.clearButton3.setVisible(False)) self.icon.setPlaceholderText('Path to Icon file for your App') self.icon.setCompleter(self.completer) self.btn3 = QPushButton(QIcon.fromTheme("document-open"), 'Open' if IS_WIN else '') self.btn3.clicked.connect(lambda: self.icon.setText( str( QFileDialog.getOpenFileName( None, "Open", path.expanduser("~"), ';;'.join([ '{}(*.{})'.format(e.upper(), e) for e in ('ico', 'png', 'bmp', 'svg', '*') ]))))) g1vlay.addWidget(self.icon_label) g1vlay.addWidget(self.icon) g1vlay.addWidget(self.btn3) # Menu Bar inicialization and detail definitions menu_salir = QAction(QIcon.fromTheme("application-exit"), 'Quit', self) menu_salir.setStatusTip('Quit') menu_salir.triggered.connect(exit) menu_minimize = QAction(QIcon.fromTheme("go-down"), 'Minimize', self) menu_minimize.setStatusTip('Minimize') menu_minimize.triggered.connect(lambda: self.showMinimized()) menu_qt = QAction(QIcon.fromTheme("help-about"), 'About Qt', self) menu_qt.setStatusTip('About Qt...') menu_qt.triggered.connect(lambda: QMessageBox.aboutQt(self)) menu_dev = QAction(QIcon.fromTheme("applications-development"), 'Developer Manual PDF', self) menu_dev.setStatusTip('Open Nuitka Developer Manual PDF...') menu_dev.triggered.connect(lambda: call( OPEN + '/usr/share/doc/nuitka/Developer_Manual.pdf.gz', shell=True) ) menu_usr = QAction(QIcon.fromTheme("help-contents"), 'User Docs', self) menu_usr.setStatusTip('Open Nuitka End User Manual PDF...') menu_usr.triggered.connect(lambda: call( OPEN + '/usr/share/doc/nuitka/README.pdf.gz', shell=True)) menu_odoc = QAction(QIcon.fromTheme("help-browser"), 'OnLine Doc', self) menu_odoc.setStatusTip('Open Nuitka on line Documentation pages...') menu_odoc.triggered.connect( lambda: open_new_tab('http://nuitka.net/doc/user-manual.html')) menu_man = QAction(QIcon.fromTheme("utilities-terminal"), 'Man', self) menu_man.setStatusTip('Open Nuitka technical command line Man Pages..') menu_man.triggered.connect( lambda: call('xterm -e "man nuitka"', shell=True)) menu_tra = QAction(QIcon.fromTheme("applications-development"), 'View Nuitka-GUI Source Code', self) menu_tra.setStatusTip('View, study, edit Nuitka-GUI Libre Source Code') menu_tra.triggered.connect(lambda: call(OPEN + __file__, shell=True)) menu_foo = QAction(QIcon.fromTheme("folder"), 'Open Output Dir', self) menu_foo.setStatusTip('Open the actual Output Directory location...') menu_foo.triggered.connect( lambda: call(OPEN + str(self.outdir.text()), shell=True)) menu_pic = QAction(QIcon.fromTheme("camera-photo"), 'Screenshot', self) menu_pic.setStatusTip('Take a Screenshot for Documentation purposes..') menu_pic.triggered.connect( lambda: QPixmap.grabWindow(QApplication.desktop().winId()).save( QFileDialog.getSaveFileName(None, "Save", path.expanduser("~"), 'PNG(*.png)', 'png'))) menu_don = QAction(QIcon.fromTheme("emblem-favorite"), 'Help Nuitka', self) menu_don.setStatusTip('Help the Nuitka Open Source Libre Free Project') menu_don.triggered.connect( lambda: open_new_tab('http://nuitka.net/pages/donations.html')) # movable draggable toolbar self.toolbar = QToolBar(self) self.toolbar.setIconSize(QSize(16, 16)) self.toolbar.toggleViewAction().setText("Show/Hide Toolbar") l_spacer, r_spacer = QWidget(self), QWidget(self) l_spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) r_spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.toolbar.addWidget(l_spacer) self.toolbar.addSeparator() self.toolbar.addActions((menu_salir, menu_minimize, menu_qt, menu_odoc, menu_foo, menu_pic, menu_don)) if not IS_WIN: self.toolbar.addActions((menu_man, menu_dev, menu_tra, menu_usr)) self.toolbar.addSeparator() self.toolbar.addWidget(r_spacer) self.addToolBar(Qt.BottomToolBarArea, self.toolbar) # Bottom Buttons Bar self.buttonBox = QDialogButtonBox(self) self.buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Close) self.buttonBox.rejected.connect(exit) self.buttonBox.accepted.connect(self.run) self.guimode = QComboBox() self.guimode.addItems(('Full UX / UI', 'Simple UX / UI')) self.guimode.setStyleSheet( """QComboBox{background:transparent;border:0; margin-left:25px;color:gray;text-decoration:underline}""") self.guimode.currentIndexChanged.connect(self.set_guimode) container = QWidget() container_layout = QGridLayout(container) # Y, X container_layout.addWidget(self.guimode, 0, 1) container_layout.addWidget(self.group2, 1, 0) container_layout.addWidget(self.group3, 2, 0) container_layout.addWidget(self.group0, 1, 1) container_layout.addWidget(self.group1, 2, 1) container_layout.addWidget(self.group4, 1, 2) container_layout.addWidget(self.group5, 2, 2) container_layout.addWidget(self.buttonBox, 3, 1) self.setCentralWidget(container) # Paleta de colores para pintar transparente if not A11Y: palette = self.palette() palette.setBrush(QPalette.Base, Qt.transparent) self.setPalette(palette) self.setAttribute(Qt.WA_OpaquePaintEvent, False) def get_fake_tree(self, target): """Return the fake tree.""" try: fake_tree = check_output(NUITKA + ' --dump-xml ' + target, shell=True) except: fake_tree = "ERROR: Failed to get Tree Dump." finally: return fake_tree.strip() def run(self): ' run the actual backend process ' self.treeview_nodes.clear() self.textedit_source.clear() self.output.clear() self.statusBar().showMessage('WAIT!, Working...') target = str(self.target.text()).strip() self.treeview_nodes.setText(self.get_fake_tree(target)) self.textedit_source.setText(open(target, "r").read().strip()) conditional_1 = sys.platform.startswith('linux') conditional_2 = self.combo3.currentIndex() != 2 command_to_run_nuitka = " ".join( ('chrt -i 0' if conditional_1 and conditional_2 else '', NUITKA, '--debug' if self.slider1.value() else '', '--verbose' if self.slider2.value() else '', '--show-progress' if self.slider3.value() else '', '--show-scons --show-modules' if self.slider4.value() else '', '--unstriped' if self.slider5.value() else '', '--trace-execution' if self.slider6.value() else '', '--remove-output' if self.slider7.value() else '', '--no-optimization' if self.slider8.value() else '', '--code-gen-no-statement-lines' if self.slider9.value() else '', '--execute' if self.slider10.value() else '', '--recurse-all' if self.slider1a.value() else '', '--recurse-none' if self.slider2a.value() else '', '--recurse-stdlib' if self.slider3a.value() else '', '--clang' if self.slider4a.value() else '', '--lto' if self.slider5a.value() else '', '--windows-disable-console' if self.slider6a.value() else '', '--windows-target' if self.slider7a.value() else '', '--python-debug' if self.slider8a.value() else '', '--exe' if self.slider9a.value() else '', '--standalone' if self.slider10a.value() else '', '--module' if self.slider11a.value() else '', '--nofreeze-stdlib' if self.slider12a.value() else '', '--mingw' if self.slider13a.value() else '', '--warn-implicit-exceptions' if self.slider11.value() else '', '--execute-with-pythonpath' if self.slider12.value() else '', '--enhanced' if self.slider13.value() else '', '--icon="{}"'.format(self.icon.text()) if self.icon.text() else '', '--python-version={}'.format( self.combo1.currentText()), '--jobs={}'.format( self.combo3.currentText()), '--output-dir="{}"'.format( self.outdir.text()), "{}".format(target))) if DEBUG: print(command_to_run_nuitka) self.process.start(command_to_run_nuitka) if not self.process.waitForStarted() and not IS_WIN: return # ERROR ! self.statusBar().showMessage(__doc__.title()) def _process_finished(self): """finished sucessfully""" self.output.setFocus() self.output.selectAll() def read_output(self): """Read and append output to the log""" self.output.append(str(self.process.readAllStandardOutput())) def read_errors(self): """Read and append errors to the log""" self.output.append(str(self.process.readAllStandardError())) def paintEvent(self, event): """Paint semi-transparent background,animated pattern,background text""" if not A11Y: p = QPainter(self) p.setRenderHint(QPainter.Antialiasing) p.setRenderHint(QPainter.TextAntialiasing) p.setRenderHint(QPainter.HighQualityAntialiasing) p.fillRect(event.rect(), Qt.transparent) # animated random dots background pattern for i in range(4096): x = randint(25, self.size().width() - 25) y = randint(25, self.size().height() - 25) # p.setPen(QPen(QColor(randint(9, 255), 255, 255), 1)) p.drawPoint(x, y) p.setPen(QPen(Qt.white, 1)) p.rotate(40) p.setFont(QFont('Ubuntu', 250)) p.drawText(200, 99, "Nuitka") p.rotate(-40) p.setPen(Qt.NoPen) p.setBrush(QColor(0, 0, 0)) p.setOpacity(0.8) p.drawRoundedRect(self.rect(), 9, 9) p.end() def set_guimode(self): """Switch between simple and full UX""" for widget in (self.group2, self.group3, self.group4, self.group5, self.icon, self.icon_label, self.btn3, self.toolbar, self.statusBar()): widget.hide() if self.guimode.currentIndex() else widget.show()
class options(QWidget): def __init__(self, parent): QWidget.__init__(self) self.init(parent) self.initShape() def init(self, parent): self.heditor = parent def initShape(self): self.vbox = QVBoxLayout() self.optab = QTabWidget() self.fill = QWidget() self.createHexOptions() # self.createPageOptions() self.createPixelOptions() self.vbox.addWidget(self.optab) self.createButtons() self.vbox.addWidget(self.fill) self.setLayout(self.vbox) def createPageOptions(self): self.pagegrid = QGridLayout() self.pagegroup = QWidget() pagelabel = QLabel("Page size : ") self.sizeEdit = QFFSpinBox(self) self.sizeEdit.setMaximum(self.heditor.filesize) self.sizeEdit.setValue(self.heditor.pageSize) # psize = QString("%.2d" % self.heditor.pageSize) # self.sizeEdit.insert(psize) headerlabel = QLabel("Header size : ") self.headEdit = QFFSpinBox(self) self.headEdit.setMaximum(self.heditor.filesize) self.headEdit.setValue(self.heditor.pageHead) # phead = QString("%.2d" % self.heditor.pageHead) # self.headEdit.insert(phead) sparelabel = QLabel("Spare size : ") self.spareEdit = QFFSpinBox(self) self.spareEdit.setMaximum(self.heditor.filesize) self.spareEdit.setValue(self.heditor.pageSpare) # pspare = QString("%.2d" % self.heditor.pageSpare) # self.spareEdit.insert(pspare) ppb = QLabel("Pages per block:") self.pagesperblock = QComboBox() self.pagesperblock.addItem("8") self.pagesperblock.addItem("16") self.pagesperblock.addItem("32") self.pagesperblock.addItem("64") self.pagesperblock.addItem("128") self.pagesperblock.addItem("256") self.pagesperblock.addItem("512") self.pagesperblock.setCurrentIndex(2) lview = QLabel("Left indication: ") self.indic = QComboBox() self.indic.addItem("Offset") self.indic.addItem("Block") # self.pagesperlineEdit = QLineEdit() # ppl = QString("%.2d" % self.heditor.pagesPerBlock) # self.pagesperlineEdit.insert(ppl) self.pagegrid.addWidget(pagelabel, 0, 0) self.pagegrid.addWidget(self.sizeEdit, 0, 1) self.pagegrid.addWidget(headerlabel, 1, 0) self.pagegrid.addWidget(self.headEdit, 1, 1) self.pagegrid.addWidget(sparelabel, 2, 0) self.pagegrid.addWidget(self.spareEdit, 2, 1) self.pagegrid.addWidget(ppb, 3, 0) self.pagegrid.addWidget(self.pagesperblock, 3, 1) self.pagegrid.addWidget(lview, 4, 0) self.pagegrid.addWidget(self.indic, 4, 1) self.pagegrid.addWidget(self.fill, 5, 0) self.pagegrid.setRowStretch(5, 1) # self.pagegrid.addWidget(self.fill, 6, 0) # self.pagegrid.addWidget(pagesperline, 6, 0) # self.pagegrid.addWidget(self.pagesperlineEdit, 7, 0) self.pagegroup.setLayout(self.pagegrid) self.vvbox.addWidget(self.pagegroup) # self.optab.insertTab(1, self.pagegroup, "Pages" ) # self.vbox.addWidget(self.pagegroup) def createHexOptions(self): self.vvbox = QVBoxLayout() self.vcontainer = QWidget() self.hexgroup = QWidget() self.hexgrid = QGridLayout() groupebylabel = QLabel("Groupe by:") self.groupeby = QComboBox() self.groupeby.addItem("1") self.groupeby.addItem("2") self.groupeby.addItem("4") offsetlabel = QLabel("Offset as") self.offsetas = QComboBox() self.offsetas.addItem("Hexadecimal") self.offsetas.addItem("Decimal") # self.hexgrid.addWidget(groupebylabel, 0, 0) # self.hexgrid.addWidget(self.groupeby, 1, 0) self.hexgrid.addWidget(offsetlabel, 0, 0) self.hexgrid.addWidget(self.offsetas, 0, 1) # self.hexgrid.addWidget(self.fill, 2, 0) # self.hexgrid.setRowStretch(2, 1) self.hexgroup.setLayout(self.hexgrid) self.vvbox.addWidget(self.hexgroup) self.createPageOptions() self.vcontainer.setLayout(self.vvbox) self.optab.insertTab(0, self.vcontainer, "General") # self.vbox.addWidget(self.hexgroup) #Offset as decimal / hexadecimal def createPixelOptions(self): self.pixgroup = QWidget() self.pixgrid = QGridLayout() formatlabel = QLabel("Format :") self.format = QComboBox() self.format.addItem("RGB") self.format.addItem("Alpha RGB") self.format.addItem("Indexed 8bit") self.format.addItem("Mono") self.connect(self.format, SIGNAL("currentIndexChanged(const QString)"), self.formatChanged) colorlabel = QLabel("Indexed Color :") self.icolor = QComboBox() self.icolor.addItem("Green") self.icolor.addItem("Red") self.icolor.addItem("Blue") self.icolor.addItem("Ascii") self.icolor.addItem("256") self.icolor.setEnabled(False) slidelabel = QLabel("Resolution : ") self.sliderspin = QSpinBox(self) self.sliderspin.setMinimum(64) self.sliderspin.setMaximum(1024) self.sliderspin.setValue(self.heditor.wpixel.view.w) self.connect(self.sliderspin, SIGNAL("valueChanged(int)"), self.slidermoved) self.slider = QSlider(Qt.Horizontal) self.slider.setMinimum(64) self.slider.setMaximum(1024) self.slider.setValue(self.heditor.wpixel.view.w) self.slider.setSingleStep(1) self.zoomlabel = QLabel("Scale factor : 1") self.zoom = QSlider(Qt.Horizontal) self.zoom.setMinimum(1) self.zoom.setMaximum(5) self.zoom.setValue(1) self.zoom.setSingleStep(1) self.zoom.setTickInterval(1) self.zoom.setTickPosition(QSlider.TicksBelow) self.connect(self.slider, SIGNAL("sliderMoved(int)"), self.slidermoved) self.connect(self.zoom, SIGNAL("sliderMoved(int)"), self.scale) self.pixgrid.addWidget(formatlabel, 0, 0) self.pixgrid.addWidget(self.format, 0, 1) self.pixgrid.addWidget(colorlabel, 1, 0) self.pixgrid.addWidget(self.icolor, 1, 1) self.pixgrid.addWidget(slidelabel, 2, 0) self.pixgrid.addWidget(self.sliderspin, 2, 1, Qt.AlignLeft) self.pixgrid.addWidget(self.slider, 3, 0) self.pixgrid.addWidget(self.zoomlabel, 4, 0, Qt.AlignLeft) self.pixgrid.addWidget(self.zoom, 5, 0) self.pixgrid.addWidget(self.fill, 6, 0) self.pixgrid.setRowStretch(6, 1) self.pixgroup.setLayout(self.pixgrid) self.optab.insertTab(1, self.pixgroup, "Pixel") def setSliderLabel(self, value): cvalue = QString() cvalue = "%2.d" % value self.sliderlabel.setText(cvalue) def setZoomLabel(self, value): zvalue = QString("Scale factor : ") zvalue += "%2.d" % value self.zoomlabel.setText(zvalue) def createButtons(self): self.applyB = QPushButton("Apply") self.connect(self.applyB, SIGNAL('clicked()'), self.apply) self.vbox.addWidget(self.applyB) def checkValue(self, value): try: n = int(value) return n except ValueError: return -1 def apply(self): #PAGE CHECK pagesize = self.sizeEdit.value() headsize = self.headEdit.value() sparesize = self.spareEdit.value() pagesperblock = self.checkValue(self.pagesperblock.currentText()) if (pagesize < 0) or (headsize < 0) or (sparesize < 0) or (pagesperblock < 0): print "Wrong values" else: offas = self.offsetas.currentText() if offas == "Decimal": self.heditor.decimalview = True elif offas == "Hexadecimal": self.heditor.decimalview = False #Hexview refresh self.heditor.readOffset(self.heditor.currentOffset) #Pageview refresh if self.indic.currentText() == "Offset": self.heditor.pageOffView = True else: self.heditor.pageOffView = False self.heditor.refreshPageValues(headsize, pagesize, sparesize, pagesperblock) if self.heditor.wpage.scroll: self.heditor.wpage.scroll.refreshValues( self.heditor.pagesPerBlock, self.heditor.pageSize) self.heditor.wpage.view.refreshAllContent() #PageView scrollbar refres #Pixel View refresh format = self.format.currentText() if format == "Indexed 8bit": self.heditor.wpixel.view.format = 0 elif format == "Mono": self.heditor.wpixel.view.format = 1 elif format == "RGB": self.heditor.wpixel.view.format = 2 elif format == "Alpha RGB": self.heditor.wpixel.view.format = 3 if self.heditor.wpixel.scroll: self.heditor.wpixel.scroll.refreshValues() #Color icolor = self.icolor.currentText() if icolor == "Red": self.heditor.wpixel.view.icolor = 0 elif icolor == "Green": self.heditor.wpixel.view.icolor = 1 elif icolor == "Blue": self.heditor.wpixel.view.icolor = 2 elif icolor == "Ascii": self.heditor.wpixel.view.icolor = 3 elif icolor == "256": self.heditor.wpixel.view.icolor = 4 pixoffset = self.heditor.wpixel.view.currentOffset self.heditor.wpixel.view.read_image(pixoffset) def slidermoved(self, value): pixoffset = self.heditor.wpixel.view.currentOffset self.heditor.wpixel.view.w = value self.sliderspin.setValue(value) # self.setSliderLabel(value) self.heditor.wpixel.view.read_image(pixoffset) if self.heditor.wpixel.scroll: self.heditor.wpixel.scroll.refreshValues() # print value def scale(self, value): self.setZoomLabel(value) self.heditor.wpixel.view.scale = value pixoffset = self.heditor.wpixel.view.currentOffset self.heditor.wpixel.view.read_image(pixoffset) def formatChanged(self, format): if format == "Indexed 8bit": self.icolor.setEnabled(True) else: self.icolor.setEnabled(False) def keyPressEvent(self, kEvent): key = kEvent.key() if key == Qt.Key_Return or key == Qt.Key_Enter: self.apply()
class DisplaySection(QWidget): def __init__(self): super(DisplaySection, self).__init__() EditorConfiguration.install_widget(self.tr("Visualización"), self) container = QVBoxLayout(self) # Text wrapping group_wrapping = QGroupBox(self.tr("Ajuste de Texto:")) box = QGridLayout(group_wrapping) self.check_wrap = QCheckBox(self.tr("Activar ajuste de texto")) box.addWidget(self.check_wrap, 0, 0) self.check_margin = QCheckBox(self.tr("Mostrar márgen derecho:")) box.addWidget(self.check_margin, 1, 0) self.slider_margin = QSlider(Qt.Horizontal) self.slider_margin.setMaximum(180) self.slider_margin.setFixedWidth(350) box.addWidget(self.slider_margin, 1, 1, Qt.AlignLeft) lcd_margin = QLCDNumber() lcd_margin.setSegmentStyle(QLCDNumber.Flat) box.addWidget(lcd_margin, 1, 2, Qt.AlignLeft) box.setAlignment(Qt.AlignLeft) container.addWidget(group_wrapping) # Add group # Extras: line number, markers, whitespace, etc group_extras = QGroupBox(self.tr("Visualización:")) box = QGridLayout(group_extras) self.check_line_numbers = QCheckBox( self.tr("Mostrar números de líneas")) box.addWidget(self.check_line_numbers, 0, 0) self.check_current_line = QCheckBox(self.tr("Resaltar línea actual")) box.addWidget(self.check_current_line, 0, 1) self.check_mark_change = QCheckBox(self.tr("Marcar línea modificada")) box.addWidget(self.check_mark_change, 1, 0) self.check_match_brace = QCheckBox(self.tr("Resaltar [], {}, (), <>")) box.addWidget(self.check_match_brace, 1, 1) self.check_whitespace = QCheckBox( self.tr("Mostrar espacios en blanco")) box.addWidget(self.check_whitespace, 2, 0) self.check_guides = QCheckBox(self.tr("Mostrar guías de indentación")) box.addWidget(self.check_guides, 2, 1) self.check_eof = QCheckBox(self.tr("Mostrar EOF")) box.addWidget(self.check_eof, 3, 0) container.addWidget(group_extras) # Add group # Spacer container.addItem( QSpacerItem(0, 10, QSizePolicy.Expanding, QSizePolicy.Expanding)) # Connections self.slider_margin.valueChanged[int].connect(lcd_margin.display) # Configuration self.check_wrap.setChecked(settings.get_setting('editor/wrap-mode')) self.check_line_numbers.setChecked( settings.get_setting('editor/show-line-number')) self.check_mark_change.setChecked( settings.get_setting('editor/mark-change')) self.check_match_brace.setChecked( settings.get_setting('editor/match-brace')) self.check_current_line.setChecked( settings.get_setting('editor/show-caret-line')) self.check_eof.setChecked(settings.get_setting('editor/eof')) self.check_margin.setChecked( settings.get_setting('editor/show-margin')) self.slider_margin.setValue( settings.get_setting('editor/width-margin')) self.check_whitespace.setChecked( settings.get_setting('editor/show-tabs-spaces')) self.check_guides.setChecked( settings.get_setting('editor/show-guides')) def save(self): settings.set_setting('editor/wrap-mode', self.check_wrap.isChecked()) settings.set_setting('editor/show-margin', self.check_margin.isChecked()) settings.set_setting('editor/width-margin', self.slider_margin.value()) settings.set_setting('editor/show-line-number', self.check_line_numbers.isChecked()) settings.set_setting('editor/mark-change', self.check_mark_change.isChecked()) settings.set_setting('editor/match-brace', self.check_match_brace.isChecked()) settings.set_setting('editor/show-caret-line', self.check_current_line.isChecked()) settings.set_setting('editor/show-tabs-spaces', self.check_whitespace.isChecked()) settings.set_setting('editor/show-guides', self.check_guides.isChecked()) settings.set_setting('editor/eof', self.check_eof.isChecked()) editor_container = Edis.get_component("principal") editor = editor_container.get_active_editor() if editor is not None: editor.set_brace_matching() editor.show_line_numbers() editor.update_options() editor.update_margin()
class MusicView(preferences.Group): def __init__(self, page): super(MusicView, self).__init__(page) layout = QGridLayout() self.setLayout(layout) self.newerFilesOnly = QCheckBox(toggled=self.changed) layout.addWidget(self.newerFilesOnly, 0, 0, 1, 3) self.magnifierSizeLabel = QLabel() self.magnifierSizeSlider = QSlider(Qt.Horizontal, valueChanged=self.changed) self.magnifierSizeSlider.setSingleStep(50) self.magnifierSizeSlider.setRange(*popplerview.MagnifierSettings.sizeRange) self.magnifierSizeSpinBox = QSpinBox() self.magnifierSizeSpinBox.setRange(*popplerview.MagnifierSettings.sizeRange) self.magnifierSizeSpinBox.valueChanged.connect(self.magnifierSizeSlider.setValue) self.magnifierSizeSlider.valueChanged.connect(self.magnifierSizeSpinBox.setValue) layout.addWidget(self.magnifierSizeLabel, 1, 0) layout.addWidget(self.magnifierSizeSlider, 1, 1) layout.addWidget(self.magnifierSizeSpinBox, 1, 2) self.magnifierScaleLabel = QLabel() self.magnifierScaleSlider = QSlider(Qt.Horizontal, valueChanged=self.changed) self.magnifierScaleSlider.setSingleStep(50) self.magnifierScaleSlider.setRange(*popplerview.MagnifierSettings.scaleRange) self.magnifierScaleSpinBox = QSpinBox() self.magnifierScaleSpinBox.setRange(*popplerview.MagnifierSettings.scaleRange) self.magnifierScaleSpinBox.valueChanged.connect(self.magnifierScaleSlider.setValue) self.magnifierScaleSlider.valueChanged.connect(self.magnifierScaleSpinBox.setValue) layout.addWidget(self.magnifierScaleLabel, 2, 0) layout.addWidget(self.magnifierScaleSlider, 2, 1) layout.addWidget(self.magnifierScaleSpinBox, 2, 2) self.enableKineticScrolling = QCheckBox(toggled=self.changed) layout.addWidget(self.enableKineticScrolling) self.showScrollbars = QCheckBox(toggled=self.changed) layout.addWidget(self.showScrollbars) app.translateUI(self) def translateUI(self): self.setTitle(_("Music View")) self.newerFilesOnly.setText(_("Only load updated PDF documents")) self.newerFilesOnly.setToolTip(_( "If checked, Frescobaldi will not open PDF documents that are not\n" "up-to-date (i.e. the source file has been modified later).")) self.magnifierSizeLabel.setText(_("Magnifier Size:")) self.magnifierSizeLabel.setToolTip(_( "Size of the magnifier glass (Ctrl+Click in the Music View).")) # L10N: as in "400 pixels", appended after number in spinbox, note the leading space self.magnifierSizeSpinBox.setSuffix(_(" pixels")) self.magnifierScaleLabel.setText(_("Magnifier Scale:")) self.magnifierScaleLabel.setToolTip(_( "Magnification of the magnifier.")) self.magnifierScaleSpinBox.setSuffix(_("percent unit sign", "%")) # L10N: "Kinetic Scrolling" is a checkbox label, as in "Enable Kinetic Scrolling" self.enableKineticScrolling.setText(_("Kinetic Scrolling")) self.showScrollbars.setText(_("Show Scrollbars")) def loadSettings(self): s = popplerview.MagnifierSettings.load() self.magnifierSizeSlider.setValue(s.size) self.magnifierScaleSlider.setValue(s.scale) s = QSettings() s.beginGroup("musicview") newerFilesOnly = s.value("newer_files_only", True, bool) self.newerFilesOnly.setChecked(newerFilesOnly) kineticScrollingActive = s.value("kinetic_scrolling", True, bool) self.enableKineticScrolling.setChecked(kineticScrollingActive) showScrollbars = s.value("show_scrollbars", True, bool) self.showScrollbars.setChecked(showScrollbars) def saveSettings(self): s = popplerview.MagnifierSettings() s.size = self.magnifierSizeSlider.value() s.scale = self.magnifierScaleSlider.value() s.save() s = QSettings() s.beginGroup("musicview") s.setValue("newer_files_only", self.newerFilesOnly.isChecked()) s.setValue("kinetic_scrolling", self.enableKineticScrolling.isChecked()) s.setValue("show_scrollbars", self.showScrollbars.isChecked())
class FeeSelectionDialog(ArmoryDialog): ############################################################################# def __init__(self, parent, main, cs_callback, get_csstate): super(FeeSelectionDialog, self).__init__(parent, main) #Button Label self.lblButtonFee = QLabelButton("") #get default values flatFee = self.main.getSettingOrSetDefault("Default_Fee", MIN_TX_FEE) flatFee = coin2str(flatFee, maxZeros=1).strip() fee_byte = str( self.main.getSettingOrSetDefault("Default_FeeByte", MIN_FEE_BYTE)) blocksToConfirm = self.main.getSettingOrSetDefault(\ "Default_FeeByte_BlocksToConfirm", NBLOCKS_TO_CONFIRM) feeStrategy = str(self.main.getSettingOrSetDefault(\ "Default_FeeByte_Strategy", FEEBYTE_CONSERVATIVE)) self.coinSelectionCallback = cs_callback self.getCoinSelectionState = get_csstate self.validAutoFee = True isSmartFee = True try: feeEstimate, isSmartFee, errorMsg = self.getFeeByteFromNode( blocksToConfirm, feeStrategy) except: feeEstimate = "N/A" self.validAutoFee = False defaultCheckState = \ self.main.getSettingOrSetDefault("FeeOption", DEFAULT_FEE_TYPE) #flat free def setFlatFee(): def callbck(): return self.selectType('FlatFee') return callbck def updateLbl(): self.updateCoinSelection() self.radioFlatFee = QRadioButton(self.tr("Flat Fee (BTC)")) self.edtFeeAmt = QLineEdit(flatFee) self.edtFeeAmt.setFont(GETFONT('Fixed')) self.edtFeeAmt.setMinimumWidth(tightSizeNChar(self.edtFeeAmt, 6)[0]) self.edtFeeAmt.setMaximumWidth(tightSizeNChar(self.edtFeeAmt, 12)[0]) self.connect(self.radioFlatFee, SIGNAL('clicked()'), setFlatFee()) self.connect(self.edtFeeAmt, SIGNAL('textChanged(QString)'), updateLbl) frmFlatFee = QFrame() frmFlatFee.setFrameStyle(STYLE_RAISED) layoutFlatFee = QGridLayout() layoutFlatFee.addWidget(self.radioFlatFee, 0, 0, 1, 1) layoutFlatFee.addWidget(self.edtFeeAmt, 0, 1, 1, 1) frmFlatFee.setLayout(layoutFlatFee) #fee/byte def setFeeByte(): def callbck(): return self.selectType('FeeByte') return callbck self.radioFeeByte = QRadioButton(self.tr("Fee/Byte (Satoshi/Byte)")) self.edtFeeByte = QLineEdit(fee_byte) self.edtFeeByte.setFont(GETFONT('Fixed')) self.edtFeeByte.setMinimumWidth(tightSizeNChar(self.edtFeeByte, 6)[0]) self.edtFeeByte.setMaximumWidth(tightSizeNChar(self.edtFeeByte, 12)[0]) self.connect(self.radioFeeByte, SIGNAL('clicked()'), setFeeByte()) self.connect(self.edtFeeByte, SIGNAL('textChanged(QString)'), updateLbl) frmFeeByte = QFrame() frmFeeByte.setFrameStyle(STYLE_RAISED) layoutFeeByte = QGridLayout() layoutFeeByte.addWidget(self.radioFeeByte, 0, 0, 1, 1) layoutFeeByte.addWidget(self.edtFeeByte, 0, 1, 1, 1) frmFeeByte.setLayout(layoutFeeByte) #auto fee/byte if isSmartFee: frmAutoFeeByte = self.setupSmartAutoFeeByteUI(\ feeEstimate, blocksToConfirm, feeStrategy) else: frmAutoFeeByte = self.setupLegacyAutoFeeByteUI(\ feeEstimate, blocksToConfirm) #adjust and close self.btnClose = QPushButton(self.tr('Close')) self.connect(self.btnClose, SIGNAL('clicked()'), self.accept) self.checkBoxAdjust = QCheckBox(self.tr('Adjust fee/byte for privacy')) self.checkBoxAdjust.setChecked(\ self.main.getSettingOrSetDefault('AdjustFee', True)) self.connect(self.checkBoxAdjust, SIGNAL('clicked()'), updateLbl) frmClose = makeHorizFrame(\ [self.checkBoxAdjust, 'Stretch', self.btnClose], STYLE_NONE) #main layout layout = QGridLayout() layout.addWidget(frmAutoFeeByte, 0, 0, 1, 4) layout.addWidget(frmFeeByte, 2, 0, 1, 4) layout.addWidget(frmFlatFee, 4, 0, 1, 4) layout.addWidget(frmClose, 5, 0, 1, 4) self.setLayout(layout) self.setWindowTitle(self.tr('Select Fee Type')) self.selectType(defaultCheckState) self.setFocus() ############################################################################# def setupLegacyAutoFeeByteUI(self, feeEstimate, blocksToConfirm): def setAutoFeeByte(): def callbck(): return self.selectType('Auto') return callbck def updateLbl(): self.updateCoinSelection() def feeByteToStr(feeByte): try: self.feeByte = feeByte return "<u>%.1f</u>" % feeByte except: self.feeByte = -1 if isinstance(feeByte, str): return feeByte else: return "N/A" radioButtonTxt = self.tr("Fee rate from node (sat/Byte): ") if not self.validAutoFee: radioButtonTxt = self.tr("Failed to fetch fee/byte from node") self.radioAutoFeeByte = QRadioButton(radioButtonTxt) self.lblAutoFeeByte = QLabel(feeByteToStr(feeEstimate)) self.lblAutoFeeByte.setFont(GETFONT('Fixed')) self.lblAutoFeeByte.setMinimumWidth( tightSizeNChar(self.lblAutoFeeByte, 6)[0]) self.lblAutoFeeByte.setMaximumWidth( tightSizeNChar(self.lblAutoFeeByte, 12)[0]) self.sliderAutoFeeByte = QSlider(Qt.Horizontal, self) self.sliderAutoFeeByte.setMinimum(2) self.sliderAutoFeeByte.setMaximum(6) self.sliderAutoFeeByte.setValue(blocksToConfirm) self.lblSlider = QLabel() def getSliderLabelTxt(): return self.tr("Blocks to confirm: %1").arg(\ unicode(self.sliderAutoFeeByte.value())) def updateAutoFeeByte(): blocksToConfirm = self.sliderAutoFeeByte.value() try: feeEstimate, version, err = \ self.getFeeByteFromNode(blocksToConfirm, FEEBYTE_CONSERVATIVE) except: feeEstimate = "N/A" self.lblSlider.setText(getSliderLabelTxt()) self.lblAutoFeeByte.setText(feeByteToStr(feeEstimate)) updateLbl() self.lblSlider.setText(getSliderLabelTxt()) self.connect(self.radioAutoFeeByte, SIGNAL('clicked()'), setAutoFeeByte()) self.sliderAutoFeeByte.valueChanged.connect(updateAutoFeeByte) self.sliderAutoFeeByte.setEnabled(False) frmAutoFeeByte = QFrame() frmAutoFeeByte.setFrameStyle(STYLE_RAISED) layoutAutoFeeByte = QGridLayout() layoutAutoFeeByte.addWidget(self.radioAutoFeeByte, 0, 0, 1, 1) layoutAutoFeeByte.addWidget(self.lblAutoFeeByte, 0, 1, 1, 1) layoutAutoFeeByte.addWidget(self.lblSlider, 1, 0, 1, 2) layoutAutoFeeByte.addWidget(self.sliderAutoFeeByte, 2, 0, 1, 2) frmAutoFeeByte.setLayout(layoutAutoFeeByte) if not self.validAutoFee: frmAutoFeeByte.setEnabled(False) return frmAutoFeeByte ############################################################################# def setupSmartAutoFeeByteUI(self, feeEstimate, blocksToConfirm, strat): def setAutoFeeByte(): def callbck(): return self.selectType('Auto') return callbck stratList = [FEEBYTE_CONSERVATIVE, FEEBYTE_ECONOMICAL] def updateLbl(): self.updateCoinSelection() def getStrategyString(): try: cbIndex = self.comboStrat.currentIndex() return stratList[cbIndex] except: return FEEBYTE_CONSERVATIVE def feeByteToStr(feeByte): try: self.feeByte = feeByte return "<u>%.1f</u>" % feeByte except: self.feeByte = -1 if isinstance(feeByte, str): return feeByte else: return "N/A" radioButtonTxt = self.tr("Fee rate from node (sat/Byte): ") if not self.validAutoFee: radioButtonTxt = self.tr("Failed to fetch fee/byte from node") self.radioAutoFeeByte = QRadioButton(radioButtonTxt) self.lblAutoFeeByte = QLabel(feeByteToStr(feeEstimate)) self.lblAutoFeeByte.setFont(GETFONT('Fixed')) self.lblAutoFeeByte.setMinimumWidth( tightSizeNChar(self.lblAutoFeeByte, 6)[0]) self.lblAutoFeeByte.setMaximumWidth( tightSizeNChar(self.lblAutoFeeByte, 12)[0]) self.sliderAutoFeeByte = QSlider(Qt.Horizontal, self) self.sliderAutoFeeByte.setMinimum(2) self.sliderAutoFeeByte.setMaximum(100) self.sliderAutoFeeByte.setValue(blocksToConfirm) self.lblSlider = QLabel() self.lblStrat = QLabel(self.tr("Profile:")) self.ttStart = self.main.createToolTipWidget( self.tr(''' <u>Fee Estimation Profiles:</u><br><br> <b>CONSERVATIVE:</b> Short term estimate. More reactive to current changes in the mempool. Use this estimate if you want a high probability of getting your transaction mined quickly. <br><br> <b>ECONOMICAL:</b> Long term estimate. Ignores short term changes to the mempool. Use this profile if you want low fees and can tolerate swings in the projected confirmation window. <br><br> The estimate profiles may not diverge until your node has gathered enough data from the network to refine its predictions. Refer to the \"estimatesmartfee\" section in the Bitcoin Core 0.15 changelog for more informations. ''')) self.comboStrat = QComboBox() currentIndex = 0 for i in range(len(stratList)): self.comboStrat.addItem(stratList[i]) if stratList[i] == strat: currentIndex = i self.comboStrat.setCurrentIndex(currentIndex) def getSliderLabelTxt(): return self.tr("Blocks to confirm: %1").arg(\ unicode(self.sliderAutoFeeByte.value())) def updateAutoFeeByte(): blocksToConfirm = self.sliderAutoFeeByte.value() strategy = getStrategyString() try: feeEstimate, version, err = \ self.getFeeByteFromNode(blocksToConfirm, strategy) except: feeEstimate = "N/A" self.lblSlider.setText(getSliderLabelTxt()) self.lblAutoFeeByte.setText(feeByteToStr(feeEstimate)) updateLbl() def stratComboChange(): updateAutoFeeByte() self.lblSlider.setText(getSliderLabelTxt()) self.connect(self.radioAutoFeeByte, SIGNAL('clicked()'), setAutoFeeByte()) self.sliderAutoFeeByte.valueChanged.connect(updateAutoFeeByte) self.sliderAutoFeeByte.setEnabled(False) self.connect(self.comboStrat, SIGNAL('currentIndexChanged(int)'), stratComboChange) frmAutoFeeByte = QFrame() frmAutoFeeByte.setFrameStyle(STYLE_RAISED) layoutAutoFeeByte = QGridLayout() layoutAutoFeeByte.addWidget(self.radioAutoFeeByte, 0, 0, 1, 2) layoutAutoFeeByte.addWidget(self.lblAutoFeeByte, 0, 2, 1, 2) layoutAutoFeeByte.addWidget(self.lblSlider, 1, 0, 1, 1) layoutAutoFeeByte.addWidget(self.sliderAutoFeeByte, 2, 0, 1, 4) layoutAutoFeeByte.addWidget(self.lblStrat, 3, 0, 1, 1) layoutAutoFeeByte.addWidget(self.comboStrat, 3, 1, 1, 2) layoutAutoFeeByte.addWidget(self.ttStart, 3, 3, 1, 1) frmAutoFeeByte.setLayout(layoutAutoFeeByte) if not self.validAutoFee: frmAutoFeeByte.setEnabled(False) return frmAutoFeeByte ############################################################################# def getFeeByteFromNode(self, blocksToConfirm, strategy): try: feeEstimateResult = estimateFee(blocksToConfirm, strategy) return feeEstimateResult.val_ * 100000, \ feeEstimateResult.isSmart_, \ feeEstimateResult.error_ except: self.validAutoFee = False return "N/A", False, "" ############################################################################# def selectType(self, strType): self.radioFlatFee.setChecked(False) self.radioFeeByte.setChecked(False) self.radioAutoFeeByte.setChecked(False) self.sliderAutoFeeByte.setEnabled(False) if strType == 'FlatFee': self.radioFlatFee.setChecked(True) elif strType == 'FeeByte': self.radioFeeByte.setChecked(True) elif strType == 'Auto': if not self.validAutoFee: self.radioFeeByte.setChecked(True) else: self.radioAutoFeeByte.setChecked(True) self.sliderAutoFeeByte.setEnabled(True) self.updateCoinSelection() self.updateLabelButton() ############################################################################# def updateCoinSelection(self): try: self.coinSelectionCallback() except: self.updateLabelButton() ############################################################################# def getLabelButton(self): return self.lblButtonFee ############################################################################# def updateLabelButtonText(self, txSize, flatFee, fee_byte): txSize = str(txSize) if txSize != 'N/A': txSize += " B" if flatFee != 'N/A': flatFee = coin2str(flatFee, maxZeros=0).strip() flatFee += " BTC" if not isinstance(fee_byte, str): fee_byte = '%.2f' % fee_byte lblStr = "Size: %s, Fee: %s" % (txSize, flatFee) if fee_byte != 'N/A': lblStr += " (%s sat/B)" % fee_byte self.lblButtonFee.setText(lblStr) ############################################################################# def updateLabelButton(self, reset=False): try: if reset: raise Exception() txSize, flatFee, feeByte = self.getCoinSelectionState() self.updateLabelButtonText(txSize, flatFee, feeByte) except: self.updateLabelButtonText('N/A', 'N/A', 'N/A') ############################################################################# def resetLabel(self): self.updateLabelButton(True) ############################################################################# def getFeeData(self): fee = 0 fee_byte = 0 if self.radioFlatFee.isChecked(): flatFeeText = str(self.edtFeeAmt.text()) fee = str2coin(flatFeeText) elif self.radioFeeByte.isChecked(): fee_byteText = str(self.edtFeeByte.text()) fee_byte = float(fee_byteText) elif self.radioAutoFeeByte.isChecked(): fee_byte = self.feeByte adjust_fee = self.checkBoxAdjust.isChecked() return fee, fee_byte, adjust_fee ############################################################################# def setZeroFee(self): self.edtFeeAmt.setText('0') self.selectType('FlatFee')
class FeeSelectionDialog(ArmoryDialog): ############################################################################# def __init__(self, parent, main, cs_callback, get_csstate): super(FeeSelectionDialog, self).__init__(parent, main) #Button Label self.lblButtonFee = QLabelButton("") #get default values flatFee = self.main.getSettingOrSetDefault("Default_Fee", MIN_TX_FEE) flatFee = coin2str(flatFee, maxZeros=1).strip() fee_byte = str(self.main.getSettingOrSetDefault("Default_FeeByte", MIN_FEE_BYTE)) blocksToConfirm = self.main.getSettingOrSetDefault(\ "Default_FeeByte_BlocksToConfirm", NBLOCKS_TO_CONFIRM) self.coinSelectionCallback = cs_callback self.getCoinSelectionState = get_csstate self.validAutoFee = True try: autoFee_byte = str(estimateFee(blocksToConfirm) / 1000.0) except: autoFee_byte = "N/A" self.validAutoFee = False defaultCheckState = \ self.main.getSettingOrSetDefault("FeeOption", DEFAULT_FEE_TYPE) #flat free def setFlatFee(): def callbck(): return self.selectType('FlatFee') return callbck def updateLbl(): self.updateCoinSelection() self.radioFlatFee = QRadioButton(self.tr("Flat Fee (BTC)")) self.edtFeeAmt = QLineEdit(flatFee) self.edtFeeAmt.setFont(GETFONT('Fixed')) self.edtFeeAmt.setMinimumWidth(tightSizeNChar(self.edtFeeAmt, 6)[0]) self.edtFeeAmt.setMaximumWidth(tightSizeNChar(self.edtFeeAmt, 12)[0]) self.connect(self.radioFlatFee, SIGNAL('clicked()'), setFlatFee()) self.connect(self.edtFeeAmt, SIGNAL('textChanged(QString)'), updateLbl) frmFlatFee = QFrame() frmFlatFee.setFrameStyle(STYLE_RAISED) layoutFlatFee = QGridLayout() layoutFlatFee.addWidget(self.radioFlatFee, 0, 0, 1, 1) layoutFlatFee.addWidget(self.edtFeeAmt, 0, 1, 1, 1) frmFlatFee.setLayout(layoutFlatFee) #fee/byte def setFeeByte(): def callbck(): return self.selectType('FeeByte') return callbck self.radioFeeByte = QRadioButton(self.tr("Fee/Byte (Satoshi/Byte)")) self.edtFeeByte = QLineEdit(fee_byte) self.edtFeeByte.setFont(GETFONT('Fixed')) self.edtFeeByte.setMinimumWidth(tightSizeNChar(self.edtFeeByte, 6)[0]) self.edtFeeByte.setMaximumWidth(tightSizeNChar(self.edtFeeByte, 12)[0]) self.connect(self.radioFeeByte, SIGNAL('clicked()'), setFeeByte()) self.connect(self.edtFeeByte, SIGNAL('textChanged(QString)'), updateLbl) frmFeeByte = QFrame() frmFeeByte.setFrameStyle(STYLE_RAISED) layoutFeeByte = QGridLayout() layoutFeeByte.addWidget(self.radioFeeByte, 0, 0, 1, 1) layoutFeeByte.addWidget(self.edtFeeByte, 0, 1, 1, 1) frmFeeByte.setLayout(layoutFeeByte) #auto fee/byte def setAutoFeeByte(): def callbck(): return self.selectType('Auto') return callbck radioButtonTxt = self.tr("Fee rate from node (sat/Byte): ") if not self.validAutoFee: radioButtonTxt = self.tr("Failed to fetch fee/byte from node") self.radioAutoFeeByte = QRadioButton(radioButtonTxt) self.lblAutoFeeByte = QLabel(autoFee_byte) self.lblAutoFeeByte.setFont(GETFONT('Fixed')) self.lblAutoFeeByte.setMinimumWidth(tightSizeNChar(self.lblAutoFeeByte, 6)[0]) self.lblAutoFeeByte.setMaximumWidth(tightSizeNChar(self.lblAutoFeeByte, 12)[0]) self.sliderAutoFeeByte = QSlider(Qt.Horizontal, self) self.sliderAutoFeeByte.setMinimum(2) self.sliderAutoFeeByte.setMaximum(6) self.sliderAutoFeeByte.setValue(blocksToConfirm) self.lblSlider = QLabel() def getSliderLabelTxt(): return self.tr("Blocks to confirm: %1").arg(\ unicode(self.sliderAutoFeeByte.value())) def updateAutoFeeByte(): blocksToConfirm = self.sliderAutoFeeByte.value() try: autoFee_byte = str(estimateFee(blocksToConfirm) / 1000.0) except: autoFee_byte = "N/A" self.lblSlider.setText(getSliderLabelTxt()) self.lblAutoFeeByte.setText(autoFee_byte) updateLbl() self.lblSlider.setText(getSliderLabelTxt()) self.connect(self.radioAutoFeeByte, SIGNAL('clicked()'), setAutoFeeByte()) self.sliderAutoFeeByte.valueChanged.connect(updateAutoFeeByte) self.sliderAutoFeeByte.setEnabled(False) frmAutoFeeByte = QFrame() frmAutoFeeByte.setFrameStyle(STYLE_RAISED) layoutAutoFeeByte = QGridLayout() layoutAutoFeeByte.addWidget(self.radioAutoFeeByte, 0, 0, 1, 1) layoutAutoFeeByte.addWidget(self.lblAutoFeeByte, 0, 1, 1, 1) layoutAutoFeeByte.addWidget(self.lblSlider, 1, 0, 1, 2) layoutAutoFeeByte.addWidget(self.sliderAutoFeeByte, 2, 0, 1, 2) frmAutoFeeByte.setLayout(layoutAutoFeeByte) if not self.validAutoFee: frmAutoFeeByte.setEnabled(False) #adjust and close self.btnClose = QPushButton(self.tr('Close')) self.connect(self.btnClose, SIGNAL('clicked()'), self.accept) self.checkBoxAdjust = QCheckBox(self.tr('Adjust fee/byte for privacy')) self.checkBoxAdjust.setChecked(\ self.main.getSettingOrSetDefault('AdjustFee', True)) self.connect(self.checkBoxAdjust, SIGNAL('clicked()'), updateLbl) frmClose = makeHorizFrame(\ [self.checkBoxAdjust, 'Stretch', self.btnClose], STYLE_NONE) #main layout layout = QGridLayout() layout.addWidget(frmAutoFeeByte, 0, 0, 1, 4) layout.addWidget(frmFeeByte, 2, 0, 1, 4) layout.addWidget(frmFlatFee, 4, 0, 1, 4) layout.addWidget(frmClose, 5, 0, 1, 4) self.setLayout(layout) self.setWindowTitle(self.tr('Select Fee Type')) self.selectType(defaultCheckState) self.setFocus() ############################################################################# def selectType(self, strType): self.radioFlatFee.setChecked(False) self.radioFeeByte.setChecked(False) self.radioAutoFeeByte.setChecked(False) self.sliderAutoFeeByte.setEnabled(False) if strType == 'FlatFee': self.radioFlatFee.setChecked(True) elif strType == 'FeeByte': self.radioFeeByte.setChecked(True) elif strType == 'Auto': if not self.validAutoFee: self.radioFeeByte.setChecked(True) else: self.radioAutoFeeByte.setChecked(True) self.sliderAutoFeeByte.setEnabled(True) self.updateCoinSelection() self.updateLabelButton() ############################################################################# def updateCoinSelection(self): try: self.coinSelectionCallback() except: self.updateLabelButton() ############################################################################# def getLabelButton(self): return self.lblButtonFee ############################################################################# def updateLabelButtonText(self, txSize, flatFee, fee_byte): txSize = str(txSize) if txSize != 'N/A': txSize += " B" if flatFee != 'N/A': flatFee = coin2str(flatFee, maxZeros=0).strip() flatFee += " BTC" if not isinstance(fee_byte, str): fee_byte = '%.2f' % fee_byte lblStr = "Size: %s, Fee: %s" % (txSize, flatFee) if fee_byte != 'N/A': lblStr += " (%s sat/B)" % fee_byte self.lblButtonFee.setText(lblStr) ############################################################################# def updateLabelButton(self, reset=False): try: if reset: raise Exception() txSize, flatFee, feeByte = self.getCoinSelectionState() self.updateLabelButtonText(txSize, flatFee, feeByte) except: self.updateLabelButtonText('N/A', 'N/A', 'N/A') ############################################################################# def resetLabel(self): self.updateLabelButton(True) ############################################################################# def getFeeData(self): fee = 0 fee_byte = 0 if self.radioFlatFee.isChecked(): flatFeeText = str(self.edtFeeAmt.text()) fee = str2coin(flatFeeText) elif self.radioFeeByte.isChecked(): fee_byteText = str(self.edtFeeByte.text()) fee_byte = float(fee_byteText) elif self.radioAutoFeeByte.isChecked(): fee_byteText = str(self.lblAutoFeeByte.text()) fee_byte = float(fee_byteText) adjust_fee = self.checkBoxAdjust.isChecked() return fee, fee_byte, adjust_fee
class Mplayer(QDialog): REVENIR, PAS_PRECEDENT_SUIVANT, PRECEDENT_SUIVANT, CURSEUR_SUR_UNE_LIGNE,\ CURSEUR_A_PART, PARCOURIR, PAS_PARCOURIR, LIST, RATIO = range(9) HAUTEUR, LARGEUR = range(2) def __init__(self, cheminVideo=[], taille=(250,225), choixWidget=(RATIO, REVENIR, PAS_PRECEDENT_SUIVANT,CURSEUR_SUR_UNE_LIGNE,PAS_PARCOURIR,LIST), debutFin=(0,0), cheminMPlayer=None, barreTaches=None, facteurLimitant=HAUTEUR, cheminParcourir=None, parent=None): """widget mplayer""" QDialog.__init__(self, parent) #=== Paramètres généraux ===# self.setAttribute(Qt.WA_DeleteOnClose) self.setWindowTitle(_(u"Player vidéo")) #On réduit la marge pour gagner de l'espace self.setContentsMargins(0,0,0,0) self.systeme = os.name ### Quand EKD windows est installé, le chemin des dépendances sont ########### ### positionnées dans les variables d'environnement donc pas besoin de ####### ### collecter le chemin des ces dépendances ################################## self.cheminMPlayer = "mplayer" ############################################################################## # liste de chemins vidéos if type(cheminVideo) != list : self.listeVideos=[cheminVideo] else : self.listeVideos = cheminVideo # est-ce que la vidéo est lue? self.estLue=False # est-ce que la vidéo est en pause? self.estEnPause=False self.debutFin = debutFin # Nom du fichier courant (le self n'est pas encore utile) txtParDefaut = u"Pas de fichier lu" if self.listeVideos.__len__()!=0: self.fichierCourant = [txtParDefaut, self.listeVideos[0]] else: self.fichierCourant = [txtParDefaut, ""] # Barre des tâches de la fenêtre self.barreTaches = barreTaches # Taille de la vidéo self.tailleLargeur=taille[0] self.tailleHauteur=taille[1] # paramètres des boutons-icones iconTaille=22 flat=1 # Pour récupérer le temps courant depuis certains cadre self.temps = 0 self.dureeTimer = 10 # temps en ms ############################################################################################################################### #Pour être plus précis lors de la lecture, on prend comme unité la miliseconde. ###################### ## Il faut donc utiliser une echelle 1000 fois plus grande pour les unités du slider self.echelle=1000 ############################################################################################################################### # Permet de récupérer la durée de la vidéo depuis une instance de la classe # Sert dans certains cadres self.dureeVideo = 0 # Chemin sur lequel peut s'ouvrir la boite de dialogue de fichier # associée au bouton parcourir self.cheminPourBoutonParcourir = cheminParcourir self.taille = taille debug("self.taille avant lecture : %s %s" % (self.taille, type(self.taille))) #=== Widgets ===# self.icone_lire=QIcon("Icones" + os.sep + "player_play.png") self.icone_pause=QIcon("Icones" + os.sep + "player_pause.png") self.icone_arret=QIcon("Icones" + os.sep + "player_stop.png") if Mplayer.REVENIR in choixWidget: self.bout_revenir = QPushButton(u"Revenir") self.bout_revenir.setIcon(QIcon("Icones" + os.sep + "revenir.png")) if Mplayer.PARCOURIR in choixWidget: self.bout_ouvVideo = QPushButton(u"Parcourir...") if Mplayer.PRECEDENT_SUIVANT in choixWidget: self.bout_prec = QPushButton(QIcon("Icones" + os.sep + "player_rew.png"),"") self.bout_prec.setIconSize(QSize(iconTaille, iconTaille)) self.bout_prec.setFlat(flat) self.bout_suivant = QPushButton(QIcon("Icones" + os.sep + "player_fwd.png"),"") self.bout_suivant.setIconSize(QSize(iconTaille, iconTaille)) self.bout_suivant.setFlat(flat) self.LISTW=False if Mplayer.LIST in choixWidget : self.LISTW = True self.listFichiers = QComboBox() self.listFichiers.hide() self.setListeVideo() self.bout_LectPause = QPushButton(self.icone_lire,"") self.bout_LectPause.setIconSize(QSize(iconTaille, iconTaille)) self.bout_LectPause.setFlat(flat) self.bout_Arret = QPushButton(self.icone_arret,"") self.bout_Arret.setIconSize(QSize(iconTaille, iconTaille)) self.bout_Arret.setFlat(flat) # widget qui contiendra la vidéo self.cibleVideo = DisplayVid(self) # par défaut le widget-cible est noir color = QColor(0, 0, 0) self.cibleVideo.setAutoFillBackground(True) self.cibleVideo.setPalette(QPalette(color)) self.cibleVideo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.cibleVideo.setFixedHeight(self.taille[1]) self.cibleVideo.setToolTip(self.fichierCourant[0]) #Choix de l'aspect ratio de la vidéo if Mplayer.RATIO in choixWidget : self.conf = QGroupBox() self.conf.setContentsMargins(0,0,0,0) self.conf.setMinimumSize(QSize(self.tailleLargeur, 0)) self.conf.setObjectName("conf") self.verticalLayout = QHBoxLayout(self.conf) self.verticalLayout.setObjectName("verticalLayout") self.choicenorm = QRadioButton(self.conf) self.choicenorm.setObjectName("choicenorm") self.verticalLayout.addWidget(self.choicenorm) self.choicewide = QRadioButton(self.conf) self.choicewide.setObjectName("choicewide") self.verticalLayout.addWidget(self.choicewide) self.choiceone = QRadioButton(self.conf) self.choiceone.setObjectName("choiceone") self.verticalLayout.addWidget(self.choiceone) self.choicenorm.setText("4:3") self.choicewide.setText("16:9") self.choiceone.setText("w:h") # Checked le ratio de la vidéo if self.listeVideos.__len__()!=0: self.changeRatio(self.listeVideos[0]) else : self.setRatio(4.0/3.0) if Mplayer.RATIO in choixWidget : self.choicenorm.setChecked(True) self.slider = QSlider(Qt.Horizontal) self.slider.setEnabled(True) self.mplayerProcess = QProcess(self) self.timer = QTimer(self) self.tempsChrono = TracerChrono() #=== mise-en-page/plan ===# mhbox = QHBoxLayout() vbox = QVBoxLayout() vbox.addWidget(self.cibleVideo) if Mplayer.RATIO in choixWidget : vbox.addWidget(self.conf) hbox = QHBoxLayout() if Mplayer.REVENIR in choixWidget: hbox.addWidget(self.bout_revenir) if Mplayer.PARCOURIR in choixWidget: hbox.addWidget(self.bout_ouvVideo) hbox.addWidget(self.bout_LectPause) hbox.addWidget(self.bout_Arret) if Mplayer.PRECEDENT_SUIVANT in choixWidget: hbox.addWidget(self.bout_prec) hbox.addWidget(self.bout_suivant) hbox.addWidget(self.tempsChrono) if Mplayer.CURSEUR_A_PART not in choixWidget: hbox.addWidget(self.slider) vbox.addLayout(hbox) if Mplayer.CURSEUR_A_PART in choixWidget: hbox.setAlignment(Qt.AlignLeft) hbox = QHBoxLayout() hbox.addWidget(self.slider) vbox.addLayout(hbox) # Liste fichier dans combobox if self.LISTW : hbox = QHBoxLayout() hbox.addWidget(self.listFichiers) vbox.addLayout(hbox) mhbox.addLayout(vbox) self.setLayout(mhbox) #=== connexion des widgets à des fonctions ===# if Mplayer.REVENIR in choixWidget: self.connect(self.bout_revenir, SIGNAL('clicked()'), SLOT('close()')) if Mplayer.PARCOURIR in choixWidget: self.connect(self.bout_ouvVideo, SIGNAL('clicked()'), self.ouvrirVideo) if Mplayer.PRECEDENT_SUIVANT in choixWidget: self.connect(self.bout_prec, SIGNAL('clicked()'), self.precedent) self.connect(self.bout_suivant, SIGNAL('clicked()'), self.suivant) #Ajouté le 08/11/2009 - Liste des fichiers dans une combobox if self.LISTW : self.connect(self.listFichiers, SIGNAL('currentIndexChanged(int)'), self.changeVideo) self.connect(self.bout_LectPause, SIGNAL('clicked()'), self.lectPause) self.connect(self.bout_Arret, SIGNAL('clicked()'), self.arretMPlayer) self.connect(self.mplayerProcess, SIGNAL('readyReadStandardOutput()'), self.recupSortie) self.connect(self.mplayerProcess, SIGNAL('finished(int,QProcess::ExitStatus)'), self.finVideo) self.connect(self.timer, SIGNAL('timeout()'), self.sonderTempsActuel) self.connect(self.slider, SIGNAL('sliderMoved(int)'), self.changerTempsCurseur) self.connect(self.cibleVideo, SIGNAL('changeSize'), self.sizeMplayer) if Mplayer.RATIO in choixWidget : self.connect(self.choicenorm, SIGNAL("clicked(bool)"), self.defRatio) self.connect(self.choicewide, SIGNAL("clicked(bool)"), self.defRatio) self.connect(self.choiceone, SIGNAL("clicked(bool)"), self.defRatio) def setListeVideo(self) : self.referenceVideo = [] self.listFichiers.clear() for vid in self.listeVideos : self.referenceVideo.append(vid) self.listFichiers.addItem(os.path.basename(vid)) if self.listeVideos.__len__() > 1 : self.listFichiers.show() def setAudio(self,au) : if au : self.cibleVideo.hide() if "conf" in self.__dict__ : self.conf.hide() else : self.cibleVideo.show() if "conf" in self.__dict__ : self.conf.show() def changeVideo(self, index) : self.arretMPlayer() if index >= 0 : # Condition ajoutée pour éviter une erreure de dépassement de range dans la liste. self.listeVideos = self.referenceVideo[index] self.listFichiers.setCurrentIndex(index) def defRatio(self, state=0) : if state : if self.choicenorm.isChecked() : self.setRatio(4.0/3.0) if self.choicewide.isChecked() : self.setRatio(16.0/9.0) if self.choiceone.isChecked() : try : dim=getVideoSize(unicode(self.listeVideos[0])) self.setRatio(dim[0]/dim[1]) except : None self.defRatio() else : self.adjustSize() def setRatio(self,ratio) : self.ratio = ratio self.sizeMplayer() def changeRatio(self,video) : rv = getVideoRatio(video) if rv[0]==0.0 and type(rv[1])==float : rat = rv[1] else : rat = rv[0] if rat > 1.7 : if "choicewide" in self.__dict__ : self.choicewide.setChecked(True) self.setRatio(16.0/9.0) elif rat > 1.3 and rat <= 1.7 : if "choicenorm" in self.__dict__ : self.choicenorm.setChecked(True) self.setRatio(4.0/3.0) elif rat < 1.3 and rat != 0.0 : if "choiceone" in self.__dict__ : self.choiceone.setChecked(True) dim=getVideoSize(video) self.setRatio(dim[0]/dim[1]) else : if "choicenorm" in self.__dict__ : self.choicenorm.setChecked(True) self.setRatio(4.0/3.0) def sizeMplayer(self) : self.cibleVideo.setFixedHeight(int(self.cibleVideo.width()/self.ratio)) def ouvrirVideo(self): """Ouverture de la boîte de dialogue de fichiers""" txt = u"Fichiers vidéo" if self.cheminPourBoutonParcourir: chemin = self.cheminPourBoutonParcourir else: try: chemin = EkdConfig.get('general','video_input_path').decode("UTF8") except: chemin = os.path.expanduser('~') liste=QFileDialog.getOpenFileNames(None, u"Ouvrir", chemin, "%s (*.avi *.mpg *.mpeg *.mjpeg *.flv *.mp4 *.ogg *.vob *.mov *.wmv *.3gp *.h264)\n*" %txt) if not liste: return self.listeVideos = liste self.changeRatio(unicode(self.listeVideos[0])) chemin = unicode(self.listeVideos[0]) EkdConfig.set('general','video_input_path',os.path.dirname(chemin).encode("UTF8")) def setVideos(self, videos) : '''Définie proprement la liste des vidéos à jouer''' if type(videos) != list : self.listeVideos = [videos] else : self.listeVideos = videos if self.LISTW and videos.__len__() > 1 : self.setListeVideo() elif self.LISTW : self.listFichiers.hide() def demarrerMPlayer(self): """démarrage de mplayer avec les arguments choisis""" if self.estLue: return True args = QStringList() # Liste Qt qui contiendra les options de mplayer # Ajout d'options à liste: args << "-option" # mplayer fonctionnera comme un terminal dans ce script args << "-slave" # on ne veut pas avoir des commentaires sans grand intérêt args << "-quiet" # Sous linux, aucun driver n'a été nécessaire et pas de manip pour Wid :) if self.systeme=='posix': # try - except? # la fenêtre de mplayer restera attaché à la fenêtre # wid prend en valeur le nombre identifiant le widget (celui qui contiendra la vidéo) args << "-wid" << QString.number(self.cibleVideo.winId()) # Objet QString car args est une liste de ch de caractères settings = QSettings() videoOutput = settings.value("vo", QVariant('')).toString() if videoOutput: args << '-vo' << videoOutput # Sous windows else: # reinterpret_cast<qlonglong> obligatoire, winId() ne se laissant pas convertir gentiment ;) args << "-wid" << self.cibleVideo.winId().__hex__() args << "-vo" << "directx:noaccel" #args << "-vo" << "gl" # alternative # chemin de la vidéo args << self.listeVideos if PYQT_VERSION_STR >= "4.1.0": # mode de canal: on fusionne le canal de sortie normal (stdout) et celui des erreurs (stderr) self.mplayerProcess.setProcessChannelMode(QProcess.MergedChannels) # démarrage de mplayer (en tenant compte des arguments définis ci-dessus) # comme un nouveau processus self.mplayerProcess.start(self.cheminMPlayer, args) # au cas où mplayer ne démarrerait pas au bout de 3 sec (ex. problème de codec) if not self.mplayerProcess.waitForStarted(3000): QMessageBox.critical(self, u"Avertissement", u"Bogue au lancement de la vidéo avec mplayer") return False # donne le temps toutes les x secondes self.timer.start(self.dureeTimer) self.estLue = True return True def recupSortie(self): """récupère les lignes d'information émises par QProcess (mplayerProcess) et en tire les conséquences""" while self.mplayerProcess.canReadLine(): # renvoie True si une ligne complète peut être lue à partir du système # stocker l'ensemble des bits d'une ligne tampon=QByteArray(self.mplayerProcess.readLine()) # readline: lit une ligne ascii à partir du système # On vérifie si on a eu des réponses if tampon.startsWith("Playing"): # On récupère les infos de base ('$ mplayer -input cmdlist' pour avoir la liste complète - file:///usr/share/doc/mplayer-doc/tech/slave.txt.gz pour plus de détails) self.mplayerProcess.write("get_video_resolution\n") # récupère la résolution de la vidéo self.mplayerProcess.write("get_time_length\n") # Nouveau fichier chargé -> on récupère son nom ind = tampon.length() - 2 # suppression du '.' à la fin tampon.remove(ind,ind) tampon.remove(0, 8) # vire Playing tampon.replace(QByteArray("\n"), QByteArray("")) tampon.replace(QByteArray("\r"), QByteArray("")) try: # Tour de passe-passe pour ne pas avoir de problème d'accents # Condition pour détection windows if os.name == 'nt': self.fichierCourant[1]=unicode(QString(tampon)) # Condition pour détection Linux ou MacOSX elif os.name in ['posix', 'mac']: self.fichierCourant[1]=unicode(QString(tampon)).encode("Latin1").decode("UTF8") except UnicodeEncodeError, e: debug(e) self.fichierCourant[1]="?" self.cibleVideo.setToolTip(self.fichierCourant[1]) if self.barreTaches is not None: self.barreTaches.showMessage(self.fichierCourant[1]) # réponse à get_video_resolution : ANS_VIDEO_RESOLUTION='<width> x <height>' if tampon.startsWith("ANS_VIDEO_RESOLUTION"): # retourne True si l'ensemble de bits démarre avec "..." debug("tampon : %s" % tampon) # ex. -> ANS_VIDEO_RESOLUTION='352 x 288' tampon.remove(0, 21) # suppression des 21 1er caract -> '352 x 288' tampon.replace(QByteArray("'"), QByteArray("")) # -> 352 x 288 tampon.replace(QByteArray(" "), QByteArray("")) # -> 352x288 tampon.replace(QByteArray("\n"), QByteArray("")) # -> 352x288 # retour chariot unix tampon.replace(QByteArray("\r"), QByteArray("")) # -> 352x288 # retour chariot windows #print "-----tampon.indexOf('x') :", tampon.indexOf('x'), type(tampon.indexOf('x')) sepIndex = tampon.indexOf('x') # récupère la position de 'x' # 3 <type 'int'> #print "-----tampon.left(sepIndex).toInt():", tampon.left(sepIndex).toInt(), type(tampon.left(sepIndex).toInt()) resX = tampon.left(sepIndex).toInt()[0] # -> 352 # (352, True) <type 'tuple'> #print "-----tampon.mid(sepIndex+1).toInt() :", tampon.mid(sepIndex+1).toInt(), type(tampon.mid(sepIndex+1).toInt()) resY = tampon.mid(sepIndex+1).toInt()[0] # -> 288 # (288, True) <type 'tuple'> # on définit les nouvelles dimensions de l'image du widget-mplayer. # try pour éviter les bogues sur les fichiers audio (sans dimension d'image)!!! #try: if resX!=0 or resY!=0: debug( "ratio : %s - %s" % (self.ratio, type(self.ratio))) else: debug("fichier audio") # réponse à get_time_length : ANS_LENGTH=xx.yy elif tampon.startsWith("ANS_LENGTH"): debug("tampon : %s" % tampon) # -> ANS_LENGTH=279.38 tampon.remove(0, 11) # vire ANS_LENGTH= tampon.replace(QByteArray("'"), QByteArray("")) tampon.replace(QByteArray(" "), QByteArray("")) tampon.replace(QByteArray("\n"), QByteArray("")) tampon.replace(QByteArray("\r"), QByteArray("")) # -> 279.38 #print "-----tampon.toFloat() :", tampon.toFloat(), type(tampon.toFloat()) tempsMax = tampon.toFloat()[0] # (279.3800048828125, True) <type 'tuple'> self.dureeVideo = tempsMax ## Modifié le 28/05/2009 : On augmente la précision du slider #self.slider.setMaximum(tempsMax) # déf du domaine de valeur du curseur self.slider.setMaximum(tempsMax*self.echelle) # ATTENTION J'AI COMMENTE CETTE LIGNE !!! #self.slider.setMaximum(tempsMax) # réponse à get_time_pos : ANS_TIME_POSITION=xx.y elif tampon.startsWith("ANS_TIME_POSITION"): #print "tampon :",tampon # -> ANS_TIME_POSITION=1.4 (temps courant) tampon.remove(0, 18) # vire ANS_TIME_POSITION= tampon.replace(QByteArray("'"), QByteArray("")) tampon.replace(QByteArray(" "), QByteArray("")) tampon.replace(QByteArray("\n"), QByteArray("")) tampon.replace(QByteArray("\r"), QByteArray("")) #print "-----tampon.toFloat() :", tampon.toFloat(), type(tampon.toFloat()) tempsCourant = tampon.toFloat()[0] # (1.3999999761581421, True) <type 'tuple'> # récupération du temps courant: utile dans certains cadres self.temps = tempsCourant # Programmer un arrêt. Utile pour les aperçus temps = float("%.1f" %self.temps) if self.debutFin!=(0,0) and self.debutFin[1]==temps: self.arretMPlayer() return self.slider.setValue(tempsCourant*self.echelle) ############################################################################# self.changerTempsChrono(tempsCourant) # modifier le chrono du bouton
class SoundLabWindow(QtGui.QMainWindow): """ Window that encapsulates the commonly operations with a sound lab window that contains a widget (QSignalVisualizer or descendant). provides usefull operations that delegates into the widget its implementation """ # region Initialize def __init__(self, parent): QtGui.QMainWindow.__init__(self, parent) self.workSpace = Workspace() # get the status bar to show messages to the user self.statusbar = self.statusBar() self.statusbar.setSizeGripEnabled(False) # action groups of common actions for sound lab window self.play_record_actions = QActionGroup(self) self.widgets_visibility_actions = QActionGroup(self) self.zoom_actions = QActionGroup(self) self.tools_actions = QActionGroup(self) self.save_images_actions = QActionGroup(self) # play volume bar (disabled for now) self.volume_bar = QSlider(QtCore.Qt.Horizontal) self.volume_bar.setToolTip(self.tr(u"Volume bar for Play.")) self.volume_bar.setMaximumWidth(100) self.volume_bar.setRange(0, 300) self.volume_bar.setValue(100) self.volume_bar.valueChanged.connect(self.change_volume) # text edit for the signal name on the toolbar self.signalNameLineEdit = QtGui.QLineEdit(self) self.signalNameLineEdit.setToolTip(self.tr(u"Signal name.")) self.signalNameLineEdit.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum)) self.signalPropertiesTextLabel = QtGui.QLabel(self) self.signalPropertiesTextLabel.setToolTip(self.tr(u"Signal properties.")) self.signalPropertiesTextLabel.setAlignment(QtCore.Qt.AlignRight) self.signalPropertiesTextLabel.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)) # endregion def configureToolBarActionsGroups(self): """ Configure the actions into groups for best visualization and user configuration. :return: """ sep1, sep2, sep3, sep4 = [QtGui.QAction(self) for _ in range(4)] for sep in [sep1, sep2, sep3, sep4]: sep.setSeparator(True) # region play record actions play_record_actions_list = [self.actionPlay_Sound, self.actionPause_Sound, self.actionStop_Sound, self.actionRecord, self.actionPlayLoop, sep2] for act in play_record_actions_list: act.setActionGroup(self.play_record_actions) # self.toolBar.addWidget(self.volume_bar) # endregion # region widgets visibility actions widgets_visibility_actions_list = [self.actionOscilogram, self.actionSpectogram, self.actionCombined, sep3] for act in widgets_visibility_actions_list: act.setActionGroup(self.widgets_visibility_actions) # endregion # region zoom actions zoom_actions_list = [self.actionZoomIn, self.actionZoom_out, self.actionZoom_out_entire_file, sep4] for act in zoom_actions_list: act.setActionGroup(self.zoom_actions) # endregion # region Save Images actions save_images_actions_list = [self.actionOsc_Image, self.actionSpecgram_Image, self.actionCombined_Image] for act in save_images_actions_list: act.setActionGroup(self.save_images_actions) # endregion # region Tools actions tools_actions_list = [self.actionZoom_Cursor, self.actionPointer_Cursor, self.actionRectangular_Cursor] for act in tools_actions_list: act.setActionGroup(self.tools_actions) # endregion actions_groups = [(self.play_record_actions, self.tr(u"Play/Record")), (self.zoom_actions, self.tr(u"Zoom")), (self.widgets_visibility_actions, self.tr(u"Widgets Visibility"))] # add to the customizable sound lab toolbar for act in actions_groups: # method sig addActionGroup(actionGroup, name) self.toolBar.addActionGroup(act[0], act[1]) # add the label for signal name (and edit line) that always wil be visible as an option # not like the other groups of actions that the user could customize visibility self.toolBar.addWidget(self.signalNameLineEdit) self.toolBar.addAction(sep1) self.toolBar.addWidget(self.signalPropertiesTextLabel) # region Widget Tools @pyqtSlot() def on_actionZoom_Cursor_triggered(self): """ Select the Zoom Tool as current working tool in the widget :return: """ self.select_tool(self.actionZoom_Cursor, Tools.ZoomTool) @pyqtSlot() def on_actionRectangular_Cursor_triggered(self): """ Select the Rectangular Cursor as current working tool in the widget :return: """ self.select_tool(self.actionRectangular_Cursor, Tools.RectangularZoomTool) @pyqtSlot() def on_actionRectangular_Eraser_triggered(self): """ Select the Rectangular Eraser as current working tool in the widget :return: """ self.select_tool(self.actionRectangular_Eraser, Tools.RectangularEraser) @pyqtSlot() def on_actionPointer_Cursor_triggered(self): """ Select the Pointer Cursor as current working tool in the widget :return: """ self.select_tool(self.actionPointer_Cursor, Tools.PointerTool) def deselectToolsActions(self): """ Change the checked status of all the actions tools to False """ self.actionZoom_Cursor.setChecked(False) self.actionRectangular_Cursor.setChecked(False) self.actionPointer_Cursor.setChecked(False) def select_tool(self, tool_action, tool_type): """ :param tool_action: the checkable action that handles the selection of the tool :param tool_type: the enum type of the tool to select in the widget :return: """ self.deselectToolsActions() tool_action.setChecked(True) self.widget.setSelectedTool(tool_type) # endregion # region Save widgets Image @pyqtSlot() def on_actionOsc_Image_triggered(self): """ Save to disc the image of the oscilogram graph. :return: """ if not self.widget.visibleOscilogram: QtGui.QMessageBox.warning(QtGui.QMessageBox(), self.tr(u"Error"), self.tr(u"The Oscilogram plot widget is not visible.") + u"\n" + self.tr( u"You should see the data that you are going to save.")) return fname = unicode(QFileDialog.getSaveFileName(self, self.tr(u"Save oscilogram graph as an Image"), u"oscilogram-Duetto-Image", u"*.jpg")) if fname: save_image(self.widget.axesOscilogram, fname) @pyqtSlot() def on_actionSpecgram_Image_triggered(self): """ Save to disc the image of the spectrogram graph. :return: """ if not self.widget.visibleSpectrogram: QtGui.QMessageBox.warning(QtGui.QMessageBox(), self.tr(u"Error"), self.tr(u"The Spectrogram plot widget is not visible.") + " \n" + self.tr( u"You should see the data that you are going to save.")) return path = unicode(QFileDialog.getSaveFileName(self, self.tr(u"Save specgram graph as an Image"), u"specgram-Duetto-Image", u"*.jpg")) save_image(self.widget.axesSpecgram, path) @pyqtSlot() def on_actionCombined_Image_triggered(self): """ Save to disc the image of the both (oscilogram and spectrogram) visualization graphs. :return: """ if not self.widget.visibleOscilogram or not self.widget.visibleSpectrogram: QtGui.QMessageBox.warning(QtGui.QMessageBox(), self.tr(u"Error"), self.tr(u"One of the plot widgets is not visible.") + " \n" + self.tr( u"You should see the data that you are going to save.")) return path = unicode(QFileDialog.getSaveFileName(self, self.tr(u"Save graph as an Image"), u"Graph Image", u"*.jpg")) save_image(self.widget, path) # endregion # region Zoom # delegate in the widget the zoom interaction with the signal @QtCore.pyqtSlot() def on_actionZoomIn_triggered(self): self.widget.zoomIn() @QtCore.pyqtSlot() def on_actionZoom_out_triggered(self): self.widget.zoomOut() @QtCore.pyqtSlot() def on_actionZoom_out_entire_file_triggered(self): self.widget.zoomNone() # endregion # region Widgets And Window Visibility @pyqtSlot() def on_actionFull_Screen_triggered(self): """ Action that switch the window visualization state between Full Screen and Normal :return: """ if self.actionFull_Screen.isChecked(): self.showFullScreen() else: self.showNormal() @pyqtSlot() def on_actionCombined_triggered(self): """ Shows both axes visualization oscilogram and spectrogram. :return: """ self.changeWidgetsVisibility(True, True) @pyqtSlot() def on_actionSpectogram_triggered(self): """ Shows the spectrogram visualization graph only. :return: """ self.changeWidgetsVisibility(False, True) @pyqtSlot() def on_actionOscilogram_triggered(self): """ Shows the oscilogram visualization graph only. :return: """ self.changeWidgetsVisibility(True, False) def changeWidgetsVisibility(self, visibleOscilogram=True, visibleSpectrogram=True): """ Method that change the visibility of the widgets oscilogram and spectrogram on the main widget :param visibleOscilogram: Visibility of the oscilogram :param visibleSpectrogram: Visibility of the spectrogram :return: """ self.widget.visibleOscilogram = visibleOscilogram self.widget.visibleSpectrogram = visibleSpectrogram # udpate the workspace self.workSpace.visibleOscilogram = visibleOscilogram self.workSpace.visibleSpectrogram = visibleSpectrogram self.widget.graph() # endregion # region Play, Pause, Stop, Record # delegate in the widget reproduction actions def change_volume(self, volume): # change volume in the player of the widget if self.widget: self.widget.change_volume(volume) self.update_status_bar(self.tr(u"The volume has been changed to "+unicode(volume) + u"%."), 1000) @pyqtSlot() def on_actionPlay_Sound_triggered(self): try: self.widget.play() except Exception as ex: QtGui.QMessageBox.warning(QtGui.QMessageBox(), self.tr(u"Error"), self.tr(u"There is no selected audio input " u"device or the selected is unavailable")) @pyqtSlot() def on_actionPlayLoop_triggered(self): self.widget.setPlayLoopEnabled(self.actionPlayLoop.isChecked()) @pyqtSlot() def on_actionStop_Sound_triggered(self): self.widget.stop() # if previous status was recording the length of signal has changed and must be updated self.updateSignalPropertiesLabel() @pyqtSlot() def on_actionPause_Sound_triggered(self): self.widget.pause() @pyqtSlot() def on_actionSwitchPlayStatus_triggered(self): """ Change the play status of the signal from play-pause and vice versa :return: """ self.widget.switchPlayStatus() # endregion # region Edition and Processing Methods # region Undo Redo @pyqtSlot() def on_actionUndo_triggered(self): self.widget.undo() self.updateSignalPropertiesLabel() @pyqtSlot() def on_actionRedo_triggered(self): self.widget.redo() self.updateSignalPropertiesLabel() # endregion # region Cut, Copy, Paste @pyqtSlot() def on_actionCut_triggered(self): self.widget.cut() self.updateSignalPropertiesLabel() @pyqtSlot() def on_actionCopy_triggered(self): self.widget.copy() @pyqtSlot() def on_actionPaste_triggered(self): self.widget.paste() self.updateSignalPropertiesLabel() # endregion # endregion def update_status_bar(self, line, time_ms=None): """ Set a new message in the status bar of the window. :type time: the time that the line message wouold be visible in status bar. :param line: string with the line to show in the status bar """ time_ms = 1500 if time_ms is None else time_ms self.statusbar.showMessage(line, time_ms) def updateSignalPropertiesLabel(self, signal = None): """ Updates the text of the current signal properties in toolbar. :return: """ signal = self.widget.signal if signal is None else signal # action signal is a place in the tool bar to show the current signal name self.signalNameLineEdit.setText(signal.name) sr, bit_depth, channels = signal.samplingRate, signal.bitDepth, signal.channelCount properties = u" " + \ u" <b>" + self.tr(u"Sampling Rate: ") + u"</b>" + unicode(sr) + u" " + \ u" <b>" + self.tr(u"Bit Depth: ") + u"</b>" + unicode(bit_depth) + u" " + \ u" <b>" + self.tr(u"Channels: ") + u"</b>" + unicode(channels) + u" " + \ u" <b>" + self.tr(u"Duration(s): ") + u"</b>" + unicode(round(signal.duration, DECIMAL_PLACES)) + \ u" " self.signalPropertiesTextLabel.setText(properties)
class PreferencesDialogBase(QDialog): def __init__(self, parent, app): flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint QDialog.__init__(self, parent, flags) self.app = app self._setupUi() self.connect(self.filterHardnessSlider, SIGNAL("valueChanged(int)"), self.filterHardnessLabel.setNum) self.connect(self.buttonBox, SIGNAL('clicked(QAbstractButton*)'), self.buttonClicked) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) def _setupScanTypeBox(self, labels): self.scanTypeHLayout = QHBoxLayout() self.scanTypeLabel = QLabel(self) self.scanTypeLabel.setText(tr("Scan Type:")) self.scanTypeLabel.setMinimumSize(QSize(100, 0)) self.scanTypeLabel.setMaximumSize(QSize(100, 16777215)) self.scanTypeHLayout.addWidget(self.scanTypeLabel) self.scanTypeComboBox = QComboBox(self) for label in labels: self.scanTypeComboBox.addItem(label) self.scanTypeHLayout.addWidget(self.scanTypeComboBox) self.widgetsVLayout.addLayout(self.scanTypeHLayout) def _setupFilterHardnessBox(self): self.filterHardnessHLayout = QHBoxLayout() self.filterHardnessLabel = QLabel(self) self.filterHardnessLabel.setText(tr("Filter Hardness:")) self.filterHardnessLabel.setMinimumSize(QSize(0, 0)) self.filterHardnessHLayout.addWidget(self.filterHardnessLabel) self.filterHardnessVLayout = QVBoxLayout() self.filterHardnessVLayout.setSpacing(0) self.filterHardnessHLayoutSub1 = QHBoxLayout() self.filterHardnessHLayoutSub1.setSpacing(12) self.filterHardnessSlider = QSlider(self) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.filterHardnessSlider.sizePolicy().hasHeightForWidth()) self.filterHardnessSlider.setSizePolicy(sizePolicy) self.filterHardnessSlider.setMinimum(1) self.filterHardnessSlider.setMaximum(100) self.filterHardnessSlider.setTracking(True) self.filterHardnessSlider.setOrientation(Qt.Horizontal) self.filterHardnessHLayoutSub1.addWidget(self.filterHardnessSlider) self.filterHardnessLabel = QLabel(self) self.filterHardnessLabel.setText("100") self.filterHardnessLabel.setMinimumSize(QSize(21, 0)) self.filterHardnessHLayoutSub1.addWidget(self.filterHardnessLabel) self.filterHardnessVLayout.addLayout(self.filterHardnessHLayoutSub1) self.filterHardnessHLayoutSub2 = QHBoxLayout() self.filterHardnessHLayoutSub2.setContentsMargins(-1, 0, -1, -1) self.moreResultsLabel = QLabel(self) self.moreResultsLabel.setText(tr("More Results")) self.filterHardnessHLayoutSub2.addWidget(self.moreResultsLabel) spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.filterHardnessHLayoutSub2.addItem(spacerItem) self.fewerResultsLabel = QLabel(self) self.fewerResultsLabel.setText(tr("Fewer Results")) self.filterHardnessHLayoutSub2.addWidget(self.fewerResultsLabel) self.filterHardnessVLayout.addLayout(self.filterHardnessHLayoutSub2) self.filterHardnessHLayout.addLayout(self.filterHardnessVLayout) def _setupBottomPart(self): # The bottom part of the pref panel is always the same in all editions. self.fontSizeLabel = QLabel(tr("Font size:")) self.fontSizeSpinBox = QSpinBox() self.fontSizeSpinBox.setMinimum(5) self.widgetsVLayout.addLayout(horizontalWrap([self.fontSizeLabel, self.fontSizeSpinBox, None])) self.languageLabel = QLabel(tr("Language:"), self) self.languageComboBox = QComboBox(self) for lang in SUPPORTED_LANGUAGES: self.languageComboBox.addItem(LANGNAMES[lang]) self.widgetsVLayout.addLayout(horizontalWrap([self.languageLabel, self.languageComboBox, None])) self.copyMoveLabel = QLabel(self) self.copyMoveLabel.setText(tr("Copy and Move:")) self.widgetsVLayout.addWidget(self.copyMoveLabel) self.copyMoveDestinationComboBox = QComboBox(self) self.copyMoveDestinationComboBox.addItem(tr("Right in destination")) self.copyMoveDestinationComboBox.addItem(tr("Recreate relative path")) self.copyMoveDestinationComboBox.addItem(tr("Recreate absolute path")) self.widgetsVLayout.addWidget(self.copyMoveDestinationComboBox) self.customCommandLabel = QLabel(self) self.customCommandLabel.setText(tr("Custom Command (arguments: %d for dupe, %r for ref):")) self.widgetsVLayout.addWidget(self.customCommandLabel) self.customCommandEdit = QLineEdit(self) self.widgetsVLayout.addWidget(self.customCommandEdit) def _setupAddCheckbox(self, name, label, parent=None): if parent is None: parent = self cb = QCheckBox(parent) cb.setText(label) setattr(self, name, cb) def _setupPreferenceWidgets(self): # Edition-specific pass def _setupUi(self): self.setWindowTitle(tr("Preferences")) self.resize(304, 263) self.setSizeGripEnabled(False) self.setModal(True) self.mainVLayout = QVBoxLayout(self) self.widgetsVLayout = QVBoxLayout() self._setupPreferenceWidgets() self.mainVLayout.addLayout(self.widgetsVLayout) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok|QDialogButtonBox.RestoreDefaults) self.mainVLayout.addWidget(self.buttonBox) if (not ISOSX) and (not ISLINUX): self.mainVLayout.removeWidget(self.ignoreHardlinkMatches) self.ignoreHardlinkMatches.setHidden(True) def _load(self, prefs, setchecked): # Edition-specific pass def _save(self, prefs, ischecked): # Edition-specific pass def load(self, prefs=None): if prefs is None: prefs = self.app.prefs self.filterHardnessSlider.setValue(prefs.filter_hardness) self.filterHardnessLabel.setNum(prefs.filter_hardness) setchecked = lambda cb, b: cb.setCheckState(Qt.Checked if b else Qt.Unchecked) setchecked(self.mixFileKindBox, prefs.mix_file_kind) setchecked(self.useRegexpBox, prefs.use_regexp) setchecked(self.removeEmptyFoldersBox, prefs.remove_empty_folders) setchecked(self.ignoreHardlinkMatches, prefs.ignore_hardlink_matches) setchecked(self.debugModeBox, prefs.debug_mode) self.copyMoveDestinationComboBox.setCurrentIndex(prefs.destination_type) self.customCommandEdit.setText(prefs.custom_command) self.fontSizeSpinBox.setValue(prefs.tableFontSize) try: langindex = SUPPORTED_LANGUAGES.index(self.app.prefs.language) except ValueError: langindex = 0 self.languageComboBox.setCurrentIndex(langindex) self._load(prefs, setchecked) def save(self): prefs = self.app.prefs prefs.filter_hardness = self.filterHardnessSlider.value() ischecked = lambda cb: cb.checkState() == Qt.Checked prefs.mix_file_kind = ischecked(self.mixFileKindBox) prefs.use_regexp = ischecked(self.useRegexpBox) prefs.remove_empty_folders = ischecked(self.removeEmptyFoldersBox) prefs.ignore_hardlink_matches = ischecked(self.ignoreHardlinkMatches) prefs.debug_mode = ischecked(self.debugModeBox) prefs.destination_type = self.copyMoveDestinationComboBox.currentIndex() prefs.custom_command = str(self.customCommandEdit.text()) prefs.tableFontSize = self.fontSizeSpinBox.value() lang = SUPPORTED_LANGUAGES[self.languageComboBox.currentIndex()] oldlang = self.app.prefs.language if oldlang not in SUPPORTED_LANGUAGES: oldlang = 'en' if lang != oldlang: QMessageBox.information(self, "", tr("dupeGuru has to restart for language changes to take effect.")) self.app.prefs.language = lang self._save(prefs, ischecked) #--- Events def buttonClicked(self, button): role = self.buttonBox.buttonRole(button) if role == QDialogButtonBox.ResetRole: self.resetToDefaults()
class GUI(QWidget): def __init__(self, parent=None): global f f = open(filename, "a") f.write("Widget init.\n") f.close() QWidget.__init__(self, parent, Qt.WindowStaysOnTopHint) self.__setup_gui__(self) self._flag = False self._change = False f = open(filename, "a") f.write("End of widget init.\n") f.close() def closeEvent(self, event): reply = QMessageBox.question(self, "Confirm", "Are you sure You want to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: event.accept() else: event.ignore() def __setup_gui__(self, Dialog): global f f = open(filename, "a") f.write("Setup of gui.\n") f.close() Dialog.setObjectName("Dialog") Dialog.resize(270, 145) self.setWindowTitle("Map Layer") screen = QDesktopWidget().screenGeometry() size = self.geometry() self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2) self.Render = QPushButton("Render", Dialog) self.Render.setGeometry(QRect(85, 90, 100, 25)) self.Render.setObjectName("Render") self.comboBox = QComboBox(Dialog) self.comboBox.setGeometry(QRect(100, 34, 115, 18)) self.comboBox.setEditable(False) self.comboBox.setMaxVisibleItems(11) self.comboBox.setInsertPolicy(QComboBox.InsertAtBottom) self.comboBox.setObjectName("comboBox") self.comboBox.addItems([ "Google Roadmap", "Google Terrain", "Google Satellite", "Google Hybrid", "Yahoo Roadmap", "Yahoo Satellite", "Yahoo Hybrid", "Bing Roadmap", "Bing Satellite", "Bing Hybrid", "Open Street Maps" ]) self.comboBox.setCurrentIndex(10) self.label1 = QLabel("Source:", Dialog) self.label1.setGeometry(QRect(55, 35, 35, 16)) self.label1.setObjectName("label1") self.slider = QSlider(Dialog) self.slider.setOrientation(Qt.Horizontal) self.slider.setMinimum(1) self.slider.setMaximum(12) self.slider.setValue(4) self.slider.setGeometry(QRect(110, 61, 114, 16)) self.label2 = QLabel("Quality: " + str(self.slider.value()), Dialog) self.label2.setGeometry(QRect(47, 61, 54, 16)) self.label2.setObjectName("label2") self.doubleSpinBox = QDoubleSpinBox(Dialog) self.doubleSpinBox.setGeometry(QRect(160, 5, 40, 20)) self.doubleSpinBox.setDecimals(0) self.doubleSpinBox.setObjectName("doubleSpinBox") self.doubleSpinBox.setMinimum(10.0) self.doubleSpinBox.setValue(20.0) self.doubleSpinBox.setEnabled(False) self.checkBox = QCheckBox("Auto refresh", Dialog) self.checkBox.setGeometry(QRect(50, 6, 100, 20)) self.checkBox.setLayoutDirection(Qt.RightToLeft) self.checkBox.setObjectName("checkBox") self.progressBar = QProgressBar(Dialog) self.progressBar.setGeometry(QRect(5, 130, 260, 10)) self.progressBar.setProperty("value", 0) self.progressBar.setTextVisible(False) self.progressBar.setObjectName("progressBar") self.progressBar.setVisible(False) QObject.connect(self.Render, SIGNAL("clicked()"), Dialog.__repaint__) QMetaObject.connectSlotsByName(Dialog) QObject.connect(self.slider, SIGNAL("valueChanged(int)"), self.__update_slider_label__) QObject.connect(self.comboBox, SIGNAL("activated(int)"), self.__combobox_changed__) self.timerRepaint = QTimer() QObject.connect(self.checkBox, SIGNAL("clicked()"), self.__activate_timer__) QObject.connect(self.timerRepaint, SIGNAL("timeout()"), self.__on_timer__) f = open(filename, "a") f.write("End of setup of gui.\n") f.close() def __combobox_changed__(self): self._change = True def __activate_timer__(self): self.doubleSpinBox.setEnabled(self.checkBox.isChecked()) if self.checkBox.isChecked(): self.timerRepaint.start(self.doubleSpinBox.value() * 1000) self.Render.setEnabled(False) if _progress == 0: self.__repaint__() else: self.timerRepaint.stop() self.Render.setEnabled(True) def __get_net_size__(self): global f f = open(filename, "a") f.write("Geting net size...\n") f.close() if not os.path.exists(Paths["Screenshot"]): Visum.Graphic.Screenshot(Paths["Screenshot"]) size = Image.open(Paths["Screenshot"]).size f = open(filename, "a") f.write("Read net size:" + str(size) + ".\n") f.close() return size def __on_timer__(self): global _paramGlobal self._flag = False Visum.Graphic.MaximizeNetWindow() param = _paramGlobal _paramGlobal = Visum.Graphic.GetWindow() shift = abs((param[0] - _paramGlobal[0]) / (param[2] - param[0])) zoom = abs((param[2] - param[0]) / (_paramGlobal[2] - _paramGlobal[0]) - 1) print _windowSizeGlobal if _windowSizeGlobal[2:4] != Visum.Graphic.GetMainWindowPos()[2:4]: self.__get_net_size__() self._flag = True elif shift > 0.4 or zoom > 0.2: self._flag = True if self._flag or self._change and _progress == 0: self.__repaint__() self._change = False def __update_slider_label__(self, value): self.label2.setText("Quality: " + str(value)) self._change = True def __update_progress_bar__(self): if _progress != 0: self.progressBar.setVisible(True) self.progressBar.setValue(_progress) else: self.progressBar.setVisible(False) def __rebuild_paths__(self): global Paths Paths["Images"] = [] list = os.listdir(Paths["ScriptFolder"]) imageList = [] for i in range(len(list)): if list[i][-3:] == "png": imageList.append(list[i]) for i in range(len(imageList)): try: Visum.Graphic.Backgrounds.ItemByKey(imageList[i]) Paths["Images"].append(Paths["ScriptFolder"] + "\\" + imageList[i]) except: pass def __repaint__(self): global _progress, f if len(Visum.Graphic.Backgrounds.GetAll) != len(Paths["Images"]): self.__rebuild_paths__() if _progress == 0: f = open(filename, "a") f.write("Doing repaint...\n") f.close() QWebSettings.clearMemoryCaches() timer = QTimer() timer.start(100) QObject.connect(timer, SIGNAL("timeout()"), self.__update_progress_bar__) Main(self.comboBox.currentIndex(), Visum.Graphic.GetWindow(), self.slider.value() / 4.0, self.__get_net_size__()) Visum.Graphic.Draw() self.__update_progress_bar__() _progress = 0 QTimer().singleShot(1500, self.__update_progress_bar__) f = open(filename, "a") f.write("End of doing repaint.\n") f.close()
class Tool(QToolBar): def __init__(self,parent): QToolBar.__init__(self,parent) self.parent = parent self.action_NewProject = QAction(Icons.newprj, 'Project', self) self.action_NewProject.triggered.connect(self.parent.treeWidget.newProject) self.action_NewProject.setToolTip("Create a New Project") self.action_Open = QAction(Icons.open, 'Open', self) self.action_Open.triggered.connect(self.parent.fileOpen) self.action_Open.setToolTip("Open File") self.action_Save = QAction(Icons.save, 'Save', self) self.action_Save.setShortcut('Ctrl+S') self.action_Save.triggered.connect(self.parent.fileSave) self.action_Save.setToolTip("Save Current File") self.action_SaveAll = QAction(Icons.saveall, 'SaveAll', self) self.action_SaveAll.setShortcut('Ctrl+A') self.action_SaveAll.triggered.connect(self.parent.fileSaveAll) self.action_SaveAll.setToolTip("Save All Files") self.action_Build = QAction(Icons.thread_view, 'Build', self) self.action_Build.setShortcut('Ctrl+B') self.action_Build.triggered.connect(self.parent.build_project) self.action_Debug = QAction(Icons.debug_exec, 'Debug', self) self.action_Refresh = QAction(Icons.refresh_tab, 'Refresh', self) self.action_Refresh.triggered.connect(self.parent.treeWidget.refreshCurrentProject) self.action_Run = QAction(Icons.run, 'Run', self) self.action_Run.setShortcut('Ctrl+R') self.action_Run.triggered.connect(self.parent.adb.run) self.action_RunFile = QAction(Icons.go, 'Cmd', self) self.action_RunFile.triggered.connect(self.parent.openCommand) self.parent.runButton.clicked.connect(self.parent.command.setCmdLine) self.action_Stop = QAction(Icons.stop, 'Stop', self) self.action_Stop.setShortcut('Ctrl+Q') self.action_Stop.triggered.connect(self.parent.adb.stop) self.action_Design = QAction(Icons.color_palette, 'Design', self) self.action_Design.triggered.connect(self.parent.design) self.action_Level = QAction(Icons.cmpC_pal, 'Level', self) self.action_Level.triggered.connect(self.parent.level) self.action_Todo = QAction(Icons.task_set, 'Todo', self) self.action_Todo.triggered.connect(self.parent.todo) self.action_Help = QAction(Icons.toc_open, 'Help', self) self.action_Help.triggered.connect(self.parent.help) self.action_Full = QAction(Icons.fullscreen, 'Full', self) self.action_Full.triggered.connect(self.parent.full) self.action_Stop.setDisabled(True) self.setToolLabel() self.setAllowedAreas(Qt.AllToolBarAreas) #self.setFixedHeight(40) #self.setIconSize(QSize(config.iconSize(),config.iconSize())) ''' Adding all Actions ''' self.addAction(self.action_NewProject) self.addAction(self.action_Open) self.addAction(self.action_Save) self.addAction(self.action_SaveAll) #self.addAction(self.action_Refresh) self.addSeparator() self.addAction(self.action_Build) self.addAction(self.action_Run) #self.addAction(self.action_RunFile) self.addAction(self.action_Stop) self.addAction(self.action_Debug) self.addSeparator() self.addAction(self.action_Design) self.addAction(self.action_Level) self.addAction(self.action_Todo) self.initOptionsMenu() self.addSeparator() self.initStyleMenu() self.initLexerMenu() self.initApiMenu() #self.addAction(self.action_Help) #self.addAction(self.action_Full) self.addSeparator() self.initModeMenu() def colorChange(self, text, color): #print "colorChange ",text,color editStyle = config.readStyle() editStyle[text] = color config.writeStyle(editStyle) for i in range(len(self.parent.files)): self.parent.tabWidget.widget(i).setEditorStyle() def setColors(self,action): print action.text() def changeAll(self): self.colorChange("base", "#ffffff") def setIcon(self,val): config.setIconSize(val) self.setIconSize(QSize(val,val)) def setToolLabel(self): if (config.toolLabel()): self.setToolButtonStyle(Qt.ToolButtonIconOnly) self.setIconSize(QSize(24,24)) else: self.setIconSize(QSize(16,16)) self.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) '''Important for multiple callbacks in for loop''' def make_callback(self, text): return lambda:self.colorChange(text) ''' Options Menu ''' def initOptionsMenu(self): men = QMenu() #Threshold Slider self.threshSlider = QSlider() self.threshSlider.setTickPosition(QSlider.TicksLeft) self.threshSlider.setOrientation(Qt.Horizontal) self.threshSlider.setValue(config.thresh()) self.threshSlider.setMinimum(0) self.threshSlider.setMaximum(5) self.threshSlider.valueChanged.connect(self.parent.setThreshold) self.threshSliderAction = QWidgetAction(men) self.threshSliderAction.setDefaultWidget(self.threshSlider) #TabsWidth Slider self.tabsSlider = QSlider() self.tabsSlider.setTickPosition(QSlider.TicksLeft) self.tabsSlider.setOrientation(Qt.Horizontal) self.tabsSlider.setValue(config.tabwidth()) self.tabsSlider.setMinimum(0) self.tabsSlider.setMaximum(8) self.tabsSlider.valueChanged.connect(self.parent.setTabWidth) self.tabsSliderAction = QWidgetAction(men) self.tabsSliderAction.setDefaultWidget(self.tabsSlider) #iconSize Slider self.iconSlider = QSlider() self.iconSlider.setTickPosition(QSlider.TicksLeft) self.iconSlider.setOrientation(Qt.Horizontal) self.iconSlider.setValue(config.iconSize()) self.iconSlider.setMinimum(16) self.iconSlider.setMaximum(32) self.iconSlider.setSingleStep(2) self.iconSlider.valueChanged.connect(self.setIcon) self.iconSliderAction = QWidgetAction(men) self.iconSliderAction.setDefaultWidget(self.iconSlider) '''Font Button''' self.fontCombo = QFontComboBox() self.fontCombo.currentFontChanged.connect(self.parent.setFont) self.fontCombo.setCurrentFont(QFont(config.fontName())) self.fontComboMenu = QWidgetAction(men) self.fontComboMenu.setDefaultWidget(self.fontCombo) '''Font Size''' self.fontSizeCombo = QComboBox() for size in range(1,40): self.fontSizeCombo.addItem(str(size)) self.fontSizeCombo.setCurrentIndex(config.fontSize()) self.fontSizeCombo.currentIndexChanged.connect(self.parent.setFontSize) self.fontSizeComboMenu = QWidgetAction(men) self.fontSizeComboMenu.setDefaultWidget(self.fontSizeCombo) action_Android = QAction(Icons.android,'Android', self) action_Android.triggered.connect(self.parent.android) action_Ant = QAction(Icons.ant_view,'Ant', self) action_Ant.triggered.connect(self.parent.antt) action_Squirrel = QAction(Icons.nut,'Squirrel', self) action_Squirrel.triggered.connect(self.parent.squirrel) action_Ios1 = QAction(Icons.ios,'iOS', self) action_Update = QAction(Icons.update,"Update",self) action_Update.triggered.connect(self.parent.update) action_explorer = QAction("Explorer",self) action_explorer.triggered.connect(self.parent.exp) action_explorer.setCheckable(True) action_explorer.setChecked(True) action_console = QAction("Console",self) action_console.triggered.connect(self.parent.cmd) action_console.setCheckable(True) action_console.setChecked(False) #action_designer = QAction("Designer",self) #action_designer.triggered.connect(self.parent.design) action_Indentation = QAction("Indentation Guides",self) action_Indentation.triggered.connect(self.parent.setIndent) action_Indentation.setCheckable(True) action_Indentation.setChecked(config.indent()) action_WhiteSpace = QAction("WhiteSpace",self) action_WhiteSpace.triggered.connect(self.parent.setWhiteSpace) action_WhiteSpace.setCheckable(True) action_WhiteSpace.setChecked(config.whiteSpace()) action_EndLine = QAction("End of Lines",self) action_EndLine.triggered.connect(self.parent.setEndLine) action_EndLine.setCheckable(True) action_Margin = QAction("Line Numbers",self) action_Margin.triggered.connect(self.parent.setMargin) action_Margin.setCheckable(True) action_Margin.setChecked(config.margin()) action_ToolLabel = QAction("Tool Labels",self) action_ToolLabel.triggered.connect(self.setToolLabel) action_ToolLabel.setCheckable(True) #action_ToolLabel.setChecked(config.toolLabel()) '''Encoding''' encodingGroup = QActionGroup(self) encodingGroup.setExclusive(True) action_Ascii = QAction("Ascii",encodingGroup) action_Ascii.setCheckable(True) action_Unicode = QAction("Unicode",encodingGroup) action_Unicode.setCheckable(False) encodingGroup.addAction(action_Ascii) encodingGroup.addAction(action_Unicode) encodingGroup.selected.connect(self.parent.setEncoding) if(config.encoding() == Encoding.ASCII): action_Ascii.setChecked(True) else: action_Unicode.setChecked(True) men.addAction(action_Update) men.addAction(self.action_Help) men.addAction(self.action_Full) men.addSeparator() men.addAction(action_Android) men.addAction(action_Ant) men.addAction(action_Squirrel) men.addAction(action_Ios1) men.addSeparator() men.addAction(action_explorer) men.addAction(action_console) #men.addAction(action_designer) men.addSeparator() men.addAction(action_Indentation) men.addAction(action_WhiteSpace) men.addAction(action_EndLine) men.addAction(action_Margin) men.addAction(action_ToolLabel) men.addSeparator() men.addActions(encodingGroup.actions()) men.addSeparator() head_font = QLabel("Font---------------------") fnt = head_font.font() fnt.setBold(True) head_font.setFont(fnt) head_fontWidgetAction = QWidgetAction(men) head_fontWidgetAction.setDefaultWidget(head_font) men.addAction(head_fontWidgetAction) men.addAction(self.fontComboMenu) men.addAction(self.fontSizeComboMenu) men.addSeparator() men.addAction(QAction("TabWidth",self)) men.addAction(self.tabsSliderAction) men.addSeparator() men.addAction(QAction("Threshold",self)) men.addAction(self.threshSliderAction) #men.addAction(QAction("Icon Size",self)) #men.addAction(self.iconSliderAction) self.action_Options = QAction(Icons.emblem_system, 'Options', self) self.action_Options.setMenu(men) self.addAction(self.action_Options) ''' Mode Menu ''' def initModeMenu(self): self.modeGroup = QActionGroup(self) self.modeGroup.setExclusive(True) self.modeGroup.selected.connect(self.parent.setMode) self.action_Squirrel = QAction(Icons.nut, 'Squ', self.modeGroup) self.action_Squirrel.setCheckable(True) self.action_Emo = QAction(Icons.emo, 'Emo', self.modeGroup) self.action_Emo.setCheckable(True) self.action_And = QAction(Icons.android, 'Android', self.modeGroup) self.action_And.setCheckable(True) self.action_Ios = QAction(Icons.ios, 'ios', self.modeGroup) self.action_Ios.setCheckable(True) self.modeGroup.addAction(self.action_Squirrel) self.modeGroup.addAction(self.action_Emo) self.modeGroup.addAction(self.action_And) self.modeGroup.addAction(self.action_Ios) self.addActions(self.modeGroup.actions()) if(config.mode() == 0): self.action_Squirrel.setChecked(True) self.action_Build.setEnabled(False) self.action_Run.setEnabled(False) elif(config.mode() == 1): self.action_Emo.setChecked(True) self.action_Build.setEnabled(True) self.action_Run.setEnabled(True) elif(config.mode() == 2): self.action_And.setChecked(True) self.action_Build.setEnabled(True) self.action_Run.setEnabled(True) elif(config.mode() == 3): self.action_Ios.setChecked(True) self.action_Build.setEnabled(False) self.action_Run.setEnabled(False) ''' Style Menu ''' def initStyleMenu(self): editStyle = config.readStyle() self.action_Style = QAction(Icons.style, 'Style', self) men = QMenu(self) men1 = QMenu() self.base = StyleWidget(self,"base",editStyle["base"]) self.back = StyleWidget(self,"back",editStyle["back"]) self.caret = StyleWidget(self,"caret",editStyle["caret"]) self.margin = StyleWidget(self,"margin",editStyle["margin"]) self.marker = StyleWidget(self,"marker",editStyle["marker"]) self.comment = StyleWidget(self,"comment",editStyle["comment"]) self.number = StyleWidget(self,"number",editStyle["number"]) self.keyword = StyleWidget(self,"keyword",editStyle["keyword"]) self.string = StyleWidget(self,"string",editStyle["string"]) self.operator = StyleWidget(self,"operator",editStyle["operator"]) self.connect(self.base, SIGNAL("colorChange"),self.colorChange) self.connect(self.back, SIGNAL("colorChange"),self.colorChange) self.connect(self.caret, SIGNAL("colorChange"),self.colorChange) self.connect(self.margin, SIGNAL("colorChange"),self.colorChange) self.connect(self.marker, SIGNAL("colorChange"),self.colorChange) self.connect(self.comment, SIGNAL("colorChange"),self.colorChange) self.connect(self.number, SIGNAL("colorChange"),self.colorChange) self.connect(self.keyword, SIGNAL("colorChange"),self.colorChange) self.connect(self.string, SIGNAL("colorChange"),self.colorChange) self.connect(self.operator, SIGNAL("colorChange"),self.colorChange) self.baseMenu = QWidgetAction(men) self.baseMenu.setDefaultWidget(self.base) self.backMenu = QWidgetAction(men) self.backMenu.setDefaultWidget(self.back) self.caretMenu = QWidgetAction(men) self.caretMenu.setDefaultWidget(self.caret) self.marginMenu = QWidgetAction(men) self.marginMenu.setDefaultWidget(self.margin) self.markerMenu = QWidgetAction(men) self.markerMenu.setDefaultWidget(self.marker) self.commentMenu = QWidgetAction(men) self.commentMenu.setDefaultWidget(self.comment) self.numberMenu = QWidgetAction(men) self.numberMenu.setDefaultWidget(self.number) self.keywordMenu = QWidgetAction(men) self.keywordMenu.setDefaultWidget(self.keyword) self.stringMenu = QWidgetAction(men) self.stringMenu.setDefaultWidget(self.string) self.operatorMenu = QWidgetAction(men) self.operatorMenu.setDefaultWidget(self.operator) self.styleGroup = QActionGroup(self) self.styleGroup.setExclusive(True) self.styleGroup.selected.connect(self.setColors) self.style1 = QAction("All Hallow's Eve",self.styleGroup) self.style1.setCheckable(True) self.style2 = QAction("Amy",self.styleGroup) self.style2.setCheckable(True) self.style3 = QAction("Aptana Studio",self.styleGroup) self.style3.setCheckable(True) self.style4 = QAction("Bespin",self.styleGroup) self.style4.setCheckable(True) self.style5 = QAction("Blackboard",self.styleGroup) self.style5.setCheckable(True) self.style6 = QAction("Choco",self.styleGroup) self.style6.setCheckable(True) self.style7 = QAction("Cobalt",self.styleGroup) self.style7.setCheckable(True) self.style8 = QAction("Dawn",self.styleGroup) self.style8.setCheckable(True) self.style9 = QAction("Eclipse",self.styleGroup) self.style9.setCheckable(True) self.styleGroup.addAction(self.style1) self.styleGroup.addAction(self.style2) self.styleGroup.addAction(self.style3) self.styleGroup.addAction(self.style4) self.styleGroup.addAction(self.style5) self.styleGroup.addAction(self.style6) self.styleGroup.addAction(self.style7) self.styleGroup.addAction(self.style8) self.styleGroup.addAction(self.style9) men1.addAction(self.baseMenu) men1.addAction(self.backMenu) men1.addAction(self.caretMenu) men1.addAction(self.marginMenu) men1.addAction(self.markerMenu) men1.addAction(self.commentMenu) men1.addAction(self.numberMenu) men1.addAction(self.keywordMenu) men1.addAction(self.stringMenu) men1.addAction(self.operatorMenu) men1.addSeparator() men2 = QMenu(self) men2.setTitle("Styles") men2.addActions(self.styleGroup.actions()) men1.addMenu(men2) self.action_Style.setMenu(men1) self.addAction(self.action_Style) ''' Lexer Menu''' def make_action_lex(self, text): action = QAction(text, self.lexGroup) action.setCheckable(True) return action def initLexerMenu(self): self.action_Lexer = QAction(Icons.file_obj, 'Lexer', self) men = QMenu() self.lexGroup = QActionGroup(self) self.lexGroup.setExclusive(True) self.lexGroup.selected.connect(self.parent.setLexer) #langs = [i for i in dir(Qsci) if i.startswith('QsciLexer')] langs = ['Bash', 'Batch', 'CMake', 'CPP', 'CSS', 'C#','HTML','Java', 'JavaScript', 'Lua', 'Makefile','Python', 'SQL', 'XML', 'YAML'] for l in langs: act = self.make_action_lex(l) self.lexGroup.addAction(act) if(langs.index(l) == 8): #For javascript act.setChecked(True) #print l[9:] # we don't need to print "QsciLexer" before each name men.addActions(self.lexGroup.actions()) self.action_Lexer.setMenu(men) self.addAction(self.action_Lexer) ''' Api Menu ''' def make_action_api(self, text): action = QAction(text, self.apiGroup) action.setCheckable(True) return action def initApiMenu(self): self.action_Api = QAction(Icons.lib, 'Api', self) men = QMenu() self.apiGroup = QActionGroup(self) self.apiGroup.setExclusive(True) self.apiGroup.selected.connect(self.parent.setApi) list = oslistdir(apiDir) apis = [] if(list != None): for i in list: if i.endswith("api"): apis.append(i.replace(".api", "")) if(apis != None): for i in apis: act = self.make_action_api(i) self.apiGroup.addAction(act) if(i == "emo"): #For emo act.setChecked(True) men.addActions(self.apiGroup.actions()) self.action_Api.setMenu(men) self.addAction(self.action_Api)
class MusicView(preferences.Group): def __init__(self, page): super(MusicView, self).__init__(page) layout = QGridLayout() self.setLayout(layout) self.newerFilesOnly = QCheckBox(toggled=self.changed) layout.addWidget(self.newerFilesOnly, 0, 0, 1, 3) self.magnifierSizeLabel = QLabel() self.magnifierSizeSlider = QSlider(Qt.Horizontal, valueChanged=self.changed) self.magnifierSizeSlider.setSingleStep(50) self.magnifierSizeSlider.setRange( *popplerview.MagnifierSettings.sizeRange) self.magnifierSizeSpinBox = QSpinBox() self.magnifierSizeSpinBox.setRange( *popplerview.MagnifierSettings.sizeRange) self.magnifierSizeSpinBox.valueChanged.connect( self.magnifierSizeSlider.setValue) self.magnifierSizeSlider.valueChanged.connect( self.magnifierSizeSpinBox.setValue) layout.addWidget(self.magnifierSizeLabel, 1, 0) layout.addWidget(self.magnifierSizeSlider, 1, 1) layout.addWidget(self.magnifierSizeSpinBox, 1, 2) self.magnifierScaleLabel = QLabel() self.magnifierScaleSlider = QSlider(Qt.Horizontal, valueChanged=self.changed) self.magnifierScaleSlider.setSingleStep(50) self.magnifierScaleSlider.setRange( *popplerview.MagnifierSettings.scaleRange) self.magnifierScaleSpinBox = QSpinBox() self.magnifierScaleSpinBox.setRange( *popplerview.MagnifierSettings.scaleRange) self.magnifierScaleSpinBox.valueChanged.connect( self.magnifierScaleSlider.setValue) self.magnifierScaleSlider.valueChanged.connect( self.magnifierScaleSpinBox.setValue) layout.addWidget(self.magnifierScaleLabel, 2, 0) layout.addWidget(self.magnifierScaleSlider, 2, 1) layout.addWidget(self.magnifierScaleSpinBox, 2, 2) self.enableKineticScrolling = QCheckBox(toggled=self.changed) layout.addWidget(self.enableKineticScrolling) self.showScrollbars = QCheckBox(toggled=self.changed) layout.addWidget(self.showScrollbars) app.translateUI(self) def translateUI(self): self.setTitle(_("Music View")) self.newerFilesOnly.setText(_("Only load updated PDF documents")) self.newerFilesOnly.setToolTip( _("If checked, Frescobaldi will not open PDF documents that are not\n" "up-to-date (i.e. the source file has been modified later).")) self.magnifierSizeLabel.setText(_("Magnifier Size:")) self.magnifierSizeLabel.setToolTip( _("Size of the magnifier glass (Ctrl+Click in the Music View).")) # L10N: as in "400 pixels", appended after number in spinbox, note the leading space self.magnifierSizeSpinBox.setSuffix(_(" pixels")) self.magnifierScaleLabel.setText(_("Magnifier Scale:")) self.magnifierScaleLabel.setToolTip( _("Magnification of the magnifier.")) self.magnifierScaleSpinBox.setSuffix(_("percent unit sign", "%")) # L10N: "Kinetic Scrolling" is a checkbox label, as in "Enable Kinetic Scrolling" self.enableKineticScrolling.setText(_("Kinetic Scrolling")) self.showScrollbars.setText(_("Show Scrollbars")) def loadSettings(self): s = popplerview.MagnifierSettings.load() self.magnifierSizeSlider.setValue(s.size) self.magnifierScaleSlider.setValue(s.scale) s = QSettings() s.beginGroup("musicview") newerFilesOnly = s.value("newer_files_only", True, bool) self.newerFilesOnly.setChecked(newerFilesOnly) kineticScrollingActive = s.value("kinetic_scrolling", True, bool) self.enableKineticScrolling.setChecked(kineticScrollingActive) showScrollbars = s.value("show_scrollbars", True, bool) self.showScrollbars.setChecked(showScrollbars) def saveSettings(self): s = popplerview.MagnifierSettings() s.size = self.magnifierSizeSlider.value() s.scale = self.magnifierScaleSlider.value() s.save() s = QSettings() s.beginGroup("musicview") s.setValue("newer_files_only", self.newerFilesOnly.isChecked()) s.setValue("kinetic_scrolling", self.enableKineticScrolling.isChecked()) s.setValue("show_scrollbars", self.showScrollbars.isChecked())
class QTSeedEditor(QDialog): """ DICOM viewer. """ @staticmethod def get_line(mode='h'): line = QFrame() if mode == 'h': line.setFrameStyle(QFrame.HLine) elif mode == 'v': line.setFrameStyle(QFrame.VLine) line.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding) return line def initUI(self, shape, vscale, height=600, mode='seed'): """ Initialize UI. Parameters ---------- shape : (int, int, int) Shape of data matrix. vscale : (float, float, float) Voxel scaling. height : int Maximal slice height in pixels. mode : str Editor mode. """ # picture grid = height / float(shape[1] * vscale[1]) mgrid = (grid * vscale[0], grid * vscale[1]) self.slice_box = SliceBox(shape[:-1], mgrid, mode) self.slice_box.setScrollFun(self.scrollSlices) self.connect(self.slice_box, SIGNAL('focus_slider'), self.focusSliceSlider) # sliders self.allow_select_slice = True self.n_slices = shape[2] self.slider = QSlider(Qt.Vertical) self.slider.label = QLabel() self.slider.label.setText('Slice: %d / %d' % (self.actual_slice, self.n_slices)) self.slider.setRange(1, self.n_slices) self.slider.valueChanged.connect(self.sliderSelectSlice) self.slider.setValue(self.actual_slice) self.slider_cw = {} self.slider_cw['c'] = QSlider(Qt.Horizontal) self.slider_cw['c'].valueChanged.connect(self.changeC) self.slider_cw['c'].label = QLabel() self.slider_cw['w'] = QSlider(Qt.Horizontal) self.slider_cw['w'].valueChanged.connect(self.changeW) self.slider_cw['w'].label = QLabel() self.view_label = QLabel('View size: %d x %d' % self.img_aview.shape[:-1]) self.voxel_label = QLabel('Voxel size [mm]:\n %.2f x %.2f x %.2f'\ % tuple(self.voxel_size[np.array(self.act_transposition)])) combo_view_options = VIEW_TABLE.keys() combo_view = QComboBox(self) combo_view.activated[str].connect(self.setView) combo_view.addItems(combo_view_options) # buttons self.btn_quit = QPushButton("Return", self) self.btn_quit.clicked.connect(self.quit) combo_dmask = QComboBox(self) combo_dmask.activated.connect(self.changeMask) self.mask_points_tab, aux = self.init_draw_mask(DRAW_MASK, mgrid) for icon, label in aux: combo_dmask.addItem(icon, label) self.slice_box.setMaskPoints( self.mask_points_tab[combo_dmask.currentIndex()]) self.status_bar = QStatusBar() self.seeds_copy = None vopts = [] vmenu = [] appmenu = [] if mode == 'seed' and self.mode_fun is not None: btn_recalc = QPushButton("Recalculate", self) btn_recalc.clicked.connect(self.recalculate) self.btn_save = QPushButton("Save seeds", self) self.btn_save.clicked.connect(self.saveload_seeds) btn_s2b = QPushButton("Seg. to bckgr.", self) btn_s2b.clicked.connect(self.seg_to_background_seeds) btn_s2f = QPushButton("Seg. to forgr.", self) btn_s2f.clicked.connect(self.seg_to_foreground_seeds) appmenu.append( QLabel('<b>Segmentation mode</b><br><br><br>' + 'Select the region of interest<br>' + 'using the mouse buttons:<br><br>' + ' <i>left</i> - inner region<br>' + ' <i>right</i> - outer region<br><br>')) appmenu.append(btn_recalc) appmenu.append(self.btn_save) appmenu.append(btn_s2f) appmenu.append(btn_s2b) appmenu.append(QLabel()) self.volume_label = QLabel('Volume:\n unknown') appmenu.append(self.volume_label) # Set middle pencil as default (M. Jirik) combo_dmask.setCurrentIndex(1) self.slice_box.setMaskPoints( self.mask_points_tab[combo_dmask.currentIndex()]) # -----mjirik---end------ if mode == 'seed' or mode == 'crop'\ or mode == 'mask' or mode == 'draw': combo_seed_label_options = ['all', '1', '2', '3', '4'] combo_seed_label = QComboBox(self) combo_seed_label.activated[str].connect(self.changeFocusedLabel) combo_seed_label.addItems(combo_seed_label_options) self.changeFocusedLabel( combo_seed_label_options[combo_seed_label.currentIndex()]) # vopts.append(QLabel('Label to delete:')) # vopts.append(combo_seed_label) vmenu.append(QLabel('Label to delete:')) vmenu.append(combo_seed_label) btn_del = QPushButton("Del Slice Seeds", self) btn_del.clicked.connect(self.deleteSliceSeeds) vmenu.append(None) vmenu.append(btn_del) btn_del = QPushButton("Del All Seeds", self) btn_del.clicked.connect(self.deleteSeedsInAllImage) vmenu.append(None) vmenu.append(btn_del) combo_contour_options = ['fill', 'contours', 'off'] combo_contour = QComboBox(self) combo_contour.activated[str].connect(self.changeContourMode) combo_contour.addItems(combo_contour_options) self.changeContourMode( combo_contour_options[combo_contour.currentIndex()]) vopts.append(QLabel('Selection mode:')) vopts.append(combo_contour) if mode == 'mask': btn_recalc_mask = QPushButton("Recalculate mask", self) btn_recalc_mask.clicked.connect(self.updateMaskRegion_btn) btn_all = QPushButton("Select all", self) btn_all.clicked.connect(self.maskSelectAll) btn_reset = QPushButton("Reset selection", self) btn_reset.clicked.connect(self.resetSelection) btn_reset_seads = QPushButton("Reset seads", self) btn_reset_seads.clicked.connect(self.resetSeads) btn_add = QPushButton("Add selection", self) btn_add.clicked.connect(self.maskAddSelection) btn_rem = QPushButton("Remove selection", self) btn_rem.clicked.connect(self.maskRemoveSelection) btn_mask = QPushButton("Mask region", self) btn_mask.clicked.connect(self.maskRegion) appmenu.append( QLabel('<b>Mask mode</b><br><br><br>' + 'Select the region to mask<br>' + 'using the left mouse button<br><br>')) appmenu.append(self.get_line('h')) appmenu.append(btn_recalc_mask) appmenu.append(btn_all) appmenu.append(btn_reset) appmenu.append(btn_reset_seads) appmenu.append(self.get_line('h')) appmenu.append(btn_add) appmenu.append(btn_rem) appmenu.append(self.get_line('h')) appmenu.append(btn_mask) appmenu.append(self.get_line('h')) self.mask_qhull = None if mode == 'crop': btn_crop = QPushButton("Crop", self) btn_crop.clicked.connect(self.crop) appmenu.append( QLabel('<b>Crop mode</b><br><br><br>' + 'Select the crop region<br>' + 'using the left mouse button<br><br>')) appmenu.append(btn_crop) if mode == 'draw': appmenu.append( QLabel('<b>Manual segmentation<br> mode</b><br><br><br>' + 'Mark the region of interest<br>' + 'using the mouse buttons:<br><br>' + ' <i>left</i> - draw<br>' + ' <i>right</i> - erase<br>' + ' <i>middle</i> - vol. erase<br><br>')) btn_reset = QPushButton("Reset", self) btn_reset.clicked.connect(self.resetSliceDraw) vmenu.append(None) vmenu.append(btn_reset) combo_erase_options = ['inside', 'outside'] combo_erase = QComboBox(self) combo_erase.activated[str].connect(self.changeEraseMode) combo_erase.addItems(combo_erase_options) self.changeEraseMode( combo_erase_options[combo_erase.currentIndex()]) vopts.append(QLabel('Volume erase mode:')) vopts.append(combo_erase) hbox = QHBoxLayout() vbox = QVBoxLayout() vbox_left = QVBoxLayout() vbox_app = QVBoxLayout() hbox.addWidget(self.slice_box) hbox.addWidget(self.slider) vbox_left.addWidget(self.slider.label) vbox_left.addWidget(self.view_label) vbox_left.addWidget(self.voxel_label) vbox_left.addWidget(QLabel()) vbox_left.addWidget(QLabel('View plane:')) vbox_left.addWidget(combo_view) vbox_left.addWidget(self.get_line()) vbox_left.addWidget(self.slider_cw['c'].label) vbox_left.addWidget(self.slider_cw['c']) vbox_left.addWidget(self.slider_cw['w'].label) vbox_left.addWidget(self.slider_cw['w']) vbox_left.addWidget(self.get_line()) vbox_left.addWidget(QLabel('Drawing mask:')) vbox_left.addWidget(combo_dmask) for ii in vopts: vbox_left.addWidget(ii) for ii in vmenu: if ii is None: vbox_left.addStretch(1) else: vbox_left.addWidget(ii) for ii in appmenu: if ii is None: vbox_app.addStretch(1) else: vbox_app.addWidget(ii) vbox_app.addStretch(1) vbox_app.addWidget(self.btn_quit) hbox.addLayout(vbox_left) hbox.addWidget(self.get_line('v')) hbox.addLayout(vbox_app) vbox.addLayout(hbox) vbox.addWidget(self.status_bar) self.my_layout = vbox self.setLayout(vbox) self.setWindowTitle('Segmentation Editor') self.show() def __init__(self, img, viewPositions=None, seeds=None, contours=None, mode='seed', modeFun=None, voxelSize=[1, 1, 1], volume_unit='mm3'): """ Initiate Editor Parameters ---------- img : array DICOM data matrix. actualSlice : int Index of actual slice. seeds : array Seeds, user defined regions of interest. contours : array Computed segmentation. mode : str Editor modes: 'seed' - seed editor 'crop' - manual crop 'draw' - drawing 'mask' - mask region modeFun : fun Mode function invoked by user button. voxelSize : tuple of float voxel size [mm] volume_unit : allow select output volume in mililiters or mm3 [mm, ml] """ QDialog.__init__(self) self.BACKGROUND_NOMODEL_SEED_LABEL = 4 self.FOREGROUND_NOMODEL_SEED_LABEL = 3 self.mode = mode self.mode_fun = modeFun self.actual_view = 'axial' self.act_transposition = VIEW_TABLE[self.actual_view] self.img = img self.img_aview = self.img.transpose(self.act_transposition) self.volume_unit = volume_unit self.last_view_position = {} for jj, ii in enumerate(VIEW_TABLE.keys()): if viewPositions is None: viewpos = img.shape[VIEW_TABLE[ii][-1]] / 2 else: viewpos = viewPositions[jj] self.last_view_position[ii] =\ img.shape[VIEW_TABLE[ii][-1]] - viewpos - 1 self.actual_slice = self.last_view_position[self.actual_view] # set contours self.contours = contours if self.contours is None: self.contours_aview = None else: self.contours_aview = self.contours.transpose( self.act_transposition) # masked data - has information about which data were removed # 1 == enabled, 0 == deleted # How to return: # editorDialog.exec_() # masked_data = editorDialog.masked self.masked = np.ones(self.img.shape, np.int8) self.voxel_size = np.squeeze(np.asarray(voxelSize)) self.voxel_scale = self.voxel_size / float(np.min(self.voxel_size)) self.voxel_volume = np.prod(voxelSize) # set seeds if seeds is None: self.seeds = np.zeros(self.img.shape, np.int8) else: self.seeds = seeds self.seeds_aview = self.seeds.transpose(self.act_transposition) self.seeds_modified = False self.initUI(self.img_aview.shape, self.voxel_scale[np.array(self.act_transposition)], 600, mode) if mode == 'draw': self.seeds_orig = self.seeds.copy() self.slice_box.setEraseFun(self.eraseVolume) # set view window values C/W lb = np.min(img) self.img_min_val = lb ub = np.max(img) dul = np.double(ub) - np.double(lb) self.cw_range = {'c': [lb, ub], 'w': [1, dul]} self.slider_cw['c'].setRange(lb, ub) self.slider_cw['w'].setRange(1, dul) self.changeC(lb + dul / 2) self.changeW(dul) self.offset = np.zeros((3, ), dtype=np.int16) # set what labels will be deleted by 'delete seeds' button self.textFocusedLabel = "all" def showStatus(self, msg): self.status_bar.showMessage(QString(msg)) QApplication.processEvents() def init_draw_mask(self, draw_mask, grid): mask_points = [] mask_iconlabel = [] for mask, label in draw_mask: w, h = mask.shape xx, yy = mask.nonzero() mask_points.append((xx - w / 2, yy - h / 2)) img = QImage(w, h, QImage.Format_ARGB32) img.fill(qRgba(255, 255, 255, 0)) for ii in range(xx.shape[0]): img.setPixel(xx[ii], yy[ii], qRgba(0, 0, 0, 255)) img = img.scaled(QSize(w * grid[0], h * grid[1])) icon = QIcon(QPixmap.fromImage(img)) mask_iconlabel.append((icon, label)) return mask_points, mask_iconlabel def saveSliceSeeds(self): aux = self.slice_box.getSliceSeeds() if aux is not None: self.seeds_aview[..., self.actual_slice] = aux self.seeds_modified = True else: self.seeds_modified = False def updateMaskRegion_btn(self): self.saveSliceSeeds() self.updateMaskRegion() def updateMaskRegion(self): crp = self.getCropBounds(return_nzs=True) if crp is not None: off, cri, nzs = crp if nzs[0].shape[0] <= 5: self.showStatus("Not enough points (need >= 5)!") else: points = np.transpose(nzs) hull = Delaunay(points) X, Y, Z = np.mgrid[cri[0], cri[1], cri[2]] grid = np.vstack([X.ravel(), Y.ravel(), Z.ravel()]).T simplex = hull.find_simplex(grid) fill = grid[simplex >= 0, :] fill = (fill[:, 0], fill[:, 1], fill[:, 2]) if self.contours is None or self.contours_old is None: self.contours = np.zeros(self.img.shape, np.int8) self.contours_old = self.contours.copy() else: self.contours[self.contours != 2] = 0 self.contours[fill] = 1 self.contours_aview = self.contours.transpose( self.act_transposition) self.selectSlice(self.actual_slice) def maskRegion(self): self.masked[self.contours == 0] = 0 self.img[self.contours != 2] = self.img_min_val self.contours.fill(0) self.contours_old = self.contours.copy() self.seeds.fill(0) self.selectSlice(self.actual_slice) def maskAddSelection(self): self.updateMaskRegion() if self.contours is None: return self.contours[self.contours == 1] = 2 self.contours_old = self.contours.copy() self.seeds.fill(0) self.selectSlice(self.actual_slice) def maskRemoveSelection(self): self.updateMaskRegion() if self.contours is None: return self.contours[self.contours == 1] = 0 self.contours_old = self.contours.copy() self.seeds.fill(0) self.selectSlice(self.actual_slice) def maskSelectAll(self): self.updateMaskRegion() self.seeds[0][0][0] = 1 self.seeds[0][0][-1] = 1 self.seeds[0][-1][0] = 1 self.seeds[0][-1][-1] = 1 self.seeds[-1][0][0] = 1 self.seeds[-1][0][-1] = 1 self.seeds[-1][-1][0] = 1 self.seeds[-1][-1][-1] = 1 self.updateMaskRegion() self.selectSlice(self.actual_slice) def resetSelection(self): self.updateMaskRegion() if self.contours is None: return self.contours.fill(0) self.contours_old = self.contours.copy() self.seeds.fill(0) self.selectSlice(self.actual_slice) def resetSeads(self): self.seeds.fill(0) if self.contours is not None: self.contours = self.contours_old.copy() self.contours_aview = self.contours.transpose( self.act_transposition) self.updateMaskRegion() self.selectSlice(self.actual_slice) def updateCropBounds(self): crp = self.getCropBounds() if crp is not None: _, cri = crp self.contours = np.zeros(self.img.shape, np.int8) self.contours[cri].fill(1) self.contours_aview = self.contours.transpose( self.act_transposition) def focusSliceSlider(self): self.slider.setFocus(True) def sliderSelectSlice(self, value): self.selectSlice(self.n_slices - value) def scrollSlices(self, inc): if abs(inc) > 0: new = self.actual_slice + inc self.selectSlice(new) def selectSlice(self, value, force=False): if not (self.allow_select_slice): return if (value < 0) or (value >= self.n_slices): return if (value != self.actual_slice) or force: self.saveSliceSeeds() if self.seeds_modified: if self.mode == 'crop': self.updateCropBounds() elif self.mode == 'mask': self.updateMaskRegion() if self.contours is None: contours = None else: contours = self.contours_aview[..., value] slider_val = self.n_slices - value self.slider.setValue(slider_val) self.slider.label.setText('Slice: %d / %d' % (slider_val, self.n_slices)) self.slice_box.setSlice(self.img_aview[..., value], self.seeds_aview[..., value], contours) self.actual_slice = value def getSeeds(self): return self.seeds def getImg(self): return self.img def getOffset(self): return self.offset * self.voxel_size def getSeedsVal(self, label): return self.img[self.seeds == label] def getContours(self): return self.contours def setContours(self, contours): """ store segmentation :param contours: segmentation :return: Nothing """ """ :param contours: :return: """ self.contours = contours self.contours_aview = self.contours.transpose(self.act_transposition) self.selectSlice(self.actual_slice) def changeCW(self, value, key): rg = self.cw_range[key] if (value < rg[0]) or (value > rg[1]): return if (value != self.slice_box.getCW()[key]): self.slider_cw[key].setValue(value) self.slider_cw[key].label.setText('%s: %d' % (key.upper(), value)) self.slice_box.setCW(value, key) self.slice_box.updateSliceCW(self.img_aview[..., self.actual_slice]) def changeC(self, value): self.changeCW(value, 'c') def changeW(self, value): self.changeCW(value, 'w') def setView(self, value): self.last_view_position[self.actual_view] = self.actual_slice # save seeds self.saveSliceSeeds() if self.seeds_modified: if self.mode == 'crop': self.updateCropBounds() elif self.mode == 'mask': self.updateMaskRegion() key = str(value) self.actual_view = key self.actual_slice = self.last_view_position[key] self.act_transposition = VIEW_TABLE[key] self.img_aview = self.img.transpose(self.act_transposition) self.seeds_aview = self.seeds.transpose(self.act_transposition) if self.contours is not None: self.contours_aview = self.contours.transpose( self.act_transposition) contours = self.contours_aview[..., self.actual_slice] else: contours = None vscale = self.voxel_scale[np.array(self.act_transposition)] height = self.slice_box.height() grid = height / float(self.img_aview.shape[1] * vscale[1]) # width = (self.img_aview.shape[0] * vscale[0])[0] # if width > 800: # height = 400 # grid = height / float(self.img_aview.shape[1] * vscale[1]) mgrid = (grid * vscale[0], grid * vscale[1]) self.slice_box.resizeSlice(new_slice_size=self.img_aview.shape[:-1], new_grid=mgrid) self.slice_box.setSlice(self.img_aview[..., self.actual_slice], self.seeds_aview[..., self.actual_slice], contours) self.allow_select_slice = False self.n_slices = self.img_aview.shape[2] slider_val = self.n_slices - self.actual_slice self.slider.setRange(1, self.n_slices) self.slider.setValue(slider_val) self.allow_select_slice = True self.slider.label.setText('Slice: %d / %d' % (slider_val, self.n_slices)) self.view_label.setText('View size: %d x %d' % self.img_aview.shape[:-1]) self.adjustSize() self.adjustSize() def changeMask(self, val): self.slice_box.setMaskPoints(self.mask_points_tab[val]) def changeContourMode(self, val): self.slice_box.contour_mode = str(val) self.slice_box.updateSlice() def changeEraseMode(self, val): self.slice_box.erase_mode = str(val) def eraseVolume(self, pos, mode): self.showStatus("Processing...") xyz = np.array(pos + (self.actual_slice, )) p = np.zeros_like(xyz) p[np.array(self.act_transposition)] = xyz p = tuple(p) if self.seeds[p] > 0: if mode == 'inside': erase_reg(self.seeds, p, val=0) elif mode == 'outside': erase_reg(self.seeds, p, val=-1) idxs = np.where(self.seeds < 0) self.seeds.fill(0) self.seeds[idxs] = 1 if self.contours is None: contours = None else: contours = self.contours_aview[..., self.actual_slice] self.slice_box.setSlice(self.img_aview[..., self.actual_slice], self.seeds_aview[..., self.actual_slice], contours) self.showStatus("Done") def cropUpdate(self, img): for ii in VIEW_TABLE.keys(): self.last_view_position[ii] = 0 self.actual_slice = 0 self.img = img self.img_aview = self.img.transpose(self.act_transposition) self.contours = None self.contours_aview = None self.seeds = np.zeros(self.img.shape, np.int8) self.seeds_aview = self.seeds.transpose(self.act_transposition) self.seeds_modified = False vscale = self.voxel_scale[np.array(self.act_transposition)] height = self.slice_box.height() grid = height / float(self.img_aview.shape[1] * vscale[1]) mgrid = (grid * vscale[0], grid * vscale[1]) self.slice_box.resizeSlice(new_slice_size=self.img_aview.shape[:-1], new_grid=mgrid) self.slice_box.setSlice(self.img_aview[..., self.actual_slice], self.seeds_aview[..., self.actual_slice], None) self.allow_select_slice = False self.n_slices = self.img_aview.shape[2] self.slider.setValue(self.actual_slice + 1) self.slider.setRange(1, self.n_slices) self.allow_select_slice = True self.slider.label.setText('Slice: %d / %d' % (self.actual_slice + 1, self.n_slices)) self.view_label.setText('View size: %d x %d' % self.img_aview.shape[:-1]) def getCropBounds(self, return_nzs=False, flat=False): nzs = self.seeds.nonzero() cri = [] flag = True for ii in range(3): if nzs[ii].shape[0] == 0: flag = False break smin, smax = np.min(nzs[ii]), np.max(nzs[ii]) if not (flat): if smin == smax: flag = False break cri.append((smin, smax)) if flag: cri = np.array(cri) out = [] offset = [] for jj, ii in enumerate(cri): out.append(slice(ii[0], ii[1] + 1)) offset.append(ii[0]) if return_nzs: return np.array(offset), tuple(out), nzs else: return np.array(offset), tuple(out) else: return None def crop(self): self.showStatus("Processing...") crp = self.getCropBounds() if crp is not None: offset, cri = crp crop = self.img[cri] self.img = np.ascontiguousarray(crop) self.offset += offset self.showStatus('Done') else: self.showStatus('Region not selected!') self.cropUpdate(self.img) def seg_to_background_seeds(self, event): self.saveSliceSeeds() self.seeds[self.seeds < 3] = 0 from PyQt4.QtCore import pyqtRemoveInputHook # pyqtRemoveInputHook() # import ipdb; ipdb.set_trace() self.seeds[(self.contours == 1) & (self.seeds < 3)] = self.BACKGROUND_NOMODEL_SEED_LABEL self.contours[...] = 0 def seg_to_foreground_seeds(self, event): self.saveSliceSeeds() self.seeds[self.seeds < 3] = 0 # from PyQt4.QtCore import pyqtRemoveInputHook # pyqtRemoveInputHook() # import ipdb; ipdb.set_trace() self.seeds[(self.contours == 1) & (self.seeds < 3)] = self.FOREGROUND_NOMODEL_SEED_LABEL self.contours[...] = 0 def saveload_seeds(self, event): if self.seeds_copy is None: self.seeds_copy = self.seeds.copy() self.seeds[...] = 0 # print "save" # from PyQt4.QtCore import pyqtRemoveInputHook # pyqtRemoveInputHook() # import ipdb; ipdb.set_trace() self.btn_save.setText("Load seeds") else: # from PyQt4.QtCore import pyqtRemoveInputHook # pyqtRemoveInputHook() # import ipdb; ipdb.set_trace() self.seeds[self.seeds_copy > 0] = self.seeds_copy[ self.seeds_copy > 0] self.seeds_copy = None self.btn_save.setText("Save seeds") def recalculate(self, event): self.saveSliceSeeds() if np.abs(np.min(self.seeds) - np.max(self.seeds)) < 2: self.showStatus('Inner and outer regions not defined!') return self.showStatus("Processing...") self.mode_fun(self) self.selectSlice(self.actual_slice) self.updateVolume() self.showStatus("Done") def changeFocusedLabel(self, textlabel): self.textFocusedLabel = textlabel # logger # print " lakjlfkj ", textlabel logger.debug(self.textFocusedLabel) def deleteSliceSeeds(self, event): if self.textFocusedLabel == 'all': self.seeds_aview[..., self.actual_slice] = 0 else: # delete only seeds with specific label self.seeds_aview[self.seeds_aview[..., self.actual_slice] == int(self.textFocusedLabel), self.actual_slice] = 0 self.slice_box.setSlice(seeds=self.seeds_aview[..., self.actual_slice]) self.slice_box.updateSlice() def deleteSeedsInAllImage(self, event): if self.textFocusedLabel == 'all': self.seeds_aview[...] = 0 else: # delete only seeds with specific label self.seeds_aview[self.seeds_aview[...] == int( self.textFocusedLabel)] = 0 self.slice_box.setSlice(seeds=self.seeds_aview[..., self.actual_slice]) self.slice_box.updateSlice() def resetSliceDraw(self, event): seeds_orig_aview = self.seeds_orig.transpose(self.act_transposition) self.seeds_aview[..., self.actual_slice] = seeds_orig_aview[ ..., self.actual_slice] self.slice_box.setSlice(seeds=self.seeds_aview[..., self.actual_slice]) self.slice_box.updateSlice() def quit(self, event): self.close() def updateVolume(self): text = 'Volume:\n unknown' if self.voxel_volume is not None: if self.mode == 'draw': vd = self.seeds else: vd = self.contours if vd is not None: nzs = vd.nonzero() nn = nzs[0].shape[0] if self.volume_unit == 'ml': text = 'Volume [ml]:\n %.2f' %\ (nn * self.voxel_volume / 1000) else: text = 'Volume [mm3]:\n %.2e' % (nn * self.voxel_volume) self.volume_label.setText(text) def getROI(self): crp = self.getCropBounds() if crp is not None: _, cri = crp else: cri = [] for jj, ii in enumerate(self.img.shape): off = self.offset[jj] cri.append(slice(off, off + ii)) return cri
def metronome(): import os, sys, time from PyQt4.QtCore import SIGNAL from PyQt4.QtGui import QApplication, QPushButton, QSlider, QWidget from PyQt4.QtGui import QHBoxLayout, QLabel import synths START = False app = QApplication(sys.argv) if START: server = scsynth.server.start(verbose=True, spew=True) else: server = scsynth.server.connect(verbose=True, spew=True) engine = Engine(server, app, spew=True, quit_on_delete=START) server.sendMsg('/dumpOSC', 1) engine.tempoclock.set_tempo(120) SYNTHDEF_PATH = os.path.join(os.path.expanduser('~'), '.pksampler', 'synthdefs') SYNTHDEFS = ('JASStereoSamplePlayer.scsyndef', 'JASSine.scsyndef', ) for fname in SYNTHDEFS: engine.server.sendMsg('/d_load', os.path.join(SYNTHDEF_PATH, fname)) FPATH = '/Users/patrick/.pksampler/clicks/click_1.wav' click = synths.Synth() click.name = 'JASStereoSamplePlayer' click['bufnum'] = engine.loader.load(FPATH) click['rateSCale'] = 1.2 click['loopIt'] = 0 time.sleep(.1) pattern = Pattern(beats=1) pattern.add(Note(0, 64, 69)) pattern.synth = click stream = engine.insert(pattern) stream.loop(True) widget = QWidget() Layout = QHBoxLayout(widget) widget.resize(100, 250) widget.show() label = QLabel(widget) label.setText(str(engine.tempoclock.bpm)) Layout.addWidget(label) def set_tempo(value): engine.tempoclock.set_tempo(value) label.setText(str(value)) slider = QSlider(widget) slider.setRange(100, 180) slider.setValue(140) QObject.connect(slider, SIGNAL('valueChanged(int)'), set_tempo) Layout.addWidget(slider) button = QPushButton('quit', widget) QObject.connect(button, SIGNAL('clicked()'), app.quit) Layout.addWidget(button) engine.start() app.exec_() engine.stop()
class PlotLcm(QMainWindow): """ A class to plot an LCM type over time. """ def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.setWindowTitle('LCM Plotter') self.createMenu() self.createMainFrame() # Each channel has data and axis associated with it. # Dictionary key is the channel name and property. self.data = {} self.axes = {} self.lastPlot = None # Stop the program if CTRL-C is received self._stopEvent = threading.Event() signal.signal(signal.SIGINT, self.handleSigint) self._lcm = lcm.LCM() self.handlerThread = threading.Thread(target=self.pollLcm) self.handlerThread.setDaemon(True) self.handlerThread.start() self.connect(self, SIGNAL('redraw()'), self.on_draw) # Create redraw signal self.drawingThread = threading.Thread(target=self.drawLoop) self.drawingThread.setDaemon(True) self.drawingThread.start() def _cleanup(self): self._stopEvent.set() self.handlerThread.join() self.drawingThread.join() def handleSigint(self, *args): self._cleanup() QApplication.quit() def pollLcm(self): while not self._stopEvent.isSet(): rc = select.select([self._lcm.fileno()], [], [self._lcm.fileno()], 0.05) if len(rc[0]) > 0 or len(rc[2]) > 0: self._lcm.handle() def drawLoop(self): while not self._stopEvent.isSet(): self.emit(SIGNAL("redraw()")) time.sleep(0.5) def handleMessage(self, channel, msg): for (lcmChannel, lcmType, lcmProperty) in self.data.keys(): if lcmChannel == channel: data = eval(lcmType + ".decode(msg)." + lcmProperty) self.data[(lcmChannel, lcmType, lcmProperty)].append(data) def save_plot(self): file_choices = "PNG (*.png)|*.png" path = unicode(QFileDialog.getSaveFileName(self, 'Save file', '', file_choices)) if path: self.canvas.print_figure(path, dpi=self.dpi) self.statusBar().showMessage('Saved to %s' % path, 2000) def on_about(self): msg = """ Plot an LCM message """ QMessageBox.about(self, "About the demo", msg.strip()) def on_draw(self): """ Redraws the figure """ for (channel, lcmType, lcmProperty) in self.axes.keys(): axis = self.axes[(channel, lcmType, lcmProperty)] axis.clear() axis.grid(self.gridCheckBox.isChecked()) axis.plot(self.data[(channel, lcmType, lcmProperty)]) axis.set_title(channel + ": " + lcmProperty) self.canvas.draw() def addPlot(self): channel = str(self.channelTextbox.text()).strip() lcmType = str(self.typeTextbox.text()).strip() lcmProperty = str(self.propertyTextbox.text()).strip() if not self.checkInputs(channel, lcmType, lcmProperty): return self.data[(channel, lcmType, lcmProperty)] = [] n = len(self.data) i = 0 self.fig.clear() # Clear the old plot first for key in self.data.keys(): i = i + 1 self.axes[key] = self.fig.add_subplot(n, 1, i) self.lastPlot = (channel, lcmType, lcmProperty) self._lcm.subscribe(channel, self.handleMessage) def clearPlots(self): for key in self.data.keys(): self.data[key] = [] def checkInputs(self, channel, lcmType, lcmProperty): # Error checking cause nobody is perfect... if channel == "": print "Warning: No channel given" return False try: __import__("marof_lcm." + lcmType) except ImportError: print "Warning: The LCM type is not in scope" return False else: try: eval("getattr(" + lcmType + ", lcmProperty)") except Exception: print "Warning: The LCM property for this type does not exist" return False # Clear the data and don't create a new axis if there is already data for this if self.data.has_key((channel, lcmType, lcmProperty)): print "This data already exists:", channel self.data[(channel, lcmType, lcmProperty)] = [] return False return True def createMainFrame(self): self.mainFrame = QWidget() self.dpi = 72 self.fig = Figure((5.0, 2.5), dpi=self.dpi, tight_layout=True) self.canvas = FigureCanvasQTAgg(self.fig) self.canvas.setParent(self.mainFrame) self.canvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.mpl_toolbar = NavigationToolbar2QTAgg(self.canvas, self.mainFrame) # Other GUI controls # self.channelTextbox = QLineEdit() self.channelTextbox.setMinimumWidth(100) self.typeTextbox = QLineEdit() self.typeTextbox.setMinimumWidth(100) self.propertyTextbox = QLineEdit() self.propertyTextbox.setMinimumWidth(100) #self.connect(self.textbox, SIGNAL('editingFinished ()'), self.on_draw) self.addPlotButton = QPushButton("Add Plot") self.connect(self.addPlotButton, SIGNAL('clicked()'), self.addPlot) self.mergePlotButton = QPushButton("Reset Data") self.connect(self.mergePlotButton, SIGNAL('clicked()'), self.clearPlots) self.gridCheckBox = QCheckBox("Show Grid") self.gridCheckBox.setChecked(False) self.connect(self.gridCheckBox, SIGNAL('stateChanged(int)'), self.on_draw) slider_label = QLabel('Bar width (%):') self.slider = QSlider(Qt.Horizontal) self.slider.setRange(1, 100) self.slider.setValue(20) self.slider.setTracking(True) self.slider.setTickPosition(QSlider.TicksBothSides) self.connect(self.slider, SIGNAL('valueChanged(int)'), self.on_draw) # # Layout with box sizers # hbox = QHBoxLayout() for w in [self.channelTextbox, self.typeTextbox, self.propertyTextbox, self.addPlotButton, self.mergePlotButton, self.gridCheckBox, slider_label, self.slider]: hbox.addWidget(w) hbox.setAlignment(w, Qt.AlignVCenter) vbox = QVBoxLayout() vbox.addWidget(self.canvas) vbox.addWidget(self.mpl_toolbar) vbox.addLayout(hbox) self.mainFrame.setLayout(vbox) self.setCentralWidget(self.mainFrame) def createMenu(self): # File menu fileMenu = self.menuBar().addMenu("File") saveMenuItem = self.create_action("&Save plot", shortcut="Ctrl+S", slot=self.save_plot, tip="Save the plot") quitAction = self.create_action("&Quit", slot=self.close, shortcut="Ctrl+Q", tip="Close the application") self.add_actions(fileMenu, (saveMenuItem, None, quitAction)) # Help menu helpMenu = self.menuBar().addMenu("Help") aboutAction = self.create_action("&About", shortcut='F1', slot=self.on_about, tip='About the demo') self.add_actions(helpMenu, (aboutAction,)) def add_actions(self, target, actions): for action in actions: if action is None: target.addSeparator() else: target.addAction(action) def create_action( self, text, slot=None, shortcut=None, icon=None, tip=None, checkable=False, signal="triggered()"): action = QAction(text, self) if icon is not None: action.setIcon(QIcon(":/%s.png" % icon)) if shortcut is not None: action.setShortcut(shortcut) if tip is not None: action.setToolTip(tip) action.setStatusTip(tip) if slot is not None: self.connect(action, SIGNAL(signal), slot) if checkable: action.setCheckable(True) return action def closeEvent(self, event): self._cleanup() # stop the drawing thread before exiting event.accept()
class QTSeedEditor(QDialog): """ DICOM viewer. """ @staticmethod def get_line(mode='h'): line = QFrame() if mode == 'h': line.setFrameStyle(QFrame.HLine) elif mode == 'v': line.setFrameStyle(QFrame.VLine) line.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding) return line def initUI(self, shape, vscale, height=600, mode='seed'): """ Initialize UI. Parameters ---------- shape : (int, int, int) Shape of data matrix. vscale : (float, float, float) Voxel scaling. height : int Maximal slice height in pixels. mode : str Editor mode. """ self.slab = {} # picture grid = height / float(shape[1] * vscale[1]) mgrid = (grid * vscale[0], grid * vscale[1]) self.slice_box = SliceBox(shape[:-1], mgrid, mode) self.slice_box.setScrollFun(self.scrollSlices) self.connect(self.slice_box, SIGNAL('focus_slider'), self.focusSliceSlider) # sliders self.allow_select_slice = True self.n_slices = shape[2] self.slider = QSlider(Qt.Vertical) self.slider.valueChanged.connect(self.sliderSelectSlice) self.slider.label = QLabel() self.slider.setRange(1, self.n_slices) self.slider_cw = {} self.slider_cw['c'] = QSlider(Qt.Horizontal) self.slider_cw['c'].valueChanged.connect(self.changeC) self.slider_cw['c'].label = QLabel() self.slider_cw['w'] = QSlider(Qt.Horizontal) self.slider_cw['w'].valueChanged.connect(self.changeW) self.slider_cw['w'].label = QLabel() self.view_label = QLabel('View size: %d x %d' % self.img_aview.shape[:-1]) self.voxel_label = QLabel('Voxel size [mm]:\n %.2f x %.2f x %.2f'\ % tuple(self.voxel_size[np.array(self.act_transposition)])) # combo_view_options = VIEW_TABLE.keys() # combo_view = QComboBox(self) # combo_view.activated[str].connect(self.setView) # combo_view.addItems(combo_view_options) #radio button group for choosing seed class ------------------------ self.current_class = 1 self.slice_box.seed_mark = self.current_class number_group = QGroupBox(QString('Class markers')) vbox_NG = QVBoxLayout() r1 = QRadioButton('class 1') r1.setStyleSheet('QRadioButton {color: red}') r1.setChecked(True) r2 = QRadioButton('class 2') r2.setStyleSheet('QRadioButton {color: green}') r3 = QRadioButton('class 3') r3.setStyleSheet('QRadioButton {color: blue}') r4 = QRadioButton('class 4') r4.setStyleSheet('QRadioButton {color: cyan}') r5 = QRadioButton('class 5') r5.setStyleSheet('QRadioButton {color: magenta}') vbox_NG.addWidget(r1) vbox_NG.addWidget(r2) vbox_NG.addWidget(r3) vbox_NG.addWidget(r4) vbox_NG.addWidget(r5) number_group.setLayout(vbox_NG) self.button_group = QButtonGroup() self.button_group.addButton(r1, 1) self.button_group.addButton(r2, 2) self.button_group.addButton(r3, 3) self.button_group.addButton(r4, 4) self.button_group.addButton(r5, 5) self.connect(self.button_group, SIGNAL("buttonClicked(int)"), self.change_seed_class) #------------------------------------------------------------------- # buttons # btn_save = QPushButton('Save', self) # btn_save.clicked.connect(self.save) btn_quit = QPushButton("Quit", self) btn_quit.clicked.connect(self.quit) # btn_crop = QPushButton('Crop', self) # btn_crop.clicked.connect(self.crop) combo_dmask = QComboBox(self) combo_dmask.activated.connect(self.changeMask) self.mask_points_tab, aux = self.init_draw_mask(DRAW_MASK, mgrid) for icon, label in aux: combo_dmask.addItem(icon, label) self.slice_box.setMaskPoints( self.mask_points_tab[combo_dmask.currentIndex()]) self.status_bar = QStatusBar() vopts = [] vmenu = [] appmenu = [] # btn_recalc = QPushButton("Recalculate", self) # btn_recalc.clicked.connect(self.recalculate) # appmenu.append(QLabel('<b>Segmentation mode</b><br><br><br>' + # 'Select the region of interest<br>' + # 'using the mouse buttons.<br><br>')) # appmenu.append(btn_recalc) # appmenu.append(QLabel()) # self.volume_label = QLabel('Volume [mm3]:\n unknown') # appmenu.append(self.volume_label) # btn_crop = QPushButton("Crop", self) # btn_crop.clicked.connect(self.crop) # appmenu.append(btn_crop) btn_save = QPushButton("Save Seeds", self) btn_save.clicked.connect(self.saveSeeds) appmenu.append(btn_save) btn_del = QPushButton("Delete Seeds", self) btn_del.clicked.connect(self.deleteSliceSeeds) appmenu.append(btn_del) # combo_contour_options = ['fill', 'contours', 'off'] # combo_contour = QComboBox(self) # combo_contour.activated[str].connect(self.changeContourMode) # combo_contour.addItems(combo_contour_options) # self.changeContourMode(combo_contour_options[combo_contour.currentIndex()]) # vopts.append(QLabel('Selection mode:')) # vopts.append(combo_contour) # btn_reset = QPushButton("Reset Seeds", self) # btn_reset.clicked.connect(self.resetSliceDraw) # # appmenu.append(None) # appmenu.append(btn_reset) hbox = QHBoxLayout() vbox = QVBoxLayout() vbox_left = QVBoxLayout() vbox_app = QVBoxLayout() hbox.addWidget(self.slice_box) hbox.addWidget(self.slider) vbox_left.addWidget(self.slider.label) vbox_left.addWidget(self.view_label) vbox_left.addWidget(self.voxel_label) # vbox_left.addWidget(QLabel()) # vbox_left.addWidget(QLabel('View plane:')) # vbox_left.addWidget(combo_view) vbox_left.addWidget(self.get_line()) vbox_left.addWidget(self.slider_cw['c'].label) vbox_left.addWidget(self.slider_cw['c']) vbox_left.addWidget(self.slider_cw['w'].label) vbox_left.addWidget(self.slider_cw['w']) vbox_left.addWidget(self.get_line()) vbox_left.addWidget(QLabel('Drawing mask:')) vbox_left.addWidget(combo_dmask) for ii in vopts: vbox_left.addWidget(ii) for ii in vmenu: if ii is None: vbox_left.addStretch(1) else: vbox_left.addWidget(ii) for ii in appmenu: if ii is None: vbox_app.addStretch(1) else: vbox_app.addWidget(ii) vbox_left.addWidget(self.get_line()) vbox_left.addWidget(number_group) # vbox_app.addWidget(btn_crop) vbox_app.addStretch(1) # vbox_app.addWidget(btn_save) vbox_app.addWidget(btn_quit) hbox.addLayout(vbox_left) hbox.addWidget(self.get_line('v')) hbox.addLayout(vbox_app) vbox.addLayout(hbox) vbox.addWidget(self.status_bar) self.setLayout(vbox) self.setWindowTitle('Seed Editor') self.show() def __init__(self, img, seeds_fname='seeds.npy', actualSlice=0, seeds=None, contours=None, mode='seed', modeFun=None, voxelSize=[1, 1, 1]): """ Initiate Editor Parameters ---------- img : array DICOM data matrix. actualSlice : int Index of actual slice. seeds : array Seeds, user defined regions of interest. contours : array Computed segmentation. mode : str Editor modes: 'seed' - seed editor 'crop' - manual crop 'draw' - drawing modeFun : fun Mode function invoked by user button. voxelSize : tuple of float voxel size [mm] """ QDialog.__init__(self) self.mode = mode self.mode_fun = modeFun self.seeds_fname = seeds_fname # self.datapath = datapath self.actual_view = 'axial' self.act_transposition = VIEW_TABLE[self.actual_view] self.last_view_position = {} for ii in VIEW_TABLE.iterkeys(): self.last_view_position[ii] = img.shape[VIEW_TABLE[ii][-1]] - 1 self.img = img self.img_aview = self.img.transpose(self.act_transposition) self.actual_slice = self.img_aview.shape[-1] - actualSlice - 1 self.last_view_position[self.actual_view] = self.actual_slice # set contours self.contours = contours if self.contours is None: self.contours_aview = None else: self.contours_aview = self.contours.transpose( self.act_transposition) self.voxel_size = np.array(voxelSize) self.voxel_scale = self.voxel_size / float(np.min(self.voxel_size)) self.voxel_volume = np.prod(voxelSize) # set seeds if seeds is None: self.seeds = np.zeros(self.img.shape, np.int8) else: self.seeds = seeds self.seeds_aview = self.seeds.transpose(self.act_transposition) self.seeds_modified = False self.initUI(self.img_aview.shape, self.voxel_scale[np.array(self.act_transposition)], 600, mode) if mode == 'draw': self.seeds_orig = self.seeds.copy() self.slice_box.setEraseFun(self.eraseVolume) # set view window values C/W lb = np.min(img) ub = np.max(img) dul = ub - lb self.cw_range = {'c': [lb, ub], 'w': [1, dul]} self.slider_cw['c'].setRange(lb, ub) self.slider_cw['w'].setRange(1, dul) self.changeC(lb + dul / 2) self.changeW(dul) self.offset = np.zeros((3, ), dtype=np.int16) def change_seed_class(self, id): self.current_class = id self.slice_box.seed_mark = self.current_class # print 'Current seed class changed to ', id, '.' def showStatus(self, msg): self.status_bar.showMessage(QString(msg)) QApplication.processEvents() def init_draw_mask(self, draw_mask, grid): mask_points = [] mask_iconlabel = [] for mask, label in draw_mask: w, h = mask.shape xx, yy = mask.nonzero() mask_points.append((xx - w / 2, yy - h / 2)) img = QImage(w, h, QImage.Format_ARGB32) img.fill(qRgba(255, 255, 255, 0)) for ii in range(xx.shape[0]): img.setPixel(xx[ii], yy[ii], qRgba(0, 0, 0, 255)) img = img.scaled(QSize(w * grid[0], h * grid[1])) icon = QIcon(QPixmap.fromImage(img)) mask_iconlabel.append((icon, label)) return mask_points, mask_iconlabel def saveSliceSeeds(self): aux = self.slice_box.getSliceSeeds() if aux is not None: self.seeds_aview[..., self.actual_slice] = aux self.seeds_modified = True else: self.seeds_modified = False def saveSeeds(self): print 'Saving seeds array ... ', # aux = np.swapaxes(np.swapaxes(self.seeds_aview, 1, 2), 0, 1) aux = np.swapaxes(self.seeds_aview, 0, 2) np.save(self.seeds_fname, aux) print 'done' def updateCropBounds(self): crp = self.getCropBounds() if crp is not None: _, cri = crp self.contours = np.zeros(self.img.shape, np.int8) self.contours[cri].fill(1) self.contours_aview = self.contours.transpose( self.act_transposition) def focusSliceSlider(self): self.slider.setFocus(True) def sliderSelectSlice(self, value): self.selectSlice(self.n_slices - value) def scrollSlices(self, inc): if abs(inc) > 0: new = self.actual_slice + inc self.selectSlice(new) def selectSlice(self, value, force=False): if not (self.allow_select_slice): return if (value < 0) or (value >= self.n_slices): return if (value != self.actual_slice) or force: self.saveSliceSeeds() if self.seeds_modified and (self.mode == 'crop'): self.updateCropBounds() if self.contours is None: contours = None else: contours = self.contours_aview[..., value] slider_val = self.n_slices - value self.slider.setValue(slider_val) self.slider.label.setText('Slice: %d / %d' % (slider_val, self.n_slices)) self.slice_box.setSlice(self.img_aview[..., value], self.seeds_aview[..., value], contours) self.actual_slice = value def getSeeds(self): return self.seeds def getImg(self): return self.img def getOffset(self): return self.offset * self.voxel_size def getSeedsVal(self, label): return self.img[self.seeds == label] def getContours(self): return self.contours def setContours(self, contours): self.contours = contours self.contours_aview = self.contours.transpose(self.act_transposition) self.selectSlice(self.actual_slice) def changeCW(self, value, key): rg = self.cw_range[key] if (value < rg[0]) or (value > rg[1]): return if (value != self.slice_box.getCW()[key]): self.slider_cw[key].setValue(value) self.slider_cw[key].label.setText('%s: %d' % (key.upper(), value)) self.slice_box.setCW(value, key) self.slice_box.updateSliceCW(self.img_aview[..., self.actual_slice]) def changeC(self, value): self.changeCW(value, 'c') def changeW(self, value): self.changeCW(value, 'w') def setView(self, value): self.last_view_position[self.actual_view] = self.actual_slice # save seeds self.saveSliceSeeds() if self.seeds_modified and (self.mode == 'crop'): self.updateCropBounds(self.seeds_aview[..., self.actual_slice]) key = str(value) self.actual_view = key self.actual_slice = self.last_view_position[key] self.act_transposition = VIEW_TABLE[key] self.img_aview = self.img.transpose(self.act_transposition) self.seeds_aview = self.seeds.transpose(self.act_transposition) if self.contours is not None: self.contours_aview = self.contours.transpose( self.act_transposition) contours = self.contours_aview[..., self.actual_slice] else: contours = None vscale = self.voxel_scale[np.array(self.act_transposition)] height = self.slice_box.height() grid = height / float(self.img_aview.shape[1] * vscale[1]) mgrid = (grid * vscale[0], grid * vscale[1]) self.slice_box.resizeSlice(new_slice_size=self.img_aview.shape[:-1], new_grid=mgrid) self.slice_box.setSlice(self.img_aview[..., self.actual_slice], self.seeds_aview[..., self.actual_slice], contours) self.allow_select_slice = False self.n_slices = self.img_aview.shape[2] slider_val = self.n_slices - self.actual_slice self.slider.setValue(slider_val) self.slider.setRange(1, self.n_slices) self.allow_select_slice = True self.slider.label.setText('Slice: %d / %d' % (slider_val, self.n_slices)) self.view_label.setText('View size: %d x %d' % self.img_aview.shape[:-1]) def changeMask(self, val): self.slice_box.setMaskPoints(self.mask_points_tab[val]) def changeContourMode(self, val): self.slice_box.contour_mode = str(val) self.slice_box.updateSlice() def changeEraseMode(self, val): self.slice_box.erase_mode = str(val) def eraseVolume(self, pos, mode): self.showStatus("Processing...") xyz = pos + (self.actual_slice, ) p = tuple(np.array(xyz)[np.array(self.act_transposition)]) if self.seeds[p] > 0: if mode == 'inside': erase_reg(self.seeds, p, val=0) elif mode == 'outside': erase_reg(self.seeds, p, val=-1) idxs = np.where(self.seeds < 0) self.seeds.fill(0) self.seeds[idxs] = 1 if self.contours is None: contours = None else: contours = self.contours_aview[..., self.actual_slice] self.slice_box.setSlice(self.img_aview[..., self.actual_slice], self.seeds_aview[..., self.actual_slice], contours) self.showStatus("Done") def cropUpdate(self, img): for ii in VIEW_TABLE.iterkeys(): self.last_view_position[ii] = 0 self.actual_slice = 0 self.img = img self.img_aview = self.img.transpose(self.act_transposition) self.contours = None self.contours_aview = None self.seeds = np.zeros(self.img.shape, np.int8) self.seeds_aview = self.seeds.transpose(self.act_transposition) self.seeds_modified = False vscale = self.voxel_scale[np.array(self.act_transposition)] height = self.slice_box.height() grid = height / float(self.img_aview.shape[1] * vscale[1]) mgrid = (grid * vscale[0], grid * vscale[1]) self.slice_box.resizeSlice(new_slice_size=self.img_aview.shape[:-1], new_grid=mgrid) self.slice_box.setSlice(self.img_aview[..., self.actual_slice], self.seeds_aview[..., self.actual_slice], None) self.allow_select_slice = False self.n_slices = self.img_aview.shape[2] self.slider.setValue(self.actual_slice + 1) self.slider.setRange(1, self.n_slices) self.allow_select_slice = True self.slider.label.setText('Slice: %d / %d' % (self.actual_slice + 1, self.n_slices)) self.view_label.setText('View size: %d x %d' % self.img_aview.shape[:-1]) def getCropBounds(self): nzs = self.seeds.nonzero() cri = [] flag = True for ii in range(3): if nzs[ii].shape[0] == 0: flag = False break smin, smax = np.min(nzs[ii]), np.max(nzs[ii]) if smin == smax: flag = False break cri.append((smin, smax)) if flag: cri = np.array(cri) out = [] offset = [] for jj, ii in enumerate(cri): out.append(slice(ii[0], ii[1] + 1)) offset.append(ii[0]) return np.array(offset), tuple(out) else: return None def crop(self): self.showStatus("Processing...") crp = self.getCropBounds() if crp is not None: offset, cri = crp crop = self.img[cri] self.img = np.ascontiguousarray(crop) self.offset += offset self.showStatus('Done') else: self.showStatus('Region not selected!') self.cropUpdate(self.img) def recalculate(self, event): self.saveSliceSeeds() if np.abs(np.min(self.seeds) - np.max(self.seeds)) < 2: self.showStatus('At least two regions must be marked!') return self.showStatus("Processing...") # idx = 3 # s = random_walker(self.img[idx,:,:], self.seeds[idx,:,:])#, mode='cg_mg') # plt.figure() # plt.imshow(mark_boundaries(self.img[idx,:,:], s)) # plt.show() # self.segmentation = np.zeros(self.img.shape) # self.segmentation[idx,:,:] = s self.segmentation = random_walker(self.img, self.seeds, mode='cg_mg') self.setContours(self.segmentation - 1) self.selectSlice(self.actual_slice) # self.updateVolume() self.showStatus("Done") def deleteSliceSeeds(self, event): self.seeds_aview[..., self.actual_slice] = 0 self.slice_box.setSlice(seeds=self.seeds_aview[..., self.actual_slice]) self.slice_box.updateSlice() def resetSliceDraw(self, event): seeds_orig_aview = self.seeds_orig.transpose(self.act_transposition) self.seeds_aview[..., self.actual_slice] = seeds_orig_aview[ ..., self.actual_slice] self.slice_box.setSlice(seeds=self.seeds_aview[..., self.actual_slice]) self.slice_box.updateSlice() def quit(self, event): self.close() # def save(self, event): # odp = os.path.expanduser("~/lisa_data") # if not op.exists(odp): # os.makedirs(odp) # # data = self.export() # # data['version'] = self.version # # data['experiment_caption'] = self.experiment_caption # # data['lisa_operator_identifier'] = self.lisa_operator_identifier # pth, filename = op.split(op.normpath(self.datapath)) # # filename += "-" + self.experiment_caption # filepath = 'org-' + filename + '.pklz' # filepath = op.join(odp, filepath) # filepath = misc.suggest_filename(filepath) # misc.obj_to_file(data, filepath, filetype='pklz') # # filepath = 'organ_last.pklz' # filepath = op.join(odp, filepath) # misc.obj_to_file(data, filepath, filetype='pklz') # def export(self): # slab = {} # slab['none'] = 0 # slab['liver'] = 1 # slab['lesions'] = 6 # slab.update(self.slab) # # data = {} # data['version'] = (1, 0, 1) # data['data3d'] = self.img # # data['crinfo'] = self.crinfo # data['segmentation'] = self.segmentation # data['slab'] = slab # # data['voxelsize_mm'] = self.voxelsize_mm # # data['orig_shape'] = self.orig_shape # # data['processing_time'] = self.processing_time # return data def updateVolume(self): text = 'Volume [mm3]:\n unknown' if self.voxel_volume is not None: if self.mode == 'draw': vd = self.seeds else: vd = self.contours if vd is not None: nzs = vd.nonzero() nn = nzs[0].shape[0] text = 'Volume [mm3]:\n %.2e' % (nn * self.voxel_volume) self.volume_label.setText(text) def getROI(self): crp = self.getCropBounds() if crp is not None: _, cri = crp else: cri = [] for jj, ii in enumerate(self.img.shape): off = self.offset[jj] cri.append(slice(off, off + ii)) return cri
class MotorizedLinearPoti(COMCUPluginBase): def __init__(self, *args): COMCUPluginBase.__init__(self, BrickletMotorizedLinearPoti, *args) self.mp = self.device self.cbe_position = CallbackEmulator(self.mp.get_position, self.cb_position, self.increase_error_count) self.current_position = None self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, 100) self.slider.setMinimumWidth(200) self.slider.setEnabled(False) plots = [('Potentiometer Position', Qt.red, lambda: self.current_position, str)] self.plot_widget = PlotWidget('Position', plots, extra_key_widgets=[self.slider], curve_motion_granularity=40, update_interval=0.025) self.motor_slider = QSlider(Qt.Horizontal) self.motor_slider.setRange(0, 100) self.motor_slider.valueChanged.connect(self.motor_slider_value_changed) self.motor_hold_position = QCheckBox("Hold Position") self.motor_drive_mode = QComboBox() self.motor_drive_mode.addItem('Fast') self.motor_drive_mode.addItem('Smooth') def get_motor_slider_value(): return self.motor_slider.value() self.motor_hold_position.stateChanged.connect(lambda x: self.motor_slider_value_changed(get_motor_slider_value())) self.motor_drive_mode.currentIndexChanged.connect(lambda x: self.motor_slider_value_changed(get_motor_slider_value())) self.motor_position_label = MotorPositionLabel('Motor Target Position:') hlayout = QHBoxLayout() hlayout.addWidget(self.motor_position_label) hlayout.addWidget(self.motor_slider) hlayout.addWidget(self.motor_drive_mode) hlayout.addWidget(self.motor_hold_position) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) layout = QVBoxLayout(self) layout.addWidget(self.plot_widget) layout.addWidget(line) layout.addLayout(hlayout) def start(self): async_call(self.mp.get_position, None, self.cb_position, self.increase_error_count) async_call(self.mp.get_motor_position, None, self.cb_motor_position, self.increase_error_count) self.cbe_position.set_period(25) self.plot_widget.stop = False def stop(self): self.cbe_position.set_period(0) self.plot_widget.stop = True def destroy(self): pass @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletMotorizedLinearPoti.DEVICE_IDENTIFIER def cb_position(self, position): self.current_position = position self.slider.setValue(position) def cb_motor_position(self, motor): self.motor_slider.blockSignals(True) self.motor_hold_position.blockSignals(True) self.motor_drive_mode.blockSignals(True) self.motor_hold_position.setChecked(motor.hold_position) self.motor_drive_mode.setCurrentIndex(motor.drive_mode) self.motor_position_label.setText(str(motor.position)) self.motor_slider.setValue(motor.position) self.motor_slider.blockSignals(False) self.motor_hold_position.blockSignals(False) self.motor_drive_mode.blockSignals(False) def motor_slider_value_changed(self, position): self.motor_position_label.setText(str(position)) self.mp.set_motor_position(self.motor_slider.value(), self.motor_drive_mode.currentIndex(), self.motor_hold_position.isChecked())
class Player(QWidget): def __init__(self,app): super(Player,self).__init__() self.mpd = app.mpd self.ih = app.imagehelper self.timer = None self.initGUI() self.initState() def initGUI(self): self.setWindowTitle(QApplication.applicationName()) self.fmt = QFontMetrics(QFont()) layout = QVBoxLayout() toplayout = QHBoxLayout() currentLayout = QGridLayout() currentLayout.setContentsMargins(0,20,0,20) currentLayout.setHorizontalSpacing(100) currentLayout.setVerticalSpacing(20) # current song information currentLayout.addWidget(QLabel("<b>Artist</b>"),1,0) self.artist = QLabel() currentLayout.addWidget(self.artist,1,1) currentLayout.addWidget(QLabel("<b>Title</b>"),2,0) self.title = QLabel() currentLayout.addWidget(self.title,2,1) currentLayout.addWidget(QLabel("<b>Albumartist</b>"),3,0) self.albumartist = QLabel() currentLayout.addWidget(self.albumartist,3,1) currentLayout.addWidget(QLabel("<b>Album</b>"),4,0) self.album = QLabel() currentLayout.addWidget(self.album,4,1) # playlist and song position self.playlistposition = QLabel() currentLayout.addWidget(self.playlistposition,5,0) poslayout = QHBoxLayout() poslayout.setSpacing(10) self.time = QLabel("00:00") poslayout.addWidget(self.time) self.position = QSlider(Qt.Horizontal) self.position.setTracking(False) self.position.setSingleStep(10) self.position.sliderReleased.connect( self.seek) self.position.sliderMoved.connect( lambda x: self.time.setText(self.mpd.timeString(x))) poslayout.addWidget(self.position) self.length = QLabel("00:00") poslayout.addWidget(self.length) currentLayout.addLayout(poslayout,5,1) toplayout.addLayout(currentLayout) layout.addLayout(toplayout) layout.addStretch(1) self.settingsWidget = QMenu() self.consumeBtn = self.settingsWidget.addAction("Consume") self.consumeBtn.setCheckable(True) self.consumeBtn.triggered.connect( lambda x: self.mpd.consume(int(x))) self.singleBtn = self.settingsWidget.addAction("Single") self.singleBtn.setCheckable(True) self.singleBtn.triggered.connect( lambda x: self.mpd.single(int(x))) toolLayout = QHBoxLayout() self.settingsBtn = QToolButton() self.settingsBtn.setFixedSize(64,64) self.settingsBtn.setIcon( self.ih.settingsButton) self.settingsBtn.clicked.connect(self.showAdditionalControls) toolLayout.addWidget(self.settingsBtn) toolWidget = QStackedWidget() transpWidget = QWidget() transpLayout = QHBoxLayout() self.prevBtn = self.createButton( self.ih.prevButton, self.ih.prevButtonPressed) self.prevBtn.clicked.connect( lambda x: self.mpd.previous()) transpLayout.addWidget(self.prevBtn) self.playBtn = self.createCheckButton( self.ih.playButton, self.ih.pauseButton) self.playBtn.clicked.connect( self.playPressed) transpLayout.addWidget(self.playBtn) self.stopBtn = self.createButton( self.ih.stopButton, self.ih.stopButtonPressed) self.stopBtn.clicked.connect( lambda x: self.mpd.stop()) transpLayout.addWidget(self.stopBtn) self.nextBtn = self.createButton( self.ih.nextButton, self.ih.nextButtonPressed) self.nextBtn.clicked.connect( lambda x: self.mpd.next()) transpLayout.addWidget(self.nextBtn) self.shuffleBtn = self.createCheckButton( self.ih.shuffleButton, self.ih.shuffleButtonPressed) self.shuffleBtn.toggled.connect( lambda x: self.mpd.random(1) if x else self.mpd.random(0)) transpLayout.addWidget(self.shuffleBtn) self.repeatBtn = self.createCheckButton( self.ih.repeatButton, self.ih.repeatButtonPressed) self.repeatBtn.toggled.connect( lambda x: self.mpd.repeat(1) if x else self.mpd.repeat(0)) transpLayout.addWidget(self.repeatBtn) transpLayout.addSpacing(64) transpWidget.setLayout(transpLayout) toolWidget.addWidget( transpWidget) self.volume = QSlider(Qt.Horizontal) self.volume.valueChanged.connect(self.mpd.setvol) toolWidget.addWidget(self.volume) toolLayout.addWidget(toolWidget) self.volumeBtn = QToolButton() self.volumeBtn.setFixedSize(64,64) self.volumeBtn.setCheckable(True) self.volumeBtn.setIcon( self.ih.volumeButton) self.volumeBtn.toggled.connect( lambda x: toolWidget.setCurrentIndex(x)) toolLayout.addWidget(self.volumeBtn) layout.addLayout(toolLayout) self.setLayout(layout) def showAdditionalControls(self): pos = self.settingsBtn.pos() pos.setY( pos.y()-self.settingsWidget.sizeHint().height()) self.settingsWidget.popup( self.mapToGlobal(pos)) def createCheckButton(self, offIcon, onIcon): i = QIcon() i.addPixmap( offIcon.pixmap(64), QIcon.Normal, QIcon.Off) i.addPixmap( onIcon.pixmap(64), QIcon.Normal, QIcon.On) b = QToolButton() b.setFixedSize(64,64) b.setCheckable(True) b.setIcon(i) b.setStyleSheet("* { background: transparent }") return b def createButton(self, normal, pressed): b = QToolButton() b.setFixedSize(64,64) b.setIcon(normal) b.setStyleSheet("* { background: transparent }") b.pressed.connect( lambda: b.setIcon(pressed)) b.released.connect( lambda: b.setIcon(normal)) return b def playPressed(self,state): if self.state == 'stop': self.mpd.play() else: self.mpd.pause(int(not state)) def initState(self): self.songid = -1 self.state = 'stop' self.artist.setText("Unknown Artist") self.title.setText("Unknown Title") self.albumartist.setText("Unknown Artist") self.album.setText("Unknown Album") self.position.setRange(0,0) self.position.setValue(0) self.position.setEnabled(False) self.length.setText("00:00") self.playlistposition.setText("0/0") self.setStopState() def setStopState(self): self.playBtn.setChecked(False) self.time.setText("00:00") self.position.setValue(0) self.volume.setEnabled(False) def updateStatus(self): status = self.mpd.status() self.repeatBtn.setChecked(int(status['repeat'])) self.shuffleBtn.setChecked(int(status['random'])) self.consumeBtn.setChecked(int(status['consume'])) self.singleBtn.setChecked(int(status['single'])) if not status.has_key('songid') and self.songid != -1: self.initState() return stateChanged = False state = status['state'] if state != self.state: stateChanged = True self.state = state volume = int(status['volume']) if self.state == 'play' or self.state == 'pause': self.playBtn.setChecked(True if self.state == 'play' else False) songid = int(status['songid']) if songid != self.songid: self.songid = songid self.updateCurrentSong() playlistlength = int(status['playlistlength']) song = int(status.get('song',-1)) self.playlistposition.setText("%d/%d" % (song+1,playlistlength)) playlistlength = int(status['playlistlength']) elapsed = float(status['elapsed']) if not self.position.isSliderDown(): timeString = self.mpd.timeString(round(elapsed)) self.time.setFixedSize( (len(timeString)+1)*self.fmt.averageCharWidth(), self.fmt.height()) self.time.setText(timeString) if self.position.maximum() > 0: self.position.setSliderPosition(round(elapsed)) if stateChanged: self.volume.setEnabled(True) if not self.volume.isSliderDown(): self.volume.setValue(volume) #nextsong = int(status['nextsong']) else: if self.songid == -1: return self.setStopState() def updateCurrentSong(self): currentsong = self.mpd.unifySongInfo(self.mpd.currentsong()) self.artist.setText( currentsong['artist']) self.title.setText( currentsong['title']) self.albumartist.setText( currentsong['albumartist']) self.album.setText( currentsong['album']) self.length.setText( currentsong['length']) self.position.setRange(0,currentsong['time']) self.position.setEnabled(True if self.position.maximum() > 0 else False) self.position.setValue(0) self.time.setText("00:00") self.volume.setEnabled(True) def seek(self): secs = self.position.sliderPosition() if self.songid == -1: return self.mpd.seekid(self.songid, secs) def hideEvent(self, ev): if self.timer: self.killTimer( self.timer) self.timer = None super(Player,self).hideEvent(ev) def showEvent(self,ev): if not self.timer: self.updateStatus() self.timer = self.startTimer(1000) super(Player,self).showEvent(ev) def timerEvent(self,ev): try: self.updateStatus() except ConnectionError, e: self.hide() QMaemo5InformationBox.information( self, "Connection Error: %s" % str(e), QMaemo5InformationBox.DefaultTimeout) except socket.error, e: QMaemo5InformationBox.information( self, "Connection Error: %s" % e[1], QMaemo5InformationBox.DefaultTimeout) self.hide()
class QtSlider(QtControl, ProxySlider): """ A Qt implementation of an Enaml ProxySlider. """ #: A reference to the widget created by the proxy. widget = Typed(QSlider) #: Cyclic notification guard flags. _guard = Int(0) #-------------------------------------------------------------------------- # Initialization API #-------------------------------------------------------------------------- def create_widget(self): """ Create the underlying QSlider widget. """ self.widget = QSlider(self.parent_widget()) def init_widget(self): """ Initialize the underlying widget. """ super(QtSlider, self).init_widget() d = self.declaration self.set_minimum(d.minimum) self.set_maximum(d.maximum) self.set_value(d.value) self.set_orientation(d.orientation) self.set_page_step(d.page_step) self.set_single_step(d.single_step) self.set_tick_interval(d.tick_interval) self.set_tick_position(d.tick_position) self.set_tracking(d.tracking) self.widget.valueChanged.connect(self.on_value_changed) #-------------------------------------------------------------------------- # Signal Handlers #-------------------------------------------------------------------------- def on_value_changed(self): """ Send the 'value_changed' action to the Enaml widget when the slider value has changed. """ if not self._guard & VALUE_FLAG: self._guard |= VALUE_FLAG try: self.declaration.value = self.widget.value() finally: self._guard &= ~VALUE_FLAG #-------------------------------------------------------------------------- # ProxySlider API #-------------------------------------------------------------------------- def set_maximum(self, maximum): """ Set the maximum value of the underlying widget. """ self.widget.setMaximum(maximum) def set_minimum(self, minimum): """ Set the minimum value of the underlying widget. """ self.widget.setMinimum(minimum) def set_value(self, value): """ Set the value of the underlying widget. """ if not self._guard & VALUE_FLAG: self._guard |= VALUE_FLAG try: self.widget.setValue(value) finally: self._guard &= ~VALUE_FLAG def set_page_step(self, page_step): """ Set the page step of the underlying widget. """ self.widget.setPageStep(page_step) def set_single_step(self, single_step): """ Set the single step of the underlying widget. """ self.widget.setSingleStep(single_step) def set_tick_interval(self, interval): """ Set the tick interval of the underlying widget. """ self.widget.setTickInterval(interval) def set_tick_position(self, tick_position): """ Set the tick position of the underlying widget. """ self.widget.setTickPosition(TICK_POSITION[tick_position]) def set_orientation(self, orientation): """ Set the orientation of the underlying widget. """ self.widget.setOrientation(ORIENTATION[orientation]) def set_tracking(self, tracking): """ Set the tracking of the underlying widget. """ self.widget.setTracking(tracking)
class GeneralSection(QWidget): """ Clase Configuracion Editor """ def __init__(self): super(GeneralSection, self).__init__() main_container = QVBoxLayout(self) # Tabs and indentation group_indentation = QGroupBox(self.tr("Indentación y Tabs:")) box = QGridLayout(group_indentation) box.setContentsMargins(20, 5, 20, 5) box.addWidget(QLabel(self.tr("Política:")), 0, 0) self.combo_tabs = QComboBox() self.combo_tabs.setFixedWidth(350) self.combo_tabs.addItems([ self.tr("Solo Espacios"), self.tr("Solo Tabulaciones"), ]) box.addWidget(self.combo_tabs, 0, 1) self.combo_tabs.setCurrentIndex( int(settings.get_setting('editor/usetabs'))) # Auto indent self.check_autoindent = QCheckBox(self.tr("Indentación Automática")) box.addWidget(self.check_autoindent, 1, 0) box.setAlignment(Qt.AlignLeft) self.check_autoindent.setChecked(settings.get_setting('editor/indent')) # Minimap group_minimap = QGroupBox(self.tr("Minimapa:")) box = QGridLayout(group_minimap) box.setContentsMargins(20, 5, 20, 5) self.check_minimap = QCheckBox( self.tr("Activar Minimapa (requiere reiniciar el Editor)")) self.check_minimap.setChecked(settings.get_setting('editor/minimap')) box.addWidget(self.check_minimap, 0, 0) #self.check_minimap_animation = QCheckBox(self.tr("Enable animation")) #self.check_minimap_animation.setChecked( #settings.get_setting('editor/minimap-animation')) #box.addWidget(self.check_minimap_animation, 1, 0) #box.addWidget(QLabel(self.tr("Size Area:")), 2, 0) #self.spin_area_minimap = QSpinBox() #self.spin_area_minimap.setFixedWidth(350) #box.addWidget(self.spin_area_minimap, 2, 1) box.setAlignment(Qt.AlignLeft) # Cursor group_caret = QGroupBox(self.tr("Cursor:")) box = QGridLayout(group_caret) box.setContentsMargins(20, 5, 20, 5) box.setAlignment(Qt.AlignLeft) # Type box.addWidget(QLabel(self.tr("Tipo:")), 0, 0) self.combo_caret = QComboBox() self.combo_caret.setFixedWidth(300) caret_types = [ self.tr('Invisible'), self.tr('Línea'), self.tr('Bloque') ] self.combo_caret.addItems(caret_types) index = settings.get_setting('editor/cursor') self.combo_caret.setCurrentIndex(index) box.addWidget(self.combo_caret, 0, 1) # Width box.addWidget(QLabel(self.tr("Ancho:")), 1, 0) self.spin_caret_width = QSpinBox() self.spin_caret_width.setFixedWidth(300) if index != 1: self.spin_caret_width.setEnabled(False) self.spin_caret_width.setRange(1, 3) self.spin_caret_width.setValue( settings.get_setting('editor/caret-width')) box.addWidget(self.spin_caret_width, 1, 1, Qt.AlignLeft) # Period box.addWidget(QLabel(self.tr("Período (ms):")), 2, 0) self.slider_caret_period = QSlider(Qt.Horizontal) self.slider_caret_period.setMaximum(500) self.slider_caret_period.setFixedWidth(300) box.addWidget(self.slider_caret_period, 2, 1, Qt.AlignLeft) lcd_caret = QLCDNumber() lcd_caret.setSegmentStyle(QLCDNumber.Flat) box.addWidget(lcd_caret, 2, 3) # Font group_typo = QGroupBox(self.tr("Fuente:")) box = QGridLayout(group_typo) box.setContentsMargins(20, 5, 20, 5) box.addWidget(QLabel(self.tr("Familia:")), 0, 0) self.combo_font = QFontComboBox() self.combo_font.setFixedWidth(350) box.addWidget(self.combo_font, 0, 1) self._load_font() box.addWidget(QLabel(self.tr("Tamaño:")), 1, 0) self.spin_size_font = QSpinBox() self.spin_size_font.setValue(settings.get_setting('editor/size-font')) self.spin_size_font.setFixedWidth(350) box.addWidget(self.spin_size_font, 1, 1) box.setAlignment(Qt.AlignLeft) # Scheme group_scheme = QGroupBox(self.tr("Tema:")) box = QVBoxLayout(group_scheme) box.setContentsMargins(20, 5, 20, 5) self.combo_scheme = QComboBox() self.combo_scheme.setFixedWidth(350) self.combo_scheme.addItems(['Dark Edis', 'White Edis']) scheme = settings.get_setting('editor/scheme') index = 0 if scheme != 'dark': index = 1 self.combo_scheme.setCurrentIndex(index) box.addWidget(self.combo_scheme) box.addWidget(QLabel(self.tr("Requiere reiniciar Edis"))) ## Agrupación main_container.addWidget(group_indentation) main_container.addWidget(group_minimap) main_container.addWidget(group_caret) main_container.addWidget(group_typo) main_container.addWidget(group_scheme) main_container.addItem( QSpacerItem(0, 10, QSizePolicy.Expanding, QSizePolicy.Expanding)) EditorConfiguration.install_widget(self.tr("General"), self) # Conexiones self.combo_scheme.currentIndexChanged['const QString&'].connect( self._change_scheme) self.combo_caret.currentIndexChanged[int].connect( self._caret_type_changed) self.slider_caret_period.valueChanged[int].connect(lcd_caret.display) self.slider_caret_period.setValue( settings.get_setting('editor/cursor-period')) def _change_scheme(self, theme): theme = theme.split()[0].lower() editor_container = Edis.get_component("principal") editor = editor_container.get_active_editor() if editor is not None: # Restyle pass def _caret_type_changed(self, index): self.spin_caret_width.setEnabled(bool(index)) def _load_font(self): font = settings.get_setting('editor/font') self.combo_font.setCurrentFont(QFont(font)) def save(self): """ Guarda las configuraciones del Editor. """ use_tabs = bool(self.combo_tabs.currentIndex()) settings.set_setting('editor/usetabs', use_tabs) auto_indent = self.check_autoindent.isChecked() settings.set_setting('editor/indent', auto_indent) settings.set_setting('editor/minimap', self.check_minimap.isChecked()) #settings.set_setting('editor/minimap-animation', #self.check_minimap_animation.isChecked()) font = self.combo_font.currentFont().family() settings.set_setting('editor/font', font) font_size = self.spin_size_font.value() settings.set_setting('editor/size-font', font_size) scheme = self.combo_scheme.currentText().split()[0].lower() settings.set_setting('editor/scheme', scheme) settings.set_setting('editor/cursor', self.combo_caret.currentIndex()) settings.set_setting('editor/caret-width', self.spin_caret_width.value()) settings.set_setting('editor/cursor-period', self.slider_caret_period.value()) editor_container = Edis.get_component("principal") editor = editor_container.get_active_editor() if editor is not None: editor.setIndentationsUseTabs(use_tabs) editor.load_font(font, font_size)
class MainWindow(object): ''' Main window in View. ''' MAIN_WINDOW_TITLE = "PyGestures" def __init__(self): ''' Constructor ''' self.mainWindow = QMainWindow(); self.mainWindow.setWindowTitle(self.MAIN_WINDOW_TITLE) self.mainWindowSignals = MainWindowSignals(self); self._createWidgets(); self._connectSignals(); self.mainWindow.setCentralWidget(self.mainWidget); self.mainWindow.show(); def _createWidgets(self): ''' ''' self.mainWidget = QWidget(self.mainWindow) self.videoWidget = VideoWidget() self.scaleButton = QPushButton("Scale capture",self.mainWindow) self.trainNetworkButton = QPushButton("Train network",self.mainWindow) self.captureButton = QPushButton("Capture",self.mainWindow) self.classifyButton = QPushButton("Classify",self.mainWindow) self.layout = QGridLayout(); self.layout.addWidget(self.videoWidget,0,0) self.layout.addWidget(self.scaleButton,1,0) self.mainWidget.setLayout(self.layout) self.cbMinSlider = QSlider(Qt.Horizontal, self.mainWindow) self.layout.addWidget(self.cbMinSlider,2,0) self.cbMaxSlider = QSlider(Qt.Horizontal, self.mainWindow) self.layout.addWidget(self.cbMaxSlider,3,0) self.crMinSlider = QSlider(Qt.Horizontal, self.mainWindow) self.layout.addWidget(self.crMinSlider,4,0) self.crMaxSlider = QSlider(Qt.Horizontal, self.mainWindow) self.layout.addWidget(self.crMaxSlider,5,0) self.layout.addWidget(self.captureButton,6,0) self.layout.addWidget(self.trainNetworkButton,7,0) self.layout.addWidget(self.classifyButton,8,0) #self.cbMinSlider.setFocusPolicy(QtCore.Qt.NoFocus) #self.cbMinSlider.setGeometry(30, 40, 100, 30) self.cbMinSlider.setValue(80) self.cbMinSlider.setRange(0,255) self.cbMinSlider.valueChanged[int].connect(self.mainWindowSignals.changedValueCbMin) self.cbMaxSlider.setRange(0,255) self.cbMaxSlider.setValue(135) self.cbMaxSlider.valueChanged[int].connect(self.mainWindowSignals.changedValueCbMax) self.crMinSlider.setRange(0,255) self.crMinSlider.setValue(130) self.crMinSlider.valueChanged[int].connect(self.mainWindowSignals.changedValueCrMin) self.crMaxSlider.setRange(0,255) self.crMaxSlider.setValue(180) self.crMaxSlider.valueChanged[int].connect(self.mainWindowSignals.changedValueCrMax) def _connectSignals(self): ''' ''' self.mainWindowSignals.camera = self.videoWidget._capture self.mainWindow.connect(self.scaleButton,SIGNAL("clicked()"),self.mainWindowSignals.prepareCapture) self.mainWindow.connect(self.captureButton,SIGNAL("clicked()"),self.mainWindowSignals.captureImage) self.mainWindow.connect(self.trainNetworkButton,SIGNAL("clicked()"),self.mainWindowSignals.trainNetwork) self.mainWindow.connect(self.classifyButton,SIGNAL("clicked()"),self.mainWindowSignals.captureImage)
class MotorizedPoti(PluginBase): def __init__(self, *args): PluginBase.__init__(self, BrickletMotorizedPoti, *args) self.mp = self.device self.cbe_position = CallbackEmulator(self.mp.get_position, self.cb_position, self.increase_error_count) self.current_position = None self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, 100) self.slider.setMinimumWidth(200) plots = [('Position', Qt.red, lambda: self.current_position, str)] self.plot_widget = PlotWidget('Position', plots, extra_key_widgets=[self.slider], curve_motion_granularity=40, update_interval=0.025) self.motor_slider = QSlider(Qt.Horizontal) self.motor_slider.setRange(0, 100) self.motor_slider.sliderReleased.connect(self.motor_slider_released) self.motor_slider.sliderMoved.connect(self.motor_slider_moved) self.motor_enable = QCheckBox("Enable Motor") self.motor_enable.stateChanged.connect(self.motor_enable_changed) self.motor_position_label = MotorPositionLabel('Motor Position: ') hlayout = QHBoxLayout() hlayout.addWidget(self.motor_position_label) hlayout.addWidget(self.motor_slider) hlayout.addWidget(self.motor_enable) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) layout = QVBoxLayout(self) layout.addWidget(self.plot_widget) layout.addWidget(line) layout.addLayout(hlayout) def start(self): async_call(self.mp.get_position, None, self.cb_position, self.increase_error_count) async_call(self.mp.get_motor_position, None, self.cb_motor_position, self.increase_error_count) async_call(self.mp.is_motor_enabled, None, self.cb_is_motor_enabled, self.increase_error_count) self.cbe_position.set_period(25) self.plot_widget.stop = False def stop(self): self.cbe_position.set_period(0) self.plot_widget.stop = True def destroy(self): pass def get_url_part(self): return 'motorized_poti' @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletMotorizedPoti.DEVICE_IDENTIFIER def cb_position(self, position): self.current_position = position self.slider.setValue(position) def cb_motor_position(self, motor_position): self.motor_slider.setValue(motor_position.position) self.motor_slider_moved(motor_position.position) def cb_is_motor_enabled(self, enabled): self.motor_enable.setChecked(enabled) def motor_slider_moved(self, position): self.motor_position_label.setText(str(position)) def motor_slider_released(self): self.mp.set_motor_position(self.motor_slider.value(), False) def motor_enable_changed(self, state): if self.motor_enable.isChecked(): self.mp.enable_motor() else: self.mp.disable_motor()