def init_calendario(self): calendario = QCalendarWidget(self) currentMonth = datetime.now().month currentYear = datetime.now().year calendario.setMinimumDate(QDate(currentYear, currentMonth, 1)) calendario.setMaximumDate( QDate(currentYear + 1, currentMonth, calendar.monthrange(currentYear, currentMonth)[1])) calendario.setSelectedDate(QDate(currentYear, currentMonth, 1)) calendario.setFont(QFont('Georgia', 10)) calendario.setStyleSheet('background-color: lightblue') calendario.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) calendario.setGeometry(200, 200, 300, 200) calendario.setGridVisible(True) return calendario
class Reservations(QWidget): """ Klasa odpowiedzialna za widget klienci """ def __init__(self, parent, db): super(QWidget, self).__init__(parent) self.parent = parent self.btn_mod = QPushButton('Zmiana statusu') self.btn_usun = QPushButton('Usuń') self.btn_dodaj = QPushButton('Dodaj') self.lbl_klient_ = QLabel('') self.lbl_usluga_ = QLabel('') self.lbl_termin_ = QDateTimeEdit() self.gb_layout = QVBoxLayout() self.kalendarz = QCalendarWidget() self.view_u = QTableView() self.view_k = QTableView() self.view_p = QTableView() self.view = QTableView() self.proxy_u = QSortFilterProxyModel(self) self.proxy_k = QSortFilterProxyModel(self) self.proxy_p = QSortFilterProxyModel(self) self.proxy = QSortFilterProxyModel(self) self.id_klient = -1 self.id_usluga = -1 self.id_pracownik = -1 self.id_rezerwacje = -1 self.data = None self.data_do = None self.dzien_tyg = 0 self.czas = [] # Lista składana przycisków godzin self.btn_godz = [QPushButton(str(i + 1)) for i in range(16)] # Parametry połączenia z bazą self.model_u = QSqlTableModel(self, db) self.model_k = QSqlTableModel(self, db) self.model_p = QSqlTableModel(self, db) self.model = QSqlTableModel(self, db) self.initUI() def initUI(self): """ Inicjuje UI """ self.view_u.setObjectName('Usługi') self.view_k.setObjectName('Klienci') self.view_p.setObjectName('Pracownicy') self.view.setObjectName('Rezerwacje') self.table_init_u() self.table_init_k() self.table_init_p() self.table_init() self.btn_mod.setDisabled(True) self.btn_usun.setDisabled(True) self.btn_dodaj.setDisabled(True) # Tworzenie kontrolek lbl_wysz_u = QLabel('Wyszukaj usługę:') lbl_wysz_k = QLabel('Wyszukaj klienta:') lbl_wysz_p = QLabel('Wyszukaj pracownika:') txt_wysz_u = QLineEdit(self) txt_wysz_k = QLineEdit(self) txt_wysz_p = QLineEdit(self) lbl_klient = QLabel('Klient:') lbl_usluga = QLabel('Usługa:') lbl_termin = QLabel('Termin:') sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.kalendarz.sizePolicy().hasHeightForWidth()) self.kalendarz.setSizePolicy(sizePolicy) # Tworzenie widoków centralbox = QHBoxLayout() hbox_wysz_u = QHBoxLayout() hbox_wysz_k = QHBoxLayout() hbox_wysz_p = QHBoxLayout() vbox_u = QVBoxLayout() vbox_k = QVBoxLayout() vbox_p = QVBoxLayout() vbox_right = QVBoxLayout() hbox_btn = QHBoxLayout() hbox_k = QHBoxLayout() hbox_u = QHBoxLayout() hbox_t = QHBoxLayout() vbox_cal = QVBoxLayout() groupbox = QGroupBox('Godziny:') groupbox.setLayout(self.gb_layout) hbox_left = QHBoxLayout() # Metody self.lbl_termin_.setCalendarWidget(self.kalendarz) self.lbl_termin_.setDate(self.kalendarz.selectedDate()) self.dzien_tyg = self.kalendarz.selectedDate().dayOfWeek() txt_wysz_u.textChanged.connect(self.searching_u) txt_wysz_k.textChanged.connect(self.searching_k) txt_wysz_p.textChanged.connect(self.searching_p) self.view_k.clicked.connect(lambda: self.clicked_table(self.view_k)) self.view_p.clicked.connect(lambda: self.clicked_table(self.view_p)) self.view_u.clicked.connect(lambda: self.clicked_table(self.view_u)) self.view.clicked.connect(lambda: self.clicked_table(self.view)) self.kalendarz.clicked.connect(self.show_data) self.btn_dodaj.clicked.connect(self.add) self.btn_mod.clicked.connect(self.modify) self.btn_usun.clicked.connect(self.remove) # Ustawianie widoków hbox_wysz_k.addWidget(lbl_wysz_k) hbox_wysz_k.addWidget(txt_wysz_k) hbox_wysz_p.addWidget(lbl_wysz_p) hbox_wysz_p.addWidget(txt_wysz_p) hbox_wysz_u.addWidget(lbl_wysz_u) hbox_wysz_u.addWidget(txt_wysz_u) vbox_u.addLayout(hbox_wysz_u) vbox_u.addWidget(self.view_u) vbox_k.addLayout(hbox_wysz_k) vbox_k.addWidget(self.view_k) vbox_p.addLayout(hbox_wysz_p) vbox_p.addWidget(self.view_p) vbox_right.addLayout(vbox_p) vbox_right.addLayout(vbox_u) vbox_right.addLayout(vbox_k) hbox_btn.addWidget(self.btn_usun) hbox_btn.addWidget(self.btn_mod) hbox_k.addWidget(lbl_klient) hbox_k.addWidget(self.lbl_klient_) hbox_u.addWidget(lbl_usluga) hbox_u.addWidget(self.lbl_usluga_) hbox_t.addWidget(lbl_termin) hbox_t.addWidget(self.lbl_termin_) vbox_cal.addWidget(self.kalendarz) vbox_cal.addLayout(hbox_u) vbox_cal.addLayout(hbox_t) vbox_cal.addLayout(hbox_k) self.view.setSizePolicy( QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)) vbox_cal.addWidget(self.view) vbox_cal.addLayout(hbox_btn) vbox_cal.addWidget(self.btn_dodaj) hbox_left.addLayout(vbox_cal) hbox_left.addWidget(groupbox) centralbox.addLayout(hbox_left) centralbox.addLayout(vbox_right) self.setLayout(centralbox) self.show() def show_data(self): self.lbl_termin_.setDate(self.kalendarz.selectedDate()) self.dzien_tyg = self.kalendarz.selectedDate().dayOfWeek() self.clicked_table(self.view_p) def table_init_u(self): """ Inicjuje wygląd tabeli usługi """ # self.model_u.setTable('uslugi') query = QSqlQuery( 'SELECT uslugi.uslugi_id, uslugi.nazwa, uslugi.cena, date_format(uslugi.czas, "%H:%i") AS czas FROM uslugi NATURAL JOIN uzytkownik_usluga WHERE uzytkownik_usluga.uzytkownik_id = ' + str(self.id_pracownik) + ';') self.model_u.setQuery(query) # self.model_u.select() self.proxy_u.setSourceModel(self.model_u) naglowki = { 'uslugi_id': 'ID', 'nazwa': 'Nazwa', 'cena': 'Cena', "czas": 'Czas', } # Ustawianie nagłówków ilosc_kolumn = self.model_u.columnCount() for i in range(ilosc_kolumn): nazwa_kolumn = self.model_u.headerData(i, Qt.Horizontal) self.model_u.setHeaderData(i, Qt.Horizontal, naglowki[nazwa_kolumn]) self.view_u.setSizeAdjustPolicy( QAbstractScrollArea.AdjustToContentsOnFirstShow) self.view_u.setSortingEnabled(True) self.view_u.setAlternatingRowColors(True) # Wczytanie danych self.view_u.setModel(self.proxy_u) self.view_u.hideColumn(0) self.view_u.sortByColumn(1, Qt.AscendingOrder) self.view_u.setEditTriggers(QAbstractItemView.NoEditTriggers) def table_init_k(self): """ Inicjuje wygląd tabeli klienta """ self.model_k.setTable('klienci') query = QSqlQuery( 'SELECT klienci_id, imie, nazwisko, email, telefon, ulica, numer_mieszkania, miejscowosc, poczta FROM ' 'klienci;') self.model_k.setQuery(query) # self.model_k.select() self.proxy_k.setSourceModel(self.model_k) naglowki = { 'klienci_id': 'ID', 'imie': 'Imię', 'nazwisko': 'Nazwisko', "email": 'Email', 'telefon': 'Telefon', 'ulica': 'Ulica', 'numer_mieszkania': 'Numer mieszkania', 'miejscowosc': 'Miejscowosc', 'poczta': 'Kod pocztowy', } # Ustawianie nagłówków ilosc_kolumn = self.model_k.columnCount() for i in range(ilosc_kolumn): nazwa_kolumn = self.model_k.headerData(i, Qt.Horizontal) self.model_k.setHeaderData(i, Qt.Horizontal, naglowki[nazwa_kolumn]) self.view_k.setSizeAdjustPolicy( QAbstractScrollArea.AdjustToContentsOnFirstShow) self.view_k.setSortingEnabled(True) self.view_k.setAlternatingRowColors(True) # Wczytanie danych self.view_k.setModel(self.proxy_k) self.view_k.hideColumn(0) self.view_k.sortByColumn(1, Qt.AscendingOrder) self.view_k.setEditTriggers(QAbstractItemView.NoEditTriggers) def table_init_p(self): """ Inicjuje wygląd tabeli pracownik """ self.model_p.setTable('uzytkownik') query = QSqlQuery( 'SELECT uzytkownik_id, imie, nazwisko FROM uzytkownik WHERE ' 'pracownik = 1;') self.model_p.setQuery(query) # self.model_p.select() self.proxy_p.setSourceModel(self.model_p) naglowki = { 'uzytkownik_id': 'ID', 'imie': 'Imię', "nazwisko": 'Nazwisko', } # Ustawianie nagłówków ilosc_kolumn = self.model_p.columnCount() for i in range(ilosc_kolumn): nazwa_kolumn = self.model_p.headerData(i, Qt.Horizontal) self.model_p.setHeaderData(i, Qt.Horizontal, naglowki[nazwa_kolumn]) self.view_p.setSizeAdjustPolicy( QAbstractScrollArea.AdjustToContentsOnFirstShow) self.view_p.setSortingEnabled(True) self.view_p.setAlternatingRowColors(True) # Wczytanie danych self.view_p.setModel(self.proxy_p) self.view_p.hideColumn(0) self.view_p.sortByColumn(1, Qt.AscendingOrder) self.view_p.setEditTriggers(QAbstractItemView.NoEditTriggers) def table_init(self): """ Inicjuje wygląd tabeli """ query = QSqlQuery( 'SELECT wizyty.wizyty_id, CONCAT(klienci.imie, " ", klienci.nazwisko) AS klient, uslugi.nazwa, ' 'wizyty.rezerwacja_od, wizyty.rezerwacja_do, wizyty.status FROM klienci, uslugi NATURAL JOIN wizyty WHERE wizyty.rezerwacja_od > CURRENT_TIMESTAMP AND wizyty.uzytkownik_id = ' + str(self.id_pracownik) + ';') self.model.setQuery(query) self.proxy.setSourceModel(self.model) naglowki = { 'wizyty_id': 'ID', 'klient': 'Klient', 'nazwa': 'Usługa', 'rezerwacja_od': 'Rezerwacja od', "rezerwacja_do": 'Rezerwacja do', 'status': 'Status rezerwacji' } # Ustawianie nagłówków ilosc_kolumn = self.model.columnCount() for i in range(ilosc_kolumn): nazwa_kolumn = self.model.headerData(i, Qt.Horizontal) self.model.setHeaderData(i, Qt.Horizontal, naglowki[nazwa_kolumn]) self.view.setSizeAdjustPolicy( QAbstractScrollArea.AdjustToContentsOnFirstShow) self.view.setSortingEnabled(True) self.view.setAlternatingRowColors(True) # Wczytanie danych self.view.setModel(self.proxy) self.view.hideColumn(0) self.view.sortByColumn(4, Qt.AscendingOrder) self.view.setEditTriggers(QAbstractItemView.NoEditTriggers) def clicked_table(self, view): """ Metoda edytująca zaznaczone wiersze - Wstawia wartości z wierszy w odpowiednie pola """ index = (view.selectionModel().currentIndex()) if view.objectName() == 'Klienci': self.id_klient = index.sibling(index.row(), 0).data() self.lbl_klient_.setText('<b>' + index.sibling(index.row(), 1).data() + ' ' + index.sibling(index.row(), 2).data() + '</b>') elif view.objectName() == 'Usługi': self.id_usluga = index.sibling(index.row(), 0).data() self.lbl_usluga_.setText('<b>' + index.sibling(index.row(), 1).data() + '</b>') self.data_do = index.sibling(index.row(), 3).data() elif view.objectName() == 'Rezerwacje': self.id_rezerwacje = index.sibling(index.row(), 0).data() if self.id_rezerwacje > 0: self.btn_mod.setEnabled(True) self.btn_usun.setEnabled(True) elif view.objectName() == 'Pracownicy': self.id_pracownik = index.sibling(index.row(), 0).data() self.czas = [] for i in reversed(range(self.gb_layout.count())): self.gb_layout.itemAt(i).widget().setParent(None) czas = datetime.datetime(2000, 1, 1, 8, 0) dzien = { 1: ('pon_od', 'pon_do'), 2: ('wt_od', 'wt_do'), 3: ('sr_od', 'sr_do'), 4: ('czw_od', 'czw_do'), 5: ('pt_od', 'pt_do'), 6: ('sob_od', 'sob_do'), 7: ('', '') } query = 'SELECT date_format({}, "%H") AS g_start, date_format({}, "%H") AS g_stop FROM godziny WHERE ' \ 'uzytkownik_id = {};'.format(dzien[self.dzien_tyg][0], dzien[self.dzien_tyg][1], self.id_pracownik) wynik = query_to_db(query) if wynik: godzina_stop = (int(wynik[1]) - int(wynik[0])) * 2 godzina = int(wynik[0]) for btn in self.btn_godz: btn.setEnabled(True) else: godzina_stop = 0 godzina = 1 for btn in self.btn_godz: btn.setDisabled(True) minuta = 0 czas = datetime.time(godzina, minuta) for i in range(godzina_stop): self.btn_godz[i].setText(czas.strftime("%H:%M")) self.czas.append(czas) self.btn_godz[i].setObjectName(str(i)) self.gb_layout.addWidget(self.btn_godz[i]) if i % 2 != 0: godzina += 1 minuta = 0 else: minuta = 30 czas = datetime.time(godzina, minuta) QMetaObject.connectSlotsByName(self) # Czyszczenie, odświeżanie self.refresh() query = QSqlQuery( 'SELECT uslugi.uslugi_id, uslugi.nazwa, uslugi.cena, date_format(uslugi.czas, "%H:%i") AS czas FROM uslugi NATURAL JOIN uzytkownik_usluga WHERE uzytkownik_usluga.uzytkownik_id = ' + str(self.id_pracownik) + ';') self.model_u.setQuery(query) self.lbl_klient_.setText('') self.lbl_usluga_.setText('') if self.id_klient > 0 and self.id_pracownik > 0 and self.id_usluga > 0: self.btn_dodaj.setEnabled(True) def if_checked(self, txt, q, val=None): """ Sprawdza poprawność wprowadzonych damych. :param val: wartości do zapytania :param q: zapytanie query MySql :param txt: komunikat """ if self.id_klient < 0 and self.id_pracownik < 0 and self.id_usluga < 0 and self.data is None: msg = QMessageBox(self) msg.setIcon(QMessageBox.Warning) msg.setText(txt) msg.setWindowTitle("Popraw dane") msg.exec_() return False else: print('Trwa zmiana w bazie danych') if val: print('Połączenie') query_to_db(q, val) else: print('Transakcja') return transaction_to_db(q) return True def refresh(self): """ Odświeża widok tabeli rezerwacji """ # Odświeżanie widoku tabeli query = QSqlQuery( 'SELECT wizyty.wizyty_id, CONCAT(klienci.imie, " ", klienci.nazwisko) AS klient, uslugi.nazwa, ' 'wizyty.rezerwacja_od, wizyty.rezerwacja_do, wizyty.status FROM wizyty,klienci,uslugi WHERE wizyty.klienci_id= klienci.klienci_id AND wizyty.uslugi_id = uslugi.uslugi_id AND wizyty.rezerwacja_od > CURRENT_TIMESTAMP AND wizyty.uzytkownik_id = ' + str(self.id_pracownik) + ';') self.model.setQuery(query) self.view.reset() def add(self): """ Dodaje rezerwację do bazy danych i odświeża widok. """ tekst = 'Nie wprowadzono wszystkich danych' self.data = self.lbl_termin_.dateTime().toString(Qt.ISODate) self.data_do = datetime.datetime.fromisoformat( self.data) + datetime.timedelta( hours=datetime.time.fromisoformat(self.data_do).hour, minutes=datetime.time.fromisoformat(self.data_do).minute) # Dodanie nowego użytkownika query = 'INSERT INTO wizyty (klienci_id, uslugi_id, uzytkownik_id, rezerwacja_od, rezerwacja_do, ' \ 'status) VALUES (%s, %s, %s, %s, %s, %s);' val = (self.id_klient, self.id_usluga, self.id_pracownik, self.data, str(self.data_do.isoformat()), 'oczekuje') print(val) if self.if_checked(tekst, query, val): msg = QMessageBox(self) msg.setIcon(QMessageBox.Information) msg.setText('Rezerwacja została dodana do bazy danych') msg.setWindowTitle("Dodano nową rezerwację") msg.exec_() self.refresh() def modify(self): """ Zmienia status rezerwacji i odświeża widok. """ tekst = 'Nie wprowadzono wszystkich danych' items = ('Oczekuje', 'Wykonana', 'Rezygnacja') item, ok = QInputDialog.getItem(self, "Wybierz status", "Wybierz nowy status rezerwacji", items, 0, False) if ok and item: # Zmodyfikowanie statusu query = 'UPDATE wizyty SET status = %s WHERE wizyty_id = %s;' val = (item.lower(), self.id_rezerwacje) if self.if_checked(tekst, query, val): msg = QMessageBox(self) msg.setIcon(QMessageBox.Information) msg.setText('Status rezerwacji został zmodyfikowany') msg.setWindowTitle("Zmodyfikowano status") msg.exec_() self.refresh() def remove(self): """ Usuwa rezerwację z bazy danych """ test = 'Błąd! Nie można usunąć danej rezerwacji!' query = 'DELETE FROM wizyty WHERE wizyty_id = %s' val = (self.id_rezerwacje, ) ret = QMessageBox.question( self, 'Usuwanie rezerwacji', "Czy na pewno chcesz usunąć daną rezerwację klienta?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if ret == QMessageBox.Yes: if self.if_checked(test, query, val): msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText('Rezerwacja została usunięta') msg.setWindowTitle("Usunięto") msg.exec_() self.refresh() @pyqtSlot() def on_0_clicked(self): self.lbl_termin_.setTime(self.czas[0]) @pyqtSlot() def on_1_clicked(self): self.lbl_termin_.setTime(self.czas[1]) @pyqtSlot() def on_2_clicked(self): self.lbl_termin_.setTime(self.czas[2]) @pyqtSlot() def on_3_clicked(self): self.lbl_termin_.setTime(self.czas[3]) @pyqtSlot() def on_4_clicked(self): self.lbl_termin_.setTime(self.czas[4]) @pyqtSlot() def on_5_clicked(self): self.lbl_termin_.setTime(self.czas[5]) @pyqtSlot() def on_6_clicked(self): self.lbl_termin_.setTime(self.czas[6]) @pyqtSlot() def on_7_clicked(self): self.lbl_termin_.setTime(self.czas[7]) @pyqtSlot() def on_8_clicked(self): self.lbl_termin_.setTime(self.czas[8]) @pyqtSlot() def on_9_clicked(self): self.lbl_termin_.setTime(self.czas[9]) @pyqtSlot() def on_10_clicked(self): self.lbl_termin_.setTime(self.czas[10]) @pyqtSlot() def on_11_clicked(self): self.lbl_termin_.setTime(self.czas[11]) @pyqtSlot() def on_12_clicked(self): self.lbl_termin_.setTime(self.czas[12]) @pyqtSlot() def on_13_clicked(self): self.lbl_termin_.setTime(self.czas[13]) @pyqtSlot() def on_14_clicked(self): self.lbl_termin_.setTime(self.czas[14]) @pyqtSlot() def on_15_clicked(self): self.lbl_termin_.setTime(self.czas[15]) @pyqtSlot(str) def searching_u(self, text): """ Wyszukuje po wszystkich kolumnach tabeli :param text: """ search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp) self.proxy_u.setFilterRegExp(search) # Odpowiedzialne za kolumnę, po której filtruje self.proxy_u.setFilterKeyColumn(-1) @pyqtSlot(str) def searching_k(self, text): """ Wyszukuje po wszystkich kolumnach tabeli :param text: """ search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp) self.proxy_k.setFilterRegExp(search) # Odpowiedzialne za kolumnę, po której filtruje self.proxy_k.setFilterKeyColumn(-1) @pyqtSlot(str) def searching_p(self, text): """ Wyszukuje po wszystkich kolumnach tabeli :param text: """ search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp) self.proxy_p.setFilterRegExp(search) # Odpowiedzialne za kolumnę, po której filtruje self.proxy_p.setFilterKeyColumn(-1)
class Calendar(QMainWindow): """ A QCalendarWidget example """ def __init__(self): # create GUI QMainWindow.__init__(self) self.setWindowTitle('Calendar widget') # Set the window dimensions self.resize(800, 600) self.setMinimumSize(700, 500) exitAction = QAction(QIcon('exit.png'), '&Exit', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('Exit application') exitAction.triggered.connect(qApp.quit) openAction = QAction(QIcon('open.png'), '&Open', self) openAction.setShortcut('Ctrl+O') openAction.setStatusTip('Open') openAction.triggered.connect(self.open_chooser) self.statusBar() menubar = self.menuBar() fileMenu = menubar.addMenu('&File') fileMenu.addAction(openAction) fileMenu.addAction(exitAction) self.displayMenu = menubar.addMenu('&Display') pwrChecked = QAction('Power', self.displayMenu, checkable=True) cadChecked = QAction('Cadence', self.displayMenu, checkable=True) speedChecked = QAction('Speed', self.displayMenu, checkable=True) hrChecked = QAction('Heartrate', self.displayMenu, checkable=True) distanceChecked = QAction('Distance', self.displayMenu, checkable=True) self.displayMenu.addAction(pwrChecked) self.displayMenu.addAction(cadChecked) self.displayMenu.addAction(speedChecked) self.displayMenu.addAction(hrChecked) self.displayMenu.addAction(distanceChecked) pwrChecked.setChecked(True) cadChecked.setChecked(True) self.displayMenu.triggered.connect(self.updatePlot) # vertical layout for widgets vbox = QVBoxLayout() centralWidget = QWidget(self) centralWidget.setLayout(vbox) self.setCentralWidget(centralWidget) #set the central widget as a gridbox topLayout = QHBoxLayout() topWidget = QWidget(self) topWidget.setLayout(topLayout) #widget to hold calendar and time selection calSelLayout = QVBoxLayout() calSelWidget = QWidget(self) calSelWidget.setLayout(calSelLayout) # Create a calendar widget and add it to our layout self.cal = QCalendarWidget() self.cal.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) #calSelLayout.setAlignment(self.cal,Qt.AlignTop) #and create a texteditor to show the read file # self.textEdit = QTextEdit() # gridbox.addWidget(self.textEdit,0,1) timeSelLayout = QHBoxLayout() timeSelWidget = QWidget(self) timeSelWidget.setLayout(timeSelLayout) # Create the hours combobox self.hoursBox = QComboBox() self.hoursBox.addItems( ["12", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"]) self.hoursBox.setCurrentIndex(4) self.hoursBox.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) timeSelLayout.addWidget(self.hoursBox) # Create the minutes combo box self.minutesBox = QComboBox() self.minutesBox.addItems(["00", "15", "30", "45"]) self.minutesBox.setCurrentIndex(3) self.minutesBox.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) timeSelLayout.addWidget(self.minutesBox) # Create the Am/Pm combo box self.ampmBox = QComboBox() self.ampmBox.addItems(["AM", "PM"]) self.ampmBox.setCurrentIndex(1) self.ampmBox.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) timeSelLayout.addWidget(self.ampmBox) # Create a label which we will use to show the date a week from now self.lbl = QLabel() timeSelLayout.addWidget(self.lbl) calSelLayout.addWidget(self.cal) calSelLayout.addWidget(timeSelWidget) calSelLayout.setAlignment(timeSelWidget, Qt.AlignTop) topLayout.addWidget(calSelWidget) bottomLayout = QHBoxLayout() bottomWidget = QWidget(self) bottomWidget.setLayout(bottomLayout) bottomLayout.setAlignment(Qt.AlignRight) # Create a process button self.goButton = QPushButton('Convert to TCX') self.goButton.setEnabled(False) self.goButton.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) bottomLayout.addWidget(self.goButton) self.goButton.clicked.connect(self.DoWork) self.plotter = PlotCanvas() self.plotter.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) topLayout.addWidget(self.plotter) vbox.addWidget(topWidget) vbox.addWidget(bottomWidget) # Connect the clicked signal to the centre handler self.cal.selectionChanged.connect(self.date_changed) #self.connect(self.cal, QtCore.SIGNAL('selectionChanged()'), self.date_changed) self.outName = '' self.fileName = '' self.hours = (time.timezone if (time.localtime().tm_isdst == 0) else time.altzone) / 3600 self.minutes = 0 self.date_changed() self.statusBar().showMessage('Please open csv file') self.show() def output_name(self, iname): # validate name ends with .CSV if iname.lower().endswith(".csv"): prefix = iname[:-3] oname = prefix + "tcx" if not os.path.exists(oname): return oname else: msgbox = QMessageBox() msgbox.setText("File %s exists, overwrite?" % oname) msgbox.setStandardButtons(QMessageBox.Yes | QMessageBox.No) retval = msgbox.exec_() if retval == QMessageBox.Yes: os.remove(oname) return oname else: raise Exception( 'File %s already exists. Cannot continue.' % oname) else: raise Exception("%s does not end with .csv" % iname) def getCalendarTime(self): offset = (time.timezone if (time.localtime().tm_isdst == 0) else time.altzone) / 3600 self.hours = int(self.hoursBox.currentText()) + int(offset) if (self.ampmBox.currentText() == "PM"): self.hours += 12 if (self.hours >= 24): self.hours = self.hours - 24 self.minutes = int(self.minutesBox.currentText()) print(self.pydate) print(self.hours) print(self.minutes) print(datetime.time(self.hours, self.minutes)) dt = datetime.datetime.combine(self.pydate, datetime.time(self.hours, self.minutes)) return dt def DoWork(self): if self.fileName: try: self.workout.setStartTime(self.getCalendarTime()) except: print("Error setting start time") self.statusBar().showMessage('Error setting start time') try: self.outName = self.output_name(self.fileName) except: print("Error setting output name to " + self.outName) self.statusBar().showMessage('Error setting output name to ' + self.outName) try: tcx_writer(self.workout).writeTCX(self.outName) self.statusBar().showMessage('Success writing TCX: %s' % self.outName) Popen_arg = r'explorer /select, "' + self.outName.replace( '/', '\\') + '"' Popen(Popen_arg) except: print("Error creating file " + self.outName) self.statusBar().showMessage('Error creating file ' + self.outName) def date_changed(self): """ Handler called when the date selection has changed """ # Fetch the currently selected date, this is a QDate object self.date = self.cal.selectedDate() # This is a gives us the date contained in the QDate as a native # python date[time] object self.pydate = self.date.toPyDate() # Calculate the date a week from now # sevendays = timedelta(days=7) # aweeklater = self.pydate + sevendays # Show this date in our label self.lbl.setText('The selected date is: %s' % self.pydate) def get_date(self): return self.date def openFileNameDialog(self): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getOpenFileName( self, "QFileDialog.getOpenFileName()", "", "CSV files (*.csv);;All Files (*)", options=options) if fileName: print(fileName) return fileName def open_chooser(self): self.fileName = self.openFileNameDialog() if self.fileName: self.workout = StagesWorkout(self.fileName, self.getCalendarTime()) self.plotter.setWorkout(self.workout) self.goButton.setEnabled(True) self.statusBar().showMessage( 'Successfully read %i stages in %s' % (len(self.workout.stages), self.fileName)) self.updatePlot() def updatePlot(self): actions = [] for action in self.displayMenu.actions(): if action.isChecked(): actions.append(action.text()) print(actions) self.plotter.plot(actions)