def main(argv=None): # pragma: no cover from AnyQt.QtWidgets import QVBoxLayout, QCheckBox, QStatusBar app = QApplication(list(argv) if argv else []) l1 = QVBoxLayout() l1.setContentsMargins(0, 0, 0, 0) blayout = QVBoxLayout() l1.addLayout(blayout) sb = QStatusBar() w = QWidget() w.setLayout(l1) messages = [ Message( Severity.Error, text="Encountered a HCF", detailedText="<em>AAA! It burns.</em>", textFormat=Qt.RichText, ), Message( Severity.Warning, text="ACHTUNG!", detailedText=('<div style="color: red">DAS KOMPUTERMASCHINE IST ' "NICHT FÜR DER GEFINGERPOKEN</div>"), textFormat=Qt.RichText, ), Message( Severity.Information, text="The rain in spain falls mostly on the plain", informativeText=( '<a href="https://www.google.si/search?q=' 'Average+Yearly+Precipitation+in+Spain">Link</a>'), textFormat=Qt.RichText, ), Message( Severity.Error, text="I did not do this!", informativeText="The computer made suggestions...", detailedText="... and the default options was yes.", ), Message(), ] mw = MessagesWidget(openExternalLinks=True) for i, m in enumerate(messages): cb = QCheckBox(m.text) def toogled(state, i=i, m=m): if state: mw.setMessage(i, m) else: mw.removeMessage(i) cb.toggled[bool].connect(toogled) blayout.addWidget(cb) sb.addWidget(mw) w.layout().addWidget(sb, 0) w.show() return app.exec_()
def main(argv=None): # pragma: no cover from AnyQt.QtWidgets import QVBoxLayout, QCheckBox, QStatusBar app = QApplication(list(argv) if argv else []) l1 = QVBoxLayout() l1.setContentsMargins(0, 0, 0, 0) blayout = QVBoxLayout() l1.addLayout(blayout) sb = QStatusBar() w = QWidget() w.setLayout(l1) messages = [ Message(Severity.Error, text="Encountered a HCF", detailedText="<em>AAA! It burns.</em>", textFormat=Qt.RichText), Message(Severity.Warning, text="ACHTUNG!", detailedText=( "<div style=\"color: red\">DAS KOMPUTERMASCHINE IST " "NICHT FÜR DER GEFINGERPOKEN</div>" ), textFormat=Qt.RichText), Message(Severity.Information, text="The rain in spain falls mostly on the plain", informativeText=( "<a href=\"https://www.google.si/search?q=" "Average+Yearly+Precipitation+in+Spain\">Link</a>" ), textFormat=Qt.RichText), Message(Severity.Error, text="I did not do this!", informativeText="The computer made suggestions...", detailedText="... and the default options was yes."), Message(), ] mw = MessagesWidget(openExternalLinks=True) for i, m in enumerate(messages): cb = QCheckBox(m.text) def toogled(state, i=i, m=m): if state: mw.setMessage(i, m) else: mw.removeMessage(i) cb.toggled[bool].connect(toogled) blayout.addWidget(cb) sb.addWidget(mw) w.layout().addWidget(sb, 0) w.show() return app.exec_()
def set_basic_layout(self): """Provide the basic widget layout Which parts are created is regulated by class attributes `want_main_area`, `want_control_area`, `want_message_bar` and `buttons_area_orientation`, the presence of method `send_report` and attribute `graph_name`. """ self.setLayout(QVBoxLayout()) self.layout().setContentsMargins(2, 2, 2, 2) if not self.resizing_enabled: self.layout().setSizeConstraint(QVBoxLayout.SetFixedSize) self.want_main_area = self.want_main_area or self.graph_name self._create_default_buttons() self._insert_splitter() if self.want_control_area: self._insert_control_area() if self.want_main_area: self._insert_main_area() if self.want_message_bar: # Use a OverlayWidget for status bar positioning. c = OverlayWidget(self, alignment=Qt.AlignBottom) c.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) c.setWidget(self) c.setLayout(QVBoxLayout()) c.layout().setContentsMargins(0, 0, 0, 0) sb = QStatusBar() sb.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Maximum) sb.setSizeGripEnabled(self.resizing_enabled) c.layout().addWidget(sb) help = self.__help_action icon = QIcon(gui.resource_filename("icons/help.svg")) icon.addFile(gui.resource_filename("icons/help-hover.svg"), mode=QIcon.Active) help_button = SimpleButton( icon=icon, toolTip="Show widget help", visible=help.isVisible(), ) @help.changed.connect def _(): help_button.setVisible(help.isVisible()) help_button.setEnabled(help.isEnabled()) help_button.clicked.connect(help.trigger) sb.addWidget(help_button) if self.graph_name is not None: icon = QIcon(gui.resource_filename("icons/chart.svg")) icon.addFile(gui.resource_filename("icons/chart-hover.svg"), mode=QIcon.Active) b = SimpleButton( icon=icon, toolTip="Save Image", ) b.clicked.connect(self.save_graph) sb.addWidget(b) if hasattr(self, "send_report"): icon = QIcon(gui.resource_filename("icons/report.svg")) icon.addFile(gui.resource_filename("icons/report-hover.svg"), mode=QIcon.Active) b = SimpleButton(icon=icon, toolTip="Report") b.clicked.connect(self.show_report) sb.addWidget(b) self.message_bar = MessagesWidget(self) self.message_bar.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) pb = QProgressBar(maximumWidth=120, minimum=0, maximum=100) pb.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Ignored) pb.setAttribute(Qt.WA_LayoutUsesWidgetRect) pb.setAttribute(Qt.WA_MacMiniSize) pb.hide() sb.addPermanentWidget(pb) sb.addPermanentWidget(self.message_bar) def statechanged(): pb.setVisible(bool(self.processingState) or self.isBlocking()) if self.isBlocking() and not self.processingState: pb.setRange(0, 0) # indeterminate pb elif self.processingState: pb.setRange(0, 100) # determinate pb self.processingStateChanged.connect(statechanged) self.blockingStateChanged.connect(statechanged) @self.progressBarValueChanged.connect def _(val): pb.setValue(int(val)) # Reserve the bottom margins for the status bar margins = self.layout().contentsMargins() margins.setBottom(sb.sizeHint().height()) self.setContentsMargins(margins)
def set_basic_layout(self): """Provide the basic widget layout Which parts are created is regulated by class attributes `want_main_area`, `want_control_area`, `want_message_bar` and `buttons_area_orientation`, the presence of method `send_report` and attribute `graph_name`. """ self.setLayout(QVBoxLayout()) self.layout().setContentsMargins(2, 2, 2, 2) if not self.resizing_enabled: self.layout().setSizeConstraint(QVBoxLayout.SetFixedSize) self.want_main_area = self.want_main_area or self.graph_name self._create_default_buttons() self._insert_splitter() if self.want_control_area: self._insert_control_area() if self.want_main_area: self._insert_main_area() if self.want_message_bar: # Use a OverlayWidget for status bar positioning. c = OverlayWidget(self, alignment=Qt.AlignBottom) c.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) c.setWidget(self) c.setLayout(QVBoxLayout()) c.layout().setContentsMargins(0, 0, 0, 0) sb = QStatusBar() sb.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Maximum) sb.setSizeGripEnabled(self.resizing_enabled) c.layout().addWidget(sb) self.message_bar = MessagesWidget(self) self.message_bar.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) pb = QProgressBar(maximumWidth=120, minimum=0, maximum=100) pb.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Ignored) pb.setAttribute(Qt.WA_LayoutUsesWidgetRect) pb.setAttribute(Qt.WA_MacMiniSize) pb.hide() sb.addPermanentWidget(pb) sb.addPermanentWidget(self.message_bar) def statechanged(): pb.setVisible(bool(self.processingState) or self.isBlocking()) if self.isBlocking() and not self.processingState: pb.setRange(0, 0) # indeterminate pb elif self.processingState: pb.setRange(0, 100) # determinate pb self.processingStateChanged.connect(statechanged) self.blockingStateChanged.connect(statechanged) @self.progressBarValueChanged.connect def _(val): pb.setValue(int(val)) # Reserve the bottom margins for the status bar margins = self.layout().contentsMargins() margins.setBottom(sb.sizeHint().height()) self.setContentsMargins(margins)
def set_basic_layout(self): """Provide the basic widget layout Which parts are created is regulated by class attributes `want_main_area`, `want_control_area`, `want_message_bar` and `buttons_area_orientation`, the presence of method `send_report` and attribute `graph_name`. """ self.setLayout(QVBoxLayout()) self.layout().setContentsMargins(2, 2, 2, 2) if not self.resizing_enabled: self.layout().setSizeConstraint(QVBoxLayout.SetFixedSize) self.want_main_area = self.want_main_area or self.graph_name self._create_default_buttons() self._insert_splitter() if self.want_control_area: self._insert_control_area() if self.want_main_area: self._insert_main_area() if self.want_message_bar: # Use a OverlayWidget for status bar positioning. c = OverlayWidget(self, alignment=Qt.AlignBottom) c.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) c.setWidget(self) c.setLayout(QVBoxLayout()) c.layout().setContentsMargins(0, 0, 0, 0) sb = QStatusBar() sb.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Maximum) sb.setSizeGripEnabled(self.resizing_enabled) c.layout().addWidget(sb) help = self.__help_action help_button = SimpleButton( icon=QIcon(gui.resource_filename("icons/help.svg")), toolTip="Show widget help", visible=help.isVisible(), ) @help.changed.connect def _(): help_button.setVisible(help.isVisible()) help_button.setEnabled(help.isEnabled()) help_button.clicked.connect(help.trigger) sb.addWidget(help_button) if self.graph_name is not None: b = SimpleButton( icon=QIcon(gui.resource_filename("icons/chart.svg")), toolTip="Save Image", ) b.clicked.connect(self.save_graph) sb.addWidget(b) if hasattr(self, "send_report"): b = SimpleButton( icon=QIcon(gui.resource_filename("icons/report.svg")), toolTip="Report" ) b.clicked.connect(self.show_report) sb.addWidget(b) self.message_bar = MessagesWidget(self) self.message_bar.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) pb = QProgressBar(maximumWidth=120, minimum=0, maximum=100) pb.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Ignored) pb.setAttribute(Qt.WA_LayoutUsesWidgetRect) pb.setAttribute(Qt.WA_MacMiniSize) pb.hide() sb.addPermanentWidget(pb) sb.addPermanentWidget(self.message_bar) def statechanged(): pb.setVisible(bool(self.processingState) or self.isBlocking()) if self.isBlocking() and not self.processingState: pb.setRange(0, 0) # indeterminate pb elif self.processingState: pb.setRange(0, 100) # determinate pb self.processingStateChanged.connect(statechanged) self.blockingStateChanged.connect(statechanged) @self.progressBarValueChanged.connect def _(val): pb.setValue(int(val)) # Reserve the bottom margins for the status bar margins = self.layout().contentsMargins() margins.setBottom(sb.sizeHint().height()) self.setContentsMargins(margins)
def __init__(self, parent_win=None): BaseWidget.__init__(self, self.TITLE, parent_win=parent_win) self._msg_duration = 3000 self._usb_port = ControlCombo('USB port', changed_event=self.__combo_usb_ports_changed_evt) self._refresh_usb_ports = ControlButton('', icon=QtGui.QIcon(conf.REFRESH_SMALL_ICON), default=self.__refresh_usb_ports_btn_pressed, helptext="Press here to refresh the list of available devices.") self._connect_btn = ControlButton('Connect', default=self.__connect_btn_pressed) # Send data self._send_btn = ControlButton('Send to sound card', default=self.__send_btn_pressed, enabled=False) self._index_to_send = ControlNumber('Index to send', default=2, minimum=2, maximum=32) self._user_metadata_send = ControlTextArea('User metadata (optional)') self._description_send = ControlTextArea('Description (optional)') self._send_panel = ControlEmptyWidget() self._send_panel.value = [self._index_to_send, self._user_metadata_send, self._description_send, self._send_btn] self._send_panel.setContentsMargins(10, 10, 10, 10) # Receive data self._index_to_read = ControlNumber('Index to read', default=2, minimum=2, maximum=32) self._read_all_checkbox = ControlCheckBox('Read all indexes', default=False, changed_event=self.__read_all_checkbox_evt) self._clear_folder_checkbox = ControlCheckBox('Clear destination folder', default=False) self._dest_folder = ControlText('Destination folder', '', changed_event=self.__folder_changed_evt) self._browse_btn = ControlButton('Browse', default=self.__prompt_browse_file_evt) self._read_btn = ControlButton('Read data', default=self.__read_btn_pressed, enabled=False) self._receive_panel = ControlEmptyWidget() self._receive_panel.value = [self._read_all_checkbox, self._index_to_read, self._clear_folder_checkbox, self._dest_folder, self._browse_btn, self._read_btn] self._receive_panel.setContentsMargins(10, 10, 10, 10) self._sound_generation = SoundGenerationPanel(parent_win=self) self._sound_generation.sound_generated = self._sound_generated_evt self._sound_gen_panel = ControlEmptyWidget() self._sound_gen_panel.value = self._sound_generation self._sound_load = LoadSoundPanel(parent_win=self) self._sound_load.sound_loaded = self._sound_loaded_evt self._sound_load_panel = ControlEmptyWidget() self._sound_load_panel.value = self._sound_load self._sound_card = SoundCardModule() self._wave_int = [] self.formset = [ ('_usb_port', '_refresh_usb_ports', '_connect_btn'), { 'a:Generate sound': ['_sound_gen_panel'], 'b:Load sound from disk': ['_sound_load_panel'], }, ' ', { 'a:Send data': ['_send_panel'], 'b:Receive data': ['_receive_panel'] } ] self._fill_usb_ports() self.set_margin(10) self._status_bar = QStatusBar(parent=self)
class SoundCardModuleGUI(SoundCardModule, BaseWidget): TITLE = 'Sound Card module' def __init__(self, parent_win=None): BaseWidget.__init__(self, self.TITLE, parent_win=parent_win) self._msg_duration = 3000 self._usb_port = ControlCombo('USB port', changed_event=self.__combo_usb_ports_changed_evt) self._refresh_usb_ports = ControlButton('', icon=QtGui.QIcon(conf.REFRESH_SMALL_ICON), default=self.__refresh_usb_ports_btn_pressed, helptext="Press here to refresh the list of available devices.") self._connect_btn = ControlButton('Connect', default=self.__connect_btn_pressed) # Send data self._send_btn = ControlButton('Send to sound card', default=self.__send_btn_pressed, enabled=False) self._index_to_send = ControlNumber('Index to send', default=2, minimum=2, maximum=32) self._user_metadata_send = ControlTextArea('User metadata (optional)') self._description_send = ControlTextArea('Description (optional)') self._send_panel = ControlEmptyWidget() self._send_panel.value = [self._index_to_send, self._user_metadata_send, self._description_send, self._send_btn] self._send_panel.setContentsMargins(10, 10, 10, 10) # Receive data self._index_to_read = ControlNumber('Index to read', default=2, minimum=2, maximum=32) self._read_all_checkbox = ControlCheckBox('Read all indexes', default=False, changed_event=self.__read_all_checkbox_evt) self._clear_folder_checkbox = ControlCheckBox('Clear destination folder', default=False) self._dest_folder = ControlText('Destination folder', '', changed_event=self.__folder_changed_evt) self._browse_btn = ControlButton('Browse', default=self.__prompt_browse_file_evt) self._read_btn = ControlButton('Read data', default=self.__read_btn_pressed, enabled=False) self._receive_panel = ControlEmptyWidget() self._receive_panel.value = [self._read_all_checkbox, self._index_to_read, self._clear_folder_checkbox, self._dest_folder, self._browse_btn, self._read_btn] self._receive_panel.setContentsMargins(10, 10, 10, 10) self._sound_generation = SoundGenerationPanel(parent_win=self) self._sound_generation.sound_generated = self._sound_generated_evt self._sound_gen_panel = ControlEmptyWidget() self._sound_gen_panel.value = self._sound_generation self._sound_load = LoadSoundPanel(parent_win=self) self._sound_load.sound_loaded = self._sound_loaded_evt self._sound_load_panel = ControlEmptyWidget() self._sound_load_panel.value = self._sound_load self._sound_card = SoundCardModule() self._wave_int = [] self.formset = [ ('_usb_port', '_refresh_usb_ports', '_connect_btn'), { 'a:Generate sound': ['_sound_gen_panel'], 'b:Load sound from disk': ['_sound_load_panel'], }, ' ', { 'a:Send data': ['_send_panel'], 'b:Receive data': ['_receive_panel'] } ] self._fill_usb_ports() self.set_margin(10) self._status_bar = QStatusBar(parent=self) def init_form(self): super(SoundCardModuleGUI, self).init_form() self.layout().addWidget(self._status_bar) def _fill_usb_ports(self): self._usb_port.add_item('', '') if self._sound_card: usb_devices = self._sound_card.devices for n, item in enumerate(usb_devices): if item.port_number: item_str = item.product + ' {n} (port={port})'.format(n=n, port=item.port_number) else: item_str = item.product + ' {n}'.format(n=n) self._usb_port.add_item(item_str, item) def _sound_generated_evt(self): if self._sound_generation.filename: self._status_bar.showMessage("Sound generated successfully and saved to '{file}'.".format( file=self._sound_generation.filename), self._msg_duration) else: self._status_bar.showMessage("Sound generated successfully.", self._msg_duration) if not self._connect_btn.enabled: self._send_btn.enabled = True def _sound_loaded_evt(self): self._status_bar.showMessage("Sound loaded successfully from disk.", self._msg_duration) if not self._connect_btn.enabled: self._send_btn.enabled = True def __read_all_checkbox_evt(self): self._index_to_read.enabled = not self._read_all_checkbox.value def __read_btn_pressed(self): if self._sound_card and not self._sound_card.connected: self.warning("Please connect to the sound card before proceeding.", "Not connected to the sound card") return # check if read all or read a specific index index_to_read = None if self._read_all_checkbox.value is True else int(self._index_to_read.value) # check if the folder exists if not os.path.isdir(self._dest_folder.value): self.critical("Folder doesn't exist. Please correct the path to an existing folder and try again", "Path not found") return # read sound self._sound_card.read_sounds(self._dest_folder.value, index_to_read, self._clear_folder_checkbox.value) self._status_bar.showMessage("Data read successfully from the sound card", self._msg_duration) def __combo_usb_ports_changed_evt(self): if self._sound_card: self._sound_card.close() self._connect_btn.enabled = True self._send_btn.enabled = False def __refresh_usb_ports_btn_pressed(self): tmp = self._usb_port.value self._usb_port.clear() self._fill_usb_ports() self._usb_port.value = tmp def __folder_changed_evt(self): if not self._dest_folder.value: self._read_btn.enabled = False else: self._read_btn.enabled = True def __prompt_browse_file_evt(self): self._dest_folder.value = QFileDialog.getExistingDirectory() if self._dest_folder.value: self._read_btn.enabled = True else: self._read_btn.enabled = False def __connect_btn_pressed(self): if not self._usb_port.value: self.warning("Please select a USB connected device before proceeding.", "No USB device selected") return if self._sound_card is not None: self._sound_card.close() self._sound_card = SoundCardModule(device=self._usb_port.value) # update visual elements self._connect_btn.enabled = False if self._sound_generation.generated or self._sound_load.loaded: self._send_btn.enabled = True def __send_btn_pressed(self): if self._sound_card and not self._sound_card.connected: self.warning("Please connect to the sound card before proceeding", "No connection to the sound card established.") return if (self._sound_generation.generated or self._sound_load.loaded) and self._sound_card.connected: wave_int = self._sound_generation.wave_int if self._sound_generation.generated else self._sound_load.wave_int # process Filename, metadata info and description data (optional parameters) temp_dir = tempfile.gettempdir() usr_metadata_file = None if self._user_metadata_send: usr_metadata_file = os.path.join(temp_dir, 'user_metadata.bin') with open(usr_metadata_file, 'w') as f: f.write(self._user_metadata_send.value) description_file = None if self._description_send: description_file = os.path.join(temp_dir, 'description.bin') with open(description_file, 'w') as f: f.write(self._description_send.value) self._sound_card.send_sound(wave_int, int(self._index_to_send.value), self._sound_generation.sample_rate, DataType.INT32, os.path.basename(self._sound_generation.filename) if self._sound_generation.filename else "Sound{id:02d}".format(id=int(self._index_to_send.value)), usr_metadata_file, description_file ) self._status_bar.showMessage("Sound sent successfully to the sound card.", self._msg_duration) # delete the temp files if usr_metadata_file is not None: os.unlink(usr_metadata_file) if description_file is not None: os.unlink(description_file)