class MDIHistory(QWidget, _HalWidgetBase): def __init__(self, parent=None): super(MDIHistory, self).__init__(parent) self.setMinimumSize(QSize(300, 200)) self.setWindowTitle("PyQt5 editor test example") lay = QVBoxLayout() lay.setContentsMargins(0,0,0,0) self.setLayout(lay) self.list = QListView() self.list.setEditTriggers(QListView.NoEditTriggers) self.list.activated.connect(self.activated) self.list.setAlternatingRowColors(True) self.list.selectionChanged = self.selectionChanged self.model = QStandardItemModel(self.list) self.MDILine = MDILine() self.MDILine.soft_keyboard = False self.MDILine.line_up = self.line_up self.MDILine.line_down = self.line_down # add widgets lay.addWidget(self.list) lay.addWidget(self.MDILine) self.reload() def _hal_init(self): STATUS.connect('state-off', lambda w: self.setEnabled(False)) STATUS.connect('state-estop', lambda w: self.setEnabled(False)) STATUS.connect('interp-idle', lambda w: self.setEnabled(STATUS.machine_is_on() and (STATUS.is_all_homed() or INFO.NO_HOME_REQUIRED))) STATUS.connect('interp-run', lambda w: self.setEnabled(not STATUS.is_auto_mode())) STATUS.connect('all-homed', lambda w: self.setEnabled(STATUS.machine_is_on())) def reload(self, w=None ): print 'RELOAD' try: fp = os.path.expanduser(INFO.MDI_HISTORY_PATH) with open(fp,'r') as inputfile: for line in inputfile: line = line.rstrip('\n') item = QStandardItem(line) self.model.appendRow(item) self.list.setModel(self.model) self.list.scrollToBottom() except Exception as e: print e LOG.error('File path is not valid: {}]n,()'.format(fp),e) def line_up(self): print 'up' def line_down(self): print 'down' def selectionChanged(self,old, new): cmd = self.getSelected() self.MDILine.setText(cmd) def getSelected(self): selected_indexes = self.list.selectedIndexes() selected_rows = [item.row() for item in selected_indexes] # iterates each selected row in descending order for selected_row in sorted(selected_rows, reverse=True): text = self.model.item(selected_row).text() return text def activated(self): cmd = self.getSelected() self.MDILine.setText(cmd) self.MDILine.submit() item = QStandardItem(cmd) self.model.appendRow(item) self.list.update() ######################################################################### # This is how designer can interact with our widget properties. # designer will show the pyqtProperty properties in the editor # it will use the get set and reset calls to do those actions ######################################################################### def set_soft_keyboard(self, data): self.MDILine.soft_keyboard = data def get_soft_keyboard(self): return self.MDILine.soft_keyboard def reset_soft_keyboard(self): self.MDILine.soft_keyboard = False # designer will show these properties in this order: soft_keyboard_option = pyqtProperty(bool, get_soft_keyboard, set_soft_keyboard, reset_soft_keyboard)
class VistaListaDipendenti(QWidget): def __init__(self, parent=None): super(VistaListaDipendenti, self).__init__(parent) self.controller = ControllerListaDipendenti() h_layout = QHBoxLayout() self.list_view = QListView() self.update_ui() h_layout.addWidget(self.list_view) buttons_layout = QVBoxLayout() open_button = QPushButton('Visualizza informazioni') open_button.setStyleSheet( 'QPushButton {background-color: #E9CFEC ; color: black; border-style: outset;border-width: 6px;' 'border-radius: 15px;border-color: #FA8072;padding: 6px}') open_button.clicked.connect(self.show_selected_info) buttons_layout.addWidget(open_button) new_button = QPushButton("Inserisci dipendente") new_button.setStyleSheet( 'QPushButton {background-color: #C3FDB8; color: black; border-style: outset;border-width: 6px;' 'border-radius: 15px;border-color: #3EB489;padding: 6px}') new_button.clicked.connect(self.show_new_dipendente) buttons_layout.addWidget(new_button) buttons_layout.addStretch() h_layout.addLayout(buttons_layout) self.setLayout(h_layout) self.resize(600, 300) self.setWindowTitle('Lista Dipendenti') def update_ui(self): self.listview_model = QStandardItemModel(self.list_view) for dipendente in self.controller.get_lista_dipendenti(): item = QStandardItem() item.setText(dipendente.nome + " " + dipendente.cognome) item.setEditable(False) font = item.font() font.setPointSize(18) item.setFont(font) self.listview_model.appendRow(item) self.list_view.setModel(self.listview_model) # Funzione che mostra a schermo le informazioni del cliente selezionato def show_selected_info(self): if len(self.list_view.selectedIndexes()) > 0: selected = self.list_view.selectedIndexes()[0].row() dipendente_selezionato = self.controller.get_dipendente_by_index(selected) self.vista_dipendente = VistaDipendente(dipendente_selezionato, self.controller.elimina_dipendente_by_id,self.update_ui) self.vista_dipendente.show() def show_new_dipendente(self): self.vista_inserisci_dipendente = VistaInserisciDipendente(self.controller, self.update_ui) self.vista_inserisci_dipendente.show() def closeEvent(self, event): self.controller.save_data()
class VistaListaPrenotazioni(QWidget): def __init__(self, parent=None): super(VistaListaPrenotazioni, self).__init__(parent) self.controller = ControlloreListaPrenotazioni() h_layout = QHBoxLayout() self.list_view = QListView() self.update_ui() h_layout.addWidget(self.list_view) buttons_layout = QVBoxLayout() open_button = QPushButton('Apri') open_button.clicked.connect(self.show_selected_info) buttons_layout.addWidget(open_button) new_button = QPushButton("Nuovo") new_button.clicked.connect(self.show_new_prenotazione) buttons_layout.addWidget(new_button) buttons_layout.addStretch() h_layout.addLayout(buttons_layout) self.setLayout(h_layout) self.resize(600, 300) self.setWindowTitle('Lista Prenotazioni') def update_ui(self): self.listview_model = QStandardItemModel(self.list_view) for prenotazione in self.controller.get_lista_delle_prenotazioni(): item = QStandardItem() item.setText(prenotazione.cliente.cognome + " " + prenotazione.cliente.nome) item.setEditable(False) font = item.font() font.setPointSize(18) item.setFont(font) self.listview_model.appendRow(item) self.list_view.setModel(self.listview_model) def show_selected_info(self): if (len(self.list_view.selectedIndexes()) > 0): selected = self.list_view.selectedIndexes()[0].row() prenotazione_selezionata = self.controller.get_prenotazione_by_index( selected) self.vista_prenotazione = VistaPrenotazione( prenotazione_selezionata, self.controller.elimina_prenotazione_by_id, self.update_ui) self.vista_prenotazione.show() def show_new_prenotazione(self): self.vista_inserisci_prenotazione = VistaInserisciPrenotazione( self.controller, self.update_ui) self.vista_inserisci_prenotazione.show() pass def closeEvent(self, event): self.controller.save_data()
class VistaListaAttrezzature(QWidget): def __init__(self, parent=None): super(VistaListaAttrezzature, self).__init__(parent) self.Controller = ControllerListaAttrezzatura() h_layout = QHBoxLayout() self.list_view = QListView() self.listview_Model = QStandardItemModel(self.list_view) for Attrezzatura in self.Controller.get_lista_delle_attrezzature(): item = QStandardItem() item.setText(Attrezzatura.nome) item.setEditable(False) font = item.font() font.setPointSize(18) item.setFont(font) self.listview_Model.appendRow(item) self.list_view.setModel(self.listview_Model) h_layout.addWidget(self.list_view) buttons_layout = QVBoxLayout() open_buttons = QPushButton("Visualizza informazioni") open_buttons.setStyleSheet( 'QPushButton {background-color: #E9CFEC ; color: black; border-style: outset;border-width: 6px;' 'border-radius: 15px;border-color: #FA8072;padding: 6px}') open_buttons.clicked.connect(self.show_selected_info) buttons_layout.addWidget(open_buttons) buttons_layout.addStretch() h_layout.addLayout(buttons_layout) self.setLayout(h_layout) self.resize(600, 400) self.setWindowTitle('Lista Attrezzature') def closeEvent(self, event): print("On close") self.Controller.save_data() event.accept() # Metodo che permette di visualizzare un Impianti attraverso l'indice def show_selected_info(self): if len(self.list_view.selectedIndexes()) > 0: selected = self.list_view.selectedIndexes()[0].row() attrezzatura_selezionata = self.Controller.get_attrezzatura_by_index( selected) self.vista_attrezzature = VistaAttrezzatura( attrezzatura_selezionata) self.vista_attrezzature.show()
class VistaListaServizi(QWidget): def __init__(self, parent=None): super(VistaListaServizi, self).__init__(parent) h_layout = QHBoxLayout() self.controller = ControlloreListaServizi() self.list_view = QListView() self.listview_model = QStandardItemModel(self.list_view) for servizio in self.controller.get_lista_dei_servizi(): item = QStandardItem() item.setText(servizio.nome) item.setEditable(False) font = item.font() font.setPointSize(18) item.setFont(font) self.listview_model.appendRow(item) self.list_view.setModel(self.listview_model) h_layout.addWidget(self.list_view) buttons_layout = QVBoxLayout() open_button = QPushButton("Apri") open_button.clicked.connect(self.show_selected_info) buttons_layout.addWidget(open_button) buttons_layout.addStretch() h_layout.addLayout(buttons_layout) self.setLayout(h_layout) self.resize(600, 300) self.setWindowTitle('Lista Servizi') def show_selected_info(self): selected = self.list_view.selectedIndexes()[0].row() servizio_selezionato = self.controller.get_servizio_by_index(selected) self.vista_servizio = VistaServizio(servizio_selezionato) self.vista_servizio.show()
class TeamChooserWidget(QWidget): def __init__(self, parent, on_next, league=None): super().__init__(parent) self.layout = QVBoxLayout() self.list_view = QListView() self.league = league self.model = TeamListModel(league) self.list_view.setModel(self.model) self.list_view.setSelectionMode(QAbstractItemView.MultiSelection) self.list_view.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.list_view.customContextMenuRequested.connect(self.list_context_menu) self.layout.addWidget(self.list_view) self.team_add = AddItemWidget(self, "New Team Name: ", self.add_team, unavailable_options=self.model.all_team_names) self.layout.addWidget(self.team_add) self.button_h_layout = QHBoxLayout() self.button_cancel = QPushButton("Cancel") self.button_cancel.clicked.connect(self.on_cancel) self.button_next = QPushButton("Next") self.button_next.clicked.connect(on_next) self.button_h_layout.addWidget(self.button_cancel) self.button_h_layout.addWidget(self.button_next) self.layout.addLayout(self.button_h_layout) self.setLayout(self.layout) self.new_teams = [] def add_team(self, name): self.new_teams.append(name) team = Team.create(name=name) self.model.add_team(team) def list_context_menu(self, pos): self.listMenu = QMenu() current_index = self.list_view.currentIndex() select = self.listMenu.addAction("Select") select.triggered.connect( lambda: self.list_view.selectionModel().select(current_index, QtCore.QItemSelectionModel.Select) ) deselect = self.listMenu.addAction("Deselect") deselect.triggered.connect( lambda: self.list_view.selectionModel().select(current_index, QtCore.QItemSelectionModel.Deselect) ) delete = self.listMenu.addAction("Delete") delete.setDisabled(current_index.data() not in self.new_teams) delete.triggered.connect(lambda: self.model.delete_team(current_index.row())) parentPosition = self.list_view.mapToGlobal(QtCore.QPoint(0, 0)) self.listMenu.move(parentPosition + pos) self.listMenu.show() def on_cancel(self): self.model.delete_added_teams() self.window().close() def get_selected_teams(self): teams = [] for i in self.list_view.selectedIndexes(): teams.append(self.model.get_team(i.row())) return teams
class VistaListaAppuntamentiVaccini(QWidget): def __init__(self, data, callback): super(VistaListaAppuntamentiVaccini, self).__init__() self.controller = ControlloreCalendarioVaccini() self.callback = callback h_layout = QHBoxLayout() self.list_view_appuntamenti = QListView() self.update_ui() h_layout.addWidget(self.list_view_appuntamenti) buttons_layout = QVBoxLayout() open_button = QPushButton('Apri') open_button.clicked.connect(self.show_selected_info) buttons_layout.addWidget(open_button) buttons_layout.addStretch() h_layout.addLayout(buttons_layout) self.setLayout(h_layout) self.resize(600, 300) self.setWindowTitle('Lista Appuntamenti Vaccini Giorno: {}'.format(data)) def show_selected_info(self): if self.list_view_appuntamenti.selectedIndexes(): selected = self.list_view_appuntamenti.selectedIndexes()[0].row() appuntamento_selezionato = self.controller.get_presidio_by_index(selected) self.vista_appuntamento = VistaAppuntamentoVaccino(appuntamento_selezionato, self.update_ui, self.controller.elimina_by_id) self.vista_vaccino.show() def update_ui(self): self.listview_appuntamenti_model = QStandardItemModel(self.list_view_appuntamenti) if self.controller.get_elenco_appuntamenti(): for appuntamento in self.controller.get_elenco_appuntamenti():item = QStandardItem() item.setText(appuntamento.cartella_paziente.nome + " " + appuntamento.cartella_paziente.cognome) item.setEditable(False) font = item.font() font.setFamily('Georgia') font.setPointSize(12) item.setFont(font) self.listview_appuntamenti_model.appendRow(item) self.list_view_appuntamenti.setModel(self.listview_appuntamenti_model)
class QueryDialog(QDialog): """a dialog to choose an item from a query """ choice = pyqtSignal(str) def __init__(self, query): super().__init__() self.query = query self.create_model() self.init_UI() def create_model(self): """creates the model as QSqlQueryModel, using the given query """ self.model = QSqlQueryModel() q = QSqlQuery() q.exec_(self.query) self.model.setQuery(q) def init_UI(self): """setup the UI """ layout = QVBoxLayout() self.setLayout(layout) self.resize(200,200) self.title = "Choose an existing project" self.list = QListView(self) layout.addWidget(self.list) self.list.setModel(self.model) self.list.setWhatsThis("Choose a project by clicking on it") self.btn = QPushButton("Accept", self) layout.addWidget(self.btn) self.btn.clicked.connect(self.on_btn_clicked) self.btn.setWhatsThis("Click here to accept your selection (works only if a project has been selected)") def on_btn_clicked(self): """when self.btn is clicked, accept the choice and emit it as self.choice """ selected = self.list.selectedIndexes() if selected: index = selected[0] chosen = self.model.data(index, Qt.DisplayRole) self.choice.emit(chosen) self.close() self.choice.emit("") self.close()
class MDIHistory(QWidget, _HalWidgetBase): def __init__(self, parent=None): super(MDIHistory, self).__init__(parent) self.setMinimumSize(QSize(200, 150)) self.setWindowTitle("PyQt5 editor test example") lay = QVBoxLayout() lay.setContentsMargins(0,0,0,0) self.setLayout(lay) self.list = QListView() self.list.setEditTriggers(QListView.NoEditTriggers) self.list.activated.connect(self.activated) self.list.setAlternatingRowColors(True) self.list.selectionChanged = self.selectionChanged self.model = QStandardItemModel(self.list) self.MDILine = MDILine() self.MDILine.soft_keyboard = False self.MDILine.line_up = self.line_up self.MDILine.line_down = self.line_down STATUS.connect('reload-mdi-history', self.reload) # add widgets lay.addWidget(self.list) lay.addWidget(self.MDILine) self.fp = os.path.expanduser(INFO.MDI_HISTORY_PATH) try: open(self.fp, 'r') except: open(self.fp, 'a+') LOG.debug('MDI History file created: {}'.format(self.fp)) self.reload() self.select_row('last') def _hal_init(self): STATUS.connect('state-off', lambda w: self.setEnabled(False)) STATUS.connect('state-estop', lambda w: self.setEnabled(False)) STATUS.connect('interp-idle', lambda w: self.setEnabled(STATUS.machine_is_on() and (STATUS.is_all_homed() or INFO.NO_HOME_REQUIRED))) STATUS.connect('interp-run', lambda w: self.setEnabled(not STATUS.is_auto_mode())) STATUS.connect('all-homed', lambda w: self.setEnabled(STATUS.machine_is_on())) def reload(self, w=None ): self.model.clear() try: with open(self.fp,'r') as inputfile: for line in inputfile: line = line.rstrip('\n') item = QStandardItem(line) self.model.appendRow(item) self.list.setModel(self.model) self.list.scrollToBottom() if self.MDILine.hasFocus(): self.select_row('last') except: LOG.debug('File path is not valid: {}'.format(fp)) def selectionChanged(self,old, new): cmd = self.getSelected() self.MDILine.setText(cmd) selectionModel = self.list.selectionModel() if selectionModel.hasSelection(): self.row = selectionModel.currentIndex().row() def getSelected(self): selected_indexes = self.list.selectedIndexes() selected_rows = [item.row() for item in selected_indexes] # iterates each selected row in descending order for selected_row in sorted(selected_rows, reverse=True): text = self.model.item(selected_row).text() return text def activated(self): cmd = self.getSelected() self.MDILine.setText(cmd) self.MDILine.submit() self.select_row('down') def select_row(self, style): selectionModel = self.list.selectionModel() parent = QModelIndex() self.rows = self.model.rowCount(parent) - 1 if style == 'last': self.row = self.rows elif style == 'up': if self.row > 0: self.row -= 1 else: self.row = self.rows elif style == 'down': if self.row < self.rows: self.row += 1 else: self.row = 0 else: return top = self.model.index(self.row, 0, parent) bottom = self.model.index(self.row, 0, parent) selectionModel.setCurrentIndex(top, QItemSelectionModel.Select | QItemSelectionModel.Rows) selection = QItemSelection(top, top) selectionModel.clearSelection() selectionModel.select(selection, QItemSelectionModel.Select) def line_up(self): self.select_row('up') def line_down(self): self.select_row('down') ######################################################################### # This is how designer can interact with our widget properties. # designer will show the pyqtProperty properties in the editor # it will use the get set and reset calls to do those actions ######################################################################### def set_soft_keyboard(self, data): self.MDILine.soft_keyboard = data def get_soft_keyboard(self): return self.MDILine.soft_keyboard def reset_soft_keyboard(self): self.MDILine.soft_keyboard = False # designer will show these properties in this order: soft_keyboard_option = pyqtProperty(bool, get_soft_keyboard, set_soft_keyboard, reset_soft_keyboard)
class MainWindow(QWidget): """ This is the graphical user interface """ def __init__(self): super().__init__() self.initUI() def initUI(self): # setup entire layout vbox = QVBoxLayout() self.setLayout(vbox) # default size self.resize(640, 480) # main window title self.setWindowTitle("Vanilla Search Engine") # main window icon self.setWindowIcon( QIcon( os.path.dirname(os.path.abspath(__file__)) + '/icons/vanilla.png')) # add query input field searchLayout = QHBoxLayout() searchLabel = QLabel("Query: ") searchLayout.addWidget(searchLabel) self.searchField = QLineEdit() # self.searchField.move(20, 20) # self.searchField.resize(200, 40) searchLayout.addWidget(self.searchField) vbox.addLayout(searchLayout) # add choice of model, Boolean, or VSM modelLabel = QLabel("Choice of model: \t\t") modelLayout = QHBoxLayout() modelGroup = QButtonGroup(self) self.modelChoiceButton1 = QRadioButton("Boolean") self.modelChoiceButton1.setChecked(True) self.modelChoiceButton2 = QRadioButton("VSM") self.modelChoiceButton2.setChecked(False) self.modelChoiceButton1.toggled.connect( lambda: self.changeChoiceState(self.modelChoiceButton1)) self.modelChoiceButton2.toggled.connect( lambda: self.changeChoiceState(self.modelChoiceButton2)) modelLayout.addWidget(modelLabel) modelLayout.addWidget(self.modelChoiceButton1) modelGroup.addButton(self.modelChoiceButton1) modelLayout.addWidget(self.modelChoiceButton2) modelGroup.addButton(self.modelChoiceButton2) modelLayout.addStretch(1) vbox.addLayout(modelLayout) # add choice of collection: UofO catalog, .. collectionLabel = QLabel("Choice of collection: \t") collectionLayout = QHBoxLayout() collectionButtonGroup = QButtonGroup(self) self.collectionChoiceButton1 = QRadioButton("UofO catalog") self.collectionChoiceButton1.setChecked(True) self.collectionChoiceButton1.toggled.connect( lambda: self.changeChoiceState(self.collectionChoiceButton1)) collectionLayout.addWidget(collectionLabel) collectionLayout.addWidget(self.collectionChoiceButton1) collectionButtonGroup.addButton(self.collectionChoiceButton1) collectionLayout.addStretch(1) vbox.addLayout(collectionLayout) # TODO: the information needed for the spelling correction # add a search button searchButtonLayout = QHBoxLayout() self.searchButton = QPushButton('Search') self.searchButton.setToolTip('This is a search button') # self.searchButton.move(20, 400) self.searchButton.clicked.connect(self.click_search) searchButtonLayout.addStretch(1) searchButtonLayout.addWidget(self.searchButton) vbox.addLayout(searchButtonLayout) # add a qeury result listView self.doc_ids = [] # record the doc IDs queryResultLayout = QHBoxLayout() queryResultLabel = QLabel("Query result: \t") self.queryResult = QListView() self.queryResult.setAcceptDrops(False) self.queryResult.setDragDropMode( QtWidgets.QAbstractItemView.NoDragDrop) self.queryResult.setSelectionMode( QtWidgets.QAbstractItemView.ExtendedSelection) self.queryResult.setResizeMode(QListView.Fixed) self.queryResult.clicked.connect(self.selectItem) queryResultLayout.addWidget(queryResultLabel) queryResultLayout.addWidget(self.queryResult) # queryResultLayout.addStretch(1) vbox.addLayout(queryResultLayout) # setup corpus access self.courses = CorpusAccess(COURSE_DICT) # centerize main window self.center() self.show() # move the window to the center of screen def center(self): frameGm = self.frameGeometry() screen = QApplication.desktop().screenNumber( QApplication.desktop().cursor().pos()) centerPoint = QApplication.desktop().screenGeometry(screen).center() frameGm.moveCenter(centerPoint) self.move(frameGm.topLeft()) @pyqtSlot() def click_search(self): # TODO: debugging print("Search button clicked.") query_string = self.searchField.text().strip() # setup QMessageBox if query_string == "": buttonReplay = self.__create_message_box( "The query string cannot be blank") else: idxf2 = Index.load(INDEX) self.doc_ids = query(idxf2, query_string) if len(self.doc_ids) == 0: msg = self.__create_message_box("Could not find anything.") else: model = QStandardItemModel() for doc in self.doc_ids: item = QStandardItem(doc) model.appendRow(item) self.queryResult.setModel(model) self.queryResult.show() def changeChoiceState(self, button: QPushButton): if button.isChecked(): if button.text() == 'Boolean': # TODO: debugging print("Radio button '%s' is clicked." % button.text()) elif button.text() == 'VSM': # TODO: debugging print("Radio button '%s' is clicked." % button.text()) elif button.text() == 'UofO catalog': # print("Radio button '%s' is clicked." % button.text()) html_file = "UofO_Courses.html" if os.path.exists(CURRENT_DIR + "/../%s" % html_file): setup(html_file=CURRENT_DIR + "/../%s" % html_file) else: raise Exception("Could not find '%s'" % html_file) def selectItem(self): selectedId = self.queryResult.selectedIndexes()[0].row() print("id selected: %d" % selectedId) print("course: %s" % self.doc_ids[selectedId]) print("course content: %s" % self.courses.get(self.doc_ids[selectedId])) self.__display_course_details( self.doc_ids[selectedId], self.courses.get(self.doc_ids[selectedId])) def __display_course_details(self, course_id, course_details): dialog = QDialog(parent=self) dialog.setWindowTitle("%s" % course_id) dialog.resize(320, 240) vbox = QVBoxLayout() hbox1 = QHBoxLayout() titelLabel = QLabel("Title: \t") title = QLineEdit() title.setText(course_details.get('title')) title.setReadOnly(True) hbox1.addWidget(titelLabel) hbox1.addWidget(title) hbox2 = QHBoxLayout() contentLabel = QLabel("Content: ") content = QTextEdit() content.setReadOnly(True) content.setText(course_details.get('content')) hbox2.addWidget(contentLabel) hbox2.addWidget(content) vbox.addLayout(hbox1) vbox.addLayout(hbox2) dialog.setLayout(vbox) dialog.exec_() def __create_message_box(self, message): message_box = QMessageBox() message_box.setIcon(QMessageBox.Information) message_box.setText(message) message_box.setWindowTitle("Search result message") message_box.setStandardButtons(QMessageBox.Ok) message_box.exec_()
class VistaMagazzino(QWidget): def __init__(self, parent=None): super(VistaMagazzino, self).__init__(parent) self.controller = ControlloreMagazzino() grid_layout = QGridLayout() v_layout_vaccini = QVBoxLayout() v_layout_tamponi = QVBoxLayout() self.list_view_vaccini = QListView() self.list_view_tamponi = QListView() self.update_ui() label_vaccini = QLabel("Presidi sezione vaccini") font_vaccini = label_vaccini.font() font_vaccini.setFamily('Georgia') font_vaccini.setPointSize(15) font_vaccini.setItalic(True) label_vaccini.setFont(font_vaccini) v_layout_vaccini.addWidget(label_vaccini) v_layout_vaccini.addWidget(self.list_view_vaccini) label_tamponi = QLabel("Presidi sezione tamponi") font_tamponi = label_vaccini.font() font_tamponi.setFamily('Georgia') font_tamponi.setPointSize(15) font_tamponi.setItalic(True) label_tamponi.setFont(font_tamponi) v_layout_tamponi.addWidget(label_tamponi) v_layout_tamponi.addWidget(self.list_view_tamponi) buttons_vaccini = QVBoxLayout() open_vaccino = QPushButton("Visualizza") open_vaccino.clicked.connect(self.show_selected_vaccino) buttons_vaccini.addWidget(open_vaccino) aggiorna_vaccino = QPushButton("Aggiorna") aggiorna_vaccino.clicked.connect(self.aggiorna_selected_materiale) buttons_vaccini.addWidget(aggiorna_vaccino) buttons_tamponi = QVBoxLayout() open_tampone = QPushButton("Visualizza") aggiorna_tampone = QPushButton("Aggiorna") open_tampone.clicked.connect(self.show_selected_tampone) aggiorna_tampone.clicked.connect(self.aggiorna_selected_materiale) buttons_tamponi.addWidget(open_tampone) buttons_tamponi.addWidget(aggiorna_tampone) grid_layout.addLayout(v_layout_vaccini, 0, 0) grid_layout.addLayout(v_layout_tamponi, 0, 1) grid_layout.addLayout(buttons_vaccini, 1, 0) grid_layout.addLayout(buttons_tamponi, 1, 1) self.setLayout(grid_layout) self.resize(600, 300) self.setWindowTitle("Lista Presidi") def update_ui(self): self.listview_vaccini_model = QStandardItemModel( self.list_view_vaccini) for vaccino in self.controller.get_elenco_vaccini(): item = QStandardItem() item.setText(vaccino.tipologia) item.setEditable(False) font = item.font() font.setFamily('Georgia') font.setPointSize(12) item.setFont(font) self.listview_vaccini_model.appendRow(item) self.list_view_vaccini.setModel(self.listview_vaccini_model) self.listview_tamponi_model = QStandardItemModel( self.list_view_tamponi) for tampone in self.controller.get_elenco_tamponi(): item = QStandardItem() item.setText(tampone.tipologia) item.setEditable(False) font = item.font() font.setFamily('Georgia') font.setPointSize(12) item.setFont(font) self.listview_tamponi_model.appendRow(item) self.list_view_tamponi.setModel(self.listview_tamponi_model) def show_selected_vaccino(self): if self.list_view_vaccini.selectedIndexes(): selected = self.list_view_vaccini.selectedIndexes()[0].row() vaccino_selezionato = self.controller.get_presidio_by_index( selected) self.vista_vaccino = VistaVaccino(vaccino_selezionato) self.vista_vaccino.show() def show_selected_tampone(self): if self.list_view_tamponi.selectedIndexes(): selected = self.list_view_tamponi.selectedIndexes()[0].row() tampone_selezionato = self.controller.get_presidio_by_index( selected + 3) self.vista_tampone = VistaTampone(tampone_selezionato) self.vista_tampone.show() def aggiorna_selected_materiale(self): if self.list_view_vaccini.selectedIndexes(): selected = self.list_view_vaccini.selectedIndexes()[0].row() selezionato = self.controller.get_presidio_by_index(selected) elif self.list_view_tamponi.selectedIndexes(): selected = self.list_view_tamponi.selectedIndexes()[0].row() selezionato = self.controller.get_presidio_by_index(selected + 3) self.vista_fornitura = VistaAggiornaFornitura( selezionato, self.controller.aggiorna_quantita_by_tipologia, self.update_ui) self.vista_fornitura.show() def closeEvent(self, event): self.controller.save_data() event.accept()
class VistaElencoDipendenti(QWidget): def __init__(self, callback): super(VistaElencoDipendenti, self).__init__() # Funzione di richiamo della vista precedente self.callback = callback # Controller dell'attrezzatura importante per effettuare le varie funzioni interne self.controller_gestione_dipendenti = ControllerElencoDipendenti() # Layout usati per visualizzare e allineare l'intera vista self.layout_verticale = QVBoxLayout() self.layout_orizzontale = QHBoxLayout() # Lista Dipendenti self.lista_dipendenti = QListView() # Definizione della vista successiva self.vista_aggiungi = VistaAggiungiDipendente(self.showFullScreen, self.controller_gestione_dipendenti, self.aggiorna) # Funzione standard che imposta uno sfondo immagine e un titolo nella attuale vista self.show_background("Elenco Dipendenti") # Spaziatura orizzontale self.layout_orizzontale.addSpacerItem(QSpacerItem(300, 0)) # Creazione e allineamento lista dei dipendenti aggiornata lista_aggiornata = self.aggiorna() self.layout_orizzontale.addWidget(lista_aggiornata) # Configurazione e allineamento dei pulsanti self.layout_orizzontale.addSpacerItem(QSpacerItem(300, 0)) self.show_pulsantiera() self.layout_orizzontale.addSpacerItem(QSpacerItem(200, 0)) # Configurazione finale del layout totale self.layout_verticale.addLayout(self.layout_orizzontale) self.layout_verticale.addSpacerItem(QSpacerItem(0, 200)) self.setLayout(self.layout_verticale) # Impostazione dello sfondo e del titolo def show_background(self, stringa): # Settaggio e ridimensionamento dell'immagine di sfondo dell'attuale vista self.setFixedSize(QDesktopWidget().width(), QDesktopWidget().height()) immagine = QImage("Data/Immagini/ListaAttrezzatura.jpg") immagine_scalata = immagine.scaled(self.width(), self.height()) palette = QPalette() palette.setBrush(10, QBrush(immagine_scalata)) self.setPalette(palette) # Settaggio e allineamento del titolo della vista titolo = QLabel(stringa) titolo.setAlignment(Qt.AlignCenter) titolo.setFont(QFont('Times New Roman', 60)) self.layout_verticale.addSpacerItem(QSpacerItem(0, 50, QSizePolicy.Fixed, QSizePolicy.Fixed)) self.layout_verticale.addWidget(titolo) self.layout_verticale.addSpacerItem(QSpacerItem(0, 100, QSizePolicy.Fixed, QSizePolicy.Fixed)) # Metodo per creazione, stile e funzionamento dei bottoni indietro, apri e aggiungi dipendente def show_pulsantiera(self): # Layout interni utilizzati per l'allineamento dei tre pulsanti layout_pulsanti = QVBoxLayout() # Configurazione del pulsante Apri layout_pulsanti.addWidget(self.pulsante("Apri", self.dipendente_selezionato)) layout_pulsanti.addSpacerItem(QSpacerItem(0, 50)) # Configurazione del pulsante Aggiungi Dipendente layout_pulsanti.addWidget(self.pulsante("Aggiungi\nDipendente", self.call_aggiungi_dipendente)) layout_pulsanti.addSpacerItem(QSpacerItem(0, 50)) # Configurazione del pulsante Indietro layout_pulsanti.addWidget(self.pulsante("Indietro", self.indietro)) # Inserimento dei tre pulsanti del layout globale self.layout_orizzontale.addLayout(layout_pulsanti) # Metodo interno per standardizzare e semplificare la creazione di un pulsante def pulsante(self, titolo, call): pulsante = QPushButton(titolo) pulsante.setFont(QFont('Times New Roman', 20, 100, True)) pulsante.setStyleSheet('QPushButton {background-color: orange; color: black;}') pulsante.setFixedSize(250, 100) pulsante.clicked.connect(call) return pulsante # Metodo utile per la selezione e la relativa visualizzazione delle informazioni dipendente def dipendente_selezionato(self): try: selezionato = self.lista_dipendenti.selectedIndexes()[0].row() lista = self.controller_gestione_dipendenti.get_lista_elenco_dipendenti() dipendente = lista[selezionato] self.vista_informazioni = VistaInformazioniDipendente(dipendente, self.controller_gestione_dipendenti.rimuovi, self.controller_gestione_dipendenti.salva_dati, self.aggiorna) self.vista_informazioni.show() except IndexError: QMessageBox.information(self, 'Attenzione!', 'Non hai selezionato nessun dipendente da visualizzare.', QMessageBox.Ok, QMessageBox.Ok) except: QMessageBox.critical(self, 'Errore!', 'Qualcosa è andato storto, riprova più tardi.', QMessageBox.Ok, QMessageBox.Ok) # Resetta la lista dei dipendenti aggiungendo le eventuali modifiche def aggiorna(self): vista_lista_model = QStandardItemModel(self.lista_dipendenti) for dipendente in self.controller_gestione_dipendenti.get_lista_elenco_dipendenti(): item = QStandardItem() nome = dipendente.get_dipendente_str() item.setText(nome) item.setEditable(False) item.setFont(QFont('Times New Roman', 30, 100)) vista_lista_model.appendRow(item) self.lista_dipendenti.setModel(vista_lista_model) return self.lista_dipendenti # Metodo per la chiamata della vista aggiungi dipendente def call_aggiungi_dipendente(self): self.vista_aggiungi.show() # Metodo che permette di ritornare alla finestra precedente def indietro(self): self.callback() self.close()
class LabelSelectionWidget(QWidget): """ A widget for selection of label values. The widget displays the contents of the model with two widgets: * The top level model items are displayed in a combo box. * The children of the current selected top level item are displayed in a subordinate list view. .. note:: This is not a QAbstractItemView subclass. """ #: Current group/root index has changed. groupChanged = Signal(int) #: Selection for the current group/root has changed. groupSelectionChanged = Signal() def __init__(self, parent=None, **kwargs): super().__init__(parent, **kwargs) self.__model = None self.__selectionMode = QListView.ExtendedSelection self.__currentIndex = -1 self.__selections = {} layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) def group_box(title): box = QGroupBox(title) box.setFlat(True) lay = QVBoxLayout() lay.setContentsMargins(0, 0, 0, 0) box.setLayout(lay) return box self.labels_combo = QComboBox() self.values_view = QListView(selectionMode=self.__selectionMode) self.labels_combo.currentIndexChanged.connect( self.__onCurrentIndexChanged) l_box = group_box(self.tr("Label")) v_box = group_box(self.tr("Values")) l_box.layout().addWidget(self.labels_combo) v_box.layout().addWidget(self.values_view) layout.addWidget(l_box) layout.addWidget(v_box) self.setLayout(layout) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) def clear(self): """ Clear the widget/model (same as ``setModel(None)``). """ if self.__model is not None: self.values_view.selectionModel().clearSelection() self.values_view.selectionModel().selectionChanged.disconnect( self.__onSelectionChanged) self.values_view.setModel(None) self.labels_combo.setModel(QStandardItemModel(self.labels_combo)) self.__currentIndex = -1 self.__selections = {} self.__model = None def setModel(self, model): """ Set the source model for display. The model should be a tree model with depth 2. Parameters ---------- model : QtCore.QAbstractItemModel """ if model is self.__model: return self.clear() if model is None: return self.__model = model self.values_view.setModel(model) self.values_view.setRootIndex(model.index(0, 0)) self.values_view.selectionModel().selectionChanged.connect( self.__onSelectionChanged) # will emit the currentIndexChanged (if the model is not empty) self.labels_combo.setModel(model) def model(self): """ Return the current model. Returns ------- model : QtCore.QAbstractItemModel """ return self.__model def setCurrentGroupIndex(self, index): """ Set the current selected group/root index row. Parameters ---------- index : int Group index. """ self.labels_combo.setCurrentIndex(index) def currentGroupIndex(self): """ Return the current selected group/root index row. Returns ------- row : index Current group row index (-1 if there is no current index) """ return self.labels_combo.currentIndex() def setSelection(self, selection): """ Set the model item selection. Parameters ---------- selection : QtCore.QItemSelection Item selection. """ if self.values_view.selectionModel() is not None: indices = selection.indexes() pind = defaultdict(list) for index in indices: parent = index.parent() if parent.isValid(): if parent == self.__model.index(parent.row(), parent.column()): pind[parent.row()].append(QPersistentModelIndex(index)) else: warnings.warn("Die Die Die") else: # top level index pass self.__selections = pind self.__restoreSelection() def selection(self): """ Return the item selection. Returns ------- selection : QtCore.QItemSelection """ selection = QItemSelection() if self.__model is None: return selection for pind in chain(*self.__selections.values()): ind = self.__model.index(pind.row(), pind.column(), pind.parent()) if ind.isValid(): selection.select(ind, ind) return selection def currentGroupSelection(self): """ Return the item selection for the current group only. """ if self.values_view.selectionModel() is not None: return self.values_view.selectionModel().selection() else: return QItemSelection() def __onCurrentIndexChanged(self, index): self.__storeSelection(self.__currentIndex, self.values_view.selectedIndexes()) self.__currentIndex = index if self.__model is not None: root = self.__model.index(index, 0) self.values_view.setRootIndex(root) self.__restoreSelection() self.groupChanged.emit(index) def __onSelectionChanged(self, old, new): self.__storeSelection(self.__currentIndex, self.values_view.selectedIndexes()) self.groupSelectionChanged.emit() def __storeSelection(self, groupind, indices): # Store current values selection for the current group groupind = self.__currentIndex indices = [ QPersistentModelIndex(ind) for ind in self.values_view.selectedIndexes() ] self.__selections[groupind] = indices def __restoreSelection(self): # Restore previous selection for root (if available) assert self.__model is not None groupind = self.__currentIndex root = self.__model.index(groupind, 0) sel = self.__selections.get(groupind, []) indices = [ self.__model.index(pind.row(), pind.column(), root) for pind in sel if pind.isValid() and pind.parent() == root ] selection = QItemSelection() for ind in indices: selection.select(ind, ind) self.values_view.selectionModel().select( selection, QItemSelectionModel.ClearAndSelect) def sizeHint(self): """Reimplemented from QWidget.sizeHint""" return QSize(100, 200)
class VistaListaAttrezzaturaProprietario(QWidget): def __init__(self, callback): super(VistaListaAttrezzaturaProprietario, self).__init__() # Attributi self.controller_lista_attrezzatura = ControllerListaAttrezzatura() self.callback = callback self.layout_verticale1 = QVBoxLayout() self.layout_orizzontale = QHBoxLayout() self.layout_verticale2 = QVBoxLayout() # Sfondo self.show_background("LISTA ATTREZZATURA") self.layout_verticale1.addSpacerItem(QSpacerItem(0, 200)) self.layout_orizzontale.addSpacerItem(QSpacerItem(100, 0)) # Lista self.vista_lista = QListView() label = self.aggiorna() self.layout_orizzontale.addWidget(label) self.layout_orizzontale.addSpacerItem(QSpacerItem(1000, 0)) # Pulsanti Apri e Indietro allineati self.show_pulsantiera() # Spaziatura self.layout_orizzontale.addSpacerItem(QSpacerItem(150, 0)) self.layout_verticale1.addLayout(self.layout_orizzontale) if self.controller_lista_attrezzatura.get_lista_filtrata() == []: self.layout_verticale1.addSpacerItem(QSpacerItem(0, 350)) else: self.layout_verticale1.addSpacerItem(QSpacerItem(0, 150)) # Impostazione layout totale self.setLayout(self.layout_verticale1) self.setWindowTitle('Lista Attrezzatura') # Metodo che, collegato al pulsante "INDIETRO", permette di tornare alla vista precedente def indietro(self): self.callback() self.controller_lista_attrezzatura.salva_dati() self.close() # Creazione, settaggio e stile dello sfondo def show_background(self, stringa): # Sfondo self.setFixedWidth(QDesktopWidget().width()) self.setFixedHeight(QDesktopWidget().height()) back_img = QImage("Data/Immagini/imagine.jpg") img = back_img.scaled(self.width(), self.height()) palette = QPalette() palette.setBrush(10, QBrush(img)) self.setPalette(palette) # Titolo titolo = QLabel(stringa) titolo.setAlignment(Qt.AlignCenter) titolo.setFont(QFont('Times New Roman', 60)) self.layout_verticale1.addSpacerItem( QSpacerItem(0, 50, QSizePolicy.Fixed, QSizePolicy.Fixed)) self.layout_verticale1.addWidget(titolo) self.layout_verticale1.addSpacerItem( QSpacerItem(0, 100, QSizePolicy.Fixed, QSizePolicy.Fixed)) # Creazione, settaggio e stile dei pulsanti def show_pulsantiera(self): if not self.controller_lista_attrezzatura.get_lista_filtrata() == []: pulsante_apri = self.pulsante("Apri", self.attrezzatura_selezionata) self.layout_verticale2.addWidget(pulsante_apri) # Pulsante aggiungi pulsante_aggiungi = self.pulsante("Aggiungi\nattreazzatura", self.aggiungi) self.layout_verticale2.addWidget(pulsante_aggiungi) # Pulsante indietro pulsante_indietro = self.pulsante("Indietro", self.indietro) self.layout_verticale2.addWidget(pulsante_indietro) self.layout_orizzontale.addLayout(self.layout_verticale2) # Metodo che aggiorna la finestra def aggiorna(self): vista_lista_model = QStandardItemModel(self.vista_lista) if self.controller_lista_attrezzatura.get_lista_attrezzatura() == []: label = QLabel(" Non ci sono oggetti disponibili") label.setAlignment(Qt.AlignCenter) label.setFont(QFont('Times New Roman', 25, 100)) label.setStyleSheet( 'QLabel {background-color: lightBlue; color: black;}') label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum) self.layout_orizzontale.addSpacerItem(QSpacerItem(0, 50)) return label else: for attrezzatura in self.controller_lista_attrezzatura.get_lista_attrezzatura( ): item = QStandardItem() nome = attrezzatura.get_nome() if attrezzatura.get_stato(): item.setForeground(QColor(0, 255, 0)) else: item.setForeground(QColor(255, 0, 0)) item.setText(nome) item.setEditable(False) item.setFont(QFont('Times New Roman', 30, 100)) vista_lista_model.appendRow(item) self.vista_lista.setModel(vista_lista_model) return self.vista_lista # Metodo che gestisce la situazione in cui al click del pulsante "APRI", non venga selezionato niente def attrezzatura_selezionata(self): try: selezionata = self.vista_lista.selectedIndexes()[0].row() lista = self.controller_lista_attrezzatura.get_lista_attrezzatura() attrezzatura = lista[selezionata] self.vista_attrezzatura = VistaAttrezzaturaProprietario( self.showFullScreen, attrezzatura, self.controller_lista_attrezzatura.rimuovi_attrezzatura, self.aggiorna) self.vista_attrezzatura.showFullScreen() except IndexError: print(1) QMessageBox.information( self, 'Attenzione!', 'Non hai selezionato nessuna attrezzatura.', QMessageBox.Ok, QMessageBox.Ok) except: QMessageBox.critical( self, 'Errore!', 'Qualcosa è andato storto, riprova più tardi.', QMessageBox.Ok, QMessageBox.Ok) # Crea un pulsante def pulsante(self, nome, call): pulsante = QPushButton(nome) pulsante.setFont(QFont('Times New Roman', 20, 100, True)) pulsante.setStyleSheet( 'QPushButton {background-color: orange; color: black;}') pulsante.setFixedSize(250, 100) pulsante.clicked.connect(call) return pulsante def aggiungi(self): self.vista_aggiungi_attrezzatura = VistaAggiungiAttrezzatura( self.showFullScreen, self.controller_lista_attrezzatura, self.aggiorna) self.vista_aggiungi_attrezzatura.show()
class MDIHistory(QWidget, _HalWidgetBase): def __init__(self, parent=None): super(MDIHistory, self).__init__(parent) self.setMinimumSize(QSize(200, 150)) self.setWindowTitle("PyQt5 editor test example") lay = QVBoxLayout() lay.setContentsMargins(0, 0, 0, 0) self.setLayout(lay) self.list = QListView() self.list.setEditTriggers(QListView.NoEditTriggers) self.list.activated.connect(self.activated) self.list.setAlternatingRowColors(True) self.list.selectionChanged = self.selectionChanged self.model = QStandardItemModel(self.list) self.MDILine = MDILine() self.MDILine.soft_keyboard = False self.MDILine.line_up = self.line_up self.MDILine.line_down = self.line_down STATUS.connect('mdi-history-changed', self.reload) # add widgets lay.addWidget(self.list) lay.addWidget(self.MDILine) self.fp = os.path.expanduser(INFO.MDI_HISTORY_PATH) try: open(self.fp, 'r') except: open(self.fp, 'a+') LOG.debug('MDI History file created: {}'.format(self.fp)) self.reload() self.select_row('last') def _hal_init(self): STATUS.connect('state-off', lambda w: self.setEnabled(False)) STATUS.connect('state-estop', lambda w: self.setEnabled(False)) STATUS.connect( 'interp-idle', lambda w: self.setEnabled(STATUS.machine_is_on( ) and (STATUS.is_all_homed() or INFO.NO_HOME_REQUIRED))) STATUS.connect('interp-run', lambda w: self.setEnabled(not STATUS.is_auto_mode())) STATUS.connect('all-homed', lambda w: self.setEnabled(STATUS.machine_is_on())) def reload(self, w=None): self.model.clear() try: with open(self.fp, 'r') as inputfile: for line in inputfile: line = line.rstrip('\n') item = QStandardItem(line) self.model.appendRow(item) self.list.setModel(self.model) self.list.scrollToBottom() if self.MDILine.hasFocus(): self.select_row('last') except: LOG.debug('File path is not valid: {}'.format(fp)) def selectionChanged(self, old, new): cmd = self.getSelected() self.MDILine.setText(cmd) selectionModel = self.list.selectionModel() if selectionModel.hasSelection(): self.row = selectionModel.currentIndex().row() def getSelected(self): selected_indexes = self.list.selectedIndexes() selected_rows = [item.row() for item in selected_indexes] # iterates each selected row in descending order for selected_row in sorted(selected_rows, reverse=True): text = self.model.item(selected_row).text() return text def activated(self): cmd = self.getSelected() self.MDILine.setText(cmd) self.MDILine.submit() self.select_row('down') def run_command(self): self.MDILine.submit() self.select_row('last') def select_row(self, style): style = style.lower() selectionModel = self.list.selectionModel() parent = QModelIndex() self.rows = self.model.rowCount(parent) - 1 if style == 'last': self.row = self.rows print 'last =', self.row elif style == 'up': if self.row > 0: self.row -= 1 else: self.row = 0 elif style == 'down': if self.row < self.rows: self.row += 1 else: self.row = self.rows else: return top = self.model.index(self.row, 0, parent) bottom = self.model.index(self.row, 0, parent) selectionModel.setCurrentIndex( top, QItemSelectionModel.Select | QItemSelectionModel.Rows) selection = QItemSelection(top, top) selectionModel.clearSelection() selectionModel.select(selection, QItemSelectionModel.Select) def line_up(self): self.select_row('up') def line_down(self): self.select_row('down') ######################################################################### # This is how designer can interact with our widget properties. # designer will show the pyqtProperty properties in the editor # it will use the get set and reset calls to do those actions ######################################################################### def set_soft_keyboard(self, data): self.MDILine.soft_keyboard = data def get_soft_keyboard(self): return self.MDILine.soft_keyboard def reset_soft_keyboard(self): self.MDILine.soft_keyboard = False # designer will show these properties in this order: soft_keyboard_option = pyqtProperty(bool, get_soft_keyboard, set_soft_keyboard, reset_soft_keyboard)
class VistaListaDipendenti(QWidget): def __init__(self, parent=None): super(VistaListaDipendenti, self).__init__(parent) self.controller = ControlloreListaDipendenti() self.setWindowIcon(QtGui.QIcon('logos/logo.png')) h_layout = QHBoxLayout() self.list_view = QListView() self.update_ui() h_layout.addWidget(self.list_view) #Bottone per aprire un dipendente buttons_layout = QVBoxLayout() open_button = QPushButton("Apri") open_button.clicked.connect(self.show_selected_info) buttons_layout.addWidget(open_button) #Bottone per creare un nuovo dipendente new_button = QPushButton("Nuovo") new_button.clicked.connect(self.show_new_dipendente) buttons_layout.addWidget(new_button) buttons_layout.addStretch() h_layout.addLayout(buttons_layout) self.setLayout(h_layout) self.resize(600, 300) self.setWindowTitle("Lista Dipendenti") #Metodo che mostra a schermo le informazioni del dipendente selezionato def show_selected_info(self): try: sourceindex = self.list_view.selectedIndexes()[0].row() dipendente_selezionato = self.controller.get_dipendente_by_index( sourceindex) self.vista_dipendente = VistaDipendente( dipendente_selezionato, self.controller.elimina_dipendente_by_id, self.update_ui) self.vista_dipendente.show() except IndexError: QMessageBox.critical(self, 'Errore', 'Per favore, seleziona un dipendente', QMessageBox.Ok, QMessageBox.Ok) #Metodo aprire la vista di inserimento del nuovo cliente def show_new_dipendente(self): self.vista_inserisci_dipendente = VistaInserisciDipendente( self.controller, self.update_ui) self.vista_inserisci_dipendente.show() #Metodo che serve per generare e/o aggiornare la vista def update_ui(self): self.listview_model = QStandardItemModel(self.list_view) for dipendente in self.controller.get_lista_dei_dipendenti(): item = QStandardItem() item.setText(dipendente.nome + " " + dipendente.cognome) item.setEditable(False) font = item.font() font.setPointSize(18) item.setFont(font) self.listview_model.appendRow(item) self.list_view.setModel(self.listview_model) #salva i dati sul file pickle alla chiusura della view def closeEvent(self, event): self.controller.save_data()
class MDIHistory(QWidget, _HalWidgetBase): def __init__(self, parent=None): super(MDIHistory, self).__init__(parent) self.setMinimumSize(QSize(300, 200)) self.setWindowTitle("PyQt5 editor test example") lay = QVBoxLayout() lay.setContentsMargins(0, 0, 0, 0) self.setLayout(lay) self.list = QListView() self.list.setEditTriggers(QListView.NoEditTriggers) self.list.activated.connect(self.activated) self.list.setAlternatingRowColors(True) self.list.selectionChanged = self.selectionChanged self.model = QStandardItemModel(self.list) self.MDILine = MDILine() self.MDILine.soft_keyboard = False self.MDILine.line_up = self.line_up self.MDILine.line_down = self.line_down # add widgets lay.addWidget(self.list) lay.addWidget(self.MDILine) self.reload() def _hal_init(self): STATUS.connect('state-off', lambda w: self.setEnabled(False)) STATUS.connect('state-estop', lambda w: self.setEnabled(False)) STATUS.connect( 'interp-idle', lambda w: self.setEnabled(STATUS.machine_is_on( ) and (STATUS.is_all_homed() or INFO.NO_HOME_REQUIRED))) STATUS.connect('interp-run', lambda w: self.setEnabled(not STATUS.is_auto_mode())) STATUS.connect('all-homed', lambda w: self.setEnabled(STATUS.machine_is_on())) def reload(self, w=None): print 'RELOAD' try: fp = os.path.expanduser(INFO.MDI_HISTORY_PATH) with open(fp, 'r') as inputfile: for line in inputfile: line = line.rstrip('\n') item = QStandardItem(line) self.model.appendRow(item) self.list.setModel(self.model) self.list.scrollToBottom() except Exception as e: print e LOG.error('File path is not valid: {}]n,()'.format(fp), e) def line_up(self): print 'up' def line_down(self): print 'down' def selectionChanged(self, old, new): cmd = self.getSelected() self.MDILine.setText(cmd) def getSelected(self): selected_indexes = self.list.selectedIndexes() selected_rows = [item.row() for item in selected_indexes] # iterates each selected row in descending order for selected_row in sorted(selected_rows, reverse=True): text = self.model.item(selected_row).text() return text def activated(self): cmd = self.getSelected() self.MDILine.setText(cmd) self.MDILine.submit() item = QStandardItem(cmd) self.model.appendRow(item) self.list.update() ######################################################################### # This is how designer can interact with our widget properties. # designer will show the pyqtProperty properties in the editor # it will use the get set and reset calls to do those actions ######################################################################### def set_soft_keyboard(self, data): self.MDILine.soft_keyboard = data def get_soft_keyboard(self): return self.MDILine.soft_keyboard def reset_soft_keyboard(self): self.MDILine.soft_keyboard = False # designer will show these properties in this order: soft_keyboard_option = pyqtProperty(bool, get_soft_keyboard, set_soft_keyboard, reset_soft_keyboard)
class ShowListWindow(QMainWindow): def __init__(self, app_context: ApplicationContext, flashcard_manager: FlashcardManager, card_list: CardList, parent=None): super(ShowListWindow, self).__init__(parent) self.app_context = app_context self.flashcard_manager = flashcard_manager self.card_list = card_list self.setFixedSize(600, 400) self.setWindowTitle(self.card_list.name + " - TangoCards") main_widget = QWidget() main_widget.setProperty("cssClass", "background") main_layout = QVBoxLayout() learn_button = QPushButton("Frag mich ab!") learn_button.clicked.connect(self.on_click_learn) main_layout.addWidget(learn_button) self.card_list_model = QStringListModel( self.card_list.get_card_name_list()) self.cards_list_component = QListView() self.cards_list_component.setModel(self.card_list_model) self.cards_list_component.setEditTriggers( QAbstractItemView.NoEditTriggers) main_layout.addWidget(self.cards_list_component) tool_buttons_widget = QWidget() tool_buttons_layout = QHBoxLayout() tool_buttons_widget.setLayout(tool_buttons_layout) add_button = QPushButton("Hinzufügen") add_button.clicked.connect(self.on_click_add) delete_button = QPushButton("Löschen") delete_button.clicked.connect(self.on_click_delete) tool_buttons_layout.addWidget(add_button) tool_buttons_layout.addWidget(delete_button) main_layout.addWidget(tool_buttons_widget) main_widget.setLayout(main_layout) self.setCentralWidget(main_widget) def update_list(self): self.card_list_model = QStringListModel( self.card_list.get_card_name_list()) self.cards_list_component.setModel(self.card_list_model) self.cards_list_component.repaint() def on_click_add(self): word_text, ok1 = QInputDialog.getText(self, 'Karte hinzufügen', 'Wort:') if not ok1: return if word_text is None or len(word_text) < 2: msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText("Der Text ist leer oder zu kurz!") msg.exec_() return if self.card_list.get_card(word_text) is not None: msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText("Wort ist bereits in der Lernkartei!") msg.exec_() return solution_text, ok2 = QInputDialog.getText(self, 'Karte hinzufügen', 'Lösung:') if not ok2: return if solution_text is None or len(word_text) < 2: msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText("Der Text ist leer oder zu kurz!") msg.exec_() return self.card_list.add_card(word_text, solution_text) self.flashcard_manager.save_list(self.card_list) self.update_list() def on_click_learn(self): if len(self.card_list.cards) < 1: msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText("Du musst erst Lernkarten hinzufügen!") msg.exec_() return window = LearnWindow(self.app_context, self.flashcard_manager, self.card_list, parent=self.parent()) self.hide() window.show() def on_click_delete(self): if len(self.cards_list_component.selectedIndexes()) < 1: return word_text = self.cards_list_component.selectedIndexes()[0].data() card = self.card_list.get_card(word_text) if card is not None: self.card_list.remove_card(card) self.flashcard_manager.save_list(self.card_list) self.update_list()
class Player(QWidget): fullScreenChanged = pyqtSignal(bool) def __init__(self, playlist, parent=None, add_button = None): super(Player, self).__init__(parent) self.add_button = add_button self.colorDialog = None self.trackInfo = "" self.statusInfo = "" self.duration = 0 self.player = QMediaPlayer() self.playlist = QMediaPlaylist() self.player.setPlaylist(self.playlist) self.player.durationChanged.connect(self.durationChanged) self.player.positionChanged.connect(self.positionChanged) self.player.metaDataChanged.connect(self.metaDataChanged) self.playlist.currentIndexChanged.connect(self.playlistPositionChanged) self.player.mediaStatusChanged.connect(self.statusChanged) self.player.bufferStatusChanged.connect(self.bufferingProgress) self.player.error.connect(self.displayErrorMessage) self.videoWidget = VideoWidget() self.player.setVideoOutput(self.videoWidget) self.playlistModel = PlaylistModel() self.playlistModel.setPlaylist(self.playlist) self.playlistView = QListView() self.playlistView.setModel(self.playlistModel) self.playlistView.setCurrentIndex( self.playlistModel.index(self.playlist.currentIndex(), 0)) self.playlistView.activated.connect(self.jump) self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, self.player.duration() / 1000) self.labelDuration = QLabel() self.slider.sliderMoved.connect(self.seek) openButton = QPushButton("Open Audio/Video File", clicked=self.open) controls = PlayerControls() controls.setState(self.player.state()) controls.setVolume(self.player.volume()) controls.setMuted(controls.isMuted()) controls.play.connect(self.player.play) controls.pause.connect(self.player.pause) controls.stop.connect(self.player.stop) controls.next.connect(self.playlist.next) controls.previous.connect(self.previousClicked) controls.changeVolume.connect(self.player.setVolume) controls.changeMuting.connect(self.player.setMuted) controls.changeRate.connect(self.player.setPlaybackRate) controls.stop.connect(self.videoWidget.update) self.player.stateChanged.connect(controls.setState) self.player.volumeChanged.connect(controls.setVolume) self.player.mutedChanged.connect(controls.setMuted) displayLayout = QHBoxLayout() displayLayout.addWidget(self.videoWidget, 2) displayLayout.addWidget(self.playlistView) controlLayout = QHBoxLayout() controlLayout.setContentsMargins(0, 0, 0, 0) controlLayout.addWidget(openButton) # button to add decoder if add_button: add_decoder_btn = QPushButton("Decode Keystrokes of Selected Media") add_decoder_btn.clicked.connect(add_button) controlLayout.addWidget(add_decoder_btn) # controlLayout.addStretch(1) controlLayout.addWidget(controls) layout = QVBoxLayout() layout.addLayout(displayLayout) hLayout = QHBoxLayout() hLayout.addWidget(self.slider) hLayout.addWidget(self.labelDuration) layout.addLayout(hLayout) layout.addLayout(controlLayout) self.setLayout(layout) if not self.player.isAvailable(): QMessageBox.warning(self, "Service not available", "The QMediaPlayer object does not have a valid service.\n" "Please check the media service plugins are installed.") controls.setEnabled(False) self.playlistView.setEnabled(False) openButton.setEnabled(False) self.metaDataChanged() self.addToPlaylist(playlist) def get_current_file(self): inds = self.playlistView.selectedIndexes() if len(inds) == 1: index = inds[0] location = self.playlistModel.m_playlist.media(index.row()).canonicalUrl() return location.path() def open(self): fileNames, _ = QFileDialog.getOpenFileNames(self, "Open Files") self.addToPlaylist(fileNames) def addToPlaylist(self, fileNames): for name in fileNames: fileInfo = QFileInfo(name) if fileInfo.exists(): url = QUrl.fromLocalFile(fileInfo.absoluteFilePath()) if fileInfo.suffix().lower() == 'm3u': self.playlist.load(url) else: self.playlist.addMedia(QMediaContent(url)) else: url = QUrl(name) if url.isValid(): self.playlist.addMedia(QMediaContent(url)) def durationChanged(self, duration): duration /= 1000 self.duration = duration self.slider.setMaximum(duration) def positionChanged(self, progress): progress /= 1000 if not self.slider.isSliderDown(): self.slider.setValue(progress) self.updateDurationInfo(progress) def metaDataChanged(self): if self.player.isMetaDataAvailable(): self.setTrackInfo("%s - %s" % ( self.player.metaData(QMediaMetaData.AlbumArtist), self.player.metaData(QMediaMetaData.Title))) def previousClicked(self): # Go to the previous track if we are within the first 5 seconds of # playback. Otherwise, seek to the beginning. if self.player.position() <= 5000: self.playlist.previous() else: self.player.setPosition(0) def jump(self, index): if index.isValid(): self.playlist.setCurrentIndex(index.row()) self.player.play() def playlistPositionChanged(self, position): self.playlistView.setCurrentIndex( self.playlistModel.index(position, 0)) def seek(self, seconds): self.player.setPosition(seconds * 1000) def statusChanged(self, status): self.handleCursor(status) if status == QMediaPlayer.LoadingMedia: self.setStatusInfo("Loading...") elif status == QMediaPlayer.StalledMedia: self.setStatusInfo("Media Stalled") elif status == QMediaPlayer.EndOfMedia: QApplication.alert(self) elif status == QMediaPlayer.InvalidMedia: self.displayErrorMessage() else: self.setStatusInfo("") def handleCursor(self, status): if status in (QMediaPlayer.LoadingMedia, QMediaPlayer.BufferingMedia, QMediaPlayer.StalledMedia): self.setCursor(Qt.BusyCursor) else: self.unsetCursor() def bufferingProgress(self, progress): self.setStatusInfo("Buffering %d%" % progress) def setTrackInfo(self, info): self.trackInfo = info if self.statusInfo != "": self.setWindowTitle("%s | %s" % (self.trackInfo, self.statusInfo)) else: self.setWindowTitle(self.trackInfo) def setStatusInfo(self, info): self.statusInfo = info if self.statusInfo != "": self.setWindowTitle("%s | %s" % (self.trackInfo, self.statusInfo)) else: self.setWindowTitle(self.trackInfo) def displayErrorMessage(self): self.setStatusInfo(self.player.errorString()) def updateDurationInfo(self, currentInfo): duration = self.duration if currentInfo or duration: currentTime = QTime((currentInfo/3600)%60, (currentInfo/60)%60, currentInfo%60, (currentInfo*1000)%1000) totalTime = QTime((duration/3600)%60, (duration/60)%60, duration%60, (duration*1000)%1000); format = 'hh:mm:ss' if duration > 3600 else 'mm:ss' tStr = currentTime.toString(format) + " / " + totalTime.toString(format) else: tStr = "" self.labelDuration.setText(tStr)
class ApplicationWidget(QWidget): """Käyttöliittymästä vastaava luokka, jossa on on vastuussa suurimmasta osasta käyttöliittymää. Se perii PyQt5:n QWidget-luokan ja ui:n pääikkunan. """ def __init__(self, parent): """Luokan konstruktori, alustaa PyQt5:n tab-rakenteen, johon myöhemmin voi lisätä käyttöliittymäkomponentteja. Args: parent: pääikkuna, johon luokka "kiinnittyy" """ super(QWidget, self).__init__(parent) self.layout = QVBoxLayout(self) self.tabs = QTabWidget() self.search_tab = QWidget() self.database_tab = QWidget() self.tabs.addTab(self.search_tab, "Search") self.tabs.addTab(self.database_tab, "Movies") self.setup_search_ui() self.setup_database_ui() self.layout.addWidget(self.tabs) self.setLayout(self.layout) def setup_search_ui(self): """Alustaa käyttöliittymäkomponentit Search-näkymässä, jossa voi hakea elokuvia. """ self.search_button = QPushButton("Search") self.add_movie_button = QPushButton("Add movie") self.add_movie_button.setEnabled(False) self.search_entry = QLineEdit() self.search_entry.setPlaceholderText("Search movie title") self.movies_found_label = QLabel("Movies found: 0") self.movie_added_label = QLabel("") self.search_model = SearchModel() self.search_view = QListView() self.search_view.setModel(self.search_model) self.search_button.clicked.connect(self.search_button_clicked) self.add_movie_button.clicked.connect(self.add_movie_clicked) self.setup_search_layout() def setup_search_layout(self): """Alustaa Search-näkymän asettelun. """ self.search_tab.layout = QVBoxLayout() search_bar_layout = QHBoxLayout() search_bar_layout.addWidget(self.search_entry) search_bar_layout.addWidget(self.search_button) self.search_tab.layout.addLayout(search_bar_layout) self.search_tab.layout.addWidget(self.movies_found_label) self.search_tab.layout.addWidget(self.search_view) self.search_tab.layout.addWidget(self.add_movie_button) self.search_tab.layout.addWidget(self.movie_added_label) self.search_tab.setLayout(self.search_tab.layout) def search_button_clicked(self): """Suoritetaan kun painetaan "Search"-nappia. Ottaa hakutekstin ja kutsuu sen perusteella IMDBSearch-luokan request_search-metodia. Metodi palauttaa listan tuloksista, joilla päivitetään listanäkymä. """ text = self.search_entry.text() text = text.strip() search = IMDBSearch() self.movie_added_label.setText("") self.search_results = search.request_search(text) self.movies_found_label.setText( f"Movies found: {search.result_length}") self.search_model.movie_list = self.search_results self.search_model.layoutChanged.emit() self.add_movie_button.setEnabled(True) def add_movie_clicked(self): """Suoritetaan kun painetaan "Add movie"-nappia. Tarkistaa, että listasta on valittu jokin elokuva ja lisää sen tietokantaan käyttämällä IMDBSearch-luokan request_title-metodia. Päivittää sen jälkeen tietokantanäkymän. """ if len(self.search_view.selectedIndexes()) > 0: index = self.search_view.selectedIndexes()[0].row() api = IMDBSearch() if api.request_title(self.search_results[index].id): self.movie_added_label.setText("Movie added!") database = DatabaseActions() self.table_model.movie_data = database.select_movies() self.table_model.layoutAboutToBeChanged.emit() self.table_model.layoutChanged.emit() def setup_database_ui(self): """Alustaa käyttöliittymäkomponentit tietokantanäkymässä, jossa voi selata lisättyjä elokuvia ja niiden tietoja. """ database = DatabaseActions() self.table_model = TableModel(database.select_movies()) self.table_view = QTableView() self.proxy_model = QtCore.QSortFilterProxyModel() self.proxy_model.setSourceModel(self.table_model) self.table_view.setModel(self.proxy_model) self.table_view.setSortingEnabled(True) self.table_view.verticalHeader().hide() self.table_view.setSelectionBehavior(QAbstractItemView.SelectRows) self.edit_button = QPushButton("Edit") self.remove_button = QPushButton("Remove") self.edit_button.clicked.connect(self.edit_button_clicked) self.remove_button.clicked.connect(self.remove_button_clicked) self.setup_database_layout() def setup_database_layout(self): """Alustaa tietokantanäkymän asettelun. """ self.database_tab.layout = QVBoxLayout() table_button_layout = QHBoxLayout() self.database_tab.layout.addWidget(self.table_view) table_button_layout.addWidget(self.edit_button, alignment=Qt.AlignLeft) table_button_layout.addWidget(self.remove_button, alignment=Qt.AlignRight) self.database_tab.layout.addLayout(table_button_layout) self.database_tab.setLayout(self.database_tab.layout) def edit_button_clicked(self): """Suoritetaan kun "Edit"-nappia painetaan. Tarkistaa onko elokuvaa valittu, ja avaa ikkunan, jossa voi muokata valitun elokuvan tietoja. Luo instanssin EditWindow-luokasta ja näyttää sen. """ if len(self.table_view.selectedIndexes()) > 0: movie_id = self.table_view.selectedIndexes()[0].data() movie_title = self.table_view.selectedIndexes()[1].data() movie_release = self.table_view.selectedIndexes()[2].data() self.w = EditWindow(movie_id, movie_title, movie_release) self.w.update_button.clicked.connect(self.update_button_clicked) self.w.show() def remove_button_clicked(self): """Suoritetaan kun "Remove"-nappia painetaan. Tarkistaa onko elokuvaa valittu ja poistaa valitun elokuvan DatabaseActions-luokan delete_row-metodilla. Päivittää sitten käyttöliittymän. """ if len(self.table_view.selectedIndexes()) > 0: movie_id = self.table_view.selectedIndexes()[0].data() database = DatabaseActions() database.delete_row(movie_id) self.table_model.movie_data = database.select_movies() self.table_model.layoutAboutToBeChanged.emit() self.table_model.layoutChanged.emit() def update_button_clicked(self): """Suoritetaan kun EditWindow-luokan "Update"-nappia painetaan. Pävittää tietokannan tiedot EditWindow:n parametreilla ja päivittää tietokannan. Lopuksi sulkee EditWindow-ikkunan. """ database = DatabaseActions() watch_date_entry = self.w.watch_date_entry.date() date = watch_date_entry.toString("yyyy-MM-dd") database.update_data(self.w.id, self.w.review_entry.currentText(), date) self.table_model.movie_data = database.select_movies() self.table_model.layoutAboutToBeChanged.emit() self.table_model.layoutChanged.emit() self.w.close()
class CtrlUserWidget(QDialog): def __init__(self, parent=None): QDialog.__init__(self, parent=parent) self.model = UsersListModel() self.model.update(db.load_users()) self.setModal(True) self.setWindowTitle('Users') self.initUI() def initUI(self): self.addBtn = QPushButton('Add user') self.addBtn.setIcon(QIcon('res/img/icons/plus_32.png')) self.editBtn = QPushButton('Edit user') self.editBtn.setIcon(QIcon('res/img/icons/edit_32.png')) self.editBtn.setDisabled(True) self.delBtn = QPushButton('Delete user') self.delBtn.setIcon(QIcon('res/img/icons/minus_32.png')) self.userView = QListView() self.userView.setEditTriggers(QAbstractItemView.NoEditTriggers) self.userView.setGeometry(0, 0, 100, 400) self.userView.setModel(self.model) self.buttons = QDialogButtonBox(QDialogButtonBox.Save, Qt.Horizontal, self) self.buttons.accepted.connect(self.accept) self.addBtn.clicked.connect(self.addUser) self.delBtn.clicked.connect(self.deleteUser) self.userView.doubleClicked.connect(self.activate_user) btnLayout = QVBoxLayout() btnLayout.addWidget(self.addBtn) btnLayout.addWidget(self.editBtn) btnLayout.addWidget(self.delBtn) upLayout = QHBoxLayout() upLayout.addWidget(self.userView) upLayout.addLayout(btnLayout) mainLayout = QVBoxLayout(self) mainLayout.addLayout(upLayout) mainLayout.addWidget(self.buttons) def showWidget(self, parent=None): dialog = CtrlUserWidget(parent) ok = dialog.exec_() return ok def addUser(self): dialog = AddUserDialog.getUser() if dialog: self.model.update(db.load_users()) self.model.layoutChanged.emit() self._update_view() return True def _update_view(self): self.userView.setModel(self.model) def deleteUser(self): indexes = self.userView.selectedIndexes() if indexes: # Indexes is a list of a single item in single-select mode. index = indexes[0] # Remove the item and refresh. db_response = db.del_user(self.model.data[index.row()][0]) if db_response: del self.model.data[index.row()] self.model.layoutChanged.emit() # Clear the selection (as it is no longer valid). self.userView.clearSelection() else: QMessageBox.warning( self, 'User is active', 'User is active. Change active User before delete', QMessageBox.Ok) def activate_user(self): indexes = self.userView.selectedIndexes() if indexes: # Indexes is a list of a single item in single-select mode. index = indexes[0] # Remove the item and refresh. db.set_active_user(self.model.data[index.row()][0]) self.model.update(db.load_users()) self.model.layoutChanged.emit() return True
class MainList(QMainWindow): def __init__(self): super(MainList, self).__init__() self.Vlayout = QVBoxLayout() self.mainUI() self.setLayout() self.setWidget() self.setCentralWidget(self.Widget) # self.progBar.setValue(self.model.datalists.count()) def mainUI(self): self.listView() self.buttonAdd = QPushButton("Add") self.buttonAdd.clicked.connect(self.addDataList) self.buttonRemove = QPushButton("Remove") self.buttonRemove.clicked.connect(self.removeDataList) self.buttonUpdate = QPushButton("Update") self.buttonUpdate.clicked.connect(self.updateDataList) self.buttonClear = QPushButton("Clear") self.buttonClear.clicked.connect(self.clearDataList) self.buttonDuplicate = QPushButton("Duplicate") self.buttonDuplicate.clicked.connect(self.duplicateDataList) self.mes = QMessageBox() self.progBar = QProgressBar() self.slider = QSlider(Qt.Horizontal) def listView(self): self.list = QListView() self.model = ListModels() self.model = ListModels(datalist=[]) self.list.setModel(self.model) def addDataList(self): add, ok = QInputDialog.getText(self.Widget, "Tambah Data", "") if len(add): self.model.datalists.append(add) self.model.layoutChanged.emit() self.progBar.setValue(len(self.model.datalists)) def updateDataList(self): selectedIndex = self.list.selectedIndexes() if selectedIndex: data, ok = QInputDialog.getText(self.Widget, "Perbaharui Data", "Masukkan data terbaru") if len(data): selectedIndexes = selectedIndex[0] self.model.datalists[selectedIndexes.row()] = data self.model.layoutChanged.emit() else: self.mes.information(self, "Warning", "Silakan pilih data dulu!") self.progBar.setValue(len(self.model.datalists)) def removeDataList(self): selectedIndex = self.list.selectedIndexes() if selectedIndex: selectedIndexes = selectedIndex[0] del self.model.datalists[selectedIndexes.row()] self.model.layoutChanged.emit() else: self.mes.information(self, "Warning", "Silakan pilih data dulu!") self.progBar.setValue(len(self.model.datalists)) def clearDataList(self): self.model.datalists.clear() self.model.layoutChanged.emit() self.progBar.setValue(len(self.model.datalists)) def duplicateDataList(self): selectedIndex = self.list.selectedIndexes() valueSlider = self.slider.value() if selectedIndex: selectedIndexes = selectedIndex[0] for x in range(valueSlider): self.model.datalists.append( self.model.datalists[selectedIndexes.row()]) self.model.layoutChanged.emit() else: self.mes.information(self, "Warning", "Silakan pilih data dulu!") self.progBar.setValue(len(self.model.datalists)) def set_width(self): widget = QWidget() layoutHorizontal = QHBoxLayout() layoutHorizontal.addWidget(self.list) layoutHorizontal.addWidget(self.setBtnLayout()) widget.setLayout(layoutHorizontal) return widget def setLayout(self): self.Vlayout.addWidget(self.set_width()) self.Vlayout.addWidget(self.progBar) self.Vlayout.addWidget(self.slider) def setBtnLayout(self): btnWidget = QWidget() Vlayout = QVBoxLayout() Vlayout.addWidget(self.buttonAdd) Vlayout.addWidget(self.buttonUpdate) Vlayout.addWidget(self.buttonRemove) Vlayout.addWidget(self.buttonDuplicate) btnWidget.setLayout(Vlayout) return btnWidget def setWidget(self): self.Widget = QWidget() self.Widget.setLayout(self.Vlayout)
class App(QWidget): def __init__(self): super().__init__() self.left = 100 self.top = 100 self.width = 1200 self.height = 720 self.setWindowTitle('Mammogram Prediction') self.setGeometry(self.left, self.top, self.width, self.height) self.initUI() def initUI(self): # Widget for showing picture. The QLabel gets a Pixmap added to it to show picture self.picture_name_label = QLabel(currently_selected_picture) self.picture_label = QLabel() self.prediction_text = QTextEdit() self.prediction_text.setReadOnly(True) self.model_label = QLabel() self.init_picture_and_predictions() self.resized_picture = self.picture.scaled(299, 299, Qt.KeepAspectRatio, Qt.FastTransformation) self.picture_label.setPixmap(self.resized_picture) self.picture_label.setMinimumWidth(299) self.picture_label.setMinimumHeight(299) self.picture_label.setContentsMargins(0, 19, 0, 0) # Tree and List view for file directory overview of pictures self.picture_directory_label = QLabel('Select a Picture:') picture_dir_path = 'pictures\\' picture_file_path = 'pictures\\' self.treeview_picture = QTreeView() self.listview_picture = QListView() self.dirModel_picture = QFileSystemModel() self.dirModel_picture.setRootPath(picture_dir_path) self.dirModel_picture.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs) self.fileModel_picture = QFileSystemModel() self.fileModel_picture.setRootPath(picture_file_path) # self.fileModel_picture.setFilter(QDir.NoDotAndDotDot | QDir.Files) self.treeview_picture.setModel(self.dirModel_picture) self.listview_picture.setModel(self.fileModel_picture) self.treeview_picture.setRootIndex( self.dirModel_picture.index(picture_dir_path)) self.listview_picture.setRootIndex( self.fileModel_picture.index(picture_file_path)) # self.treeview_picture.setCurrentIndex( self.dirModel_picture.index(0, 0)) self.treeview_picture.clicked.connect( self.on_picture_treeview_clicked) self.listview_picture.clicked.connect( self.on_picture_listview_clicked) self.treeview_picture.setColumnHidden(1, True) self.treeview_picture.setColumnWidth(0, 275) self.treeview_picture.setMinimumWidth(500) self.listview_picture.setMinimumWidth(500) # List view for file directory overview of five label models self.model_directory_label = QLabel('Select a Five Label Model:') model_path = 'trained_five_Models\\' self.listview_model = QListView() self.dirModel_model = QFileSystemModel() self.dirModel_model.setRootPath(model_path) self.dirModel_model.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs) self.listview_model.setModel(self.dirModel_model) self.listview_model.setRootIndex( self.dirModel_model.index(model_path)) self.listview_model.clicked.connect(self.on_model_listview_clicked) # List view for file directory overview of binary models self.model_binary_directory_label = QLabel( 'Select a Binary Model:') model_binary_path = 'trained_binary_Models\\' self.listview_model_binary = QListView() self.dirModel_model_binary = QFileSystemModel() self.dirModel_model_binary.setRootPath(model_binary_path) self.dirModel_model_binary.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs) self.listview_model_binary.setModel(self.dirModel_model_binary) self.listview_model_binary.setRootIndex( self.dirModel_model_binary.index(model_binary_path)) self.listview_model_binary.setSelectionMode( QAbstractItemView.MultiSelection) self.listview_model_binary.clicked.connect( self.on_model_binary_listview_clicked) # Layout handling. # self.gridlayout = QGridLayout() # self.gridlayout.addWidget(self.model_directory_label, 0, 0) # self.gridlayout.setColumnStretch(-15, -11) # self.gridlayout.addWidget(self.listview_model, 1, 0) # self.gridlayout.addWidget(self.picture_directory_label, 2, 0) # self.gridlayout.addWidget(self.treeview_picture, 3, 0) # # self.gridlayout.addWidget(self.model_binary_directory_label, 0, 1) # self.gridlayout.addWidget(self.listview_model_binary, 1, 1) # self.gridlayout.addWidget(self.listview_picture, 3, 1) # # self.gridlayout.addWidget(self.picture_label, 0, 2) # self.gridlayout.addWidget(self.picture_name_label, 1, 2) # self.gridlayout.addWidget(self.prediction_text, 3, 2) self.vbox = QVBoxLayout() self.vbox_left = QVBoxLayout() self.vbox_right = QVBoxLayout() self.hbox_outer = QHBoxLayout() self.hbox_top = QHBoxLayout() self.hbox_buttom = QHBoxLayout() self.vbox_five_label = QVBoxLayout() self.vbox_binary = QVBoxLayout() self.vbox.addLayout(self.hbox_outer) self.hbox_outer.addLayout(self.vbox_left) self.hbox_outer.addLayout(self.vbox_right) self.vbox_left.addLayout(self.hbox_top) self.hbox_top.addLayout(self.vbox_five_label) self.hbox_top.addLayout(self.vbox_binary) self.vbox_five_label.addWidget(self.model_directory_label) self.vbox_five_label.addWidget(self.listview_model) self.vbox_binary.addWidget(self.model_binary_directory_label) self.vbox_binary.addWidget(self.listview_model_binary) self.vbox_left.addWidget(self.picture_directory_label) self.vbox_left.addLayout(self.hbox_buttom) self.hbox_buttom.addWidget(self.treeview_picture) self.hbox_buttom.addWidget(self.listview_picture) self.vbox_right.addWidget(self.picture_label, alignment=Qt.AlignHCenter) self.vbox_right.addWidget(self.picture_name_label, alignment=Qt.AlignHCenter) self.vbox_right.addWidget(self.model_label, alignment=Qt.AlignHCenter) self.vbox_right.addWidget(self.prediction_text) self.vbox_right.setAlignment(Qt.AlignCenter) self.setLayout(self.vbox) self.sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred) self.setSizePolicy(self.sizePolicy) self.show() def init_picture_and_predictions(self): if currently_selected_picture == 'Currently No Image Selected': self.picture = QtGui.QPixmap('GUI/no_image_selected.png') self.prediction_text.setText('') def on_picture_treeview_clicked(self, index): pathof_selected_dir = self.dirModel_picture.fileInfo( index).absoluteFilePath() self.listview_picture.setRootIndex( self.fileModel_picture.setRootPath(pathof_selected_dir)) def on_picture_listview_clicked(self, index): global currently_selected_model global currently_selected_model_name global currently_selected_picture currently_selected_picture = self.fileModel_picture.fileInfo( index).absoluteFilePath() try: Image.open(currently_selected_picture) self.picture_name_label.setText(currently_selected_picture) self.picture_label.setPixmap( QtGui.QPixmap(currently_selected_picture)) except IOError: print('Exception: Chosen file is not a picture') # Checks if the selected picture has size 299 image_in = cv2.imread(currently_selected_picture) size = image_in.shape[:2] if size[0] == 299: if currently_selected_model is not None: for model in currently_selected_model: new_prediction = self.makePrediction( model, self.convertPictureToNumpy( currently_selected_picture)) split = currently_selected_model_name.split('_') if split[4] in ('neg', 'bc', 'bm', 'mc', 'mm'): self.show_binary_prediction( new_prediction, split[4]) else: self.show_five_prediction(new_prediction) else: self.prediction_text.setText( 'No Model is Chosen for Prediction. Choose one to the left.' ) # If the selected picture is not size 299 it will be padded and cropped else: cropped_images = resize_image_padding( currently_selected_picture) self.listview_picture.setRootIndex( self.fileModel_picture.setRootPath('pictures/cropped/%s' % cropped_images)) def on_model_listview_clicked(self, index): global currently_selected_model global currently_selected_picture currently_selected_model = [] selected_model_path = self.dirModel_model.fileInfo( index).absoluteFilePath() currently_selected_model.append(self.getModel(selected_model_path)) self.model_label.setText(currently_selected_model_name[0]) if currently_selected_picture != 'Currently No Image Selected': for model in currently_selected_model: new_prediction = self.makePrediction( model, self.convertPictureToNumpy(currently_selected_picture)) self.show_five_prediction(new_prediction) def on_model_binary_listview_clicked(self): global currently_selected_model global currently_selected_picture currently_selected_model = [] self.prediction_text.setText('') self.model_label.setText('') for x in self.listview_model_binary.selectedIndexes(): selected_model_path = self.dirModel_model_binary.fileInfo( x).absoluteFilePath() currently_selected_model.append( self.getModel(selected_model_path)) # if not currently_selected_model_name: # self.model_label.setText(currently_selected_model_name) if currently_selected_picture != 'Currently No Image Selected': for y in currently_selected_model: new_prediction = self.makePrediction( y, self.convertPictureToNumpy(currently_selected_picture)) self.show_binary_prediction(new_prediction, y.category) def getModel(self, model_path): global currently_selected_model_name currently_selected_model_name = [] split = os.path.split(model_path)[1].split('_') model_version = split[0] + '_' + split[1] + '_' + split[ 2] + '_' + split[3] currently_selected_model_name.append(os.path.split(model_path)[1]) model = getattr(sys.modules[__name__], model_version)() checkpoint_path = model_path + '/cp.ckpt' model.load_weights(checkpoint_path) return model def makePrediction(self, input_model, input_picture): image = tf.reshape(input_picture, [-1, 299, 299, 1]) image = tf.cast(image, tf.float32) image = image / 255.0 return input_model.predict(image) def convertPictureToNumpy(self, filename): img = Image.open(filename) np_array = np.array(img, dtype='uint8') return np_array def show_five_prediction(self, prediction): self.prediction_text.setText( "Probability of Negative: %s" % prediction[0, 0] + "\n\nProbability of Benign Calcification: %s" % prediction[0, 1] + "\n\nProbability of Benign Mass: %s" % prediction[0, 2] + "\n\nProbability of Malignant Calcification: %s" % prediction[0, 3] + "\n\nProbability of Malignant Mass: %s" % prediction[0, 4]) def show_binary_prediction(self, prediction, category): if category == 'neg': self.prediction_text.append( "Probability of Negative: %s %s \n" % (prediction[0, 0], prediction[0, 1])) elif category == 'bc': self.prediction_text.append( "Probability of Benign Calcification: %s %s \n" % (prediction[0, 0], prediction[0, 1])) elif category == 'bm': self.prediction_text.append( "Probability of Benign Mass: %s %s \n" % (prediction[0, 0], prediction[0, 1])) elif category == 'mc': self.prediction_text.append( "Probability of Malignant Calcification: %s %s \n" % (prediction[0, 0], prediction[0, 1])) elif category == 'mm': self.prediction_text.append( "Probability of Malignant Mass: %s %s \n" % (prediction[0, 0], prediction[0, 1])) else: self.prediction_text.append( "Probability of ????: %s %s \n" % (prediction[0, 0], prediction[0, 1])) def openFileDialog(self): fileName, _ = QFileDialog.getOpenFileName( self, "QFileDialog.getOpenFileName()", "", "All Files (*);;Python Files (*.py)") if fileName: return fileName def is_png(data): return data[:8] == '\x89PNG\x0d\x0a\x1a\x0a'
class MyMainWindow(QMainWindow): def __init__(self): super().__init__() self.centralwidget = QWidget(self) self.layoutVerti = QVBoxLayout(self.centralwidget) self.layoutHoriz = QHBoxLayout(self.centralwidget) self.listView = QListView(self.centralwidget) self.buttonNew = QPushButton("新建单位", self.centralwidget) self.buttonTake = QPushButton("移出单位", self.centralwidget) self.layoutHoriz.addWidget(self.buttonNew) self.layoutHoriz.addWidget(self.buttonTake) self.layoutVerti.addWidget(self.listView) self.layoutVerti.addLayout(self.layoutHoriz) self.setCentralWidget(self.centralwidget) self.listView = self.listView # 连接信号 & 槽 self.buttonNew.clicked.connect(self.add_unit) self.buttonTake.clicked.connect(self.del_unit) # 创建新数据 unit_a = Unit(PlayerId(0), 0, 0, 0, 0, 0, 0, 0, 0, 0) units = [] for x in range(5, 10): new_unit = Unit(PlayerId(0), x, 0, 0, x, x, 0, 0, 0, 0) units.append(new_unit) # 添加新数据到 model 里 self.list_model = UnitsListModel() self.list_model.addItem(unit_a) self.list_model.addItems(units) # 绑定 model → listView self.listView.setModel(self.list_model) player_, x_, y_, z_, reference_id_, status_, rotation_, unit_const_, initial_animation_frame_, garrisoned_in_id_\ = PlayerId(0), 5.0, 5.0, 5.0, 8, 2, 3.1415926 / 4, 2, 5, -1 def create_new_unit(self): # self.player_ = PlayerId(0) self.x_ += 1.0 self.y_ += 1.0 self.z_ += 1.0 self.reference_id_ += 1 self.unit_const_ += 1 # self.status_ = 2 # self.rotation_ = 3.1415926 / 4 self.initial_animation_frame_ += 1 # self.garrisoned_in_id_ = -1 new_unit = Unit(self.player_, self.x_, self.y_, self.z_, self.reference_id_, self.unit_const_, self.status_, self.rotation_, self.initial_animation_frame_, self.garrisoned_in_id_) return new_unit def add_unit(self): self.list_model.addItem(self.create_new_unit()) def del_unit(self): self.list_model.deleteItem( self.listView.selectedIndexes()[0].row()) # TODO: 获取当前选择的索引
class MusicPlayer(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.options = self.parent().options self.ffmpeg = self.options['paths']['ffmpeg_bin'] self.thumbnails = self.options['paths']['thumbnails'] self.thumb_width = self.options['thumbnail']['width'] self.thumb_height = self.options['thumbnail']['height'] self.jumping = False self.blocked = False self.durations = {} self.playback_value = 0 self.text = ["None", "Repeat", "Random"] self.playlist_list = [] self.values = [ QMediaPlaylist.Loop, QMediaPlaylist.CurrentItemInLoop, QMediaPlaylist.Random ] # Thumbnail widget self.image_label = QLabel() # Control widgets self.playButton = QToolButton(clicked=self.play) self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.stopButton = QToolButton(clicked=self.stop) self.stopButton.setIcon(self.style().standardIcon(QStyle.SP_MediaStop)) self.stopButton.setEnabled(False) self.playbackButton = QToolButton(clicked=self.playback_mode) self.playbackButton.setText(self.text[0]) self.nextButton = QToolButton(clicked=self.next_song) self.nextButton.setIcon(self.style().standardIcon( QStyle.SP_MediaSkipForward)) self.previousButton = QToolButton(clicked=self.previous_song) self.previousButton.setIcon(self.style().standardIcon( QStyle.SP_MediaSkipBackward)) self.muteButton = QToolButton(clicked=self.mute_clicked) self.muteButton.setIcon(self.style().standardIcon( QStyle.SP_MediaVolume)) self.volumeSlider = QSlider(Qt.Horizontal, sliderMoved=self.change_volume) self.volumeSlider.setRange(0, 100) self.volumeSlider.setPageStep(1) self.volumeSlider.setValue(50) # Player and playlist setup self.player = QMediaPlayer() self.player.setVolume(50) self.player.stateChanged.connect(self.waveform) self.playlist = QMediaPlaylist() self.playlist.setPlaybackMode(self.values[0]) self.playlist.setCurrentIndex(1) self.player.setPlaylist(self.playlist) self.playlistModel = PlaylistModel() self.playlistModel.setPlaylist(self.playlist) self.playlistView = QListView() self.playlistView.setModel(self.playlistModel) self.playlistView.setCurrentIndex( self.playlistModel.index(self.playlist.currentIndex(), 0)) self.playlistView.activated.connect(self.jump) self.playlistView.setContextMenuPolicy(Qt.CustomContextMenu) self.playlistView.customContextMenuRequested.connect( self.list_view_menu) self.playlist.currentIndexChanged.connect( lambda position: self.change_thumbnail(position)) song_search = QLineEdit() song_search.textChanged.connect(self.search) song_search.setClearButtonEnabled(True) # Playlist self.playlist_name = QComboBox() self.playlist_name.currentTextChanged.connect(self.switch_playlist) self.refresh_lists() self.up_button = QToolButton(clicked=self.move_up) self.up_button.setIcon(self.style().standardIcon(QStyle.SP_ArrowUp)) self.down_button = QToolButton(clicked=self.move_down) self.down_button.setIcon(self.style().standardIcon( QStyle.SP_ArrowDown)) # Sound wave widget self.wave_graphic = WaveGraphic(self) #self.wave_graphic.hide() # Testing slider again self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, self.player.duration() / 1000) self.slider.sliderMoved.connect(self.seek) self.player.durationChanged.connect(self.durationChanged) self.player.positionChanged.connect(self.positionChanged) # Shortcuts QShortcut(QKeySequence(Qt.CTRL + Qt.Key_F), self, song_search.setFocus) # Layouts setup playlist_layout = QHBoxLayout() playlist_layout.addWidget(self.playlist_name) playlist_layout.addWidget(self.up_button) playlist_layout.addWidget(self.down_button) control_layout = QHBoxLayout() control_layout.setContentsMargins(0, 0, 0, 0) control_layout.addWidget(self.stopButton) control_layout.addWidget(self.previousButton) control_layout.addWidget(self.playButton) control_layout.addWidget(self.nextButton) control_layout.addWidget(self.muteButton) control_layout.addWidget(self.volumeSlider) control_layout.addWidget(self.playbackButton) display_layout = QVBoxLayout() display_layout.addWidget(song_search) display_layout.addWidget(self.playlistView) display_layout.addLayout(playlist_layout) music_layout = QVBoxLayout() music_layout.addWidget(self.image_label) music_layout.addWidget(self.slider) music_layout.addLayout(control_layout) main_layout = QHBoxLayout() main_layout.addLayout(music_layout) main_layout.addLayout(display_layout) main_2_layout = QVBoxLayout() main_2_layout.addLayout(main_layout) main_2_layout.addWidget(self.wave_graphic) self.setLayout(main_2_layout) def waveform(self, status): if status == QMediaPlayer.PlayingState: self.wave_graphic.start() elif status == QMediaPlayer.PausedState: self.wave_graphic.pause() else: self.wave_graphic.stop() def list_view_menu(self, point): menu = QMenu("Menu", self) recommend_action = QAction('&Recommend Songs', self) menu.addAction(recommend_action) # TODO: [FEATURE] add rename song recommend_action.triggered.connect( lambda: self.parent().call_download_manager(self.get_links())) rename_action = QAction('&Rename', self) menu.addAction(rename_action) # TODO: [FEATURE] add rename song rename_action.triggered.connect(lambda: print("rename")) # Show the context menu. menu.exec_(self.playlistView.mapToGlobal(point)) def get_links(self): title = self.playlistView.selectedIndexes()[0].data() link = getYoutubeURLFromSearch(title) if len(link) > 1: return youtube_recommendations(link) def move_up(self): index = self.playlistView.currentIndex().row() if index - 1 >= 0: item, above = self.playlist.media(index), self.playlist.media( index - 1) self.playlist.removeMedia(index) self.playlist.removeMedia(index - 1) self.playlist.insertMedia(index - 1, item) self.playlist.insertMedia(index, above) self.blocked = True self.playlistView.setCurrentIndex( self.playlistModel.index(index - 1, 0)) self.blocked = False self.stop() def move_down(self): index = self.playlistView.currentIndex().row() if index + 1 <= self.playlistModel.rowCount(): item, below = self.playlist.media(index), self.playlist.media( index + 1) self.playlist.removeMedia(index + 1) self.playlist.removeMedia(index) self.playlist.insertMedia(index, below) self.playlist.insertMedia(index + 1, item) self.blocked = True self.playlistView.setCurrentIndex( self.playlistModel.index(index + 1, 0)) self.blocked = False self.stop() def search(self, part_of_song): for index in range(self.playlistModel.rowCount()): item = self.playlistModel.data(self.playlistModel.index( index, 0)).lower() self.playlistView.setRowHidden(index, part_of_song.lower() not in item) def change_thumbnail(self, position=0): self.playlistView.setCurrentIndex(self.playlistModel.index( position, 0)) song = self.playlistView.selectedIndexes()[0].data() if self.wave_graphic.is_song_cached(song): self.wave_graphic.load_waves(song) else: wc_ = WaveConverter(song, self.wave_graphic.set_wav) wc_.convert() if self.playlistView.currentIndex().data() is None or self.blocked: return max_ratio = 0 img = None for item in listdir(self.thumbnails): if item.endswith('.jpg'): ratio = similar( item, self.playlistView.currentIndex().data().replace( '.mp3', '.jpg')) if ratio > max_ratio: max_ratio = ratio img = item if img: p = QPixmap(self.thumbnails + img) self.image_label.setPixmap( p.scaled(self.thumb_width, self.thumb_height, Qt.KeepAspectRatio)) def switch_playlist(self, current_text): self.playlist.clear() if current_text == "No Playlist": self.refresh() else: if read_playlist(current_text): songs = read_playlist(current_text).split('\n') for song in songs: self.playlist.addMedia( QMediaContent(QUrl.fromLocalFile(song))) def refresh(self): # Change it so it will go to same song. if self.playlist_name.currentText() != "No Playlist": return paths = fetch_options()['paths']['music_path'].split(';') current_songs = [ self.playlistModel.data(self.playlistModel.index(row, 0)) for row in range(self.playlistModel.rowCount()) ] for path in paths: if not path: continue for item in listdir(path): if isfile(join(path, item)) and item.endswith(".mp3") and ( item not in current_songs): self.playlist.addMedia( QMediaContent(QUrl.fromLocalFile(join(path, item)))) def refresh_lists(self): path = fetch_options()['paths']['playlist'] self.playlist_name.clear() self.playlist_list = ["No Playlist"] self.playlist_name.addItem("No Playlist") for item in listdir(path): if isfile(join(path, item)) and item.endswith(".lst"): self.playlist_list.append(item.split('.')[0]) self.playlist_name.addItem(item.split('.')[0]) def playback_mode(self): # Normal -> Loop -> Random def up_value(value, max_value=3): if value + 1 == max_value: return 0 return value + 1 self.playback_value = up_value(self.playback_value) self.playlist.setPlaybackMode(self.values[self.playback_value]) self.playbackButton.setText(self.text[self.playback_value]) def jump(self, index): if index.isValid() and not self.blocked: self.playlist.setCurrentIndex(index.row()) self.jumping = True self.play() def play(self): if self.blocked: return if self.player.state() != QMediaPlayer.PlayingState or self.jumping: self.player.play() self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPause)) self.jumping = False else: self.player.pause() self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) self.stopButton.setEnabled(True) def change_volume(self, value): self.player.setVolume(value) def stop(self): if self.player.state() != QMediaPlayer.StoppedState: self.player.stop() self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.stopButton.setEnabled(False) def next_song(self): self.playlist.next() self.playlistView.setCurrentIndex( self.playlistModel.index(self.playlist.currentIndex(), 0)) def previous_song(self): self.playlist.previous() self.playlistView.setCurrentIndex( self.playlistModel.index(self.playlist.currentIndex(), 0)) def mute_clicked(self): self.player.setMuted(not self.player.isMuted()) self.muteButton.setIcon(self.style().standardIcon( QStyle.SP_MediaVolume if not self.player.isMuted() else QStyle. SP_MediaVolumeMuted)) def durationChanged(self, duration): duration /= 1000 self.slider.setMaximum(duration) def positionChanged(self, progress): progress /= 1000 if not self.slider.isSliderDown(): self.slider.setValue(progress) def seek(self, seconds): self.player.setPosition(seconds * 1000)
class _StyleList(QWidget): def __init__( self, api: Api, model: AssStylesModel, selection_model: QItemSelectionModel, parent: QWidget, ) -> None: super().__init__(parent) self._api = api self._model = model selection_model.selectionChanged.connect(self._on_selection_change) self._styles_list_view = QListView(self) self._styles_list_view.setModel(model) self._styles_list_view.setSelectionModel(selection_model) self._add_button = QPushButton("Add", self) self._add_button.clicked.connect(self._on_add_button_click) self._remove_button = QPushButton("Remove", self) self._remove_button.setEnabled(False) self._remove_button.clicked.connect(self._on_remove_button_click) self._duplicate_button = QPushButton("Duplicate", self) self._duplicate_button.setEnabled(False) self._duplicate_button.clicked.connect(self._on_duplicate_button_click) self._move_up_button = QPushButton("Move up", self) self._move_up_button.setEnabled(False) self._move_up_button.clicked.connect(self._on_move_up_button_click) self._move_down_button = QPushButton("Move down", self) self._move_down_button.setEnabled(False) self._move_down_button.clicked.connect(self._on_move_down_button_click) self._rename_button = QPushButton("Rename", self) self._rename_button.setEnabled(False) self._rename_button.clicked.connect(self._on_rename_button_click) strip = QWidget(self) strip_layout = QGridLayout(strip) strip_layout.setContentsMargins(0, 0, 0, 0) strip_layout.addWidget(self._add_button, 0, 0) strip_layout.addWidget(self._remove_button, 0, 1) strip_layout.addWidget(self._duplicate_button, 0, 2) strip_layout.addWidget(self._move_up_button, 1, 0) strip_layout.addWidget(self._move_down_button, 1, 1) strip_layout.addWidget(self._rename_button, 1, 2) layout = QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self._styles_list_view) layout.addWidget(strip) @property def _selected_style(self) -> Optional[AssStyle]: selected_row = self._selected_row if selected_row is None: return None return self._api.subs.styles[selected_row] @property def _selected_row(self) -> Optional[int]: indexes = self._styles_list_view.selectedIndexes() if not indexes: return None return cast(int, indexes[0].row()) def _on_selection_change( self, selected: QItemSelection, _deselected: QItemSelection, ) -> None: anything_selected = len(selected.indexes()) > 0 self._remove_button.setEnabled(anything_selected) self._rename_button.setEnabled(anything_selected) self._duplicate_button.setEnabled(anything_selected) self._move_up_button.setEnabled(anything_selected and selected.indexes()[0].row() > 0) self._move_down_button.setEnabled( anything_selected and selected.indexes()[0].row() < len(self._api.subs.styles) - 1) @async_slot() async def _on_add_button_click(self) -> None: style_name = await self._prompt_for_unique_style_name() if not style_name: return style = AssStyle(name=style_name) self._api.subs.styles.append(style) idx = style.index self._styles_list_view.selectionModel().select( self._model.index(idx, 0), QItemSelectionModel.SelectionFlag( QItemSelectionModel.SelectionFlag.Clear | QItemSelectionModel.SelectionFlag.Select), ) async def _prompt_for_unique_style_name(self, style_name: str = "" ) -> Optional[str]: prompt_text = "Name of the new style:" while True: dialog = QInputDialog(self) dialog.setLabelText(prompt_text) dialog.setTextValue(style_name) dialog.setInputMode(QInputDialog.TextInput) if not await async_dialog_exec(dialog): return None style_name = dialog.textValue() exists = False for style in self._api.subs.styles: if style.name == style_name: exists = True if not exists: return style_name prompt_text = '"{}" already exists. Choose different name:'.format( style_name) @async_slot() async def _on_remove_button_click(self) -> None: style = self._selected_style assert style is not None idx = style.index if not await show_prompt( f'Are you sure you want to remove style "{style.name}"?', self): return self._styles_list_view.selectionModel().clear() with self._api.undo.capture(): del self._api.subs.styles[idx] def _on_duplicate_button_click(self, event: QMouseEvent) -> None: style = self._selected_style assert style is not None idx = style.index style_copy = copy(style) style_copy.name += " (copy)" with self._api.undo.capture(): self._api.subs.styles.insert(idx + 1, style_copy) self._styles_list_view.selectionModel().select( self._model.index(idx + 1, 0), QItemSelectionModel.SelectionFlag( QItemSelectionModel.SelectionFlag.Clear | QItemSelectionModel.SelectionFlag.Select), ) def _on_move_up_button_click(self, event: QMouseEvent) -> None: style = self._selected_style assert style is not None idx = style.index with self._api.undo.capture(): self._api.subs.styles[idx:idx + 1] = [] self._api.subs.styles[idx - 1:idx - 1] = [style] self._styles_list_view.selectionModel().select( self._model.index(idx - 1, 0), QItemSelectionModel.SelectionFlag( QItemSelectionModel.SelectionFlag.Clear | QItemSelectionModel.SelectionFlag.Select), ) def _on_move_down_button_click(self, event: QMouseEvent) -> None: style = self._selected_style assert style is not None idx = style.index with self._api.undo.capture(): self._api.subs.styles[idx:idx + 1] = [] self._api.subs.styles[idx + 1:idx + 1] = [style] self._styles_list_view.selectionModel().select( self._model.index(idx + 1, 0), QItemSelectionModel.SelectionFlag( QItemSelectionModel.SelectionFlag.Clear | QItemSelectionModel.SelectionFlag.Select), ) @async_slot() async def _on_rename_button_click(self) -> None: style = self._selected_style assert style is not None idx = style.index old_name = style.name new_name = await self._prompt_for_unique_style_name(old_name) if not new_name: return with self._api.undo.capture(): style.name = new_name for line in self._api.subs.events: if line.style_name == old_name: line.style_name = new_name self._styles_list_view.selectionModel().select( self._model.index(idx, 0), QItemSelectionModel.SelectionFlag.Select)
class SelectColumnDialog(QDialog): """ Dialog for selecting a single column from the current dataframe """ def __init__(self, columns=None, selected=None, parent=None): super(SelectColumnDialog, self).__init__(parent) self.setWindowTitle("Select Column") self.columns = columns self.selected = selected # Name of selected variable, or None. # Available self.varlist_model = QStandardItemModel(self) # Proxy model for filtering/sorting self.proxy = QSortFilterProxyModel(self) self.proxy.setSourceModel(self.varlist_model) self.proxy.setFilterKeyColumn(0) # Filters based on the only column self.proxy.setFilterCaseSensitivity( Qt.CaseInsensitive ) # Case insensitive search # Setup Layout layout = QVBoxLayout(self) # Left Side Group Box ("Available") varlist_box = QGroupBox("Available Variables") varlist_box_layout = QVBoxLayout() # Multiselect listing available columns self.varlist = QListView(self) self.varlist.setModel(self.proxy) self.varlist.setSelectionMode(QAbstractItemView.SingleSelection) self.varlist.selectionModel().selectionChanged.connect(self.selected_change) self.varlist.setEditTriggers(QAbstractItemView.NoEditTriggers) varlist_box_layout.addWidget(self.varlist) # Add a search box self.varlist_search = QLineEdit(parent=self) self.varlist_search.setPlaceholderText("Search...") self.varlist_search.textChanged.connect(self.proxy.setFilterFixedString) varlist_box_layout.addWidget(self.varlist_search) # Set layout and add to the main layout varlist_box.setLayout(varlist_box_layout) layout.addWidget(varlist_box) # Ok/Cancel QBtn = QDialogButtonBox.Ok | QDialogButtonBox.Cancel self.buttonBox = QDialogButtonBox(QBtn) self.buttonBox.accepted.connect(self.submit) self.buttonBox.rejected.connect(self.reject) layout.addWidget(self.buttonBox) # Reset to update self.reset_list() def selected_change(self): """ Update the current selection. Disable "Ok" if nothing is selected. """ selection_indexes = self.varlist.selectedIndexes() if len(selection_indexes) == 0: self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) else: self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(True) selected_index = selection_indexes[0] self.selected = self.proxy.itemData(selected_index)[0] def reset_list(self): """Clear the search field and show the full list""" self.varlist_search.setText("") self.varlist_model.clear() for idx, v in enumerate(self.columns): self.varlist_model.appendRow(QStandardItem(v)) if v == self.selected: selection_index = self.varlist_model.index(idx, 0) mode = ( QtCore.QItemSelectionModel.Select | QtCore.QItemSelectionModel.Rows ) self.varlist.selectionModel().select(selection_index, mode) def submit(self): # TODO: Add any warnings here self.selected = self.selected self.accept() @staticmethod def get_column(columns=None, selected=None, parent=None): if columns is None: return "No columns", None, None # Launch dialog to select a column dlg = SelectColumnDialog(columns, selected, parent) result = dlg.exec_() if result: # Update the selected value if the dialog accepted selected = dlg.selected return selected
class VideoPlayer(QWidget): def __init__(self, aPath, parent=None): super(VideoPlayer, self).__init__(parent) self.setAttribute(Qt.WA_NoSystemBackground, True) self.setAcceptDrops(True) self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.StreamPlayback) self.mediaPlayer.setVolume(80) self.videoWidget = QVideoWidget(self) self.videoWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.videoWidget.setMinimumSize(QSize(640, 360)) self.lbl = QLineEdit('00:00:00') self.lbl.setReadOnly(True) self.lbl.setFixedWidth(70) self.lbl.setUpdatesEnabled(True) self.lbl.setStyleSheet(stylesheet(self)) self.elbl = QLineEdit('00:00:00') self.elbl.setReadOnly(True) self.elbl.setFixedWidth(70) self.elbl.setUpdatesEnabled(True) self.elbl.setStyleSheet(stylesheet(self)) self.playButton = QPushButton() self.playButton.setEnabled(False) self.playButton.setFixedWidth(32) self.playButton.setStyleSheet("background-color: black") self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.playButton.clicked.connect(self.play) self.positionSlider = QSlider(Qt.Horizontal, self) self.positionSlider.setStyleSheet(stylesheet(self)) self.positionSlider.setRange(0, 100) self.positionSlider.sliderMoved.connect(self.setPosition) self.positionSlider.sliderMoved.connect(self.handleLabel) self.positionSlider.setSingleStep(2) self.positionSlider.setPageStep(20) self.positionSlider.setAttribute(Qt.WA_TranslucentBackground, True) self.clip = QApplication.clipboard() self.process = QProcess(self) self.process.readyRead.connect(self.dataReady) self.process.finished.connect(self.playFromURL) self.myurl = "" # channel list self.channelList = QListView(self) self.channelList.setMinimumSize(QSize(150, 0)) self.channelList.setMaximumSize(QSize(150, 4000)) self.channelList.setFrameShape(QFrame.Box) self.channelList.setObjectName("channelList") self.channelList.setStyleSheet("background-color: black; color: #585858;") self.channelList.setFocus() # for adding items to list must create a model self.model = QStandardItemModel() self.channelList.setModel(self.model) self.controlLayout = QHBoxLayout() self.controlLayout.setContentsMargins(5, 0, 5, 0) self.controlLayout.addWidget(self.playButton) self.controlLayout.addWidget(self.lbl) self.controlLayout.addWidget(self.positionSlider) self.controlLayout.addWidget(self.elbl) self.mainLayout = QHBoxLayout() # contains video and cotrol widgets to the left side self.layout = QVBoxLayout() self.layout.setContentsMargins(0, 0, 0, 0) self.layout.addWidget(self.videoWidget) self.layout.addLayout(self.controlLayout) # adds channels list to the right self.mainLayout.addLayout(self.layout) self.mainLayout.addWidget(self.channelList) self.setLayout(self.mainLayout) self.myinfo = "©2020\nTIVOpy v1.0" self.widescreen = True #### shortcuts #### self.shortcut = QShortcut(QKeySequence("q"), self) self.shortcut.activated.connect(self.handleQuit) self.shortcut = QShortcut(QKeySequence("u"), self) self.shortcut.activated.connect(self.playFromURL) self.shortcut = QShortcut(QKeySequence(Qt.Key_Space), self) self.shortcut.activated.connect(self.play) self.shortcut = QShortcut(QKeySequence(Qt.Key_F), self) self.shortcut.activated.connect(self.handleFullscreen) self.shortcut = QShortcut(QKeySequence(Qt.Key_Escape), self) self.shortcut.activated.connect(self.exitFullscreen) self.shortcut.activated.connect(self.handleFullscreen) self.shortcut = QShortcut(QKeySequence("i"), self) self.shortcut.activated.connect(self.handleInfo) self.shortcut = QShortcut(QKeySequence("s"), self) self.shortcut.activated.connect(self.toggleSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Right), self) self.shortcut.activated.connect(self.forwardSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Left), self) self.shortcut.activated.connect(self.backSlider) self.mediaPlayer.setVideoOutput(self.videoWidget) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.positionChanged.connect(self.handleLabel) self.mediaPlayer.durationChanged.connect(self.durationChanged) self.mediaPlayer.error.connect(self.handleError) self.populateChannelList() self.selectChannel() self.initialPlay() def playFromURL(self): self.mediaPlayer.pause() self.myurl = self.clip.text() self.mediaPlayer.setMedia(QMediaContent(QUrl(self.myurl))) self.playButton.setEnabled(True) self.mediaPlayer.play() self.hideSlider() print(self.myurl) def dataReady(self): self.myurl = str(self.process.readAll(), encoding='utf8').rstrip() ### self.myurl = self.myurl.partition("\n")[0] print(self.myurl) self.clip.setText(self.myurl) self.playFromURL() def play(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def mediaStateChanged(self, state): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPause)) else: self.playButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPlay)) def positionChanged(self, position): self.positionSlider.setValue(position) def durationChanged(self, duration): self.positionSlider.setRange(0, duration) mtime = QTime(0, 0, 0, 0) mtime = mtime.addMSecs(self.mediaPlayer.duration()) self.elbl.setText(mtime.toString()) def setPosition(self, position): self.mediaPlayer.setPosition(position) def handleError(self): self.playButton.setEnabled(False) print("Error: ", self.mediaPlayer.errorString()) def handleQuit(self): self.mediaPlayer.stop() print("Goodbye ...") app.quit() def contextMenuRequested(self, point): menu = QMenu() actionURL = menu.addAction(QIcon.fromTheme("browser"), "URL from Clipboard (u)") menu.addSeparator() actionToggle = menu.addAction(QIcon.fromTheme("next"), "Show / Hide Channels (s)") actionFull = menu.addAction(QIcon.fromTheme("view-fullscreen"), "Fullscreen (f)") menu.addSeparator() actionInfo = menu.addAction(QIcon.fromTheme("help-about"), "About (i)") menu.addSeparator() actionQuit = menu.addAction(QIcon.fromTheme("application-exit"), "Exit (q)") actionQuit.triggered.connect(self.handleQuit) actionFull.triggered.connect(self.handleFullscreen) actionInfo.triggered.connect(self.handleInfo) actionToggle.triggered.connect(self.toggleSlider) actionURL.triggered.connect(self.playFromURL) menu.exec_(self.mapToGlobal(point)) def wheelEvent(self, event): mscale = event.angleDelta().y() / 13 self.mediaPlayer.setVolume(self.mediaPlayer.volume() + mscale) print("Volume: " + str(self.mediaPlayer.volume())) def mouseDoubleClickEvent(self, event): if event.buttons() == Qt.LeftButton: self.handleFullscreen() def handleFullscreen(self): if self.windowState() and Qt.WindowFullScreen: self.showNormal() else: self.showFullScreen() def exitFullscreen(self): self.showNormal() def handleInfo(self): QMessageBox.about(self, "About", self.myinfo) def toggleSlider(self): if self.positionSlider.isVisible(): self.hideSlider() else: self.showSlider() def hideSlider(self): self.channelList.hide() self.playButton.hide() self.lbl.hide() self.positionSlider.hide() self.elbl.hide() def showSlider(self): self.channelList.show() self.playButton.show() self.lbl.show() self.positionSlider.show() self.elbl.show() self.channelList.setFocus() def forwardSlider(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() + 1000 * 60) def backSlider(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() - 1000 * 60) def volumeUp(self): self.mediaPlayer.setVolume(self.mediaPlayer.volume() + 10) print("Volume: " + str(self.mediaPlayer.volume())) def volumeDown(self): self.mediaPlayer.setVolume(self.mediaPlayer.volume() - 10) print("Volume: " + str(self.mediaPlayer.volume())) def dragEnterEvent(self, event): if event.mimeData().hasUrls(): event.accept() elif event.mimeData().hasText(): event.accept() else: event.ignore() def dropEvent(self, event): print("drop") if event.mimeData().hasUrls(): url = event.mimeData().urls()[0].toString() print("url = ", url) self.mediaPlayer.stop() self.mediaPlayer.setMedia(QMediaContent(QUrl(url))) self.playButton.setEnabled(True) self.mediaPlayer.play() elif event.mimeData().hasText(): mydrop = event.mimeData().text() print("generic url = ", mydrop) self.mediaPlayer.setMedia(QMediaContent(QUrl(mydrop))) self.playButton.setEnabled(True) self.mediaPlayer.play() self.hideSlider() def loadFilm(self, f): self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(f))) self.playButton.setEnabled(True) self.mediaPlayer.play() def populateChannelList(self): # file must be in same directory as the script FILEPATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "canaletv.txt") # lines from file with "channel name" -- "link" channelArray = [] # split file by line and adding it to the array with open(FILEPATH) as f: for line in f: channelArray.append(line.rstrip()) # dictionary with key = channel name and value = link self.channelDict = dict(ch.split(" -- ") for ch in channelArray) for channel in self.channelDict.keys(): item = QStandardItem(channel) self.model.appendRow(item) def selectedItemBehavior(self, index): # gets the link for the selected channel and plays it itms = self.channelList.selectedIndexes() for it in itms: channel = it.data() link = self.channelDict[channel] self.mediaPlayer.setMedia(QMediaContent(QUrl(link))) self.play() def selectChannel(self): # selecting channel from sidebar calls selectedItemBehavior self.selModel = self.channelList.selectionModel() self.selModel.selectionChanged.connect(self.selectedItemBehavior) def initialPlay(self): # play somenting when app opens self.mediaPlayer.setMedia(QMediaContent(QUrl("https://vid.hls.protv.ro/proxhdn/proxhd_3_34/index.m3u8?1"))) self.play() def handleLabel(self): self.lbl.clear() mtime = QTime(0, 0, 0, 0) self.time = mtime.addMSecs(self.mediaPlayer.position()) self.lbl.setText(self.time.toString())
class VistaListaMenuCliente(QWidget): def __init__(self, nome, tavolo): super(VistaListaMenuCliente, self).__init__() self.controller = ControlloreListaMenu() self.ordinazione = ControlloreOrdinazione(Ordinazione(nome, tavolo), self.controller) self.controller.update() self.h_layout = QHBoxLayout() self.list_view = QListView() self.listview_model = QStandardItemModel(self.list_view) for ProdottoSingolo in self.controller.get_lista_menu(): item = QStandardItem() item.setText("{} ".format(ProdottoSingolo.prodotto) + "{}€".format(ProdottoSingolo.prezzo)) item.setEditable(False) font = item.font() font.setPointSize(18) item.setFont(font) self.listview_model.appendRow(item) self.list_view.setModel(self.listview_model) self.h_layout.addWidget(self.list_view) buttons_layout = QVBoxLayout() open_button = QPushButton("Apri") open_button.clicked.connect(self.show_selected_info) buttons_layout.addWidget(open_button) order_button = QPushButton("Aggiungi ordine") order_button.clicked.connect(self.add_ordinazione) buttons_layout.addWidget(order_button) delete_button = QPushButton("Elimina ordine") delete_button.clicked.connect(self.delete_ordinazione) buttons_layout.addWidget(delete_button) view_button = QPushButton("Visualizza ordine") view_button.clicked.connect(self.view_ordinazione) buttons_layout.addWidget(view_button) check_button = QPushButton("Conferma ordine") check_button.clicked.connect(self.check_ordinazione) buttons_layout.addWidget(check_button) buttons_layout.addStretch() self.h_layout.addLayout(buttons_layout) self.setLayout(self.h_layout) self.resize(600, 300) self.setWindowTitle("Lista Menu") def closeEvent(self, event): print("ON CLOSE") self.controller.save_data() event.accept() def show_selected_info(self): if len(self.list_view.selectedIndexes()) > 0: selected = self.list_view.selectedIndexes()[0].row() prodotto_selezionato = self.controller.get_prodotto_by_index( selected) self.vista_prodotto = VistaProdotto(prodotto_selezionato) self.vista_prodotto.show() def view_ordinazione(self): msg = QMessageBox() if self.ordinazione.get_ordinazione(): self.vista_ordinazione = VistaOrdinazione(self.ordinazione) self.vista_ordinazione.show() else: msg.setText('Ordine vuoto') msg.setWindowTitle("Attenzione!") msg.exec_() def add_ordinazione(self): if len(self.list_view.selectedIndexes()) > 0: selected = self.list_view.selectedIndexes()[0].row() prodotto_selezionato = self.controller.get_prodotto_by_index( selected) if not self.ordinazione.inserisci_ordinazione( ControlloreProdotto(prodotto_selezionato)): msg = QMessageBox() msg.setText('Prodotto non disponibile!') msg.setWindowTitle("Avviso") msg.exec_() def delete_ordinazione(self): reply = QMessageBox.question(self, 'Quit', 'Vuoi cancelllare l\'ordine?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: self.ordinazione.elimina_ordinazione() def check_ordinazione(self): self.ordinazione.conferma_ordinazione() msg = QMessageBox() msg.setText('Ordine confermato!') msg.setWindowTitle("Avviso") msg.exec_() self.close()
class VistaListaProdotti(QWidget): def __init__(self, parent=None): super(VistaListaProdotti, self).__init__(parent) self.carrello = ControlloreCarrello() self.controller = ControlloreListaProdotti() self.setWindowIcon(QtGui.QIcon('logos/logo.png')) main_layout = QHBoxLayout() v_layout = QVBoxLayout() self.list_view = QListView() self.update_ui() #Crea un elenco fittizio sopra l'elenco reale per poter usare la barra di ricerca self.filter_proxy_model = QSortFilterProxyModel() self.filter_proxy_model.setSourceModel(self.listview_model) self.filter_proxy_model.setFilterCaseSensitivity(Qt.CaseInsensitive) self.filter_proxy_model.setFilterKeyColumn(0) self.list_view.setModel(self.filter_proxy_model) search_field = QLineEdit() search_field.setStyleSheet('font-size: 15px; height: 30px;') search_field.textChanged.connect( self.filter_proxy_model.setFilterRegExp) v_layout.addWidget(search_field) v_layout.addWidget(self.list_view) main_layout.addLayout(v_layout) buttons_layout = QVBoxLayout() buttons_layout.addItem(QSpacerItem(40, 40)) #Bottone per aprire un prodotto open_button = QPushButton("Apri") open_button.clicked.connect(self.show_selected_info) buttons_layout.addWidget(open_button) #Bottone per creare un nuovo prodotto new_button = QPushButton("Nuovo") new_button.clicked.connect(self.show_new_prodotto) buttons_layout.addWidget(new_button) buttons_layout.addStretch() main_layout.addLayout(buttons_layout) self.setLayout(main_layout) self.resize(600, 300) self.setWindowTitle("Lista Prodotti") #Metodo che mostra a schermo le informazioni del prodotto selezionato def show_selected_info(self): try: sourceindex = self.list_view.selectedIndexes()[0].row() prodotto_selezionato = self.controller.get_prodotto_by_index( sourceindex) self.vista_prodotto = VistaProdotto( prodotto_selezionato, self.controller.elimina_prodotto_by_id, self.update_ui, self.carrello) self.vista_prodotto.show() except IndexError: QMessageBox.critical(self, 'Errore', 'Per favore, seleziona un prodotto', QMessageBox.Ok, QMessageBox.Ok) #Metodo aprire la vista di inserimento del nuovo prodotto def show_new_prodotto(self): self.vista_inserisci_prodotto = VistaInserisciProdotto( self.controller, self.update_ui) self.vista_inserisci_prodotto.show() #Metodo che serve per generare e/o aggiornare la vista def update_ui(self): self.listview_model = QStandardItemModel(self.list_view) for prodotto in self.controller.get_lista_dei_prodotti(): item = QStandardItem() item.setText(prodotto.marca + " " + prodotto.nome) item.setEditable(False) font = item.font() font.setPointSize(18) item.setFont(font) self.listview_model.appendRow(item) self.list_view.setModel(self.listview_model) # salva i dati sul file pickle alla chiusura della view def closeEvent(self, event): self.controller.save_data() #Metodo per collegare l'indice selezionato all'elenco fittizio all'indice dell'elenco reale def toSourceIndex(self, index): return self.filter_proxy_model.mapToSource(index).row()
class ConfigurationView(QWidget): """ Displays the configuration view. """ def __init__(self, parent=None): super(ConfigurationView, self).__init__(parent) self._layout = QBoxLayout(QBoxLayout.TopToBottom) self.setLayout(self._layout) self._editView = EditView(parent) # initialize list view self._listView = QListView() self._configuration_model = self._get_config_model() self._listView.setModel(self._configuration_model) # initialize detail view self._detailView = QWidget() self._detailLayout = QBoxLayout(QBoxLayout.TopToBottom) self._detailView.setLayout(self._detailLayout) self._detailPanels = {} self._currentDetailPanel = None self._currentConfiguration = None # type: Configuration self._config_wide_print_amounts = {} self._recalculateEffectivePrintAmounts = False # add widgets to layout self._layout.addWidget(QLabel("List of Configurations")) self._layout.addWidget(self._listView) self._layout.addWidget(self._detailView) self._create_detail_view() # hide detail view on start self._detailView.hide() # selected configs map self._selected_configs = {} self._selected_counter = 0 # add event listener for selection change self._listView.clicked.connect(self._on_selection_change) self._listView.selectionModel().currentChanged.connect(self._on_selection_change) def add_configuration(self, configuration): """ Adds the given configuration to the list view and opens the edit view. :param configuration: :type configuration: Configuration """ item = create_new_list_item(configuration.get_name()) self._configuration_model.appendRow(item) self._editView.show_for_configuration(configuration) def select_first_item(self): rect = QRect(0,0,1,1) self._listView.setSelection(rect, QItemSelectionModel.Select) def update_model(self): self._configuration_model = self._get_config_model() self._listView.setModel(self._configuration_model) @staticmethod def _get_config_model(): data = DataStorage() configurations_order = data.get_configurations_order() model = QStandardItemModel() for name in configurations_order: item = create_new_list_item(name) model.appendRow(item) return model def _on_selection_change(self, model_index): """ Called on selecting a new item in the listView. :param model_index: index of selected item :type model_index: QModelIndex """ data = DataStorage() configurations = data.get_configurations() selected_item = self._configuration_model.itemFromIndex(model_index) # type: QStandardItem current_config_name = selected_item.text() current_config = configurations[current_config_name] # type: Configuration self._show_detail_view(current_config) config_wide_print_amount = self._config_wide_print_amounts[current_config_name] material_print_amounts = current_config.get_effective_material_print_amounts( config_wide_print_amount, self._recalculateEffectivePrintAmounts ) self._recalculateEffectivePrintAmounts = False if self._selected_counter == 0: MaterialView.reset_check_state_and_print_amount() for material in current_config.get_materials(): item = get_item(MaterialView.get_model().invisibleRootItem(), material.get_name()) if item is not None: print_amount = material_print_amounts[material.get_name()] if is_checked(selected_item): check_item(item) if current_config_name not in self._selected_configs: print_amount += int(item.text(1)) else: print_amount = int(item.text(1)) item.setText(1, str(print_amount)) if is_checked(selected_item) and current_config_name not in self._selected_configs: self._selected_configs[current_config_name] = True self._selected_counter += 1 if not is_checked(selected_item) and current_config_name in self._selected_configs: self._selected_configs.pop(current_config_name) self._selected_counter -= 1 self._currentConfiguration = current_config def _create_detail_view(self): """ Adds the permanent elements to the detail view. """ edit_button = QPushButton("Edit") edit_button.clicked.connect(self._show_edit_view) self._detailLayout.addWidget(QLabel("Detail view for selected configuration")) self._detailLayout.addWidget(edit_button) def _change_config_wide_print_amount(self, new_value): self._config_wide_print_amounts[self._currentConfiguration.get_name()] = new_value self._recalculateEffectivePrintAmounts = True def _create_update_function_for_sub_configs(self, sub_config, configuration): def update_func(new_value): if self._currentConfiguration.get_name() == configuration.get_name(): self._currentConfiguration.set_config_print_amount(sub_config, new_value) self._recalculateEffectivePrintAmounts = True return update_func def _show_edit_view(self): """ Shows the edit view for the selected configuration. """ self._editView.show_for_configuration(self._currentConfiguration) selected_indexes = self._listView.selectedIndexes() self._on_selection_change(selected_indexes[0]) def _show_detail_view(self, configuration: Configuration): """ Shows the detail view for the selected configuration. :param configuration: :type configuration: Configuration """ if self._currentDetailPanel is not None: self._currentDetailPanel.hide() if configuration.get_name() in self._detailPanels: self._currentDetailPanel = self._detailPanels[configuration.get_name()] self._currentDetailPanel.show() else: panel = QWidget() layout = QFormLayout() panel.setLayout(layout) config_wide_counter = QSpinBox() config_wide_counter.setMinimum(1) config_wide_counter.setValue(1) config_wide_counter.valueChanged.connect(self._change_config_wide_print_amount) # add panel to parent layout self._detailLayout.addWidget(panel) # save panel for future use self._detailPanels[configuration.get_name()] = panel self._currentDetailPanel = panel self._config_wide_print_amounts[configuration.get_name()] = 1 # panel layout.addRow("Print this config x times", config_wide_counter) layout.addRow("Child configurations", QLabel()) configurations = configuration.get_configurations() config_print_amounts = configuration.get_config_print_amounts() for config in configurations: # type: Configuration config_counter = QSpinBox() config_counter.setMinimum(1) config_counter.setValue(config_print_amounts[config.get_name()]) update_func = self._create_update_function_for_sub_configs(config, configuration) config_counter.valueChanged.connect(update_func) layout.addRow("Print config " + config.get_name() + " x times", config_counter) self._detailView.show()
class VistaListaPrenotazioniAdmin(QWidget): def __init__(self, data_inizio=None, parent=None): super(VistaListaPrenotazioniAdmin, self).__init__(parent) self.controllore_lista_prenotazioni = ControlloreListaPrenotazioni() self.data_inizio = data_inizio self.v_layout = QVBoxLayout() self.font = QFont("Arial", 15, 15, True) #Se non è stata passata alcuna data di inizio visualizza tutte le prenotazioni, altrimenti visualizza le prenotazioni #che iniziano in quella data if data_inizio is not None: self.label_prenotazioni_by_data = QLabel("Arrivi del giorno " + data_inizio.strftime("%d/%m/%Y") + ":") else: self.label_prenotazioni_by_data = QLabel("Tutte le prenotazioni: ") self.label_prenotazioni_by_data.setStyleSheet("font: 20pt \"Papyrus\";""color: rgb(0,0,255);") self.label_prenotazioni_by_data.setAlignment(Qt.AlignCenter) self.v_layout.addWidget(self.label_prenotazioni_by_data) self.v_layout.addSpacing(15) self.lista_prenotazioni = QListView() self.aggiorna_dati_prenotazioni() self.v_layout.addWidget(self.lista_prenotazioni) self.bottone_dettagli_prenotaizone = QPushButton("Dettagli prenotazione") self.bottone_dettagli_prenotaizone.setFont(self.font) self.bottone_dettagli_prenotaizone.setStyleSheet("background-color: rgb(170,180,255);") self.bottone_dettagli_prenotaizone.clicked.connect(self.dettagli_prenotazione) self.shortcut_open = QShortcut(QKeySequence('Return'), self) self.shortcut_open.activated.connect(self.dettagli_prenotazione) self.v_layout.addWidget(self.bottone_dettagli_prenotaizone) self.v_layout.addSpacing(15) #Se è stata passata una data di inizio, verrà creato nella finestra un piccolo sommario della situazione del #resort in quella data if data_inizio is not None: self.label_stato_resort = QLabel("Sommario prenotazioni:") self.label_stato_resort.setAlignment(Qt.AlignCenter) self.label_stato_resort.setStyleSheet("font: 18pt \"Papyrus\";""color: rgb(0,0,255);") self.v_layout.addWidget(self.label_stato_resort) self.lista_stato_resort = QListView() self.get_stato_resort(data_inizio) self.lista_stato_resort.setAlternatingRowColors(True) self.lista_stato_resort.setEditTriggers(QAbstractItemView.NoEditTriggers) self.v_layout.addWidget(self.lista_stato_resort) self.setLayout(self.v_layout) self.resize(900, 800) self.setWindowTitle("Lista Prenotazioni") #Ottiene i dati delle prenotazioni e li mette nella lista visualizzata def aggiorna_dati_prenotazioni(self): self.modello_lista_prenotazioni = QStandardItemModel() for prenotazione in self.controllore_lista_prenotazioni.get_lista_prenotazioni(): if self.data_inizio == prenotazione.data_inizio: item = QStandardItem() item.setText("Prenotazione del " + prenotazione.data_inizio.strftime("%d/%m/%Y") + " - " + prenotazione.data_fine.strftime("%d/%m/%Y") + " effettuata da " + prenotazione.email_cliente) item.setEditable(False) item.setFont(self.font) self.modello_lista_prenotazioni.appendRow(item) elif self.data_inizio is None: item = QStandardItem() item.setText("Prenotazione del " + prenotazione.data_inizio.strftime("%d/%m/%Y") + " - " + prenotazione.data_fine.strftime("%d/%m/%Y") + " effettuata da " + prenotazione.email_cliente) item.setEditable(False) item.setFont(self.font) self.modello_lista_prenotazioni.appendRow(item) self.lista_prenotazioni.setModel(self.modello_lista_prenotazioni) #Visualizza i dettagli della prenotazione selezionata, se non ne è stata selezionata alcuna mostra un messaggio di errore def dettagli_prenotazione(self): try: indice = self.lista_prenotazioni.selectedIndexes()[0].row() if self.data_inizio is not None: lista_prenotazioni_filtrata = [] for prenotazione in self.controllore_lista_prenotazioni.get_lista_prenotazioni(): if prenotazione.data_inizio == self.data_inizio: lista_prenotazioni_filtrata.append(prenotazione) da_visualizzare = lista_prenotazioni_filtrata[indice] else: da_visualizzare = self.controllore_lista_prenotazioni.get_lista_prenotazioni()[indice] except: QMessageBox.critical(self, "Errore", "Seleziona la prenotazione da visualizzare", QMessageBox.Ok, QMessageBox.Ok) return self.vista_prenotazione = VistaPrenotazione(ControllorePrenotazione(da_visualizzare)) self.vista_prenotazione.show() #Crea il sommario dello stato del reort nella data passata come argomento def get_stato_resort(self, data_controllo_stato): self.modello_stato_resort = QStandardItemModel() #Inizializza il numero di posti occupati dei serivizi disponibili a 0 numero_suite_occupate = 0 numero_stanze_doppie_occupate = 0 numero_stanze_familiari_occupate = 0 numero_bungalow_occupati = 0 numero_mezzi_elettrici_occupati = 0 numero_prenotazioni_centro_benessere = 0 for prenotazione in self.controllore_lista_prenotazioni.get_lista_prenotazioni(): #Controlla se la data del sommario ricade tra l'inizio e la fine di ogni prenotazione if data_controllo_stato >= prenotazione.data_inizio and data_controllo_stato <= prenotazione.data_fine: #Se il controllo dà esito positivo, viene aggiunto un posto occupato al servizio di alloggio scelto nella prenotazione if prenotazione.servizio_alloggio == Servizio("Suite", "Alloggio", 235): numero_suite_occupate = numero_suite_occupate + 1 if prenotazione.servizio_alloggio == Servizio("Camera doppia", "Alloggio", 80): numero_stanze_doppie_occupate = numero_stanze_doppie_occupate + 1 if prenotazione.servizio_alloggio == Servizio("Camera famigliare", "Alloggio", 125): numero_stanze_familiari_occupate = numero_stanze_familiari_occupate + 1 if prenotazione.servizio_alloggio == Servizio("Bungalow", "Alloggio", 150): numero_bungalow_occupati = numero_bungalow_occupati + 1 #Se il controllo dà esito positivo, viene aggiunto un numero di posti occupati al servizio aggiuntivo # pari al numero di persone della prenotazione for servizio_aggiuntivo in prenotazione.servizi_aggiuntivi: if servizio_aggiuntivo == Servizio("Noleggio mezzi elettrici", "Servizi aggiuntivi", 30): numero_mezzi_elettrici_occupati = numero_mezzi_elettrici_occupati + prenotazione.numero_persone if servizio_aggiuntivo == Servizio("Centro benessere", "Servizi aggiuntivi", 50): numero_prenotazioni_centro_benessere = numero_prenotazioni_centro_benessere + prenotazione.numero_persone #I dati vengono aggiunti alla lista del sommario tramite degli item item_suite = QStandardItem() item_suite.setFont(self.font) item_suite.setEditable(False) item_suite.setText("Suite occupate: " + str(numero_suite_occupate)) self.modello_stato_resort.appendRow(item_suite) item_camere_doppie = QStandardItem() item_camere_doppie.setFont(self.font) item_camere_doppie.setEditable(False) item_camere_doppie.setText("Camere doppie occupate: " + str(numero_stanze_doppie_occupate)) self.modello_stato_resort.appendRow(item_camere_doppie) item_camere_famigliari = QStandardItem() item_camere_famigliari.setFont(self.font) item_camere_famigliari.setEditable(False) item_camere_famigliari.setText("Camere famigliari occupate: " + str(numero_stanze_doppie_occupate)) self.modello_stato_resort.appendRow(item_camere_famigliari) item_bungalow = QStandardItem() item_bungalow.setFont(self.font) item_bungalow.setEditable(False) item_bungalow.setText("Bungalow occupati: " + str(numero_bungalow_occupati)) self.modello_stato_resort.appendRow(item_bungalow) item_vuoto = QStandardItem() item_vuoto.setEditable(False) self.modello_stato_resort.appendRow(item_vuoto) item_mezzi_elettrici = QStandardItem() item_mezzi_elettrici.setFont(self.font) item_mezzi_elettrici.setEditable(False) item_mezzi_elettrici.setText("Numero mezzi elettrici noleggiati: " + str(numero_mezzi_elettrici_occupati)) self.modello_stato_resort.appendRow(item_mezzi_elettrici) item_centro_benessere = QStandardItem() item_centro_benessere.setFont(self.font) item_centro_benessere.setEditable(False) item_centro_benessere.setText("Numero prenotazioni centro benessere: " + str(numero_prenotazioni_centro_benessere)) self.modello_stato_resort.appendRow(item_centro_benessere) self.lista_stato_resort.setModel(self.modello_stato_resort)
class VistaListaDipendenti(QWidget): def __init__(self, parent=None): super(VistaListaDipendenti, self).__init__(parent) self.controller = ControlloreListaDipendenti() self.v_layout = QVBoxLayout() self.list_view = QListView() self.aggiorna_dati() self.v_layout.addWidget(self.list_view) self.h_layout = QHBoxLayout() self.create_button("Inserisci Dipendente", self.go_inserisci_dipendente, "background-color: rgb(0, 255, 0);") self.create_button("Visualizza - Modifica", self.go_modifica_dipendente, "background-color: rgb(170,180,255);") self.create_button("Elimina Dipendente", self.elimina_dipendente, "background-color: rgb(255, 0, 0);") self.v_layout.addLayout(self.h_layout) self.setLayout(self.v_layout) self.resize(300, 500) self.move(250, 150) self.setWindowTitle("Lista Dipendenti") self.show() def create_button(self, testo, comando, background_color): bottone = QPushButton(testo) bottone.setFont(QFont("Arial", 15, 1, True)) bottone.setStyleSheet(background_color) bottone.clicked.connect(comando) self.h_layout.addWidget(bottone) #Funzione di callback che aggiorna i dati della lista dipendenti visualizzata def aggiorna_dati(self): self.list_view_model = QStandardItemModel(self.list_view) for dipendente in self.controller.get_lista_dipendenti(): item = QStandardItem() item.setText(dipendente.nome + " " + dipendente.cognome) item.setEditable(False) item.setFont(QFont("Arial", 16)) self.list_view_model.appendRow(item) self.list_view.setModel(self.list_view_model) def go_inserisci_dipendente(self): self.vista_inserisci_dipendente = VistaInserisciDipendente(self.controller, self.aggiorna_dati) self.vista_inserisci_dipendente.show() #Mostra la finestra di modifica del dipendente selezionato, se non si è selezionato alcun dipendente mostra #un messaggio di errore def go_modifica_dipendente(self): try: indice = self.list_view.selectedIndexes()[0].row() da_visualizzare = self.controller.get_lista_dipendenti()[indice] except: QMessageBox.critical(self, "Errore", "Seleziona il dipendente da visualizzare", QMessageBox.Ok, QMessageBox.Ok) return self.vista_modifica_dipendente = VistaModificaDipendente(ControlloreDipendente(da_visualizzare), self.aggiorna_dati, self.controller.get_lista_dipendenti()) self.vista_modifica_dipendente.show() #Chiede conferma di eliminare il dipendente selezionato, in caso affermativo lo cancella def elimina_dipendente(self): try: indice = self.list_view.selectedIndexes()[0].row() da_eliminare = self.controller.get_lista_dipendenti()[indice] except: QMessageBox.critical(self, "Errore", "Seleziona il dipendente da eliminare", QMessageBox.Ok, QMessageBox.Ok) return risposta = QMessageBox.warning(self, "Conferma", "Sei sicuro di volere eliminare il dipendente?", QMessageBox.Yes, QMessageBox.No) if risposta == QMessageBox.Yes: self.controller.elimina_dipendente_by_id(da_eliminare.id) QMessageBox.about(self, "Eliminato", "Il dipendente è stato eliminato") self.aggiorna_dati() else: return #Alla chiusura della finestra salva le modifiche apportate alla lista dei dipendenti def closeEvent(self, event): self.controller.save_data()