def _clearField(self, sender: QPushButton, name: QLineEdit, link: QLineEdit) -> None: if (name.text() and link.text()): name.setText('') link.setText('') name.clear() link.clear()
class InputDialog(QDialog): def __init__(self, parent=None): super().__init__(parent) self.label = QLabel() self.label.setStyleSheet('font: 10pt \'맑은 고딕\'') self.input = QLineEdit() self.input.setStyleSheet('font: 10pt \'맑은 고딕\'') self.btn_ok = NPButton('확인', 10, self) self.btn_ok.clicked.connect(self.accept) self.btn_cancel = NPButton('취소', 10, self) self.btn_cancel.clicked.connect(self.reject) grid = QGridLayout() grid.addWidget(self.label, 0, 0, 1, 8) grid.addWidget(self.input, 1, 0, 1, 8) grid.addWidget(self.btn_ok, 2, 6, 1, 1) grid.addWidget(self.btn_cancel, 2, 7, 1, 1) self.setLayout(grid) self.setWindowIcon(QIcon('icon.png')) self.setStyleSheet('font: 10pt \'맑은 고딕\'') self.setWindowFlag(Qt.WindowContextHelpButtonHint, False) def get_text(self, title, lbl): self.setWindowTitle(title) self.label.setText(lbl) self.input.clear() if self.exec_() == self.Accepted: return self.input.text(), True else: return '', False
class MainWindow(QWidget): # Inherits QWidget def __init__(self): super().__init__() self.label = QLabel(self) self.button = QPushButton('Очистить', self) self.line_edit = QLineEdit(self) self.initializeUI() def initializeUI(self): self.setGeometry(100, 100, 400, 200) self.setWindowTitle('QLineEdit Test') QLabel("Введите login", self).move(100, 10) name_label = QLabel("Login:"******"Очистить" if sender.text() == 'Очистить': self.line_edit.clear() # очищаем текст
class AutoFilterMenu(QMenu): """A widget to show the auto filter 'menu'. Attributes: parent (QTableView): the parent widget. """ asc_sort_triggered = Signal() desc_sort_triggered = Signal() filter_triggered = Signal(dict) def __init__(self, parent): """Initialize class.""" super().__init__(parent) self.auto_filter = dict() # Layout self.all_item_model = AutoFilterMenuAllItemModel(self) self.value_item_model = AutoFilterMenuValueItemModel(self) self.text_filter = QLineEdit(self) self.text_filter.setPlaceholderText("Search...") self.text_filter.setClearButtonEnabled(True) self.all_item_view = AutoFilterMenuView(self) self.value_item_view = AutoFilterMenuView(self) self.all_item_view.setModel(self.all_item_model) self.value_item_view.setModel(self.value_item_model) text_filter_action = QWidgetAction(self) text_filter_action.setDefaultWidget(self.text_filter) all_item_view_action = QWidgetAction(self) all_item_view_action.setDefaultWidget(self.all_item_view) value_item_view_action = QWidgetAction(self) value_item_view_action.setDefaultWidget(self.value_item_view) self.addAction(text_filter_action) self.addAction(all_item_view_action) self.addAction(value_item_view_action) ok_action = self.addAction("Ok") self.text_filter.textEdited.connect(self.value_item_model.set_filter_reg_exp) ok_action.triggered.connect(self._handle_ok_action_triggered) self.all_item_model.checked_state_changed.connect(self.value_item_model.set_all_items_checked_state) self.value_item_model.all_checked_state_changed.connect(self.all_item_model.set_checked_state) self.aboutToShow.connect(self._fix_geometry) def set_data(self, data): """Set data to show in the menu.""" self.value_item_model.reset_model(data) @Slot(name="_fix_geometry") def _fix_geometry(self): """Fix geometry, shrink views as possible.""" all_item_view_height = self.all_item_view.sizeHintForRow(0) self.all_item_view.setMaximumHeight(all_item_view_height) self.text_filter.clear() self.text_filter.setFocus() @Slot("bool", name="_handle_ok_action_triggered") def _handle_ok_action_triggered(self, checked=False): """Called when user presses Ok. Collect selections and emit signal. """ auto_filter = self.value_item_model.get_auto_filter() self.filter_triggered.emit(auto_filter)
class LoadFileDialog(QDialog): def __init__(self, parent, listeners_pool): super(LoadFileDialog, self).__init__(parent) self.listeners_pool = listeners_pool widget_creator = WidgetCreator() self.use_cases_service = UseCasesService() self.setWindowTitle("Cargar fichero...") self.resize(400, 100) self.setModal(True) layout = QGridLayout() self.setLayout(layout) load_file_label = QLabel("Ruta del fichero:") self.load_file_textbox = QLineEdit() load_file_label.setBuddy(self.load_file_textbox) button_load = widget_creator.create_button("Cargar fichero", "upload", self.load_file) button_cancel = widget_creator.create_button("Cancelar", "cancel", self.reject) button_search = widget_creator.create_button("", "search", self.choose_file) button_box = QHBoxLayout() button_box.addWidget(button_load) button_box.addWidget(button_cancel) layout.addWidget(load_file_label, 0, 0) layout.addWidget(self.load_file_textbox, 0, 1) layout.addWidget(button_search, 0, 2) layout.addLayout(button_box, 1, 1) self.show() def choose_file(self): file_dialog = QFileDialog() file_name = file_dialog.getOpenFileName() self.load_file_textbox.insert(file_name[0]) def load_file(self): file_name = self.load_file_textbox.text() values = self.use_cases_service.load_file(file_name) self.listeners_pool.send_event('pending-expenses-table', 'refresh_rows') message = "Registros cargados: " + str(values['inserted']) + "\nRegistros ignorados: " + str(values['ignored']) info_dialog = InfoDialog(self, title="Cargado fichero", message=message) #TODO Check whether file exists #TODO Check extension is correct self.load_file_textbox.clear()
class SearchBar(QWidget): QueryLaunched = Signal(str) StopPressed = Signal() def __init__(self, parent=None): super().__init__(parent) self._query_edit = QLineEdit() self._query_edit.setClearButtonEnabled(True) self._query_edit.setPlaceholderText("Type you query here") self._query_edit.returnPressed.connect(self._HandleReturnPressed) self._query_edit.addAction(QIcon(icons.SEARCH), QLineEdit.LeadingPosition) self._kill_button = QToolButton() self._kill_button.setIcon(QIcon(icons.STOP)) self._kill_button.setAutoRaise(True) self._kill_button.setMinimumSize(31, 31) self._kill_button.setEnabled(False) self._kill_button.clicked.connect(self.StopPressed) layout = QHBoxLayout() layout.addWidget(self._kill_button) layout.addWidget(self._query_edit) layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.setFocusProxy(self._query_edit) def Clear(self): self._query_edit.clear() def SetStopEnabled(self, bool_): self._kill_button.setEnabled(bool_) def SetQueryEditEnabled(self, bool_): self._query_edit.setEnabled(bool_) def SetQuery(self, query): self._query_edit.setText(query) def LaunchQuery(self, query): self._query_edit.setText(query) self._HandleReturnPressed() def _HandleReturnPressed(self): query = " ".join(self._query_edit.text().split()) if query == "": return self.QueryLaunched.emit(query)
class FileArea(QWidget): def __init__(self, parent=None): super(FileArea, self).__init__(parent) # Fonts self.text_font = QFont('monospace', 16) self.button_font = QFont('monospace', 18) self.selected_file_name_font = QFont('monospace', 10) self.file_selection_button = QPushButton('Select File') self.file_selection_button.setFont(self.button_font) self.file_selection_button.clicked.connect(self.open_file) self.selected_file_name = QLineEdit() self.selected_file_name.setReadOnly(True) self.selected_file_name.setFont(self.selected_file_name_font) self.file_preview = QTextEdit() self.file_preview.setReadOnly(True) self.file_preview.setFont(self.text_font) # Create layout and add widgets layout = QVBoxLayout() layout.addWidget(self.file_selection_button) layout.addWidget(self.selected_file_name) layout.addWidget(self.file_preview) # Set layout self.setLayout(layout) def get_file_path(self): file_path = QFileDialog.getOpenFileNames( filter= "Text files (*.txt);;XML files (*.xml);;CSV files (*.csv);;Word files (*.doc *.docx)" ) file_path = file_path[0][0] self.selected_file_name.setText(file_path) return file_path def get_file_contents(self, file_path): with open(file_path, 'r', encoding="utf8") as file: file_contents = file.read() self.file_preview.insertPlainText(file_contents) return file_contents def open_file(self): self.file_preview.clear() self.selected_file_name.clear() file_path = self.get_file_path() file_contents = self.get_file_contents(file_path) return file_contents
class Example(QWidget): def __init__(self): super().__init__() self.initUI() self.num = randint(1, 100) def initUI(self): self.setGeometry(300, 300, 300, 300) self.setWindowTitle("guess") self.setWindowIcon(QIcon('icon.jpg')) self.bt1 = QPushButton("我猜", self) self.bt1.setGeometry(115, 150, 70, 30) self.bt1.setToolTip('<b>点击这里猜游戏</b>') self.bt1.clicked.connect(self.showMessage) self.text = QLineEdit('在这里输入数字', self) self.text.selectAll() self.text.setFocus() self.text.setGeometry(80, 50, 150, 30) self.show() def showMessage(self): guessnumber = int(self.text.text()) print(self.num) if guessnumber > self.num: QMessageBox.about(self, '看结果', '猜大了!') self.text.setFocus() elif guessnumber < self.num: QMessageBox.about(self, '看结果', '猜小了!') self.text.setFocus() else: QMessageBox.about(self, '看结果', '答对了!进入下一轮!') self.num = randint(1, 100) self.text.clear() self.text.setFocus() def closeEvent(self, event): reply = QMessageBox.question(self, '确认', '确认退出吗', QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: event.accept() else: event.ignore()
class LoginWindow(QDialog): def __init__(self, parent): super(LoginWindow, self).__init__(parent) self.setWindowTitle("Kérem adja meg a bejelentkezési adatokat") main_layout = QVBoxLayout(self) name_layout = QHBoxLayout() name_label = QLabel("E-mail cím vagy név:") self.name = QLineEdit() name_layout.addWidget(name_label) name_layout.addWidget(self.name) main_layout.addLayout(name_layout) password_layout = QHBoxLayout() password_label = QLabel("Jelszó:") self.password = QLineEdit() self.password.setEchoMode(QLineEdit.Password) password_layout.addWidget(password_label) password_layout.addWidget(self.password) main_layout.addLayout(password_layout) button_layout = QHBoxLayout() self.login_button = QPushButton("Bejelentkezés") self.cancel_button = QPushButton("Kiürít") self.exit_button = QPushButton("Kilépés") button_layout.addWidget(self.login_button) button_layout.addWidget(self.cancel_button) button_layout.addWidget(self.exit_button) main_layout.addLayout(button_layout) self.login_button.clicked.connect(self.accept) self.cancel_button.clicked.connect(self.form_clear) self.exit_button.clicked.connect(self.reject) def accept(self): if len(self.name.text()) and len(self.password.text()): print(f"Bejelentkezési név: {self.name.text()}") print(f"Jelszó: {self.password.text()}") # pass super(LoginWindow, self).accept() else: return def form_clear(self): self.name.clear() self.password.clear() def reject(self): super(LoginWindow, self).reject()
class ContactForm(QWidget): def __init__(self): super(ContactForm, self).__init__() self.setWindowTitle("My Contact Form") self.resize(400, 0) # main layout main_layout = QVBoxLayout(self) # line edits self.name_field = QLineEdit() self.name_field.setPlaceholderText("Name...") main_layout.addWidget(self.name_field) self.phone_field = QLineEdit() self.phone_field.setPlaceholderText("Phone...") main_layout.addWidget(self.phone_field) self.email_field = QLineEdit() self.email_field.setPlaceholderText("Email...") main_layout.addWidget(self.email_field) self.address_field = QLineEdit() self.address_field.setPlaceholderText("Address...") main_layout.addWidget(self.address_field) save_btn = QPushButton("Save") main_layout.addWidget(save_btn) # connect signals save_btn.clicked.connect(self.save_action) def check_fields(self): for k, v in self.user_data.items(): if not len(v): print(f'{k} has no value!') return False return True def save_action(self): self.user_data = { "name": self.name_field.text(), "phone": self.phone_field.text(), "email": self.email_field.text(), "address": self.address_field.text(), } if self.check_fields(): with open("contact_list.json", "a") as f: json.dump(self.user_data, f) self.name_field.clear() self.phone_field.clear() self.email_field.clear() self.address_field.clear()
class Form(QDialog): def __init__(self, parent=None): super(Form, self).__init__(parent) self.edit = QLineEdit('Write my name here') self.button = QPushButton('Show Greetings') layout = QVBoxLayout() layout.addWidget(self.edit) layout.addWidget(self.button) self.setLayout(layout) self.button.clicked.connect(self.greetings) def greetings(self): print('Hello %s' % self.edit.text()) self.edit.clear()
class TextFieldDialog(QDialog): PRE = "PRE" APPEND = "APPEND" REPLACE = "REPLACE" def __init__(self, plugin_manager): super(TextFieldDialog, self).__init__() self.plugin_manager = plugin_manager self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.edit_line = QLineEdit() self.layout = QVBoxLayout() self.layout.addWidget(self.edit_line) self.layout.addWidget(self.buttonBox) self.setWindowIcon( QIcon(os.path.join(c.ICON_PATH, c.THEME_NEUTRAL, "quote.png"))) self.setWindowTitle("Word") self.setLayout(self.layout) def set_values(self, word, word_pos, action): self.edit_line.clear() self.edit_line.setFocus() self.word = word self.word_pos = word_pos self.action = action self.exec_() def accept(self): replace = False if self.action == self.REPLACE: replace = True if self.action == self.APPEND: self.word_pos = self.word_pos + 1 self.plugin_manager.set_word_at(self.edit_line.text(), self.word_pos, replace) super(TextFieldDialog, self).accept()
class JDaApp(QWidget): def __init__(self): super().__init__() self.iniciaUI() def iniciaUI(self): """ Inicializa a janela e mostra seu conteuda na tela """ self.setGeometry(100,100, 400, 200) self.setWindowTitle("Login") self.displayWidgets() self.show() def displayWidgets(self): """ Configura os widgets da app """ # Criando um label e um edit para o nome nome_label = QLabel("Nome:",self) nome_label.move(70, 50) # localiza o label na tela self.nome_edit = QLineEdit(self) self.nome_edit.setAlignment(Qt.AlignLeft) # Este é o padrão self.nome_edit.move(130, 50) self.nome_edit.resize(200, 20) # mudando o tamanho da caixa de texto self.limpar_btn = QPushButton('Limpar', self) self.limpar_btn.clicked.connect(self.limparCxTxt) self.limpar_btn.move(160, 110) # localizando o botão na tela def limparCxTxt(self): """ Quando acionado o butão limpa a caixa de texto """ sender = self.sender() if sender.text() == 'Limpar': self.nome_edit.clear()
class Tagging(QWidget): def __init__(self): super().__init__() self._selected_filepath = '' layout = QGridLayout() self.setLayout(layout) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(QLabel('Add tag:')) self._entry = QLineEdit() self._entry.returnPressed.connect(self._add_tag_to_selected_file) layout.addWidget(self._entry, 0, 1) self._tagtable = TagTable(self._remove_selected_file_tag) self._tagtable_model = QStandardItemModel() self._tagtable_model.setHorizontalHeaderLabels(['Tag', '# Files']) self._tagtable.setModel(self._tagtable_model) layout.addWidget(self._tagtable, 1, 0, 1, 2) def reload(self, filepath): self._selected_filepath = filepath filename = os.path.split(filepath)[-1] tags = data.get_file_tags(filename) self._tagtable_model.removeRows(0, self._tagtable_model.rowCount()) for name, count in tags: self._tagtable_model.appendRow( [QStandardItem(name), QStandardItem(str(count))]) self._entry.clear() print('Loaded {} tags for {}'.format(len(tags), filename)) def _remove_selected_file_tag(self): filename = os.path.split(self._selected_filepath)[-1] tagname = self._get_selected_tag() data.delete_filetag(filename, tagname) print('Removed tag {} from {}'.format(tagname, filename)) self.reload(self._selected_filepath) def _get_selected_tag(self): idx = self._tagtable.selectionModel().currentIndex() if idx.column() != 0: # Get tagname even if another column is selected idx = idx.siblingAtColumn(0) return self._tagtable_model.itemFromIndex(idx).text() def _add_tag_to_selected_file(self): filename = os.path.split(self._selected_filepath)[-1] tagname = self._entry.text().strip().replace(' ', '_').lower() if tagname == '': print('Refusing to add empty tag') return if data.create_filetag(filename, tagname): self.reload(self._selected_filepath) print('Added tag {} to {}'.format(tagname, filename)) else: print('{} already has tag {}'.format(filename, tagname)) self._entry.clear()
class ElementAllegroMonitored(QFrame): def __init__(self, name, link, is_done, price, xpath, time, is_monitoring, parent=None, shared_dict=None): QFrame.__init__(self, parent) self.shared_dict = shared_dict self.setMinimumSize(QSize(0, 300)) self.setStyleSheet("""QFrame{border-bottom: 0.5px solid #aaa;}""") self.setFrameShape(QFrame.StyledPanel) self.setFrameShadow(QFrame.Raised) self.horizontalLayout = QHBoxLayout(self) # create description frame and layout self.frame_description = QFrame(self) self.frame_description.setMinimumSize(QSize(440, 16777215)) self.frame_description.setStyleSheet("""QFrame{border: none;}""") self.frame_description.setFrameShape(QFrame.StyledPanel) self.frame_description.setFrameShadow(QFrame.Raised) self.gridLayout_description = QGridLayout(self.frame_description) self.horizontalLayout.addWidget(self.frame_description) self.gridLayout_description.setColumnStretch(0, 1) self.gridLayout_description.setColumnStretch(1, 2) self.gridLayout_description.setColumnStretch(2, 3) self.gridLayout_description.setColumnStretch(3, 1) self.gridLayout_description.setColumnStretch(4, 6) # fill description layout self.label_name = QLabel(name, self.frame_description) self.label_name.setStyleSheet(styles.label_allegro_monitored_name) self.label_name.setTextFormat(Qt.MarkdownText) self.label_name.setAlignment(Qt.AlignJustify | Qt.AlignVCenter) self.label_name.setWordWrap(False) self.gridLayout_description.addWidget(self.label_name, 0, 0, 1, 5) self.url_link = "<a href=\"" + link + "\" style = \" color: #838836; text-decoration: none; font-family:corbel; title=\"Go to monitored page\"\">check product</a>" self.label_monitored_link = QLabel(url_link, self.frame_description) self.label_monitored_link.setStyleSheet(styles.label_allegro_monitored_link) self.gridLayout_description.addWidget(self.label_monitored_link, 1, 1, 2, 2) self.label_monitored_link.setOpenExternalLinks(True) self.label_stat = QLabel(self.frame_description) self.label_stat.setStyleSheet(styles.label_allegro_monitored_stat) self.gridLayout_description.addWidget(self.label_stat, 1, 4, 1, 1) self.label_is_on = QLabel(self.frame_description) self.label_is_on.setStyleSheet(styles.label_allegro_monitored_stat) self.gridLayout_description.addWidget(self.label_is_on, 5, 0, 1, 2) self.label_new_time = QLabel("Actual refresh time[s]: " + str(time)+" s", self.frame_description) self.label_new_time.setStyleSheet(styles.label_allegro_monitored_stat) self.gridLayout_description.addWidget(self.label_new_time, 4, 0, 1, 3) self.lineEdit_new_time = QLineEdit(self.frame_description) self.lineEdit_new_time.setMinimumSize(QSize(0, 33)) self.lineEdit_new_time.setStyleSheet(styles.lineEdit) self.gridLayout_description.addWidget(self.lineEdit_new_time, 4, 3, 1, 2) self.lineEdit_new_time.setPlaceholderText("Set new interval") self.label_new_price = QLabel("Actual price: " + str(price), self) self.label_new_price.setStyleSheet(styles.label_allegro_monitored_stat) self.gridLayout_description.addWidget(self.label_new_price, 3, 0, 1, 3) self.lineEdit_new_price = QLineEdit(self) self.lineEdit_new_price.setMinimumSize(QSize(0, 35)) self.lineEdit_new_price.setStyleSheet(styles.lineEdit) self.gridLayout_description.addWidget(self.lineEdit_new_price, 3, 3, 1, 2) self.lineEdit_new_price.setPlaceholderText("Set new price") self.label_img_link = QLabel(self.frame_description) self.label_img_link.setMaximumSize(QSize(20, 20)) self.label_img_link.setStyleSheet("""QLabel{border: none;}""") self.label_img_link.setPixmap(QPixmap(os.path.join(path, "img/link.png"))) self.label_img_link.setScaledContents(True) self.gridLayout_description.addWidget(self.label_img_link, 1, 0, 2, 1) self.label_img_stat = QLabel("done", self.frame_description) if is_done: self.label_stat.setText("done") self.label_img_stat.setPixmap(QPixmap(os.path.join(path, "img/check.png"))) else: self.label_stat.setText("in progress") self.label_img_stat.setPixmap(QPixmap(os.path.join(path, "img/loading.png"))) self.label_img_stat.setMaximumSize(QSize(20, 20)) self.label_img_stat.setStyleSheet("""QLabel{border: none;}""") self.label_img_stat.setScaledContents(True) self.gridLayout_description.addWidget(self.label_img_stat, 1, 3, 1, 1) self.label_img_monitor = QLabel("done", self.frame_description) if is_monitoring: monitor_text = "I am just monitoring" self.label_img_monitor.setPixmap(QPixmap(os.path.join(path, "img/monitoring.png"))) else: monitor_text = "I am going to buy" self.label_img_monitor.setPixmap(QPixmap(os.path.join(path, "img/buy.png"))) self.label_is_monitoring = QLabel(monitor_text, self) self.label_is_monitoring.setStyleSheet(styles.label_allegro_monitored_stat) self.gridLayout_description.addWidget(self.label_is_monitoring, 2, 4, 1, 1) self.label_img_monitor.setMaximumSize(QSize(20, 20)) self.label_img_monitor.setStyleSheet("""QLabel{border: none;}""") self.label_img_monitor.setScaledContents(True) self.gridLayout_description.addWidget(self.label_img_monitor, 2, 3, 1, 1) # create spacer and delete btn self.spacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(self.spacer) self.pushButton_delete = QPushButton(self) # self.pushButton_delete.clicked.connect( lambda: self.deleteLater()) self.pushButton_delete.clicked.connect(lambda: self.on_delete(link)) icon = QIcon() icon.addFile(os.path.join(path, "img/delete.png"), QSize(), QIcon.Selected, QIcon.Off) # icon.Active.addFile(os.path.join(path, "img/icon.png"), QSize(), QIcon.Selected, QIcon.Off) self.pushButton_delete.setIcon(icon) self.pushButton_delete.setIconSize(QSize(50, 50)) self.pushButton_delete.setStyleSheet("""QPushButton{border:none; }""") self.pushButton_delete.setCursor(QCursor(Qt.PointingHandCursor)) # self.pushButton_delete.ico self.horizontalLayout.addWidget(self.pushButton_delete) self.is_on = data.get_switch_state(link) self.pushButton_switch = QPushButton(self) self.pushButton_switch.clicked.connect(lambda: self.on_switch(link)) self.icon_on = QIcon() self.icon_off = QIcon() self.icon_on.addFile(os.path.join(path, "img/switch_on.png"), QSize(), QIcon.Selected, QIcon.On) self.icon_off.addFile(os.path.join(path, "img/switch_off.png"), QSize(), QIcon.Selected, QIcon.Off) if self.is_on: self.label_is_on.setText("Disable") self.pushButton_switch.setIcon(self.icon_on) else: self.label_is_on.setText("Enable") self.pushButton_switch.setIcon(self.icon_off) self.pushButton_switch.setIconSize(QSize(100, 40)) self.pushButton_switch.setStyleSheet("""QPushButton{border:none; }""") self.pushButton_switch.setCursor(QCursor(Qt.PointingHandCursor)) self.gridLayout_description.addWidget(self.pushButton_switch, 5, 2, 1, 1) self.pushButton_save_changes = QPushButton("Save", self) self.pushButton_save_changes.clicked.connect(lambda: self.on_save_changes(link)) self.pushButton_save_changes.setIconSize(QSize(100, 20)) self.pushButton_save_changes.setStyleSheet(styles.btn_dark) self.pushButton_save_changes.setCursor(QCursor(Qt.PointingHandCursor)) self.gridLayout_description.addWidget(self.pushButton_save_changes, 5, 3, 1, 2) def on_delete(self, link): data.delete_monitored_element(link) self.deleteLater() self.shared_dict['isTerminatedP2'] = True def on_save_changes(self, link): data.change_price_time(link, self.lineEdit_new_price.text(), self.lineEdit_new_time.text()) if self.lineEdit_new_price.text() != '': self.label_new_price.setText("Actual price: " + self.lineEdit_new_price.text()) if self.lineEdit_new_time.text() != '': self.label_new_time.setText("Actual refresh time[s]: " + self.lineEdit_new_time.text() + " s") self.lineEdit_new_time.clear() self.lineEdit_new_price.clear() self.shared_dict['isTerminatedP2'] = True def on_switch(self, link): # m.stop_run_monitor() if self.is_on: self.label_is_on.setText("Enable") self.pushButton_switch.setIcon(self.icon_off) self.is_on = False data.switch_state(self.is_on, link) else: self.label_is_on.setText("Disable") self.pushButton_switch.setIcon(self.icon_on) self.is_on = True data.switch_state(self.is_on, link) self.shared_dict['isTerminatedP2'] = True
class PageAllegroAdd(QWidget): def __init__(self, parent=None, shared_dict=None): QWidget.__init__(self, parent) parent.addWidget(self) self.shared_dict = shared_dict self.gridLayout = QGridLayout(self) self.gridLayout.setContentsMargins(0, 0, 0, 0) self.gridLayout.setRowStretch(0, 1) self.gridLayout.setRowStretch(1, 1) self.gridLayout.setRowStretch(2, 1) self.gridLayout.setRowStretch(3, 1) self.gridLayout.setRowStretch(4, 1) self.gridLayout.setRowStretch(5, 1) self.gridLayout.setRowStretch(6, 1) self.gridLayout.setRowStretch(7, 1) self.gridLayout.setRowStretch(8, 1) self.gridLayout.setRowStretch(9, 1) self.gridLayout.setRowStretch(10, 1) self.gridLayout.setRowStretch(11, 1) self.gridLayout.setRowStretch(12, 1) self.gridLayout.setRowStretch(13, 1) self.gridLayout.setRowStretch(14, 2) self.gridLayout.setRowStretch(15, 1) self.gridLayout.setColumnStretch(0, 5) self.gridLayout.setColumnStretch(1, 5) self.gridLayout.setColumnStretch(2, 1) self.gridLayout.setColumnStretch(3, 2) self.gridLayout.setColumnStretch(4, 1) self.gridLayout.setColumnStretch(5, 2) self.gridLayout.setColumnStretch(6, 1) self.gridLayout.setColumnStretch(7, 2) self.gridLayout.setColumnStretch(8, 3) self.gridLayout.setColumnStretch(9, 5) # create lineEdits self.lineEdit_login = QLineEdit(self) self.lineEdit_login.setMinimumSize(QSize(0, 60)) self.lineEdit_login.setSizeIncrement(QSize(40, 40)) self.lineEdit_login.setStyleSheet(styles.lineEdit) self.lineEdit_login.setMaxLength(32767) self.gridLayout.addWidget(self.lineEdit_login, 4, 1, 1, 3) self.lineEdit_login.setPlaceholderText("login or email of your account") self.lineEdit_password = QLineEdit(self) self.lineEdit_password.setMinimumSize(QSize(20, 60)) self.lineEdit_password.setStyleSheet(styles.lineEdit) self.lineEdit_password.setEchoMode(QLineEdit.Password) self.lineEdit_password.setReadOnly(False) self.gridLayout.addWidget(self.lineEdit_password, 7, 1, 1, 3) self.lineEdit_password.setPlaceholderText("password of your account") self.lineEdit_email = QLineEdit(self) self.lineEdit_email.setMinimumSize(QSize(0, 60)) self.lineEdit_email.setStyleSheet(styles.lineEdit) self.lineEdit_email.setFrame(True) self.lineEdit_email.setEchoMode(QLineEdit.Normal) self.gridLayout.addWidget(self.lineEdit_email, 7, 5, 1, 4) self.lineEdit_email.setPlaceholderText("email to which the notification will be sent") self.lineEdit_link = QLineEdit(self) self.lineEdit_link.setMinimumSize(QSize(0, 60)) self.lineEdit_link.setStyleSheet(styles.lineEdit) self.gridLayout.addWidget(self.lineEdit_link, 10, 1, 1, 8) self.lineEdit_link.setPlaceholderText("link to the page that you want to monitor") self.lineEdit_price = QLineEdit(self) self.lineEdit_price.setMinimumSize(QSize(0, 60)) self.lineEdit_price.setStyleSheet(styles.lineEdit) self.gridLayout.addWidget(self.lineEdit_price, 13, 1, 1, 1) self.lineEdit_price.setPlaceholderText("Price below which to notificate") self.lineEdit_xpath = QLineEdit(self) self.lineEdit_xpath.setMinimumSize(QSize(0, 60)) self.lineEdit_xpath.setStyleSheet(styles.lineEdit) self.gridLayout.addWidget(self.lineEdit_xpath, 13, 3, 1, 3) self.lineEdit_xpath.setPlaceholderText("XPATH of element with the price") self.lineEdit_time = QLineEdit(self) self.lineEdit_time.setMinimumSize(QSize(0, 60)) self.lineEdit_time.setStyleSheet(styles.lineEdit) self.gridLayout.addWidget(self.lineEdit_time, 13, 7, 1, 2) self.lineEdit_time.setPlaceholderText("interval between refreshes") # Create Labels self.label_title = QLabel("Add new monitoring object", self) self.label_title.setStyleSheet(styles.label_title) self.label_title.setAlignment(Qt.AlignCenter) self.gridLayout.addWidget(self.label_title, 0, 1, 1, 8) self.label_info = QLabel("", self) self.label_info.setStyleSheet(styles.label_info_wrong) self.label_info.setAlignment(Qt.AlignCenter) self.gridLayout.addWidget(self.label_info, 1, 1, 1, 8) self.label_login = QLabel("Allegro login", self) self.label_login.setStyleSheet(styles.label_lineEdit) self.gridLayout.addWidget(self.label_login, 3, 1, 1, 3) self.label_password = QLabel("Allegro password", self) self.label_password.setStyleSheet(styles.label_lineEdit) self.gridLayout.addWidget(self.label_password, 6, 1, 1, 3) self.label_email = QLabel("Email to notificate", self) self.label_email.setStyleSheet(styles.label_lineEdit) self.gridLayout.addWidget(self.label_email, 6, 5, 1, 4) self.label_link = QLabel("Product link", self) self.label_link.setStyleSheet(styles.label_lineEdit) self.gridLayout.addWidget(self.label_link, 9, 1, 1, 8) self.label_price = QLabel("Price", self) self.label_price.setStyleSheet(styles.label_lineEdit) self.gridLayout.addWidget(self.label_price, 12, 1, 1, 1) self.label_xpath = QLabel("Monitored element", self) self.label_xpath.setStyleSheet(styles.label_lineEdit) self.gridLayout.addWidget(self.label_xpath, 12, 3, 1, 3) self.label_time = QLabel("Refresh time[s]", self) self.label_time.setStyleSheet(styles.label_lineEdit) self.gridLayout.addWidget(self.label_time, 12, 7, 1, 2) self.pushButton_search = QPushButton(self) self.pushButton_search.clicked.connect(lambda: webbrowser.open('https://allegro.pl/')) icon = QIcon() icon.addFile(os.path.join(path, "img/search.png"), QSize(), QIcon.Selected, QIcon.Off) self.pushButton_search.setIcon(icon) self.pushButton_search.setIconSize(QSize(100, 100)) self.pushButton_search.setStyleSheet("""QPushButton{border:none;}""") self.pushButton_search.setCursor(QCursor(Qt.PointingHandCursor)) self.gridLayout.addWidget(self.pushButton_search, 3, 7, 3, 1) # Create spacers self.spacer_search_l = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.gridLayout.addItem(self.spacer_search_l, 5, 5, 1, 2) self.spacer_search_r = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.gridLayout.addItem(self.spacer_search_r, 5, 8, 1, 1) self.spacer_search_t = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.gridLayout.addItem(self.spacer_search_t, 2, 1, 1, 8) self.spacer_search_b = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.gridLayout.addItem(self.spacer_search_b, 5, 1, 1, 8) self.spacer_email_l = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.gridLayout.addItem(self.spacer_email_l, 7, 4, 1, 1) self.spacer_link_l = QSpacerItem(40, 20, QSizePolicy.MinimumExpanding, QSizePolicy.Minimum) self.gridLayout.addItem(self.spacer_link_l, 13, 0, 1, 1) self.spacer_link_r = QSpacerItem(40, 20, QSizePolicy.MinimumExpanding, QSizePolicy.Minimum) self.gridLayout.addItem(self.spacer_link_r, 13, 9, 1, 1) self.spacer_link_t = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.gridLayout.addItem(self.spacer_link_t, 8, 1, 1, 8) self.spacer_link_b = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.gridLayout.addItem(self.spacer_link_b, 11, 1, 1, 8) self.spacer_price_b = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.gridLayout.addItem(self.spacer_price_b, 14, 1, 1, 7) # create frame bottom self.frame_bottom = QFrame(self) self.frame_bottom.setStyleSheet("""QFrame{background-color: #fff; padding: 10px;}""") self.frame_bottom.setFrameShape(QFrame.StyledPanel) self.frame_bottom.setFrameShadow(QFrame.Raised) self.gridLayout.addWidget(self.frame_bottom, 15, 0, 1, 10) self.horizontalLayout_frame_bottom = QHBoxLayout(self.frame_bottom) self.spacer_frame_bottom_l = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_frame_bottom.addItem(self.spacer_frame_bottom_l) self.pushButton_bn = QPushButton("Buy when price drops", self.frame_bottom) self.pushButton_bn.setMinimumSize(QSize(0, 40)) self.pushButton_bn.setStyleSheet(styles.btn_light) self.horizontalLayout_frame_bottom.addWidget(self.pushButton_bn) self.pushButton_bn.setShortcut("Return") self.spacer_frame_bottom_c = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_frame_bottom.addItem(self.spacer_frame_bottom_c) self.pushButton_monitor = QPushButton("Monitor", self.frame_bottom) self.pushButton_monitor.clicked.connect(lambda: self.new_link_handler(True)) self.pushButton_monitor.setMinimumSize(QSize(0, 40)) self.pushButton_monitor.setStyleSheet(styles.btn_dark) self.horizontalLayout_frame_bottom.addWidget(self.pushButton_monitor) self.spacer_frame_bottom_r = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_frame_bottom.addItem(self.spacer_frame_bottom_r) self.horizontalLayout_frame_bottom.setStretch(0, 1) self.horizontalLayout_frame_bottom.setStretch(1, 1) self.horizontalLayout_frame_bottom.setStretch(2, 2) self.horizontalLayout_frame_bottom.setStretch(3, 1) self.horizontalLayout_frame_bottom.setStretch(4, 1) self.timer = QTimer(self) auto_login, auto_pwd, auto_email, auto_time = data.get_autofill() self.lineEdit_login.setText(auto_login) self.lineEdit_password.setText(auto_pwd) self.lineEdit_email.setText(auto_email) self.lineEdit_time.setText(str(auto_time)) def new_link_handler(self, is_monitoring): # check if fields were filled properly no_warnings = True is_email = False link = "" login = "" email = "" password = "" xpath = "" price = 0 time = 60 if self.lineEdit_email.text() == "": self.lineEdit_email.setStyleSheet(styles.lineEdit_warning) no_warnings = False else: self.lineEdit_email.setStyleSheet(styles.lineEdit) email = self.lineEdit_email.text() for symbol in email: if symbol == '@': is_email = True if not is_email: self.lineEdit_email.setStyleSheet(styles.lineEdit_warning) no_warnings = False if self.lineEdit_login.text() == "": self.lineEdit_login.setStyleSheet(styles.lineEdit_warning) no_warnings = False else: self.lineEdit_login.setStyleSheet(styles.lineEdit) login = self.lineEdit_login.text() if self.lineEdit_link.text() == "": self.lineEdit_link.setStyleSheet(styles.lineEdit_warning) no_warnings = False else: self.lineEdit_link.setStyleSheet(styles.lineEdit) link = self.lineEdit_link.text() if self.lineEdit_password.text() == "": self.lineEdit_password.setStyleSheet(styles.lineEdit_warning) no_warnings = False else: self.lineEdit_password.setStyleSheet(styles.lineEdit) password = self.lineEdit_password.text() if self.lineEdit_price.text() == "": self.lineEdit_price.setStyleSheet(styles.lineEdit_warning) no_warnings = False else: self.lineEdit_price.setStyleSheet(styles.lineEdit) price = float(self.lineEdit_price.text()) if self.lineEdit_xpath.text() == "": self.lineEdit_xpath.setStyleSheet(styles.lineEdit_warning) no_warnings = False else: self.lineEdit_xpath.setStyleSheet(styles.lineEdit) xpath = self.lineEdit_xpath.text() if self.lineEdit_time.text() == "": self.lineEdit_time.setStyleSheet(styles.lineEdit_warning) no_warnings = False else: self.lineEdit_time.setStyleSheet(styles.lineEdit) time = int(self.lineEdit_time.text()) if no_warnings: self.lineEdit_login.clear() self.lineEdit_password.clear() self.lineEdit_email.clear() self.lineEdit_link.clear() self.lineEdit_price.clear() self.lineEdit_xpath.clear() self.lineEdit_time.clear() try: data.add_monitored_elements(login, email, password, link, price, xpath, time, is_monitoring) self.shared_dict['isTerminatedP2'] = True except InvalidArgumentException: self.set_info_text("Warning. Wrong link submitted", True) except KeyError: self.set_info_text("Error. This page has already monitored", True) else: self.set_info_text("Info. Object was successfully added", False) self.lineEdit_login.setText(self.auto_login) self.lineEdit_password.setText(self.auto_pwd) self.lineEdit_email.setText(self.auto_email) self.lineEdit_time.setText(self.auto_time) self.lineEdit_link.clear() self.lineEdit_price.clear() self.lineEdit_xpath.clear() else: self.set_info_text("Warning. Fill all field properly", True) return data.get_element(link) # def on_monitor(self): # new_price = monitoring.check_if_price_lower(self.label_link, self.label_xpath, self.label_price, self.label_time) # email_send.send_email(self.label_email, self.label_link, new_price) def set_info_text(self, text, is_warning): self.label_info.setText(text) if is_warning: self.label_info.setStyleSheet(styles.label_info_wrong) else: self.label_info.setStyleSheet(styles.label_info_right) self.timer.setInterval(5000) self.timer.timeout.connect(lambda: self.label_info.setText("")) self.timer.start()
class DatasheetView(QMainWindow): def __init__(self, pdfPath=None, pageNumber=1): super().__init__() # initialize data files # self.fileStore = path.join(path.curdir, "/files") # mkdir(self.fileStore) self.svgFiles = [] # window dimensions self.top = 300 self.left = 800 self.width = 860 self.height = 980 self.setGeometry(self.left, self.top, self.width, self.height) # window title self.setWindowTitle("Hello") # sets up main layout -- splitters self.initUILayout() self.initUIToolbar() self.populatePDF(pdfPath, pageNumber) self.show() def initUILayout(self): # set left-side, Dynamic View self.dynamicViewDisplay = QLabel() self.vBoxA = QVBoxLayout() self.vBoxA.addWidget(self.dynamicViewDisplay) self.groupA = QGroupBox() self.groupA.setTitle("Dynamic Veiw") self.groupA.setLayout(self.vBoxA) # set left-side, Static View self.staticViewDisplay = QLabel() self.vBoxB = QVBoxLayout() self.vBoxB.addWidget(self.staticViewDisplay) self.groupB = QGroupBox() self.groupB.setTitle("Static View") self.groupB.setLayout(self.vBoxB) # add Dynamic and Static Views to resizeable left-side Splitter self.altViewSplit = QSplitter(Qt.Vertical) self.altViewSplit.addWidget(self.groupA) self.altViewSplit.addWidget(self.groupB) # set up Tools View section self.toolsTabView = QTabWidget() self.toolsTabView.setTabsClosable(True) self.toolsTabView.setMovable(True) self.toolsTabView.setDocumentMode(True) # self.toolsTabView.setTabBarAutoHide(True) # add attribute for storing page notes self.notesDB = [] self.notesDisplay = QListWidget(self) self.notesDisplay.setMaximumHeight(200) # add ToC to Tools View self.ToCListView = QListWidget() self.toolsTabView.addTab(self.ToCListView, "Table of Contents") # add notes list to tools view self.toolsTabView.addTab(self.notesDisplay, "Notes") # add tools view to the left-side splitter self.altViewSplit.addWidget(self.toolsTabView) # set right-side view -- SVG Viewer self.mainDisplay = QSvgWidget() self.vBoxMain = QVBoxLayout() self.vBoxMain.addWidget(self.mainDisplay) self.notesArea = QLineEdit() self.notesArea.setPlaceholderText("Add a note about this page...") self.notesArea.returnPressed.connect(self.onAddNote) self.vBoxMain.addWidget(self.notesArea) self.mainViewGroup = QGroupBox() self.mainViewGroup.setTitle("Main View") self.mainViewGroup.setLayout(self.vBoxMain) # join both sides together self.leftRightSplit = QSplitter(Qt.Horizontal) self.leftRightSplit.addWidget(self.altViewSplit) self.leftRightSplit.addWidget(self.mainViewGroup) self.setCentralWidget(self.leftRightSplit) def initUIToolbar(self): mainMenu = self.menuBar() # get the menu bar already in use by this QMainWindow class fileMenu = mainMenu.addMenu("File") editMenu = mainMenu.addMenu("Edit") LayoutMenu = mainMenu.addMenu("Layout") AboutMenu = mainMenu.addMenu("About") saveAction = fileMenu.addAction("Save") quitAction = fileMenu.addAction("Exit Bettersheets") quitAction.triggered.connect(self.quitApp) copyAction = editMenu.addAction("Copy") resetAction = LayoutMenu.addAction("Reset Default Layout") # mainMenu.setNativeMenuBar(True) # mainMenu.show() self. toolBar = self.addToolBar("Tools") self.toolBar.addAction(saveAction) self.toolBar.addAction(copyAction) def contextMenuEvent(self, event): # return super().contextMenuEvent(event) contextMenu = QMenu() selectAction = contextMenu.addAction("Select Area") extractAction = contextMenu.addAction("Extract Content") openAction = contextMenu.addAction("Open PDF") closeAction = contextMenu.addAction("Close PDF") quitAction = contextMenu.addAction("Quit") triggered_action = contextMenu.exec_(self.mapToGlobal(event.pos())) if triggered_action == quitAction: self.quitApp() def quitApp(self): self.close() def onAddNote(self): print("note added") text = self.notesArea.text() if text: self.notesDB.append(text) self.notesDisplay.clear() self.notesDisplay.addItems(self.notesDB) self.notesArea.clear() def populatePDF(self, pdfPath, pageNumber): if pdfPath: self.document = PDFContext(pdfPath, pageNumber) ToC = self.document.getToC() ToC_headings_list = [x[1] for x in ToC] self.ToCListView.clear() self.ToCListView.addItems(ToC_headings_list) # display page in main view self.document.openPDF(pdfPath, pageNumber) self.SVGString = self.document.getRender(self.document.currentPageNumber) # set filename of current PDF self.pdfName = path.split(pdfPath)[1].split('.')[0] # write current page to .svg file file_loc = self._writeSVGToFile_(self.pdfName, pageNumber, self.SVGString) # open the file we just wrote to self.mainDisplay.load(file_loc) @staticmethod def _writeSVGToFile_(pdfName: str, pageNumber: int, svg_string: str) -> str: """ return the full file path we just wrote """ file_loc = f"./src/main/files/{pdfName}-page-{pageNumber}.svg" with open(file_loc , 'w') as f: f.write(svg_string) print("File_loc: ", file_loc) return file_loc
class VentanaAdministradorDePersonas(QFrame): def __init__(self, parent=None): super(VentanaAdministradorDePersonas, self).__init__(parent) raiz.setWindowTitle("Administracion de personas") self.operacionesConPersonas = OperacionesConPersonas() self.instanciarVentana() def instanciarVentana(self): #Contenedor De todas las cosas de arriba a abajo layoutGeneral = QVBoxLayout() #Cosas de Derecha layoutDerecha = QVBoxLayout() #Ordena cosas de arriba a abajo layoutDerecha.setMargin(20) self.btnAgregarPersona = QPushButton("Agregar persona") self.btnAgregarPersona.setToolTip("Toma los datos ") self.btnAgregarPersona.clicked.connect(self.agregarPersona) layoutDerecha.addWidget(self.btnAgregarPersona) self.btnBuscarPersona = QPushButton("Buscar persona") self.btnBuscarPersona.setToolTip("Busca por cedula a una persona") self.btnBuscarPersona.clicked.connect(self.buscarPersona) layoutDerecha.addWidget(self.btnBuscarPersona) self.btnEliminarPersona = QPushButton("Eliminar persona") self.btnEliminarPersona.setToolTip( "Elimina a la persona que esta en busqueda") self.btnEliminarPersona.clicked.connect(self.eliminarPersona) layoutDerecha.addWidget(self.btnEliminarPersona) self.btnActualizarPersona = QPushButton("Actualizar persona") self.btnActualizarPersona.setToolTip( "Cambia los datos de la persona seleccionada") self.btnActualizarPersona.clicked.connect(self.actualizarPersona) layoutDerecha.addWidget(self.btnActualizarPersona) self.btnLimpiarTexto = QPushButton("Limpiar") self.btnLimpiarTexto.setToolTip( "Limpia los campos de texto para ingresar datos") self.btnLimpiarTexto.clicked.connect(self.limpiarCampos) layoutDerecha.addWidget(self.btnLimpiarTexto) self.btnVolverAlMenu = QPushButton("Volver") self.btnVolverAlMenu.setToolTip("Vuelve al menu principal") self.btnVolverAlMenu.clicked.connect(self.volverAlMenu) layoutDerecha.addWidget(self.btnVolverAlMenu) #Cosas de Izquierda layoutIzquierda = QVBoxLayout() #ordena cosas de arriba a abajo self.lblDNI = QLabel("DNI: ") layoutIzquierda.addWidget(self.lblDNI) self.DNI = QLineEdit() layoutIzquierda.addWidget(self.DNI) self.lblPrimerNombre = QLabel("Primer nombre: ") layoutIzquierda.addWidget(self.lblPrimerNombre) self.PrimerNombre = QLineEdit() layoutIzquierda.addWidget(self.PrimerNombre) self.lblSegundoNombre = QLabel("Segundo nombre: ") layoutIzquierda.addWidget(self.lblSegundoNombre) self.SegundoNombre = QLineEdit() layoutIzquierda.addWidget(self.SegundoNombre) self.lblPrimerApellido = QLabel("Primer apellido: ") layoutIzquierda.addWidget(self.lblPrimerApellido) self.PrimerApellido = QLineEdit() layoutIzquierda.addWidget(self.PrimerApellido) self.lblSegundoApellido = QLabel("Segundo apellido: ") layoutIzquierda.addWidget(self.lblSegundoApellido) self.SegundoApellido = QLineEdit() layoutIzquierda.addWidget(self.SegundoApellido) self.lblFechaDeNacimiento = QLabel("Fecha de nacimiento") layoutIzquierda.addWidget(self.lblFechaDeNacimiento) self.fechaDeNacimiento = QDateEdit() self.fechaDeNacimiento.setDisplayFormat("yyyy-MM-dd") self.fechaDeNacimiento.setCalendarPopup(True) self.fechaDeNacimiento.setDate(date.today()) layoutIzquierda.addWidget(self.fechaDeNacimiento) #Cosas de layout de arriba layoutSuperior = QHBoxLayout() #Ordena cosas de derecha a izquierda layoutSuperior.addLayout(layoutIzquierda) layoutSuperior.addLayout(layoutDerecha) #Cosas layout de abajo layoutInferior = QVBoxLayout() self.mostrarError = QPlainTextEdit(readOnly=True) layoutInferior.addWidget(self.mostrarError) #cosas del layout general layoutGeneral.addLayout(layoutSuperior) layoutGeneral.addLayout(layoutInferior) self.setLayout(layoutGeneral) #Redimensionar raiz.adjustSize() self.adjustSize() def agregarPersona(self): self.limpiarErrores() try: laPersona = self.llenarPersona() salida = self.operacionesConPersonas.insertarPersona(laPersona) self.mostrarError.insertPlainText(str(salida)) self.limpiarCampos( ) #habilitamos la edicion y evitamos dejar datos basura except Exception as e: self.mostrarError.insertPlainText(''.join(e.args)) pass def buscarPersona(self): self.limpiarErrores() try: laPersona = self.operacionesConPersonas.buscarPersonaPorDNI( int(''.join(self.DNI.text()))) if type(laPersona) == type(""): self.mostrarError.insertPlainText(''.join(laPersona)) return None self.llenarCampos(laPersona) except Exception as e: self.mostrarError.insertPlainText(''.join(e.args)) def eliminarPersona(self): self.limpiarErrores() try: laPersona = self.llenarPersona() mensajeDeConfirmacion = "DNI: " + self.DNI.text() opcionElegida = QMessageBox.question( self, "Desea eliminar a la persona?", mensajeDeConfirmacion, QMessageBox.Yes, QMessageBox.No) if opcionElegida == QMessageBox.Yes: respuesta = self.operacionesConPersonas.eliminarPersona( laPersona) if type(respuesta) == type(""): self.mostrarError.insertPlainText(''.join(respuesta)) self.limpiarCampos() return None except Exception as e: self.mostrarError.insertPlainText(''.join(e.args)) def actualizarPersona(self): self.limpiarErrores() try: laPersona = self.llenarPersona() mensajeDeConfirmacion = "DNI: " + self.DNI.text() opcionElegida = QMessageBox.question( self, "Desea eliminar a la persona?", mensajeDeConfirmacion, QMessageBox.Yes, QMessageBox.No) if opcionElegida == QMessageBox.Yes: respuesta = self.operacionesConPersonas.actualizarPersona( laPersona) if type(respuesta) == type(""): self.mostrarError.insertPlainText(''.join(respuesta)) self.limpiarCampos() return None except Exception as e: print(e.args) def llenarCampos(self, laPersona): self.limpiarCampos() self.DNI.setText(str(laPersona.getDNI())) self.DNI.setReadOnly(True) self.PrimerNombre.setText(laPersona.getPrimerNombre()) self.SegundoNombre.setText(laPersona.getSegundoNombre()) self.PrimerApellido.setText(laPersona.getPrimerApellido()) self.SegundoApellido.setText(laPersona.getSegundoApellido()) self.fechaDeNacimiento.setDate(laPersona.getFechaDeNacimiento()) def llenarPersona(self): return Persona(int(''.join(self.DNI.text())), ''.join(self.PrimerNombre.text()), ''.join(self.SegundoNombre.text()), ''.join(self.PrimerApellido.text()), ''.join(self.SegundoApellido.text()), ''.join(self.fechaDeNacimiento.text())) def limpiarCampos(self): self.DNI.clear() self.DNI.setReadOnly(False) self.PrimerNombre.clear() self.SegundoNombre.clear() self.PrimerApellido.clear() self.SegundoApellido.clear() self.fechaDeNacimiento.setDate(date.today()) #limpiar campos de texto y permitir la edicion de todos ellos def limpiarErrores(self): self.mostrarError.clear() def volverAlMenu(self): raiz.setCentralWidget(None) raiz.setCentralWidget(VentanaPrincipal())
class Widget(QWidget): def __init__(self): QWidget.__init__(self) self.row = 0 self.coins_sum = 0 self.settings = QSettings('NoneCompany', 'freebot') VBoxLayout = QVBoxLayout() # Right HBoxLayout = QHBoxLayout() # Left self.create_form() self.set_placeholders() self.define_table() FormLayout = QHBoxLayout() FormLayout.addWidget(self.form_login) FormLayout.addWidget(self.form_password) FormLayout.addWidget(self.form_proxy) self.create_buttons() FromButtonsLayout = QHBoxLayout() FromButtonsLayout.addWidget(self.add_button) FromButtonsLayout.addWidget(self.clear_button) self.series = QtCharts.QLineSeries() self.chart_view = QtCharts.QChartView() self.chart_view.setRenderHint(QPainter.Antialiasing) VBoxLayout.addWidget(self.form_key) VBoxLayout.addLayout(FormLayout) VBoxLayout.addLayout(FromButtonsLayout) VBoxLayout.addWidget(self.chart_view) VBoxLayout.addWidget(self.start_button) HBoxLayout.addWidget(self.table) HBoxLayout.addLayout(VBoxLayout) self.setLayout(HBoxLayout) self.update_chart([time(), 0], True) self.create_connections() def set_placeholders(self): self.form_login.setPlaceholderText('login') self.form_password.setPlaceholderText('password') self.form_proxy.setPlaceholderText('proxy') self.form_key.setPlaceholderText('API-key rucaptcha.com') def create_form(self): self.form_login = QLineEdit() self.form_password = QLineEdit() self.form_proxy = QLineEdit() self.form_key = QLineEdit() def create_buttons(self): self.add_button = QPushButton('add') self.clear_button = QPushButton('clear') self.start_button = QPushButton('start') def create_connections(self): self.add_button.clicked.connect(self.fillin_table) self.start_button.clicked.connect(self.init_threads) self.clear_button.clicked.connect(self.clear_table) def define_table(self): self.table = QTableWidget() self.table.setColumnCount(len(CONSTANTS.TABLE_COLUMNS)) self.table.setHorizontalHeaderLabels(CONSTANTS.TABLE_COLUMNS) self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) if self.settings.contains('key'): self.form_key.setText(self.get_settings('key')) if self.settings.contains('table'): for row in literal_eval(self.get_settings('table')): self.add_account(*row, False) def set_settings(self, key, value): if key == 'table': if self.settings.contains('table'): table = literal_eval(self.get_settings('table')) table.append(value) value = table else: value = [value] self.settings.setValue(key, str(value)) def get_settings(self, key): return self.settings.value(key) @Slot(int, list) def change_column_color(self, row, RGB): for col in range(len(CONSTANTS.TABLE_COLUMNS)): self.table.item(row, col).setBackground(QColor(*RGB)) @Slot(int, str) def change_column_text(self, row, text): self.table.item(row, 3).setText(text) @Slot() def clear_table(self): self.settings.clear() self.table.setRowCount(0) self.row = 0 @Slot() def fillin_table(self, settings=False): if self.check_form_state(): return self.add_account(self.form_login.text(), self.form_password.text(), self.form_proxy.text()) self.form_login.clear() self.form_proxy.clear() self.form_password.clear() @Slot(list) def update_chart(self, data, init=False): self.coins_sum += data[1] MStime_now = float(QDateTime.currentDateTime().toMSecsSinceEpoch()) if init: self.series.append(MStime_now, self.coins_sum) for i in range(6): if i and not i % 2: self.series.append(MStime_now + (i * 1), self.coins_sum) else: self.series.append(MStime_now + (i * 1), 0.00000001) else: self.series.append(MStime_now, self.coins_sum) chart = QtCharts.QChart() chart.addSeries(self.series) if not init: chart.setAnimationOptions(QtCharts.QChart.SeriesAnimations) chart.setTitle('Progress') axisX = QtCharts.QDateTimeAxis() axisX.setTickCount(5) axisX.setFormat('HH:mm:ss') axisX.setTitleText('time') chart.addAxis(axisX, Qt.AlignBottom) self.series.attachAxis(axisX) axisY = QtCharts.QValueAxis() axisY.setTickCount(5) axisY.setLabelFormat('%.8f') axisY.setTitleText('coins') chart.addAxis(axisY, Qt.AlignLeft) self.series.attachAxis(axisY) self.chart_view.setChart(chart) @Slot() def init_threads(self): self.start_button.setEnabled(False) self.set_settings('key', self.form_key.text()) self.threads = [ Bridge(self, row, self.table.item(row, 0).text(), self.table.item(row, 1).text(), self.table.item(row, 2).text(), self.form_key.text()) for row in range(self.table.rowCount()) ] def check_form_state(self): return not self.form_login.text() \ or not self.form_password.text() \ or not self.form_proxy.text() def add_account(self, login, password, proxy, record=True): self.table.insertRow(self.row) self.table.setItem(self.row, 0, QTableWidgetItem(login)) self.table.setItem(self.row, 1, QTableWidgetItem(password)) self.table.setItem(self.row, 2, QTableWidgetItem(proxy)) self.table.setItem(self.row, 3, QTableWidgetItem('?')) if record: self.set_settings('key', self.form_key.text()) self.set_settings('table', [login, password, proxy]) self.row += 1
class ConsoleDialog(QDialog): def __init__(self, title: str, program: str, args: List[str], commands: List[str]): super().__init__() self.setWindowTitle(title) self.program = program self.args = args self.layout = QGridLayout() self.output = QTextEdit() self.output.acceptRichText = True self.input = QLineEdit() self.completer = QCompleter(commands, self) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.input.setCompleter(self.completer) self.input.setFocus() self.layout.addWidget(self.output) self.layout.addWidget(self.input) self.setLayout(self.layout) self.connect(self.input, SIGNAL("returnPressed(void)"), self.execute_user_command) self.connect(self.completer, SIGNAL("activated(const QString&)"), self.input.clear, Qt.QueuedConnection) def execute_user_command(self): cmd = str(self.input.text()) self.run_command(cmd) def run_command(self, cmd: str): log.info( 'run_command', program=self.program, args=self.args, cmd=cmd ) self.output.append(f'> {cmd}\n') self.input.clear() process = QProcess() process.setProgram(self.program) process.setCurrentReadChannel(0) # noinspection PyUnresolvedReferences process.readyReadStandardError.connect( lambda: self.handle_error(process) ) # noinspection PyUnresolvedReferences process.readyReadStandardOutput.connect( lambda: self.handle_output(process) ) connect_args = list(self.args) args = cmd.split(' ') if args[0] == self.program.split('/')[-1]: args.pop(0) process.setArguments(connect_args + args) process.start() def handle_error(self, process: QProcess): output: QByteArray = process.readAllStandardError() message = output.data().decode('utf-8').strip() self.output.append(message) def handle_output(self, process: QProcess): output: QByteArray = process.readAllStandardOutput() message = output.data().decode('utf-8').strip() if message.startswith('{') or message.startswith('['): formatter = HtmlFormatter() formatter.noclasses = True formatter.linenos = False formatter.nobackground = True message = highlight(message, JsonLexer(), formatter) self.output.insertHtml(message) else: self.output.append(message) # This is just for generating the command lists in constants # commands = None # if '== Blockchain ==' in message: # commands = self.parse_litecoin_cli_commands(message) # elif 'lncli [global options] command [command options]' in message: # commands = self.parse_lncli_commands(message) # if commands is not None: # log.debug('commands', commands=commands) max_scroll = self.output.verticalScrollBar().maximum() self.output.verticalScrollBar().setValue(max_scroll) @staticmethod def parse_litecoin_cli_commands(message: str): log.debug('parse_litecoin_cli_commands') commands = [] for line in message.split(sep='\n'): line = line.strip() if not line or line.startswith('=='): continue command = line.split()[0] command = command.strip() commands.append(command) return commands @staticmethod def parse_lncli_commands(message: str): log.debug('parse_lncli_commands') at_commands = False commands = [] for line in message.split(sep='\n'): line = line.strip() if not at_commands: if 'COMMANDS:' in line: at_commands = True log.debug('commands line', line=line) continue elif 'GLOBAL OPTIONS' in line: return commands elif line.endswith(':') or not line: continue command = line.split()[0] command = command.strip().replace(',', '') commands.append(command) return commands def show(self): self.showMaximized() self.raise_() self.setWindowState(self.windowState() & ~Qt.WindowMinimized | Qt.WindowActive) self.activateWindow() self.input.setFocus() self.run_command('help')
class SearchWindow(QWidget): def __init__(self, rboost): super().__init__() self.rboost = rboost self.layout = QVBoxLayout() self._add_input_layout() self._add_output_layout() self.table_view = None self._add_table_view_layout() self.setLayout(self.layout) def _add_input_layout(self): self.input_layout = QHBoxLayout() self._add_label() self._add_input_line() search_button = QPushButton('Search') search_button.clicked.connect(self.show_results) clear_button = QPushButton('Clear') clear_button.clicked.connect(self.clear_results) self.input_layout.addWidget(search_button) self.input_layout.addWidget(clear_button) self.layout.addLayout(self.input_layout) def _add_label(self): label = QLabel('Label:') label.setFont(QFont('Arial', 16)) label.setAlignment(Qt.AlignVCenter | Qt.AlignRight) self.input_layout.addWidget(label) def _add_input_line(self): self.layout = QVBoxLayout() self.input_line = QLineEdit() self.input_line.setFont(QFont('Arial', 20)) self.input_line.setMaximumWidth(800) self.input_layout.addWidget(self.input_line) def _add_output_layout(self): self.output_layout = QVBoxLayout() self.label_not_found = QLabel() self.label_not_found.setFont(QFont('Times', 12)) self.label_not_found.setStyleSheet('QLabel {color : red}') self.similar_labels = QLabel() self.similar_labels.setFont(QFont('Times', 12)) self.output_layout.addWidget(self.label_not_found) self.output_layout.addWidget(self.similar_labels) self.layout.addLayout(self.output_layout) def _add_table_view_layout(self, df=None): self.table_view_layout = QHBoxLayout() if self.table_view is not None: self.table_view_layout.removeWidget(self.table_view) self.table_view.deleteLater() self.table_view = self._create_table_view(df=df) self.table_view_layout.addWidget(self.table_view) self.layout.addLayout(self.table_view_layout) def _create_table_view(self, df): if df is None: df = pd.DataFrame() model = PandasModel(df) table_view = QTableView() table_view.setModel(model) table_view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) return table_view def _get_dataframe(self, label): dframe = self.rboost.database.dataframe colname = self.rboost.documents_df_cols['keywords'] df = dframe[dframe[colname].apply(lambda keywords: label in keywords)] return df def _get_messages(self, label, df): msg1 = f'Label "{label}" not found in RBoost!' if df.empty else '' similar_labels = [ lab for lab in self.rboost.labnames if 0 < lev.distance(label, lab) < 3 ] msg2 = 'Similar labels found: "' + '", "'.join(similar_labels) + '"' \ if similar_labels else 'Similar labels found: None' return msg1, msg2 def show_results(self): label = self.input_line.text() df = self._get_dataframe(label=label) msg1, msg2 = self._get_messages(label=label, df=df) self.label_not_found.setText(msg1) self.similar_labels.setText(msg2) self._add_table_view_layout(df=df) self.setLayout(self.layout) def clear_results(self): self.input_line.clear() self.label_not_found.clear() self.similar_labels.clear() empty_df = pd.DataFrame() self._add_table_view_layout(df=empty_df) self.setLayout(self.layout)
class View(QMainWindow): def __init__(self, model, controller): super().__init__() self._model = model self._controller = controller self.segmentcursor = False self.togglecolors = {"#1f77b4": "m", "m": "#1f77b4"} ################################################################# # define GUI layout and connect input widgets to external slots # ################################################################# self.setWindowTitle("biopeaks") self.setGeometry(50, 50, 1750, 750) self.setWindowIcon(QIcon(":/python_icon.png")) # figure0 for signal self.figure0 = Figure() self.canvas0 = FigureCanvas(self.figure0) # Enforce minimum height, otherwise resizing with self.splitter causes # mpl to throw an error because figure is resized to height 0. The # widget can still be fully collapsed with self.splitter- self.canvas0.setMinimumHeight(1) # in pixels self.ax00 = self.figure0.add_subplot(1, 1, 1) self.ax00.set_frame_on(False) self.figure0.subplots_adjust(left=0.04, right=0.98, bottom=0.25) self.line00 = None self.scat = None self.segmentspan = None # figure1 for marker self.figure1 = Figure() self.canvas1 = FigureCanvas(self.figure1) self.canvas1.setMinimumHeight(1) self.ax10 = self.figure1.add_subplot(1, 1, 1, sharex=self.ax00) self.ax10.get_xaxis().set_visible(False) self.ax10.set_frame_on(False) self.figure1.subplots_adjust(left=0.04, right=0.98) self.line10 = None # figure2 for statistics self.figure2 = Figure() self.canvas2 = FigureCanvas(self.figure2) self.canvas2.setMinimumHeight(1) self.ax20 = self.figure2.add_subplot(3, 1, 1, sharex=self.ax00) self.ax20.get_xaxis().set_visible(False) self.ax20.set_frame_on(False) self.line20 = None self.ax21 = self.figure2.add_subplot(3, 1, 2, sharex=self.ax00) self.ax21.get_xaxis().set_visible(False) self.ax21.set_frame_on(False) self.line21 = None self.ax22 = self.figure2.add_subplot(3, 1, 3, sharex=self.ax00) self.ax22.get_xaxis().set_visible(False) self.ax22.set_frame_on(False) self.line22 = None self.figure2.subplots_adjust(left=0.04, right=0.98) # navigation bar self.navitools = CustomNavigationToolbar(self.canvas0, self) # peak editing self.editcheckbox = QCheckBox("editable", self) self.editcheckbox.stateChanged.connect(self._model.set_peakseditable) # peak saving batch self.savecheckbox = QCheckBox("save during batch processing", self) self.savecheckbox.stateChanged.connect(self._model.set_savebatchpeaks) # peak auto-correction batch self.correctcheckbox = QCheckBox("correct during batch processing", self) self.correctcheckbox.stateChanged.connect( self._model.set_correctbatchpeaks) # selecting stats for saving self.periodcheckbox = QCheckBox("period", self) self.periodcheckbox.stateChanged.connect( lambda: self.select_stats("period")) self.ratecheckbox = QCheckBox("rate", self) self.ratecheckbox.stateChanged.connect( lambda: self.select_stats("rate")) self.tidalampcheckbox = QCheckBox("tidal amplitude", self) self.tidalampcheckbox.stateChanged.connect( lambda: self.select_stats("tidalamp")) # channel selection self.sigchanmenulabel = QLabel("biosignal") self.sigchanmenu = QComboBox(self) self.sigchanmenu.addItem("A1") self.sigchanmenu.addItem("A2") self.sigchanmenu.addItem("A3") self.sigchanmenu.addItem("A4") self.sigchanmenu.addItem("A5") self.sigchanmenu.addItem("A6") self.sigchanmenu.currentTextChanged.connect(self._model.set_signalchan) # initialize with default value self._model.set_signalchan(self.sigchanmenu.currentText()) self.markerchanmenulabel = QLabel("marker") self.markerchanmenu = QComboBox(self) self.markerchanmenu.addItem("none") self.markerchanmenu.addItem("I1") self.markerchanmenu.addItem("I2") self.markerchanmenu.addItem("A1") self.markerchanmenu.addItem("A2") self.markerchanmenu.addItem("A3") self.markerchanmenu.addItem("A4") self.markerchanmenu.addItem("A5") self.markerchanmenu.addItem("A6") self.markerchanmenu.currentTextChanged.connect( self._model.set_markerchan) # initialize with default value self._model.set_markerchan(self.markerchanmenu.currentText()) # processing mode (batch or single file) self.batchmenulabel = QLabel("mode") self.batchmenu = QComboBox(self) self.batchmenu.addItem("single file") self.batchmenu.addItem("multiple files") self.batchmenu.currentTextChanged.connect(self._model.set_batchmode) self.batchmenu.currentTextChanged.connect(self.toggle_options) # initialize with default value self._model.set_batchmode(self.batchmenu.currentText()) self.toggle_options(self.batchmenu.currentText()) # modality selection self.modmenulabel = QLabel("modality") self.modmenu = QComboBox(self) self.modmenu.addItem("ECG") self.modmenu.addItem("PPG") self.modmenu.addItem("RESP") self.modmenu.currentTextChanged.connect(self._model.set_modality) self.modmenu.currentTextChanged.connect(self.toggle_options) # initialize with default value self._model.set_modality(self.modmenu.currentText()) self.toggle_options(self.modmenu.currentText()) # segment selection; this widget can be openend / set visible from # the menu and closed from within itself (see mapping of segmentermap); # it provides utilities to select a segment from the signal self.segmentermap = QSignalMapper(self) self.segmenter = QDockWidget("select a segment", self) # disable closing such that widget can only be closed by confirming # selection or custom button self.segmenter.setFeatures(QDockWidget.NoDockWidgetFeatures) # Limit number of decimals to four. regex = QRegExp("[0-9]*\.?[0-9]{4}") validator = QRegExpValidator(regex) self.startlabel = QLabel("start") self.startedit = QLineEdit() self.startedit.setValidator(validator) self.endlabel = QLabel("end") self.endedit = QLineEdit() self.endedit.setValidator(validator) segmentfromcursor = QAction(QIcon(":/mouse_icon.png"), "select with mouse", self) segmentfromcursor.triggered.connect(self.enable_segmentedit) self.startedit.addAction(segmentfromcursor, QLineEdit.TrailingPosition) self.endedit.addAction(segmentfromcursor, QLineEdit.TrailingPosition) self.previewedit = QPushButton("preview segment") lambdafn = lambda: self._model.set_segment( [self.startedit.text(), self.endedit.text()]) self.previewedit.clicked.connect(lambdafn) self.confirmedit = QPushButton("confirm segment") self.confirmedit.clicked.connect(self._controller.segment_signal) self.confirmedit.clicked.connect(self.segmentermap.map) self.segmentermap.setMapping(self.confirmedit, 0) self.abortedit = QPushButton("abort segmentation") self.abortedit.clicked.connect(self.segmentermap.map) # reset the segment to None self.segmentermap.setMapping(self.abortedit, 2) self.segmenterlayout = QFormLayout() self.segmenterlayout.addRow(self.startlabel, self.startedit) self.segmenterlayout.addRow(self.endlabel, self.endedit) self.segmenterlayout.addRow(self.previewedit) self.segmenterlayout.addRow(self.confirmedit) self.segmenterlayout.addRow(self.abortedit) self.segmenterwidget = QWidget() self.segmenterwidget.setLayout(self.segmenterlayout) self.segmenter.setWidget(self.segmenterwidget) self.segmenter.setVisible(False) self.segmenter.setAllowedAreas(Qt.RightDockWidgetArea) self.addDockWidget(Qt.RightDockWidgetArea, self.segmenter) # Set up dialog to gather user input for custom files. regex = QRegExp("[1-9][0-9]") validator = QRegExpValidator(regex) self.signallabel = QLabel("biosignal column") self.signaledit = QLineEdit() self.signaledit.setValidator(validator) self.markerlabel = QLabel("marker column") self.markeredit = QLineEdit() self.markeredit.setValidator(validator) regex = QRegExp("[0-9]{2}") validator = QRegExpValidator(regex) self.headerrowslabel = QLabel("number of header rows") self.headerrowsedit = QLineEdit() self.headerrowsedit.setValidator(validator) regex = QRegExp("[0-9]{5}") validator = QRegExpValidator(regex) self.sfreqlabel = QLabel("sampling rate") self.sfreqedit = QLineEdit() self.sfreqedit.setValidator(validator) self.separatorlabel = QLabel("column separator") self.separatormenu = QComboBox(self) self.separatormenu.addItem("comma") self.separatormenu.addItem("tab") self.separatormenu.addItem("colon") self.separatormenu.addItem("space") self.continuecustomfile = QPushButton("continue loading file") self.continuecustomfile.clicked.connect(self.set_customheader) self.customfiledialog = QDialog() self.customfiledialog.setWindowTitle("custom file info") self.customfiledialog.setWindowIcon(QIcon(":/file_icon.png")) self.customfiledialog.setWindowFlags( Qt.WindowCloseButtonHint ) # remove help button by only setting close button self.customfilelayout = QFormLayout() self.customfilelayout.addRow(self.signallabel, self.signaledit) self.customfilelayout.addRow(self.markerlabel, self.markeredit) self.customfilelayout.addRow(self.separatorlabel, self.separatormenu) self.customfilelayout.addRow(self.headerrowslabel, self.headerrowsedit) self.customfilelayout.addRow(self.sfreqlabel, self.sfreqedit) self.customfilelayout.addRow(self.continuecustomfile) self.customfiledialog.setLayout(self.customfilelayout) # set up menubar menubar = self.menuBar() # signal menu signalmenu = menubar.addMenu("biosignal") openSignal = signalmenu.addMenu("load") openEDF = QAction("EDF", self) openEDF.triggered.connect(lambda: self._model.set_filetype("EDF")) openEDF.triggered.connect(self._controller.get_fpaths) openSignal.addAction(openEDF) openOpenSignals = QAction("OpenSignals", self) openOpenSignals.triggered.connect( lambda: self._model.set_filetype("OpenSignals")) openOpenSignals.triggered.connect(self._controller.get_fpaths) openSignal.addAction(openOpenSignals) openCustom = QAction("Custom", self) openCustom.triggered.connect( lambda: self._model.set_filetype("Custom")) openCustom.triggered.connect(lambda: self.customfiledialog.exec_()) openSignal.addAction(openCustom) segmentSignal = QAction("select segment", self) segmentSignal.triggered.connect(self.segmentermap.map) self.segmentermap.setMapping(segmentSignal, 1) signalmenu.addAction(segmentSignal) self.segmentermap.mapped.connect(self.toggle_segmenter) saveSignal = QAction("save", self) saveSignal.triggered.connect(self._controller.get_wpathsignal) signalmenu.addAction(saveSignal) # peak menu peakmenu = menubar.addMenu("peaks") findPeaks = QAction("find", self) findPeaks.triggered.connect(self._controller.find_peaks) peakmenu.addAction(findPeaks) autocorrectPeaks = QAction("autocorrect", self) autocorrectPeaks.triggered.connect(self._controller.autocorrect_peaks) peakmenu.addAction(autocorrectPeaks) savePeaks = QAction("save", self) savePeaks.triggered.connect(self._controller.get_wpathpeaks) peakmenu.addAction(savePeaks) loadPeaks = QAction("load", self) loadPeaks.triggered.connect(self._controller.get_rpathpeaks) peakmenu.addAction(loadPeaks) # stats menu statsmenu = menubar.addMenu("statistics") calculateStats = QAction("calculate", self) calculateStats.triggered.connect(self._controller.calculate_stats) statsmenu.addAction(calculateStats) saveStats = QAction("save", self) saveStats.triggered.connect(self._controller.get_wpathstats) statsmenu.addAction(saveStats) # set up status bar to display error messages and current file path self.statusBar = QStatusBar() self.setStatusBar(self.statusBar) self.progressBar = QProgressBar(self) self.progressBar.setRange(0, 1) self.statusBar.addPermanentWidget(self.progressBar) self.currentFile = QLabel() self.statusBar.addPermanentWidget(self.currentFile) # set up the central widget containing the plot and navigationtoolbar self.centwidget = QWidget() self.setCentralWidget(self.centwidget) # connect canvas0 to keyboard and mouse input for peak editing; # only widgets (e.g. canvas) that currently have focus capture # keyboard input: "You must enable keyboard focus for a widget if # it processes keyboard events." self.canvas0.setFocusPolicy(Qt.ClickFocus) self.canvas0.setFocus() self.canvas0.mpl_connect("key_press_event", self._controller.edit_peaks) self.canvas0.mpl_connect("button_press_event", self.get_xcursor) # arrange the three figure canvases in splitter object self.splitter = QSplitter(Qt.Vertical) # setting opaque resizing to false is important, since resizing gets # very slow otherwise once axes are populated self.splitter.setOpaqueResize(False) self.splitter.addWidget(self.canvas0) self.splitter.addWidget(self.canvas1) self.splitter.addWidget(self.canvas2) self.splitter.setChildrenCollapsible(False) # define GUI layout self.vlayout0 = QVBoxLayout(self.centwidget) self.vlayout1 = QVBoxLayout() self.vlayoutA = QFormLayout() self.vlayoutB = QFormLayout() self.vlayoutC = QVBoxLayout() self.vlayoutD = QVBoxLayout() self.hlayout0 = QHBoxLayout() self.optionsgroupA = QGroupBox("processing options") self.vlayoutA.addRow(self.modmenulabel, self.modmenu) self.vlayoutA.addRow(self.batchmenulabel, self.batchmenu) self.optionsgroupA.setLayout(self.vlayoutA) self.optionsgroupB = QGroupBox("channels") self.vlayoutB.addRow(self.sigchanmenulabel, self.sigchanmenu) self.vlayoutB.addRow(self.markerchanmenulabel, self.markerchanmenu) self.optionsgroupB.setLayout(self.vlayoutB) self.optionsgroupC = QGroupBox("peaks") self.vlayoutC.addWidget(self.editcheckbox) self.vlayoutC.addWidget(self.savecheckbox) self.vlayoutC.addWidget(self.correctcheckbox) self.optionsgroupC.setLayout(self.vlayoutC) self.optionsgroupD = QGroupBox("select statistics for saving") self.vlayoutD.addWidget(self.periodcheckbox) self.vlayoutD.addWidget(self.ratecheckbox) self.vlayoutD.addWidget(self.tidalampcheckbox) self.optionsgroupD.setLayout(self.vlayoutD) self.vlayout1.addWidget(self.optionsgroupA) self.vlayout1.addWidget(self.optionsgroupB) self.vlayout1.addWidget(self.optionsgroupC) self.vlayout1.addWidget(self.optionsgroupD) self.optionsgroupwidget = QWidget() self.optionsgroupwidget.setLayout(self.vlayout1) self.optionsgroup = QDockWidget("configurations", self) self.optionsgroup.setAllowedAreas(Qt.LeftDockWidgetArea) self.toggleoptionsgroup = self.optionsgroup.toggleViewAction() self.toggleoptionsgroup.setText("show/hide configurations") menubar.addAction(self.toggleoptionsgroup) self.optionsgroup.setWidget(self.optionsgroupwidget) self.addDockWidget(Qt.LeftDockWidgetArea, self.optionsgroup) self.vlayout0.addWidget(self.splitter) self.hlayout0.addWidget(self.navitools) self.vlayout0.addLayout(self.hlayout0) ############################################## # connect output widgets to external signals # ############################################## self._model.signal_changed.connect(self.plot_signal) self._model.marker_changed.connect(self.plot_marker) self._model.peaks_changed.connect(self.plot_peaks) self._model.period_changed.connect(self.plot_period) self._model.rate_changed.connect(self.plot_rate) self._model.tidalamp_changed.connect(self.plot_tidalamp) self._model.path_changed.connect(self.display_path) self._model.segment_changed.connect(self.plot_segment) self._model.status_changed.connect(self.display_status) self._model.progress_changed.connect(self.display_progress) self._model.model_reset.connect(self.reset_plot) ########### # methods # ########### def plot_signal(self, value): self.ax00.clear() self.ax00.relim() # reset navitools history self.navitools.update() self.line00 = self.ax00.plot(self._model.sec, value, zorder=1) self.ax00.set_xlabel("seconds", fontsize="large", fontweight="heavy") self.canvas0.draw() # print("plot_signal listening") # print(self.ax0.collections, self.ax0.patches, self.ax0.artists) def plot_peaks(self, value): # self.scat is listed in ax.collections if self.ax00.collections: self.ax00.collections[0].remove() self.scat = self.ax00.scatter(self._model.sec[value], self._model.signal[value], c="m", zorder=2) self.canvas0.draw() # print("plot_peaks listening") # print(self.ax0.collections, self.ax0.patches, self.ax0.artists) def plot_segment(self, value): # If an invalid signal has been selected reset the segmenter interface. if value is None: self.toggle_segmenter(1) return if self.ax00.patches: # self.segementspan is listed in ax.patches self.ax00.patches[0].remove() self.segmentspan = self.ax00.axvspan(value[0], value[1], color="m", alpha=0.25) self.canvas0.draw() self.confirmedit.setEnabled(True) # print(self.ax0.collections, self.ax0.patches, self.ax0.artists) def plot_marker(self, value): self.ax10.clear() self.ax10.relim() self.line10 = self.ax10.plot(value[0], value[1]) self.canvas1.draw() # print("plot_marker listening") def plot_period(self, value): self.ax20.clear() self.ax20.relim() self.navitools.home() if self._model.savestats["period"]: self.line20 = self.ax20.plot(self._model.sec, value, c="m") else: self.line20 = self.ax20.plot(self._model.sec, value) self.ax20.set_ylim(bottom=min(value), top=max(value)) self.ax20.set_title("period", pad=0, fontweight="heavy") self.ax20.grid(True, axis="y") self.navitools.update() self.canvas2.draw() # print("plot_period listening") def plot_rate(self, value): self.ax21.clear() self.ax21.relim() self.navitools.home() if self._model.savestats["rate"]: self.line21 = self.ax21.plot(self._model.sec, value, c="m") else: self.line21 = self.ax21.plot(self._model.sec, value) self.ax21.set_ylim(bottom=min(value), top=max(value)) self.ax21.set_title("rate", pad=0, fontweight="heavy") self.ax21.grid(True, axis="y") self.navitools.update() self.canvas2.draw() # print("plot_rate listening") def plot_tidalamp(self, value): self.ax22.clear() self.ax22.relim() self.navitools.home() if self._model.savestats["tidalamp"]: self.line22 = self.ax22.plot(self._model.sec, value, c="m") else: self.line22 = self.ax22.plot(self._model.sec, value) self.ax22.set_ylim(bottom=min(value), top=max(value)) self.ax22.set_title("amplitude", pad=0, fontweight="heavy") self.ax22.grid(True, axis="y") self.navitools.update() self.canvas2.draw() # print("plot_tidalamp listening") def display_path(self, value): self.currentFile.setText(value) def display_status(self, status): # display status until new status is set self.statusBar.showMessage(status) def display_progress(self, value): # if value is 0, the progressbar indicates a busy state self.progressBar.setRange(0, value) def toggle_segmenter(self, value): if not self._model.loaded: return # Open segmenter when called from signalmenu or clear segmenter # upon selection of invalid segment. if value == 1: self.segmenter.setVisible(True) self.confirmedit.setEnabled(False) self.startedit.clear() self.endedit.clear() if self.ax00.patches: self.ax00.patches[0].remove() self.canvas0.draw() # Close segmenter after segment has been confirmed. elif value == 0: self.segmenter.setVisible(False) if self.ax00.patches: self.ax00.patches[0].remove() self.canvas0.draw() # Close segmenter after segmentation has been aborted (reset # segment). elif value == 2: self._model.set_segment([0, 0]) # This will reset the model to None self.segmenter.setVisible(False) if self.ax00.patches: self.ax00.patches[0].remove() self.canvas0.draw() def enable_segmentedit(self): # disable peak editing to avoid interference self.editcheckbox.setChecked(False) if self.startedit.hasFocus(): self.segmentcursor = "start" elif self.endedit.hasFocus(): self.segmentcursor = "end" def set_customheader(self): """Populate the customheader with inputs from the customfiledialog""" # Check if one of the mandatory fields is missing. mandatoryfields = self.signaledit.text() and self.headerrowsedit.text( ) and self.sfreqedit.text() if not mandatoryfields: self._model.status = ( "Please provide values for 'biosignal column'" ", 'number of header rows' and 'sampling" " rate'.") return seps = {"comma": ",", "tab": "\t", "colon": ":", "space": " "} self._model.customheader = dict.fromkeys( self._model.customheader, None ) # reset header here since it cannot be reset in controller.get_fpaths() self._model.customheader["signalidx"] = int(self.signaledit.text()) self._model.customheader["skiprows"] = int(self.headerrowsedit.text()) self._model.customheader["sfreq"] = int(self.sfreqedit.text()) self._model.customheader["separator"] = seps[ self.separatormenu.currentText()] if self.markeredit.text(): # not mandatory self._model.customheader["markeridx"] = int(self.markeredit.text()) self.customfiledialog.done(QDialog.Accepted) # close the dialog window self._controller.get_fpaths() # move on to file selection def get_xcursor(self, event): # event.button 1 corresponds to left mouse button if event.button != 1: return # limit number of decimal places to two if self.segmentcursor == "start": self.startedit.selectAll() self.startedit.insert("{:.2f}".format(event.xdata)) elif self.segmentcursor == "end": self.endedit.selectAll() self.endedit.insert("{:.2f}".format(event.xdata)) # disable segment cursor again after value has been set self.segmentcursor = False def select_stats(self, event): """ select or deselect statistics to be saved; toggle boolean with xor operator ^=, toggle color with dictionary """ self._model.savestats[event] ^= True line = None if event == "period": if self.line20: line = self.line20[0] elif event == "rate": if self.line21: line = self.line21[0] elif event == "tidalamp": if self.line22: line = self.line22[0] if line: line.set_color(self.togglecolors[line.get_color()]) self.canvas2.draw() def toggle_options(self, event): if event in ["ECG", "PPG"]: self.tidalampcheckbox.setEnabled(False) self.tidalampcheckbox.setChecked(False) self.ax22.set_visible(False) self.canvas2.draw() elif event == "RESP": self.tidalampcheckbox.setEnabled(True) self.ax22.set_visible(True) self.canvas2.draw() elif event == "multiple files": self.editcheckbox.setEnabled(False) self.editcheckbox.setChecked(False) self.savecheckbox.setEnabled(True) self.correctcheckbox.setEnabled(True) self.markerchanmenu.setEnabled(False) elif event == "single file": self.editcheckbox.setEnabled(True) self.markerchanmenu.setEnabled(True) self.savecheckbox.setEnabled(False) self.savecheckbox.setChecked(False) self.correctcheckbox.setEnabled(False) self.correctcheckbox.setChecked(False) def reset_plot(self): self.ax00.clear() self.ax00.relim() self.line00 = None self.scat = None self.segmentspan = None self.ax10.clear() self.ax10.relim() self.line10 = None self.ax20.clear() self.ax20.relim() self.line20 = None self.ax21.clear() self.ax21.relim() self.line21 = None self.ax22.clear() self.ax22.relim() self.line22 = None self.canvas0.draw() self.canvas1.draw() self.canvas2.draw() self.navitools.update() self.currentFile.clear()
class App(QWidget): def __init__(self): super().__init__() self.title = 'Thermodynamic data' qd = QDesktopWidget() screen = qd.screenGeometry(qd) width = 600 height = 300 x = screen.width() / 2 - width / 2 y = screen.height() / 2 - height / 2 self.width = width self.height = height self.left = x self.top = y self.ignore_events = False self.initUI() def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.tableView1 = QTableView() self.tableWidget1 = QTableWidget() self.model = thTableModel() self.cas_filter = QLineEdit() self.name_filter = QLineEdit() self.formula_filter = QLineEdit() self.phase_filter = QComboBox() self.delete_selected_button = QPushButton() self.copy_selected_button = QPushButton() self.phases_vol_button = QPushButton() self.temp_text = QLineEdit() self.plot_window = PlotWindow() self.cp_button = QPushButton() self.psat_button = QPushButton() self.tableView1.setModel(self.model) self.tableWidget1.setColumnCount( self.tableView1.model().columnCount() + 1 + 1 + 1 + 1 + 1) self.widget_col_names = ['z_i', 'h_ig', 's_ig', 'g_ig', 'cp_ig' ] + self.tableView1.model().column_names self.widget_col_units = ['-', 'J/mol', 'J/mol/K', 'J/mol', 'J/mol/K' ] + self.tableView1.model().column_units self.widget_col_names_units = [ self.widget_col_names[i] + '\n' + self.widget_col_units[i] for i in range(len(self.widget_col_names)) ] self.tableWidget1.setHorizontalHeaderLabels( self.widget_col_names_units) self.phase_filter.addItems(['', 'G', 'L', 'S', 'C']) self.tableWidget1.setEnabled(False) self.tableWidget1.setSelectionBehavior(QTableWidget.SelectRows) self.tableWidget1.installEventFilter(self) self.delete_selected_button.setText('delete selected') self.copy_selected_button.setText('copy selected') self.phases_vol_button.setText('ph, v') self.temp_text.setValidator(QDoubleValidator(0, 6000, 16)) self.temp_text.setPlaceholderText('1000 K') # Add box layout, add table to box layout and add box layout to widget self.layout = QGridLayout() self.layout.addWidget(self.tableView1, 1, 1, 1, 4) self.layout.addWidget(self.cas_filter, 3, 1, 1, 1) self.layout.addWidget(self.name_filter, 3, 2, 1, 1) self.layout.addWidget(self.formula_filter, 3, 3, 1, 1) self.layout.addWidget(self.phase_filter, 3, 4, 1, 1) self.layout.addWidget(QLabel('find by: cas'), 2, 1, 1, 1) self.layout.addWidget(QLabel('name'), 2, 2, 1, 1) self.layout.addWidget(QLabel('formula'), 2, 3, 1, 1) self.layout.addWidget(QLabel('phase'), 2, 4, 1, 1) self.layout.addWidget(QLabel('selection'), 4, 1, 1, 4) self.layout.addWidget(self.tableWidget1, 5, 1, 1, 4) self.layout.addWidget(self.delete_selected_button, 6, 4, 1, 1) self.layout.addWidget(self.copy_selected_button, 6, 1, 1, 1) self.layout.addWidget(self.phases_vol_button, 6, 2, 1, 1) self.layout.addWidget(self.temp_text, 6, 3, 1, 1) self.setLayout(self.layout) for item in [self.cas_filter, self.name_filter, self.formula_filter]: item.textChanged.connect(self.apply_filters) self.phase_filter.currentTextChanged.connect(self.apply_filters) self.tableView1.selectionModel().selectionChanged.connect( partial(self.add_selection_to_widget)) self.tableWidget1.cellChanged.connect(partial(self.update_props)) self.delete_selected_button.clicked.connect( partial(self.delete_selected)) self.copy_selected_button.clicked.connect(partial(self.copy_selection)) self.phases_vol_button.clicked.connect(partial(self.phases_vol)) self.temp_text.editingFinished.connect(partial(self.update_temp)) #self.tableView1.horizontalHeader().setClickable(False) self.props_i = self.tableView1.model().df.iloc[[]] self.props_i['z_i'] = zeros(0) self.props_i['h_ig'] = zeros(0) self.props_i['s_ig'] = zeros(0) self.props_i['g_ig'] = zeros(0) self.props_i['cp_ig'] = zeros(0) # Show widget self.show() def apply_filters(self): cas_filter = self.cas_filter.text().upper().strip().replace(' ', '') name_filter = self.name_filter.text().upper().strip() formula_filter = self.formula_filter.text().upper().strip() phase_filter = self.phase_filter.currentText() self.model.apply_filter(cas_filter, name_filter, formula_filter, phase_filter) def add_selection_to_widget(self, selected, deselected): # indexes = self.tableView1.selectedIndexes() indexes = selected.indexes() index = indexes[0] column_of_cas = self.tableView1.model().column_names.index('cas_no') column_of_phase = self.tableView1.model().column_names.index('phase') phase = self.tableView1.model().index(index.row(), column_of_phase).data() cas = self.tableView1.model().index(index.row(), column_of_cas).data() already_in_table = False for item in self.tableWidget1.findItems(cas, Qt.MatchExactly): if phase == self.tableWidget1.item( item.row(), column_of_phase + 1 + 1 + 1 + 1 + 1).text(): already_in_table = True if not already_in_table: row_index = int(self.tableView1.model().headerData( index.row(), Qt.Vertical)) column_names = self.tableView1.model().column_names header_to_add = QTableWidgetItem(str(row_index)) # save df with new props z_i_orig = self.props_i['z_i'] h_ig_orig = self.props_i['h_ig'] s_ig_orig = self.props_i['s_ig'] g_ig_orig = self.props_i['g_ig'] cp_ig_orig = self.props_i['cp_ig'] index_orig = self.props_i.index self.props_i = self.tableView1.model().df.loc[[ int(self.tableWidget1.verticalHeaderItem(i).text()) for i in range(self.tableWidget1.rowCount()) ] + [row_index], :] self.props_i['z_i'] = zeros(len(self.props_i)) self.props_i['h_ig'] = zeros(len(self.props_i)) self.props_i['s_ig'] = zeros(len(self.props_i)) self.props_i['g_ig'] = zeros(len(self.props_i)) self.props_i['cp_ig'] = zeros(len(self.props_i)) self.props_i.loc[index_orig, 'z_i'] = z_i_orig self.props_i.loc[index_orig, 'h_ig'] = h_ig_orig self.props_i.loc[index_orig, 's_ig'] = s_ig_orig self.props_i.loc[index_orig, 'g_ig'] = g_ig_orig self.props_i.loc[index_orig, 'cp_ig'] = cp_ig_orig self.props_i.loc[row_index, 'z_i'] = float(0) # add item to widget self.tableWidget1.setRowCount(self.tableWidget1.rowCount() + 1) self.tableWidget1.setVerticalHeaderItem( self.tableWidget1.rowCount() - 1, header_to_add) for i in range(len(column_names)): # columns in TableWidget shifted by 1+1+1+1+1 vs. Tableview due to first columns z_i, h_ig, s_ig, g_ig, cp_ig data = self.tableView1.model().index(index.row(), i).data() if isinstance(data, str) or data is None: item_to_add = QTableWidgetItem(data) else: item_to_add = QTableWidgetItem(locale.str(data)) item_to_add.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable) self.tableWidget1.setItem(self.tableWidget1.rowCount() - 1, i + 1 + 1 + 1 + 1 + 1, item_to_add) # additional column with z_i item_to_add = QTableWidgetItem(locale.str(0)) item_to_add.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable) self.tableWidget1.setItem(self.tableWidget1.rowCount() - 1, 0, item_to_add) if len(indexes) > 0 or self.tableWidget1.rowCount() > 0: self.tableWidget1.setEnabled(True) def update_props(self, row, col): if col == 0: # change z_i df_index = int(self.tableWidget1.verticalHeaderItem(row).text()) new_value = float( self.tableWidget1.item(row, col).text().replace(',', '.')) self.props_i.loc[df_index, 'z_i'] = new_value else: pass def update_temp(self): if self.temp_text.hasAcceptableInput(): self.temp_text.setPlaceholderText(self.temp_text.text() + ' K') t = float(self.temp_text.text().replace(',', '.')) # K self.temp_text.clear() else: t = 1000 # K self.temp_text.clear() mm_i = (self.props_i['poling_molwt'] / 1000).tolist() # kg/mol tc_i = self.props_i['poling_tc'].tolist() # K pc_i = (self.props_i['poling_pc'] * 1e5).tolist() # Pa omega_i = self.props_i['poling_omega'].tolist() vc_i = (self.props_i['poling_vc'] * 10**-6).tolist() # m^3/mol delhf0_poling = (self.props_i['poling_delhf0'] * 1000).tolist() # J/mol delgf0_poling = (self.props_i['poling_delgf0'] * 1000).tolist() # J/mol delsf0_poling = [(delhf0_poling[i] - delgf0_poling[i]) / 298.15 for i in range(len(self.props_i))] # J/mol/K a_low = [ self.props_i['a' + str(i) + '_low'].tolist() for i in range(1, 7 + 1) ] a_high = [ self.props_i['a' + str(i) + '_high'].tolist() for i in range(1, 7 + 1) ] cp_r_low = [ sum([a_low[j][i] * t**j for j in range(4 + 1)]) for i in range(len(self.props_i)) ] # cp/R cp_r_high = [ sum([a_high[j][i] * t**j for j in range(4 + 1)]) for i in range(len(self.props_i)) ] # cp/R if t > 1000: # poly a_low is for 200 - 1000 K; a_high is for 1000 - 6000 K a = a_high cp_ig = [8.3145 * cp_r_high[i] for i in range(len(self.props_i))] # J/mol/K else: a = a_low cp_ig = [8.3145 * cp_r_low[i] for i in range(len(self.props_i))] # J/mol/K s_cp_r_dt = [ sum([1 / (j + 1) * a[j][i] * t**(j + 1) for j in range(4 + 1)]) - sum([ 1 / (j + 1) * a_low[j][i] * 298.15**(j + 1) for j in range(4 + 1) ]) for i in range(len(self.props_i)) ] # int(Cp/R*dT,298,15K,T) # int(Cp/R/T*dT,298.15K,T) s_cp_r_t_dt = [ a[0][i] * log(t) + a[6][i] + sum([1 / (j) * a[j][i] * t**(j) for j in range(1, 3 + 1)]) for i in range(len(self.props_i)) ] # int(Cp/(RT)*dT,0,T) h_ig = [ delhf0_poling[i] + 8.3145 * s_cp_r_dt[i] for i in range(len(self.props_i)) ] s_ig = [8.3145 * s_cp_r_t_dt[i] for i in range(len(self.props_i))] g_ig = [h_ig[i] - t * s_ig[i] for i in range(len(self.props_i))] for i in range(len(self.props_i)): for j, col in enumerate([h_ig, s_ig, g_ig, cp_ig]): #print(col) item_to_add = QTableWidgetItem(locale.str(col[i])) item_to_add.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable) self.tableWidget1.setItem(i, j + 1, item_to_add) def copy_selection(self): selection = self.tableWidget1.selectedIndexes() if selection: rows = sorted(index.row() for index in selection) columns = range(len(self.widget_col_names)) rowcount = rows[-1] - rows[0] + 1 colcount = columns[-1] - columns[0] + 1 + 1 table = [[''] * colcount for _ in range(rowcount + 1)] table[0] = [] for i in range(len(self.widget_col_names)): text_to_add = self.widget_col_names[ i] + '/(' + self.widget_col_units[i] + ')' table[0] += [text_to_add] for index in selection: row = index.row() - rows[0] column = index.column() - columns[0] table[row + 1][column] = index.data().replace( chr(34), '' ) # ensure string can be read as csv by removing quotation mark (ascii character 34) table = table + [['T=' + self.temp_text.placeholderText()] + ['' for _ in range(colcount - 1)]] stream = io.StringIO() csv.writer(stream, delimiter=';', quoting=csv.QUOTE_NONE).writerows(table) QApplication.clipboard().setText(stream.getvalue()) def eventFilter(self, source, event): if self.ignore_events: pass elif (event.type() == QEvent.KeyPress and event.matches(QKeySequence.Copy)): self.copy_selection() return True elif (event.type() == QEvent.KeyPress and event.matches(QKeySequence.Delete)): if len(self.tableWidget1.selectedIndexes()) > 1: self.delete_selected() return True return super(App, self).eventFilter(source, event) def delete_selected(self): if len(self.tableWidget1.selectedIndexes()) > 0: while len(self.tableWidget1.selectedIndexes()) > 0: current_row = self.tableWidget1.selectedIndexes()[0].row() row_index = int( self.tableWidget1.verticalHeaderItem(current_row).text()) self.tableWidget1.removeRow(current_row) self.props_i = self.props_i.drop([row_index]) self.tableWidget1.selectRow(current_row) if self.tableWidget1.rowCount() == 0: self.tableWidget1.setEnabled(False) def phases_vol(self): self.plot_window.show() t = linspace(60, 220, 10) p = 1.01325 # bar phase_fraction = empty_like(t) v_l = empty_like(t) v_v = empty_like(t) z_i = self.props_i['z_i'] # normalize z_i sum_z_i = sum(z_i) if sum_z_i <= 0: z_i = 1 / len(z_i) * ones(len(z_i)) z_i = z_i.tolist() elif sum_z_i != 1.0: z_i = z_i / sum_z_i z_i = z_i.to_list() else: z_i = z_i.to_list() mm_i = (self.props_i['poling_molwt'] / 1000).tolist() # kg/mol tc_i = self.props_i['poling_tc'].tolist() # K pc_i = (self.props_i['poling_pc']).tolist() # bar omega_i = self.props_i['poling_omega'].tolist() vc_i = (self.props_i['poling_vc'] * 10**-6).tolist() # m^3/mol state = State(t[0], p, z_i, mm_i, tc_i, pc_i, omega_i, 'pr') for i in range(len(t)): state.set_t(t[i]) phase_fraction[i] = state.v_f v_l[i] = state.v_l v_v[i] = state.v_v self.plot_window.ax[0].plot(t, phase_fraction) self.plot_window.ax[0].set_xlabel('T / K') self.plot_window.ax[0].set_xlabel('V / F') self.plot_window.ax[1].semilogy(t, v_l, label='v_l') self.plot_window.ax[1].semilogy(t, v_v, label='v_v') self.plot_window.ax[1].set_xlabel('T / K') self.plot_window.ax[1].set_xlabel(r'$\frac{V}{m^3 / mol}$') self.plot_window.ax[1].legend() self.plot_window.fig.tight_layout()
class UpdatePrompt(QDialog): def __init__(self): super().__init__() self.makeView() return def makeView(self): layout = QVBoxLayout() btnLayout = QHBoxLayout() self.centStack = QStackedWidget() self.updateButton = QPushButton('Update') self.cancelButton = QPushButton('Cancel') notifyLabel = QLabel('There are upgrades scheduled') self.inputBox = QLineEdit() self.outputBox = QTextBrowser() #refreshIcon = QIcon.fromTheme('process-working') self.refreshIcon = QMovie('assets/spin3.gif') refreshAnimation = QLabel() layout.addWidget(notifyLabel) layout.addWidget(self.centStack) layout.addWidget(self.inputBox) layout.addLayout(btnLayout) btnLayout.addWidget(self.cancelButton) btnLayout.addWidget(self.updateButton) self.centStack.addWidget(refreshAnimation) self.centStack.addWidget(self.outputBox) refreshAnimation.setMovie(self.refreshIcon) refreshAnimation.setAlignment(Qt.AlignCenter) self.refreshIcon.start() self.inputBox.setEchoMode(QLineEdit.Password) self.inputBox.setFocus() self.inputBox.returnPressed.connect(self.pkgUpdates) self.updateButton.clicked.connect(self.pkgUpdates) self.cancelButton.clicked.connect(self.cancelUpdates) self.updateButton.setDefault(True) self.centStack.setCurrentIndex(1) notifyLabel.setAlignment(Qt.AlignTop) self.outputBox.setReadOnly(True) #self.outputBox.setAlignment(Qt.AlignTop) self.setWindowTitle('Package Upgrades') self.setLayout(layout) self.resize(450, 250) return async def asetup(self, password): async with trio.open_nursery() as nursery: finishedState = trio.Event() nursery.start_soon(self.upProc, password, 'update', finishedState) #nursery.start_soon(self.KEAlive, finishedState) return async def upProc(self, password, cmd, finishedState): proc = await trio.open_process(['sudo', '-S', 'apt-get', cmd, '-y'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) await proc.stdin.send_all((password + '\n').encode()) while (proc.poll() == None): QCoreApplication.processEvents() await trio.sleep(0.1) result = '' result = await self.pullOutput(proc) self.appendToOutput(result) proc.terminate() if (cmd == 'update'): await self.upProc(password, 'upgrade', finishedState) finishedState.set() return async def pullOutput(self, proc): x = await proc.stdout.receive_some() x = x.decode() result = '' while (x != ''): QCoreApplication.processEvents() result = result + x x = await proc.stdout.receive_some() x = x.decode() return result async def KEAlive(self, finishedState): while finishedState.is_set(): QCoreApplication.processEvents() trio.sleep(0.1) return return def appendToOutput(self, add): currentText = self.outputBox.toPlainText() self.outputBox.setText(currentText + 'Running updates\n' + add + '\n') print(add) return def pkgUpdates(self): self.centStack.setCurrentIndex(0) self.refreshIcon.start() QCoreApplication.processEvents() password = self.inputBox.text() if (password == ''): self.passError('The password field cannot be empty') return self.inputBox.clear() self.inputBox.setDisabled(True) self.updateButton.setDisabled(True) trio.run(self.asetup, password) self.centStack.setCurrentIndex(1) self.refreshIcon.stop() self.updateButton.setDisabled(False) self.inputBox.setDisabled(False) return def passError(self, s): passError = QDialog(self) msg = QLabel(s) layout = QVBoxLayout() layout.addWidget(msg) passError.setLayout(layout) okBtn = QPushButton('OK') okBtn.clicked.connect(passError.reject) layout.addWidget(okBtn) passError.exec_() return def cancelUpdates(self): #Needs way of closing subprocess during async run self.reject() return
class DatasheetView(QMainWindow): def __init__(self, pdfPath=None, openPages=[1]): super().__init__() if pdfPath: self.myPdfContext = PDFContext(pdfPath, openPages) # store diretory for debugging purposes self.svgDirectory = self.myPdfContext.directory # window dimensions self.top = 300 self.left = 800 self.width = 860 self.height = 980 self.setGeometry(self.left, self.top, self.width, self.height) # window title self.setWindowTitle("BetterSheets") # sets up main layout -- splitters self.initUILayout() self.initUIToolbar() self.initToC() # self.initPdfViewer() # must be called after initUI to ensure PDFContext object exists self.show() print(self.mainDisplay.getVisibleChild()) def initUILayout(self): # set left-side, Dynamic View self.dynamicViewDisplay = QLabel() self.vBoxA = QVBoxLayout() self.vBoxA.addWidget(self.dynamicViewDisplay) self.groupA = QGroupBox() self.groupA.setTitle("Dynamic Veiw") self.groupA.setLayout(self.vBoxA) # set left-side, Static View self.staticViewDisplay = QLabel() self.vBoxB = QVBoxLayout() self.vBoxB.addWidget(self.staticViewDisplay) self.groupB = QGroupBox() self.groupB.setTitle("Static View") self.groupB.setLayout(self.vBoxB) # add Dynamic and Static Views to resizeable left-side Splitter self.altViewSplit = QSplitter(Qt.Vertical) self.altViewSplit.addWidget(self.groupA) self.altViewSplit.addWidget(self.groupB) # set up Tools View section self.toolsTabView = QTabWidget() self.toolsTabView.setTabsClosable(True) self.toolsTabView.setMovable(True) self.toolsTabView.setDocumentMode(True) # self.toolsTabView.setTabBarAutoHide(True) # add attribute for storing page notes self.notesDB = [] self.notesDisplay = QListWidget(self) self.notesDisplay.setMaximumHeight(200) # add ToC to Tools View self.ToCListView = QListWidget() self.toolsTabView.addTab(self.ToCListView, "Table of Contents") # add notes list to tools view self.toolsTabView.addTab(self.notesDisplay, "Notes") # add tools view to the left-side splitter self.altViewSplit.addWidget(self.toolsTabView) # set up main viewport self.mainDisplay = QDatasheetPageDisplayWidget(self.myPdfContext) self.mainDisplay.renderPages(1, 4) self.mainScroller = QScrollArea(self) self.mainScroller.setWidget(self.mainDisplay) self.mainScroller.setWidgetResizable(True) self.mainScroller.setBackgroundRole(QtGui.QPalette.Dark) self.mainScroller.setFixedHeight(800) print(self.mainScroller.viewport().childrenRect()) # set up document tools self.hBoxDocTools = QHBoxLayout() self.searchLabel = QLabel("Search: ") self.searchBox = QLineEdit() self.searchBox.setPlaceholderText("Search") # self. self.vBoxMain = QVBoxLayout() self.vBoxMain.addWidget(self.mainScroller) self.notesArea = QLineEdit() self.notesArea.setPlaceholderText("Add a note about this page...") self.notesArea.returnPressed.connect(self.onAddNote) self.vBoxMain.addWidget(self.notesArea) self.mainViewGroup = QGroupBox() self.mainViewGroup.setTitle("Main View") self.mainViewGroup.setLayout(self.vBoxMain) # join both sides together self.leftRightSplit = QSplitter(Qt.Horizontal) self.leftRightSplit.addWidget(self.altViewSplit) self.leftRightSplit.addWidget(self.mainViewGroup) self.setCentralWidget(self.leftRightSplit) def initUIToolbar(self): mainMenu = self.menuBar( ) # get the menu bar already in use by this QMainWindow subclass fileMenu = mainMenu.addMenu("File") editMenu = mainMenu.addMenu("Edit") LayoutMenu = mainMenu.addMenu("Layout") AboutMenu = mainMenu.addMenu("About") saveAction = fileMenu.addAction("Save") quitAction = fileMenu.addAction("Exit Bettersheets") quitAction.triggered.connect(self.quitApp) copyAction = editMenu.addAction("Copy") resetAction = LayoutMenu.addAction("Reset Default Layout") self.toolBar = self.addToolBar("Tools") self.toolBar.addAction(saveAction) self.toolBar.addAction(copyAction) def contextMenuEvent(self, event): # return super().contextMenuEvent(event) contextMenu = QMenu() selectAction = contextMenu.addAction("Select Area") extractAction = contextMenu.addAction("Extract Content") openAction = contextMenu.addAction("Open PDF") closeAction = contextMenu.addAction("Close PDF") quitAction = contextMenu.addAction("Quit") triggered_action = contextMenu.exec_(self.mapToGlobal(event.pos())) if triggered_action == quitAction: self.quitApp() def quitApp(self): self.close() def onAddNote(self): print("note added") text = self.notesArea.text() if text: self.notesDB.append(text) self.notesDisplay.clear() self.notesDisplay.addItems(self.notesDB) self.notesArea.clear() def initPdfViewer(self, openPages: int): pass def initToC(self): # get table of contents ToC = self.myPdfContext.getToC() ToC_headings_list = [x[1] for x in ToC] self.ToCListView.clear() self.ToCListView.addItems(ToC_headings_list)
class FaceLoadingWidget(QWidget): """ Widget that provides GUI in Face loading page. """ def __init__(self, parent=None): QWidget.__init__(self, parent) self.__setup_ui() def __setup_ui(self): self.layout = QVBoxLayout() self.enter_name_label = QLabel("Enter user name:") self.layout.addWidget(self.enter_name_label) self.name_line_edit = QLineEdit() self.layout.addWidget(self.name_line_edit) self.id_label = QLabel( "Enter user id (leave blank if the user is new)") self.layout.addWidget(self.id_label) self.id_line_edit = QLineEdit() self.layout.addWidget(self.id_line_edit) self.from_file_button = QPushButton("From file") self.from_file_button.clicked.connect(self.load_from_file) self.layout.addWidget(self.from_file_button) self.from_camera_button = QPushButton("From camera") self.from_camera_button.clicked.connect(self.load_from_camera) self.layout.addWidget(self.from_camera_button) self.layout.addStretch() self.back_button = QPushButton("Back") self.back_button.clicked.connect(self.back) self.layout.addWidget(self.back_button) self.setLayout(self.layout) @Slot() def load_from_file(self): file_name = QFileDialog.getOpenFileName( self, "Open Image", os.getcwd(), "Image Files (*.png *.jpg *.bmp)")[0] user_name = self.name_line_edit.text() id_inp = self.id_line_edit.text() if not id_inp: id_ = app.get_next_face_id() else: id_ = int(id_inp) if file_name and user_name: try: app.load_from_file(file_name, id_, user_name) success_message = QErrorMessage(self) success_message.showMessage( f"Successfully loaded a new face of {user_name} (id {id_})" ) self.name_line_edit.clear() self.id_line_edit.clear() except (EmptyImageError, FaceNotFoundError) as e: error_message = QErrorMessage(self) error_message.showMessage(str(e)) else: error_message = QErrorMessage(self) error_message.showMessage("File name or user name not provided") @Slot() def load_from_camera(self): user_name = self.name_line_edit.text() id_inp = self.id_line_edit.text() if not id_inp: id_ = app.get_next_face_id() else: id_ = int(id_inp) if user_name: app.load_from_camera(id_, user_name) success_message = QErrorMessage(self) success_message.showMessage( f"Successfully loaded a new face of {user_name} (id {id_})") self.name_line_edit.clear() self.id_line_edit.clear() else: error_message = QErrorMessage(self) error_message.showMessage("User name not provided") @Slot() def back(self): self.parent().set_main_menu()
class Music(QMainWindow): def __init__(self): super(Music, self).__init__() self.setGeometry(20, 50, 522, 175) self.setMinimumSize(522, 175) self.setMaximumSize(522, 175) self.setWindowTitle('Muse') self.setWindowIcon(QIcon('arti.PNG')) self.setFont(QFont('Roboto', 12)) palette = QPalette() palette.setColor(palette.Window, QColor('#000000')) palette.setColor(palette.WindowText, QColor('#FFFFFF')) self.setPalette(palette) self.menubar = QMenuBar(self) self.menubar.setGeometry(0, 0, 682, 21) self.menubar.setFont(QFont('Roboto', 10)) self.date_menu = QMenu(self.menubar) self.date_menu.setTitle(str(datetime.now().strftime('%d-%m-%Y'))) self.setMenuBar(self.menubar) self.menubar.addAction(self.date_menu.menuAction()) self.song = QLineEdit(self) self.song.setPlaceholderText( 'Enter the name of song you want to search for:') self.song.setGeometry(10, 30, 501, 31) self.spotify = QRadioButton(self) self.spotify.setText('Spotify') self.spotify.setGeometry(120, 80, 101, 21) self.gaana = QRadioButton(self) self.gaana.setText('Gaana') self.gaana.setGeometry(330, 80, 91, 21) self.search = QPushButton(self) self.search.setText('Search') self.search.setGeometry(380, 130, 121, 31) self.search.clicked.connect(lambda: self.on_click()) self.search.setCursor(QCursor(Qt.PointingHandCursor)) self.label = QLabel(self) self.label.setGeometry(10, 130, 341, 31) def on_click(self): self.song_search = self.song.text() if self.song.text(): if self.spotify.isChecked(): self.speak('Searching your song on Spotify.') spotify_url = 'https://open.spotify.com/search/' webbrowser.open(spotify_url + self.song_search) elif self.gaana.isChecked(): self.speak('Searching your song on Gaana.') gaana_url = 'https://gaana.com/search/' webbrowser.open(gaana_url + self.song_search) else: self.speak('Please choose either Spotify or Gaana.') else: self.speak('Please type a song name first') self.song.clear() def speak(self, audio): self.engine = pyttsx3.init('sapi5') self.voices = self.engine.getProperty('voices') self.engine.setProperty('voice', self.voices[1].id) self.engine.setProperty('rate', 165) self.engine.say(audio) self.label.setText(audio) self.engine.runAndWait()
class Form(QDialog): def __init__(self, parent=None): super(Form, self).__init__(parent) #set the size #Creat widgets self.setWindowTitle("Cover Letter Developer") self.label1 = QLabel('Input Company Name') self.edit1 = QLineEdit("") self.label2 = QLabel('Input Position Title') self.edit2 = QLineEdit("") self.label3 = QLabel('How did you get introduced to the company?') self.edit3 = QLineEdit("") self.label4 = QLabel( 'What skills do you have that would help the COOP/Internship') self.edit4 = QLineEdit("") self.button = QPushButton("Develop") # Creat layout and add widgets layout = QVBoxLayout() layout.addWidget(self.label1) layout.addWidget(self.edit1) layout.addWidget(self.label2) layout.addWidget(self.edit2) layout.addWidget(self.label3) layout.addWidget(self.edit3) layout.addWidget(self.label4) layout.addWidget(self.edit4) layout.addWidget(self.button) #set dialog layout self.setLayout(layout) self.button.clicked.connect(self.coverlet) def coverlet(self): name = self.edit1.text() pos = self.edit2.text() intro = self.edit3.text() skills = self.edit4.text() mytext = """ Dear """ + name + """’s Hiring Team, \n """ + """ """ + """ I am writing to apply to the """ + pos + """ Intern/COOP position at """ + name + """. I am a 4th year at Wentworth Institute of Technology, pursuing a Bachelor of Science degree in Electro-mechanical Engineering. The Electro-mechanical Engineering program combines the technical disciplines of Electrical and Mechanical Engineering. """ + intro + """ """ + """As an intern at """ + name + """ , I will bring my toolset of """ + skills + """. Additionally I have experience in quality and reliability of electronic circuit systems through the tests that I have done when I was Analog Devices like shock, high voltage, HALT testing. Along with developing reliability testers that I programmed using LabView(a graphical programming language). My C programming and Python experience is from a project that I have done for a Junior Design Project and you can see the pictures through my personal website list below. """ + """ """ + """ As an engineering student, the most valuable thing that I have currently learned about myself is that when faced with a difficult problem I may initially fail, but I don’t quit until I eventually solve the problem. I am a quick learner and will be a good asset to """ + name + """. Wentworth Institute of Technology incorporates COOPS/internships as part of its curriculum, and, therefore, I would be available to work full time throughout the summer for a minimum of 14 weeks. I would be honored to intern for """ + name + """ and gain experience in engineering and further """ + name + """ initiative. has a reputation for excellence, and I value your commitment to making the world a better and safer place. """ + """ """ + """ You may contact me by phone, email or my personal website, which I have supplied below. Thank you for your time and consideration. """ anothertext = """ Respectfully yours, Martynas Baranauskas [email protected] 781-572-9775 Personal Website: https://baranauskasm.wixsite.com/mysite or scan QR code with smartphone camera """ document = Document() p = document.add_paragraph(mytext) g = document.add_paragraph(anothertext) k = document.add_picture('qr_code.png', width=Inches(0.7)) # document.add_page_break() # the saving of the document and the path to the filename = name + '_' + pos + '_baranauskas_.docx' # filepath = r'C:\Users\baranauskasm\Desktop\COOP Stuff\Summer 2020 COOP (future)\cover letters\automated cover letters' document.save(filename) print("-----------------------------------------------------") print(name + "_" + pos + "_baranauskas.doxc document was developed") print("------------------------------------------------------") #clear the form for another submition self.edit1.clear() self.edit2.clear() self.edit3.clear() self.edit4.clear()
class MainWindow(QMainWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setObjectName("main_window") self.setEnabled(True) self.resize(608, 248) size_policy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) size_policy.setHorizontalStretch(0) size_policy.setVerticalStretch(0) size_policy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) self.setSizePolicy(size_policy) self.setAcceptDrops(True) self.setWindowTitle("FileHookPi") self.central_widget = QWidget(self) self.central_widget.setObjectName("central_widget") self.horizontalLayout = QHBoxLayout(self.central_widget) self.horizontalLayout.setObjectName("horizontalLayout") self.text_box = QPlainTextEdit(self.central_widget) self.text_box.setAcceptDrops(False) self.text_box.setReadOnly(True) self.text_box.setObjectName("text_box") self.horizontalLayout.addWidget(self.text_box) self.buttons_vertical_layout = QVBoxLayout() self.buttons_vertical_layout.setObjectName("buttons_vertical_layout") self.open_file_button = QPushButton(self.central_widget) self.open_file_button.setText("Open File") self.open_file_button.setObjectName("open_file_button") self.open_file_button.clicked.connect(self.select_file) self.buttons_vertical_layout.addWidget(self.open_file_button) self.line_counter = QLineEdit(self.central_widget) size_policy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) size_policy.setHorizontalStretch(0) size_policy.setVerticalStretch(0) size_policy.setHeightForWidth( self.line_counter.sizePolicy().hasHeightForWidth()) self.line_counter.setSizePolicy(size_policy) self.line_counter.setAcceptDrops(False) self.line_counter.setReadOnly(True) self.line_counter.setObjectName("line_counter") self.buttons_vertical_layout.addWidget(self.line_counter) self.next_line_button = QPushButton(self.central_widget) self.next_line_button.setText("Next Line") self.next_line_button.setObjectName("next_line_button") self.next_line_button.clicked.connect(self.advance_line) self.buttons_vertical_layout.addWidget(self.next_line_button) self.horizontalLayout.addLayout(self.buttons_vertical_layout) self.menuBar().addMenu(FileMenu(self)) self.setCentralWidget(self.central_widget) self.current_file = None self.line_count = 0 def select_file(self, *, advance=True): path, *_ = QFileDialog.getOpenFileName(self, "Open File", filter="Text Files (*.txt)") if not path: return self.open_file(path, advance=advance) def open_file(self, path, *, advance=True): if self.current_file is not None: self.cleanup() self.current_file = open(path, "r", encoding="utf-8") self.setWindowFilePath(path) if advance: self.advance_line() def advance_line(self): if self.current_file is None: return try: line = self.current_file.readline() except Exception as exc: message_box = QMessageBox( parent=self, text=f"Failed to read:\n{type(exc).__name__}: {exc}", icon=QMessageBox.Critical) message_box.setInformativeText("Close the file?") message_box.setStandardButtons(QMessageBox.No | QMessageBox.Yes) message_box.setDefaultButton(QMessageBox.Yes) if message_box.exec_() == QMessageBox.Yes: self.cleanup() return if not line: return self.line_count += 1 self.line_counter.setText(str(self.line_count)) QApplication.clipboard().setText(line.rstrip("\n")) self.text_box.setPlainText(line + self.text_box.toPlainText()) def cleanup(self): if self.current_file is not None: self.current_file.close() self.current_file = None self.text_box.clear() self.line_count = 0 self.line_counter.clear() self.setWindowFilePath("") def dragEnterEvent(self, event): urls = event.mimeData().urls() if urls and os.path.isfile(urls[0].path()): event.accept() def dropEvent(self, event): self.open_file(event.mimeData().urls()[0].path()) def closeEvent(self, event): self.cleanup() event.accept()
class Artigence(QMainWindow): def __init__(self): super(Artigence, self).__init__() # Basic Settings self.setGeometry(300, 200, 682, 422) self.setMinimumSize(QSize(682, 422)) self.setMaximumSize(QSize(682, 422)) self.setWindowIcon(QIcon("arti.PNG")) self.setWindowTitle("Artigence Home") # Color Scheme self.palette = QPalette() self.palette.setColor(self.palette.Window, QColor('#000000')) self.palette.setColor(self.palette.WindowText, QColor('#FFFFFF')) self.setPalette(self.palette) self.light_palette = QPalette() self.light_palette.setColor(self.light_palette.Window, QColor('#FFFFFF')) self.light_palette.setColor(self.light_palette.WindowText, QColor('#000000')) # Setting MenuBar self.menubar = QMenuBar(self) self.menubar.setGeometry(0, 0, 682, 21) self.date_menu = QMenu(self.menubar) self.date_menu.setTitle(str(datetime.now().strftime('%d-%m-%Y'))) self.theme_menu = QMenu(self.menubar) self.theme_menu.setTitle('Theme') self.dark_theme = QAction('Dark Theme') self.dark_theme.setShortcut(QKeySequence('Ctrl+Shift+D')) self.theme_menu.addAction(self.dark_theme) self.dark_theme.triggered.connect(lambda: self.dark()) self.light_theme = QAction('Light Theme') self.light_theme.setShortcut(QKeySequence('Ctrl+Shift+L')) self.theme_menu.addAction(self.light_theme) self.light_theme.triggered.connect(lambda: self.light()) self.app_menu = QMenu(self.menubar) self.app_menu.setTitle('Apps') self.calculator_menu = QAction('Calculator') self.calculator_menu.setShortcut(QKeySequence('Alt+C')) self.app_menu.addAction(self.calculator_menu) self.calculator_menu.triggered.connect(lambda: self.calculator_func()) self.game_menu = QAction('GameHub') self.game_menu.setShortcut(QKeySequence('Alt+G')) self.app_menu.addAction(self.game_menu) self.game_menu.triggered.connect(lambda: self.games_func()) self.music_menu = QAction('Muse (Music)') self.music_menu.setShortcut(QKeySequence('Alt+M')) self.app_menu.addAction(self.music_menu) self.music_menu.triggered.connect(lambda: self.music_func()) self.news_menu = QAction('News') self.news_menu.setShortcut(QKeySequence('Alt+E')) self.app_menu.addAction(self.news_menu) self.news_menu.triggered.connect(lambda: self.news_func()) self.notepad_menu = QAction('Notepad') self.notepad_menu.setShortcut(QKeySequence('Alt+N')) self.app_menu.addAction(self.notepad_menu) self.notepad_menu.triggered.connect(lambda: self.notepad_func()) self.pronunciator = QAction('Pronunciator') self.pronunciator.setShortcut(QKeySequence('Alt+P')) self.app_menu.addAction(self.pronunciator) self.pronunciator.triggered.connect(lambda: self.pronunciator_func()) self.translate_menu = QAction('Translate') self.translate_menu.setShortcut(QKeySequence('Alt+T')) self.app_menu.addAction(self.translate_menu) self.translate_menu.triggered.connect(lambda: self.translate_func()) self.weather_menu = QAction('Weather') self.weather_menu.setShortcut(QKeySequence('Alt+W')) self.app_menu.addAction(self.weather_menu) self.weather_menu.triggered.connect(lambda: self.weather_func()) self.setMenuBar(self.menubar) self.menubar.addAction(self.date_menu.menuAction()) self.menubar.addAction(self.theme_menu.menuAction()) self.menubar.addAction(self.app_menu.menuAction()) # Creating Widgets self.query = QLineEdit(self) self.query.setGeometry(QRect(20, 30, 451, 41)) self.query.setMinimumSize(QSize(451, 41)) self.query.setMaximumSize(QSize(451, 41)) self.query.setPlaceholderText("Enter your Query Here:") self.query.setFont(QFont('Roboto', 16)) self.query.setClearButtonEnabled(True) self.update = QPushButton(self) self.update.setGeometry(QRect(491, 30, 171, 41)) self.update.setMinimumSize(QSize(1, 1)) self.update.setMaximumSize(QSize(171, 51)) self.update.setText("What's New in the Updates?") self.update.setCursor(QCursor(Qt.PointingHandCursor)) self.suggestions = QLabel(self) self.suggestions.setGeometry(QRect(20, 220, 111, 31)) self.suggestions.setMinimumSize(QSize(111, 31)) self.suggestions.setMaximumSize(QSize(111, 31)) self.suggestions.setText("Suggestions:") self.suggestions.setFont(QFont('Roboto', 14)) self.chrome = QPushButton(self) self.chrome.setGeometry(QRect(20, 260, 91, 31)) self.chrome.setCursor(QCursor(Qt.PointingHandCursor)) self.chrome.setText('Open Chrome') self.games = QPushButton(self) self.games.setGeometry(QRect(420, 260, 91, 31)) self.games.setCursor(QCursor(Qt.PointingHandCursor)) self.games.setText('Games') self.cmd = QPushButton(self) self.cmd.setGeometry(QRect(160, 260, 91, 31)) self.cmd.setCursor(QCursor(Qt.PointingHandCursor)) self.cmd.setText('Open Cmd') self.joke = QPushButton(self) self.joke.setGeometry(QRect(160, 310, 91, 31)) self.joke.setCursor(QCursor(Qt.PointingHandCursor)) self.joke.setText('Joke Please!!') self.music = QPushButton(self) self.music.setGeometry(QRect(290, 260, 91, 31)) self.music.setCursor(QCursor(Qt.PointingHandCursor)) self.music.setText('Music') self.youtube = QPushButton(self) self.youtube.setGeometry(QRect(290, 310, 91, 31)) self.youtube.setCursor(QCursor(Qt.PointingHandCursor)) self.youtube.setText('Youtube') self.time = QPushButton(self) self.time.setGeometry(QRect(20, 310, 91, 31)) self.time.setCursor(QCursor(Qt.PointingHandCursor)) self.time.setText('Tell Time') self.weather = QPushButton(self) self.weather.setGeometry(QRect(420, 310, 91, 31)) self.weather.setCursor(QCursor(Qt.PointingHandCursor)) self.weather.setText('Weather') self.calculator = QPushButton(self) self.calculator.setGeometry(QRect(550, 260, 101, 31)) self.calculator.setCursor(QCursor(Qt.PointingHandCursor)) self.calculator.setText('Calculator') self.wikipedia = QPushButton(self) self.wikipedia.setGeometry(QRect(550, 310, 101, 31)) self.wikipedia.setCursor(QCursor(Qt.PointingHandCursor)) self.wikipedia.setText('India Wikipedia') self.news = QPushButton(self) self.news.setGeometry(QRect(20, 360, 91, 31)) self.news.setCursor(QCursor(Qt.PointingHandCursor)) self.news.setText('Latest News') self.meaning = QPushButton(self) self.meaning.setGeometry(QRect(420, 360, 231, 31)) self.meaning.setCursor(QCursor(Qt.PointingHandCursor)) self.meaning.setText('Meaning of Obsolete (or any word)') self.harry_potter = QPushButton(self) self.harry_potter.setGeometry(QRect(290, 360, 91, 31)) self.harry_potter.setCursor(QCursor(Qt.PointingHandCursor)) self.harry_potter.setText('Harry Potter') self.translate = QPushButton(self) self.translate.setGeometry(QRect(160, 360, 91, 31)) self.translate.setCursor(QCursor(Qt.PointingHandCursor)) self.translate.setText('Open Translate') self.line = QFrame(self) self.line.setGeometry(QRect(20, 200, 661, 16)) self.line.setFrameShape(QFrame.HLine) self.line.setFrameShadow(QFrame.Sunken) self.label = QLabel(self) self.label.setGeometry(QRect(20, 100, 631, 91)) self.label.setFont(QFont('Roboto', 12)) self.label.setTextFormat(Qt.AutoText) self.label.setWordWrap(True) self.wish() # Making the Widgets Functional self.query.returnPressed.connect(lambda: self.on_enter()) self.query.returnPressed.connect(lambda: self.clear_text()) self.update.clicked.connect(lambda: self.update_func()) self.music.clicked.connect(lambda: self.music_func()) self.games.clicked.connect(lambda: self.games_func()) self.calculator.clicked.connect(lambda: self.calculator_func()) self.weather.clicked.connect(lambda: self.weather_func()) self.news.clicked.connect(lambda: self.news_func()) self.translate.clicked.connect(lambda: self.translate_func()) self.time.clicked.connect(lambda: self.time_func()) self.joke.clicked.connect(lambda: self.joke_func()) self.youtube.clicked.connect(lambda: self.youtube_func()) self.wikipedia.clicked.connect(lambda: self.wikipedia_func()) self.chrome.clicked.connect(lambda: self.chrome_func()) self.cmd.clicked.connect(lambda: self.cmd_func()) self.meaning.clicked.connect(lambda: self.meaning_func()) self.harry_potter.clicked.connect(lambda: self.potter_func()) def pronunciator_func(self): self.speak('Opening Pronunciator') from pronunciator import Pronunciator self.pronunciator_win = Pronunciator() self.pronunciator_win.show() def pong_func(self): import pong def notepad_func(self): self.speak('Opening Notepad') from notepad import Notepad self.notepad_win = Notepad() self.notepad_win.show() def update_func(self): os.startfile('Each Version Updates.txt') def translate_func(self): self.speak( 'Opening Translate\nPlease Wait as opening Translate may take up to 4-5 seconds' ) from translate import Translate self.translate_win = Translate() self.translate_win.show() def games_func(self): self.speak('Opening GameHub') from games import GameHub self.game_win = GameHub() self.game_win.show() def weather_func(self): self.speak('Opening Weather.') from weather import Weather self.weather_win = Weather() self.weather_win.show() def music_func(self): self.speak('Opening Muse') from music import Music self.music_win = Music() self.music_win.show() def calculator_func(self): self.speak('Opening Calculator.') from calculator import Calculator self.calculator_win = Calculator() self.calculator_win.show() def news_func(self): self.speak('Opening News.') from news import News self.news_win = News() self.news_win.show() self.speak( 'Welcome to News.\nThese are the latest international headlines according to BBC News Network.' ) def chrome_func(self): try: chrome_path = 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe' os.startfile(chrome_path) self.speak('Opening Chrome.') except Exception: self.speak( 'No Google Chrome installation found on the host device.') def cmd_func(self): cmd_path = 'C:\\Windows\\system32\\cmd.exe' os.startfile(cmd_path) self.speak('Opening Command Prompt.') def time_func(self): question = 'time' app_id = 'LLQ4QY-A7K3LEL4T8' client = wolframalpha.Client(app_id) res = client.query(question) answer = next(res.results).text self.speak(answer) def joke_func(self): self.speak(pyjokes.get_joke()) def youtube_func(self): webbrowser.open('https://www.youtube.com') self.speak('Opening Youtube.') def wikipedia_func(self): try: self.speak('Searching Wikipedia. Please Wait...') query = 'India'.replace('wikipedia', '') result = wikipedia.summary(query, sentences=1) self.speak('According to Wikipedia...') self.speak(result) except Exception as e: self.speak(e) def meaning_func(self): question = 'obsolete' app_id = 'LLQ4QY-A7K3LEL4T8' client = wolframalpha.Client(app_id) res = client.query(question) answer = next(res.results).text self.speak(answer) def potter_func(self): new = 2 google_url = "http://google.com/?#q=" webbrowser.open(google_url + 'Harry Potter', new=new) def clear_text(self): self.query.clear() def on_enter(self): user_query = self.query.text().lower() if 'wikipedia' in user_query: try: self.speak('Searching Wikipedia. Please Wait...') user_query = user_query.replace('wikipedia', '') result = wikipedia.summary(user_query, sentences=1) self.speak('According to Wikipedia...') self.speak(result) except Exception as e: self.speak('Please try again later.') self.speak(e) elif 'youtube' in user_query: webbrowser.open('https://www.youtube.com') self.speak('Opening Youtube.') elif 'google' in user_query: webbrowser.open('https://www.google.com/') self.speak('Opening Google.') elif 'chrome' in user_query: # You'll have to download google chrome first on your desktop/pc. try: chrome_path = 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe' os.startfile(chrome_path) self.speak('Opening Chrome') except Exception: self.speak( 'No Google Chrome installation found on the host device.') elif 'cmd' in user_query: cmd_path = 'C:\\Windows\\system32\\cmd.exe' os.startfile(cmd_path) self.speak('Opening Command Prompt.') elif 'control panel' in user_query: cp_path = 'C:\\Windows\\system32\\control.exe' os.startfile(cp_path) self.speak('Opening Control Panel.') elif 'bye' in user_query or 'goodbye' in user_query or 'good night' in user_query or 'see you later' in user_query: self.speak(random.choice(self.bye)) sys.exit() elif 'hello' in user_query or 'hi' in user_query: self.speak(random.choice(self.hello)) elif 'joke' in user_query: self.speak(pyjokes.get_joke()) elif 'who are you' in user_query: self.speak('I am Artigence, your artificial intelligence.') elif 'map' in user_query or 'maps' in user_query: self.speak('Opening Google Maps.') webbrowser.open("https://www.google.com/maps") elif 'open calculator' in user_query or 'calculator' in user_query: self.calculator_func() elif 'news' in user_query: self.news_func() self.speak( 'Welcome to News.\nThese are the latest international headlines according to BBC News Network.' ) elif 'weather' in user_query: self.weather_func() elif 'games' in user_query: self.games_func() elif 'pronunciator' in user_query or 'pronounce' in user_query: self.pronunciator_func() elif 'translate' in user_query: self.translate_func() elif 'music' in user_query: self.music_func() elif 'notepad' in user_query: self.notepad_func() else: try: question = user_query app_id = 'LLQ4QY-A7K3LEL4T8' client = wolframalpha.Client(app_id) res = client.query(question) answer = next(res.results).text self.label.setText(answer) self.label.adjustSize() except: new = 2 google_url = "http://google.com/?#q=" query = user_query webbrowser.open(google_url + query, new=new) # The A.I. will speak through this function def speak(self, audio): self.engine = pyttsx3.init('sapi5') voices = self.engine.getProperty('voices') self.engine.setProperty('voice', voices[1].id) self.engine.setProperty('rate', 165) self.label.setText(audio) self.engine.say(audio) self.engine.runAndWait() self.label.clear() def wish(self): hour = int(datetime.now().hour) if 0 <= hour < 12: self.speak('Good Morning.') elif 12 <= hour < 18: self.speak('Good Afternoon.') else: self.speak('Good Evening.') self.speak('I am Artigence.') self.speak('How may I help you today') hello = ['Kon\'nichiwa', 'Ciao', 'Hola', 'Bonjour', 'Hello', 'Hi', 'Hiya'] bye = [ 'Adios', 'Goodbye', 'Bye-Bye', 'See you next time.', 'Artigence Out.', 'It was nice talking to you sir. Have a nice day.' ] def dark(self): self.setPalette(self.palette) def light(self): self.setPalette(self.light_palette)