class SqlModel(object): def __init__(self,databasetype="QSQLITE",databasename="data.db",sqltablename="里程碑"): db=QSqlDatabase.addDatabase(databasetype) db.setDatabaseName(databasename) self.sqltablename=sqltablename self.__tablemodel() def __tablemodel(self): self.model=QSqlTableModel() self.model.setTable(self.sqltablename) self.model.setEditStrategy(QSqlTableModel.OnFieldChange) self.model.select() def modelview(self): self.view=QTableView() self.view.setModel(self.model) # modelwidget=QTabWidget() # modelwidget.addTab(self.view, viewname) return self.view def tabadd(self): row = self.model.rowCount() self.model.insertRow(row) index = self.model.index(row) self.view.setCurrentIndex(index) self.view.edit(index) def tabdel(self): index = self.modelview().currentIndex() print(index) # self.model.removeRow(index.row()) def tabupdate(self): self.model.updateRowInTable() def row(self): row=self.model.rowCount() return row def line(self): line=self.model.columnCount() return line def rowvalue(self): rowvalue=self.model.insertRowIntoTable(QSqlRecord="") def data(self): self.model.data() def run(self,WindowTitle= "data"): app = QApplication(sys.argv) dig=QDialog() layout=QHBoxLayout() layout.addWidget(self.modelview()) dig.setLayout(layout) dig.setWindowTitle(WindowTitle) dig.resize(430,450) # dig.hide() # time.sleep(10) dig.show() sys.exit(app.exec_())
class NarzPoz(QWidget): def __init__(self, parent): super(QWidget, self).__init__(parent) self.pozycja = 'Brak' self.proxy = QSortFilterProxyModel(self) self.proxy_poz = QSortFilterProxyModel(self) self.edit_wysz = QLineEdit(self) self.combo_typ = QComboBox(self) self.lbl_wysz = QLabel("Wyszukaj") self.lbl_typ = QLabel("Wybierz typ narzędzia:") self.combo_poz = QComboBox(self) self.lbl_poz = QLabel("Wybierz pozycję:") self.listaPozycji = [] self.table = QTableView(self) self.table_narz = QTableView(self) sciezka = czy_istnieje() db = QSqlDatabase.addDatabase('QSQLITE') db.setDatabaseName(sciezka) if db.open(): print('Otworzono bazę danych') self.model = QSqlTableModel(self, db) self.model_poz = QSqlTableModel(self, db) self.parent = parent self.formularz = QGroupBox("Przypisz narzędzia") self.initUI() def initUI(self): self.naglowki_kolumn() # todo dodać okno z wyborem oprawki po wyborze narzędzia typy_narzedzi = [ 'Brak', 'Frez palcowy', 'Frez płytkowy (głowica)', 'Gwintownik', 'Nóż tokarski', # 'Oprawka', 'Piła', 'Pozostałe', 'Rozwiertak', 'Wiertło', 'Wiertło składane', 'Wygniatak' ] self.widok() # Zatwierdzenie ok_button = QPushButton("Dodaj do pozycji") cancel_button = QPushButton("Cofnij") wydrukuj_btn = QPushButton("Wyeksportuj") usun_btn = QPushButton("Usuń pozycję") dodaj_btn = QPushButton("Dodaj pozycję") hbox = QHBoxLayout() hbox.addStretch(1) hbox.addWidget(ok_button) hbox.addWidget(cancel_button) # Layouty layout_v = QVBoxLayout() l_1 = QHBoxLayout() l_2 = QHBoxLayout() l_3 = QHBoxLayout() layout_h = QHBoxLayout() # Funkcje self.combo_typ.addItems(typy_narzedzi) self.combo_poz.addItems(self.listaPozycji) self.proxy_poz.setSourceModel(self.model_poz) self.table.setModel(self.proxy_poz) self.proxy.setSourceModel(self.model) self.table_narz.setModel(self.proxy) # Przyporzadkowanie l_1.addWidget(self.lbl_typ) l_1.addWidget(self.combo_typ) l_2.addWidget(self.lbl_wysz) l_2.addWidget(self.edit_wysz) l_3.addWidget(wydrukuj_btn) l_3.addWidget(usun_btn) l_3.addWidget(dodaj_btn) layout_h.addWidget(self.lbl_poz) layout_h.addWidget(self.combo_poz) layout_v.addLayout(layout_h, 1) layout_v.addLayout(l_1) layout_v.addLayout(l_2) layout_v.addLayout(l_3) layout_v.addWidget(self.table) layout_v.addWidget(self.table_narz) self.formularz.setLayout(layout_v) main_layout = QVBoxLayout() main_layout.addWidget(self.formularz) main_layout.addLayout(hbox) self.setLayout(main_layout) # connecty # ok_button.clicked.connect(self.dodaj) cancel_button.clicked.connect(self.anulowanie) dodaj_btn.clicked.connect(self.dodaj_poz) ok_button.clicked.connect(self.klikniecie) usun_btn.clicked.connect(self.usun_pozycje) wydrukuj_btn.clicked.connect(self.wydrukuj) self.edit_wysz.textChanged.connect(self.wyszukiwanie) self.combo_typ.activated[str].connect(self.onActiveNarz) self.combo_poz.activated[str].connect(self.onActivePoz) # Menu kontekstowe własne self.table.setContextMenuPolicy(Qt.CustomContextMenu) self.table.customContextMenuRequested.connect(self.prawoklik) def wydrukuj(self): poz_lista = [ 'Wykaz narzędzi ' + self.pozycja, "SELECT * FROM '" + self.pozycja + "'", 'Baza nie zawiera żadnych pozycji. Plik nie zostanie zapisany.', ] from gui import Window if self.pozycja != 'Brak': Window.export(self, poz_lista) self.parent.statusBar().showMessage("Wyeksportowano do pliku", 10000) else: QMessageBox.critical(self, 'Wybierz pozycję', 'Nie wybrano żadnej pozycji!', QMessageBox.Ok, QMessageBox.Ok) def naglowki_kolumn(self): # Nagłówki kolumn self.listaPozycji.append('Brak') for i in naglowki(): if "/" in i[0]: self.listaPozycji.append(i[0]) def usun_pozycje(self): text, ok = QInputDialog.getItem(self, 'Usuń pozycje', 'Wybierz pozycję do usunięcia', self.listaPozycji[1:], editable=False) if ok: if text != 'Brak': print(text) query = 'DROP TABLE "main"."' + text + '";' polaczenie(query) self.listaPozycji.clear() self.naglowki_kolumn() indeks = self.combo_poz.findText(text) self.combo_poz.removeItem(indeks) self.parent.statusBar().showMessage("Usunięto pozycję", 10000) else: msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setWindowIcon(QIcon('icons/cow.png')) msg.setText("Wybierz poprawną pozycję") msg.setWindowTitle("Niewłaściwa pozycja") msg.exec_() self.usun_pozycje() def prawoklik(self): menu = QMenu(self) akcja = QAction('Usuń narzędzie', self) akcja.triggered.connect(self.usun_wiersz) menu.addAction(akcja) menu.exec_(QCursor.pos()) def usun_wiersz(self): selected = self.table.currentIndex() self.model_poz.removeRow(selected.row()) self.model_poz.submitAll() self.model_poz.select() self.parent.statusBar().showMessage("Usunięto narzędzie", 10000) def dodaj_poz(self): text, ok = QInputDialog.getText(self, 'Wprowadź pozycje', 'Pozycja:') if ok and text: query = 'CREATE TABLE IF NOT EXISTS "' + text + '" ("id_poz" INTEGER PRIMARY ' \ 'KEY AUTOINCREMENT, ' \ '"symbol_narz" TEXT, ' \ '"vc" INTEGER, "obroty" ' \ 'INTEGER, "fz" REAL, "posuw" ' \ 'INTEGER); ' print(query) polaczenie(query) self.listaPozycji.clear() self.combo_poz.addItem(text) self.naglowki_kolumn() self.parent.statusBar().showMessage("Dodano pozycję " + text, 10000) else: print("Nie wpisano pozycji") def onActivePoz(self, tekst): self.pozycja = tekst naglowki = { 'id_poz': 'ID', 'symbol_narz': 'Symbol narzędzia', 'vc': 'Prędkość skrawania Vc [m/min]', 'obroty': 'Obroty n [obr/min]', 'fz': 'Posuw na ząb fz [mm/ostrze]', 'posuw': 'Posuw liniowy f [mm/min]' } self.model_poz.setTable(tekst) self.model_poz.setEditStrategy(QSqlTableModel.OnFieldChange) self.model_poz.select() # Ustawianie nagłówków ilosc_kolumn = self.model_poz.columnCount() for i in range(ilosc_kolumn): nazwa_kolumn = self.model_poz.headerData(i, Qt.Horizontal) self.model_poz.setHeaderData(i, Qt.Horizontal, naglowki[nazwa_kolumn]) def onActiveNarz(self, tekst): slownik = { 'Frez palcowy': 'frezy_palcowe', 'Frez płytkowy (głowica)': 'frezy_plytkowe', 'Gwintownik': 'gwintowniki', 'Nóż tokarski': 'noze_tokarskie', 'Oprawka': 'oprawki', 'Piła': 'pily', 'Pozostałe': 'pozostale', 'Rozwiertak': 'rozwiertaki', 'Wiertło': 'wiertla', 'Wiertło składane': 'wiertla_skladane', 'Wygniatak': 'wygniataki', 'Brak': '' } naglowki = { 'idfrezy_palcowe': 'ID', 'symbol_freza': 'Symbol', 'producent_fr': 'Producent', 'srednica_fr': 'Średnica', 'dl_fr': 'Długość całkowita', 'dl_rob_fr': 'Długość robocza', 'idfrezy_plytkowe': 'ID', 'symbol_frez_pl': 'Symbol', 'producent_fp': 'Producent', 'srednica_fr_pl': 'Średnica', 'ilosc_plytek': 'Ilość płytek', 'symbol_pl': 'Symbol płytek', 'ilosc_krawedzi_pl': 'Ilość krawędzi płytki', 'idgwintowniki': 'ID', 'symbol_g': 'Symbol', 'producent_gw': 'Producent', 'rozmiar_gwintu': 'Rozmiar gwintu i skok', 'typ_gwintownika': 'Typ gwintownika', 'idnoze_tokarskie': 'ID', 'symbol_n': 'Symbol', 'producent_n': 'Producent', 'plytki_n': 'Symbol płytek', 'ilosc_krawedzi_pl_n': 'Ilość krawędzi', 'idpily': 'ID', 'symbol_p': 'Symbol', 'producent_pil': 'Producent', 'srednica_p': 'Średnica', 'grubosc_p': 'Grubość', 'rodzaj_pl_p': 'Symbol płytek', 'ilosc_pl_p': 'Ilość płytek', 'ilosc_kraw_p': 'Ilość krawędzi płytki', 'idpozostale': 'ID', 'symbol_poz': 'Symbol', 'producent_poz': 'Producent', 'srednica_poz': 'Średnica', 'ilosc_pl_poz': 'Ilość płytek', 'plytki_poz': 'Symbol płytek', 'idrozwiertaki': 'ID', 'symbol_r': 'Symbol', 'producent_roz': 'Producent', 'rozmiar_r': 'Rozmiar', 'idwiertla': 'ID', 'symbol_w': 'Symbol', 'producent_w': 'Producent', 'srednica_w': 'Średnica', 'dlugosc_w': 'Długość [mm]', 'idwiertla_skladane': 'ID', 'symbol_w_skl': 'Symbol', 'producent_ws': 'Producent', 'srednica_w_skl': 'Średnica', 'plytki_w_skl': 'Symbol płytek', 'idwygniataki': 'ID', 'symbol_wyg': 'Symbol', 'producent_wyg': 'Producent', 'rozmiar_gw': 'Rozmiar gwintu' } self.model.setTable(slownik[tekst]) self.model.setEditStrategy(QSqlTableModel.OnManualSubmit) self.model.select() # 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]) @pyqtSlot(str) def wyszukiwanie(self, text): search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp) self.proxy.setFilterRegExp(search) # Odpowiedzialne za kolumnę, po której filtruje self.proxy.setFilterKeyColumn(-1) # opcja z wyszukiwaniem def widok(self): # Ustawianie własciwości widoku self.table_narz.setEditTriggers(QAbstractItemView.NoEditTriggers) self.table_narz.setSelectionMode(QAbstractItemView.SingleSelection) self.table_narz.setSelectionBehavior(QAbstractItemView.SelectRows) self.table_narz.verticalHeader().setVisible(False) self.table_narz.setSortingEnabled(True) self.table_narz.setModel(self.model) self.table.verticalHeader().setVisible(False) self.table.setSortingEnabled(True) self.table.setAlternatingRowColors(True) self.table.setModel(self.model_poz) # self.table.hideColumn(0) self.table_narz.doubleClicked.connect(self.klikniecie) @pyqtSlot() def klikniecie(self): x = self.table_narz.currentIndex().row() y = self.table_narz.currentIndex().column() nazwa = self.table_narz.currentIndex().sibling(x, 1).data() print(nazwa) # Dodanie narzędzia do pozycji if nazwa: print(nazwa) query = "INSERT INTO '" + self.model_poz.tableName( ) + "'(symbol_narz) VALUES ('" + nazwa + "') " polaczenie(query) # Odświeża tabelę self.model_poz.select() self.parent.statusBar().showMessage( "Dodano narzędzie " + nazwa + " do pozycji " + self.model_poz.tableName(), 10000) else: print(self.model_poz.tableName()) print("Brak wybranego narzędzia") def anulowanie(self): self.parent.statusBar().clearMessage() from opcje_qt import Wewnatrz menu_gl = Wewnatrz(self.parent) self.parent.setCentralWidget(menu_gl)
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 Employee(QWidget): """ Klasa odpowiedzialna za widget Zmiany hasła """ def __init__(self, parent, db): super(QWidget, self).__init__(parent) self.btn_usun = QPushButton('Usuń') self.btn_modyfikuj = QPushButton('Modyfikuj') self.id_modify = -1 self.view = QTableView() self.cb_pracownik = QCheckBox('Pracownik') self.txt_login = QLineEdit() self.txt_nazwisko = QLineEdit() self.txt_imie = QLineEdit() self.parent = parent self.layout = QHBoxLayout() self.lbl_wysz = QLabel("Wyszukaj:") self.txt_wysz = QLineEdit(self) self.proxy = QSortFilterProxyModel(self) # Parametry połączenia z bazą self.model = QSqlTableModel(self, db) self.initUI() def initUI(self): """ Inicjuje UI """ fbox = QFormLayout() fbox.addRow(self.lbl_wysz, self.txt_wysz) self.txt_wysz.textChanged.connect(self.searching) self.table_init() # Pokazuje wszystko # self.model.select() group_box = QGroupBox("Edycja danych użytkownika") fbox2 = QFormLayout() lbl_imie = QLabel('Imię:') lbl_nazwisko = QLabel('Nazwisko:') lbl_login = QLabel('Login:'******'Dodaj') self.btn_modyfikuj.setDisabled(True) self.btn_usun.setDisabled(True) fbox2.addRow(lbl_imie, self.txt_imie) fbox2.addRow(lbl_nazwisko, self.txt_nazwisko) fbox2.addRow(lbl_login, self.txt_login) fbox2.addRow(self.cb_pracownik) lhbox = QHBoxLayout() lhbox.addWidget(self.btn_usun) lhbox.addSpacing(35) lhbox.addWidget(self.btn_modyfikuj) lhbox.addSpacing(35) lhbox.addWidget(btn_dodaj) fbox2.addRow(lhbox) group_box.setLayout(fbox2) fbox.addRow(group_box) # Formatka dni self.group_box_dni = QGroupBox('Godziny pracy') fbox_dni = QFormLayout() lhbox_pon = QHBoxLayout() lhbox_wt = QHBoxLayout() lhbox_sr = QHBoxLayout() lhbox_czw = QHBoxLayout() lhbox_pt = QHBoxLayout() lhbox_sob = QHBoxLayout() lbl_pon = QLabel('Poniedziałek') lbl_wt = QLabel('Wtorek') lbl_sr = QLabel('Środa') lbl_czw = QLabel('Czwartek') lbl_pt = QLabel('Piątek') lbl_sob = QLabel('Sobota') self.txt_pon_od = QLineEdit() self.txt_pon_do = QLineEdit() self.txt_wt_od = QLineEdit() self.txt_wt_do = QLineEdit() self.txt_sr_od = QLineEdit() self.txt_sr_do = QLineEdit() self.txt_czw_od = QLineEdit() self.txt_czw_do = QLineEdit() self.txt_pt_od = QLineEdit() self.txt_pt_do = QLineEdit() self.txt_sob_od = QLineEdit() self.txt_sob_do = QLineEdit() self.pola = (self.txt_pon_od, self.txt_pon_do, self.txt_wt_od, self.txt_wt_do, self.txt_sr_od, self.txt_sr_do, self.txt_czw_od, self.txt_czw_do, self.txt_pt_od, self.txt_pt_do, self.txt_sob_od, self.txt_sob_do) lhbox_pon.addWidget(self.txt_pon_od) lhbox_pon.addSpacing(30) lhbox_pon.addWidget(self.txt_pon_do) lhbox_wt.addWidget(self.txt_wt_od) lhbox_wt.addSpacing(30) lhbox_wt.addWidget(self.txt_wt_do) lhbox_sr.addWidget(self.txt_sr_od) lhbox_sr.addSpacing(30) lhbox_sr.addWidget(self.txt_sr_do) lhbox_czw.addWidget(self.txt_czw_od) lhbox_czw.addSpacing(30) lhbox_czw.addWidget(self.txt_czw_do) lhbox_pt.addWidget(self.txt_pt_od) lhbox_pt.addSpacing(30) lhbox_pt.addWidget(self.txt_pt_do) lhbox_sob.addWidget(self.txt_sob_od) lhbox_sob.addSpacing(30) lhbox_sob.addWidget(self.txt_sob_do) fbox_dni.addRow(lbl_pon, lhbox_pon) fbox_dni.addRow(lbl_wt, lhbox_wt) fbox_dni.addRow(lbl_sr, lhbox_sr) fbox_dni.addRow(lbl_czw, lhbox_czw) fbox_dni.addRow(lbl_pt, lhbox_pt) fbox_dni.addRow(lbl_sob, lhbox_sob) group_box_szablon = QGroupBox('Szablony') btn1 = QPushButton('7-15') btn2 = QPushButton('8-16') btn3 = QPushButton('9-17') btn4 = QPushButton('10-18') vbox = QVBoxLayout() vbox.addWidget(btn1) vbox.addWidget(btn2) vbox.addWidget(btn3) vbox.addWidget(btn4) group_box_szablon.setLayout(vbox) hbox_dni = QHBoxLayout() hbox_dni.addLayout(fbox_dni) hbox_dni.addWidget(group_box_szablon) self.group_box_dni.setLayout(hbox_dni) fbox.addRow(self.group_box_dni) self.group_box_dni.setVisible(False) self.view.clicked.connect(self.change) btn_dodaj.clicked.connect(self.add) self.btn_modyfikuj.clicked.connect(self.modify) self.btn_usun.clicked.connect(self.remove) self.cb_pracownik.stateChanged.connect(self.changeGroupBox) btn1.clicked.connect(lambda: self.hour(7)) btn2.clicked.connect(lambda: self.hour(8)) btn3.clicked.connect(lambda: self.hour(9)) btn4.clicked.connect(lambda: self.hour(10)) self.layout.addLayout(fbox) self.layout.addWidget(self.view) self.setLayout(self.layout) self.show() def hour(self, godz): """ Wypełnia godzinami odpowiednie pola :param godz: int godzina rozpoczęcia """ for i, value in enumerate(self.pola): if i % 2 == 0: value.setText(str(timedelta(hours=godz))) else: value.setText(str(timedelta(hours=godz + 8))) def changeGroupBox(self, state): """ Sprawdza, czy zaznaczono checkbox pracownik :param state: status pola pracownik """ if state == Qt.Checked: self.group_box_dni.setVisible(True) else: self.group_box_dni.setVisible(False) def table_init(self): """ Inicjuje wygląd tabeli """ self.model.setTable('uzytkownik') query = QSqlQuery( 'SELECT uzytkownik_id, uzytkownik_nazwa, imie, nazwisko, pracownik FROM uzytkownik;' ) self.model.setQuery(query) self.proxy.setSourceModel(self.model) naglowki = { 'uzytkownik_id': 'ID', 'uzytkownik_nazwa': 'Login', 'imie': 'Imię', "nazwisko": 'Nazwisko', 'pracownik': 'Pracownik', } # 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]) # TODO Poprawić wiywietlanie kolumny Pracownik 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(1, Qt.AscendingOrder) self.view.setEditTriggers(QAbstractItemView.NoEditTriggers) 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 len(self.txt_imie.text()) < 2 or len( self.txt_nazwisko.text()) < 2 or len( self.txt_login.text()) < 5: msg = QMessageBox() 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) # Odświeżanie widoku tabeli self.model.select() self.view.reset() return True def employee_type(self): """ Sprawdza, czy dana osoba jest pracownikiem, czy nie. :return: int Pracownik """ return 1 if self.cb_pracownik.checkState() else 0 def add(self): """ Dodaje nową osobę do bazy danych i odświeża widok. """ tekst = "Dane zostały błędnie wprowadzone.\nLogin musi mieć minimum 5 znaków." # Dodanie nowego użytkownika query1 = 'INSERT INTO uzytkownik (imie, nazwisko, uzytkownik_nazwa, haslo, pracownik) VALUES (%s, %s, %s, ' \ 'sha(%s), %s)' val1 = (self.txt_imie.text(), self.txt_nazwisko.text(), self.txt_login.text(), self.txt_login.text(), self.employee_type()) # Dodanie godzin do pracownika if self.cb_pracownik.checkState(): query2 = 'INSERT INTO godziny (uzytkownik_id, pon_od, pon_do, wt_od, wt_do, sr_od, sr_do, czw_od, czw_do, pt_od, pt_do, sob_od, sob_do) VALUES (LAST_INSERT_ID(),"' + self.txt_pon_od.text( ) + '","' + self.txt_pon_do.text() + '","' + self.txt_wt_od.text( ) + '","' + self.txt_wt_do.text() + '","' + self.txt_sr_od.text( ) + '","' + self.txt_sr_do.text() + '","' + self.txt_czw_od.text( ) + '","' + self.txt_czw_do.text() + '","' + self.txt_pt_od.text( ) + '","' + self.txt_pt_do.text() + '","' + self.txt_sob_od.text( ) + '","' + self.txt_sob_do.text() + '");' val2 = None else: query2 = None val2 = None if self.if_checked(tekst, [(query1, val1), (query2, val2)]): msg = QMessageBox(self) msg.setIcon(QMessageBox.Information) msg.setText('Dodano nowego użytkownika') msg.setWindowTitle("Dodano użytkownika") msg.exec_() else: msg = QMessageBox(self) msg.setIcon(QMessageBox.Warning) msg.setText('Dany użytkownik istnieje już w bazie') msg.setWindowTitle("Błąd!") msg.exec_() # Odświeżanie widoku tabeli self.model.select() self.view.reset() def modify(self): """ Modyfikuje bazę danych """ query = 'SELECT * FROM godziny WHERE uzytkownik_id = %s' val = (self.id_modify, ) wynik = query_to_db(query, val) test = 'Dane zostały błędnie zmodyfikowane.' query = 'UPDATE uzytkownik SET imie = %s, nazwisko = %s, uzytkownik_nazwa = %s, ' \ 'pracownik = %s WHERE uzytkownik_id = %s' val = (self.txt_imie.text(), self.txt_nazwisko.text(), self.txt_login.text(), self.employee_type(), self.id_modify) self.if_checked(test, query, val) if wynik and self.cb_pracownik.checkState(): query = 'UPDATE godziny SET pon_od = %s, pon_do = %s, wt_od = %s, wt_do = %s, sr_od = %s, sr_do = %s, ' \ 'czw_od = %s, czw_do = %s, pt_od = %s, pt_do = %s, sob_od = %s, sob_do = %s WHERE uzytkownik_id = %s;' val = (self.txt_pon_od.text(), self.txt_pon_do.text(), self.txt_wt_od.text(), self.txt_wt_do.text(), self.txt_sr_od.text(), self.txt_sr_do.text(), self.txt_czw_od.text(), self.txt_czw_do.text(), self.txt_pt_od.text(), self.txt_pt_do.text(), self.txt_sob_od.text(), self.txt_sob_do.text(), self.id_modify) query_to_db(query, val) elif self.cb_pracownik.checkState(): query = 'INSERT INTO godziny SET uzytkownik_id = %s, pon_od = %s, pon_do = %s, wt_od = %s, wt_do = %s, ' \ 'sr_od = %s, ' \ 'sr_do = %s, ' \ 'czw_od = %s, czw_do = %s, pt_od = %s, pt_do = %s, sob_od = %s, sob_do = %s; ' val = (self.id_modify, self.txt_pon_od.text(), self.txt_pon_do.text(), self.txt_wt_od.text(), self.txt_wt_do.text(), self.txt_sr_od.text(), self.txt_sr_do.text(), self.txt_czw_od.text(), self.txt_czw_do.text(), self.txt_pt_od.text(), self.txt_pt_do.text(), self.txt_sob_od.text(), self.txt_sob_do.text()) query_to_db(query, val) msg = QMessageBox(self) msg.setIcon(QMessageBox.Information) msg.setText('Zmodyfikowano dane użytkownika') msg.setWindowTitle("Zmodyfikowano użytkownika") msg.exec_() # Odświeżanie widoku tabeli self.model.select() self.view.reset() def remove(self): """ Usuwa dane z bazy danych """ test = 'Błąd! Nie można usunąć danego użytkownika!' query1 = 'DELETE FROM uzytkownik WHERE uzytkownik_id = %s' val = (self.id_modify, ) query2 = 'DELETE FROM godziny WHERE uzytkownik_id = %s' query3 = 'DELETE FROM uzytkownik_usluga WHERE uzytkownik_id = %s' query4 = 'DELETE FROM wizyty WHERE uzytkownik_id = %s' if self.id_modify == 1: msg = QMessageBox() msg.setIcon(QMessageBox.Critical) msg.setText('Błąd! Nie można usunąć domyślnego użytkownika') msg.setWindowTitle("Popraw dane") msg.exec_() else: ret = QMessageBox.question( self, 'Usuwanie użytkownika', "Czy na pewno chcesz usunąć danego użytkownika?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if ret == QMessageBox.Yes: if self.if_checked(test, [(query4, val), (query3, val), (query2, val), (query1, val)]): msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText('Użytkownik został usunięty') msg.setWindowTitle("Usunięto") msg.exec_() self.txt_imie.setText('') self.txt_login.setText('') self.txt_nazwisko.setText('') if self.cb_pracownik.checkState(): self.cb_pracownik.toggle() # Odświeżanie widoku tabeli self.model.select() self.view.reset() def change(self): """ Metoda edytująca zaznaczone wiersze - Wstawia wartości z wierszy w odpowiednie pola """ index = (self.view.selectionModel().currentIndex()) value = index.sibling(index.row(), index.column()).data() self.id_modify = index.sibling(index.row(), 0).data() self.txt_imie.setText(index.sibling(index.row(), 2).data()) self.txt_nazwisko.setText(index.sibling(index.row(), 3).data()) self.txt_login.setText(index.sibling(index.row(), 1).data()) if self.id_modify >= 0 and self.txt_imie.text( ) and self.txt_login.text() and self.txt_nazwisko.text(): self.btn_modyfikuj.setEnabled(True) self.btn_usun.setEnabled(True) else: self.btn_usun.setDisabled(True) self.btn_modyfikuj.setDisabled(True) if index.sibling(index.row(), 4).data() == 1: if not self.cb_pracownik.checkState(): self.cb_pracownik.toggle() else: if self.cb_pracownik.checkState(): for value in self.pola: value.setText('') self.cb_pracownik.toggle() if self.cb_pracownik.checkState(): query = 'SELECT * FROM godziny WHERE uzytkownik_id = %s' val = (self.id_modify, ) wynik = query_to_db(query, val) for i, value in enumerate(self.pola, 2): if wynik: value.setText(str(wynik[i])) else: value.setText('') @pyqtSlot(str) def searching(self, text): """ Wyszukuje po wszystkich kolumnach tabeli :param text: """ search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp) self.proxy.setFilterRegExp(search) # Odpowiedzialne za kolumnę, po której filtruje self.proxy.setFilterKeyColumn(-1)
class TablePage(QWidget): exportSignal = QtCore.pyqtSignal(object) def __init__(self, db, table_name, condition, crossTable=False): """当crossTable为False时,为单张表查看,可读可写,table_name为表名,condition为过滤条件 当crossTable为True时,为同类型多张表查询,只可以读不可以写,table_name为表类型名,condition为过滤条件""" super(QWidget, self).__init__() self.exportSignal.connect(self.exportSlot) self.db = db if self.db.open(): # 开启数据库连接 logging.info("db is open") else: logging.critical("db is not open!!!") err = self.db.lastError() logging.critical(err.text()) logging.critical(QtSql.QSqlDatabase.drivers()) logging.critical(QApplication.libraryPaths()) self.__table_name = table_name self.__crossTable = crossTable self.__dm = DataManager() if crossTable: self.model = QSqlQueryModel(self) for section, value in enumerate( ['id'] + ExcelCheck.headers[table_name]): # 设置表头为该类型表的表头,包括id self.model.setHeaderData(section, Qt.Horizontal, value) if condition == "": query = " union ".join([ f"select * from {t}" for t in self.__dm.get_my_tables(table_name) ]) else: query = " union ".join([ f"select * from {t} where {condition}" for t in self.__dm.get_my_tables(table_name) ]) print(query) try: self.model.setQuery(query, self.db) except Exception as e: logging.exception(e) QMessageBox.warning(self, "查询出错", str(e)) else: self.model = QSqlTableModel(self, db=self.db) self.model.setTable(table_name) self.model.setFilter(condition) self.model.select() tableView = QTableView() tableView.setModel(self.model) layout = QGridLayout() layout.addWidget(tableView) self.setLayout(layout) def exportToExcel(self, filePath): # 填写表头list if self.__crossTable: header = ["id"] + ExcelCheck.headers[self.__table_name] # 在前面加上id列 else: header = self.__dm.get_column_names(table_name=self.__table_name) # 确定s_num集合 s_num = set() for i, name in enumerate(header): if name in ["发票号码"]: # 属于s_num的列 s_num.add(i) # 填写表格内容二维数组 content = [["" for c in range(self.model.columnCount())] for r in range(self.model.rowCount())] for i in range(self.model.rowCount()): for j in range(self.model.columnCount()): content[i][j] = self.model.index(i, j).data() print(header) print(content) logging.info("正在启动子线程") # 设置成为守护主线程,主线程退出后子线程直接销毁不再执行子线程的代码 threading.Thread(target=self.writeToExcelWork, args=(filePath, header, content, s_num), daemon=True).start() def writeToExcelWork(self, filePath, header, content, s_num): try: logging.info("子线程已启动,正在调用Easyexcel进行导出") pythoncom.CoInitialize() excel = Easyexcel(filepath=filePath, visible=False) logging.info("Easyexcel对象创建成功,正在写入") excel.set_sheet("Sheet1", header, content, s_num) logging.info("数据写入完成,正在关闭Easyexcel对象") excel.close() logging.info("Easyexcel已正常关闭") self.exportSignal.emit("文件已导出,路径为" + filePath) except Exception as e: logging.exception(e) self.exportSignal.emit(e) def exportSlot(self, info): if isinstance(info, str): QMessageBox.information(self, "文件已导出", info) elif isinstance(info, Exception): QMessageBox.warning(self, "文件导出出错", str(info))
class View(QtWidgets.QTableView): def __init__(self, name, parent=None): QtWidgets.QTableView.__init__(self, parent) #设置所有表的基本信息 getDBs = (self.getLocalDB,self.getLocalDB, self.getLocalDB\ ,self.getServerDB,self.getLocalDB,\ self.getLocalDB,self.getLocalDB,self.getLocalDB) #建立基本结构 self.viewId = viewNames.index(name) self.db = getDBs[self.viewId](name) self.model = QSqlTableModel(self, self.db) self.setModel(self.model) self.show() print(self.model.lastError().text()) #添加属性 self.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection) self.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) self.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) def getKeys(self): indexs = self.selectedIndexes() rowCnt = int(len(indexs) / self.model.columnCount()) indexs = numpy.array(indexs).reshape(rowCnt, self.model.columnCount()) values = [] values_temp = [] for index in indexs: values_temp = [] for keyColumn in keyColumns[self.viewId]: values_temp.append(self.model.data(index[keyColumn])) if len(keyColumns[self.viewId]) == 1: values.append(values_temp[0]) else: values.append(tuple(values_temp)) return tuple(values) def filter(self, *args): if self.viewId == 3: #如果是examExamServer的话,为了添加is_download,必须把本地exam的ids作为形参输入 keys = getKeysExamExamLocal() args = list(args) args.append(keys) self.query = QSqlQuery(getQuerys[self.viewId](*args), self.db) self.model.setQuery(self.query) print(self.model.lastError().text()) self.update() def getLocalDB(self, dbName): db = QSqlDatabase.addDatabase("QPSQL", dbName + '%f' % random.random()) #db = QSqlDatabase.addDatabase("QPSQL",dbName) db.setHostName(config.localDBHost) db.setPort(config.localDBPort) db.setDatabaseName(config.localDBName) db.setUserName(config.localDBUser) db.setPassword(config.localDBPasswd) if (db.open() == False): QtWidgets.QMessageBox.critical(None, "Database Error", db.lastError().text()) return db def getServerDB(self, dbName): db = QSqlDatabase.addDatabase("QPSQL", dbName) db.setHostName(config.serverDBHost) db.setPort(config.serverDBPort) db.setDatabaseName(config.serverDBName) db.setUserName(config.serverDBUser) db.setPassword(config.serverDBPasswd) if (db.open() == False): QtWidgets.QMessageBox.critical(None, "Database Error", db.lastError().text()) return db
class Wyswietl(QWidget): def __init__(self, parent): super(QWidget, self).__init__(parent) self.parent = parent self.proxy = QSortFilterProxyModel(self) self.edit_wysz = QLineEdit(self) self.combo_typ = QComboBox(self) self.lbl_wysz = QLabel("Wyszukaj") self.lbl_typ = QLabel("Wybierz typ narzędzia:") self.table = QTableView(self) sciezka = czy_istnieje() db = QSqlDatabase.addDatabase('QSQLITE') db.setDatabaseName(sciezka) if db.open(): print('Otworzono bazę danych') self.model = QSqlTableModel(self, db) self.formularz = QGroupBox("Wyświetl narzędzia") self.initUI() def initUI(self): typy_narzedzi = [ 'Brak', 'Frez palcowy', 'Frez płytkowy (głowica)', 'Gwintownik', 'Nóż tokarski', # 'Oprawka', 'Piła', 'Pozostałe', 'Rozwiertak', 'Wiertło', 'Wiertło składane', 'Wygniatak' ] self.widok() self.combo_typ.addItems(typy_narzedzi) cancel_button = QPushButton("Cofnij") hbox = QHBoxLayout() hbox.addStretch(1) hbox.addWidget(cancel_button) l_h = QHBoxLayout() l_h.addWidget(self.lbl_typ) l_h.addWidget(self.combo_typ) l_h2 = QHBoxLayout() l_h2.addWidget(self.lbl_wysz) l_h2.addWidget(self.edit_wysz) layout_v = QVBoxLayout() layout_v.addLayout(l_h) layout_v.addLayout(l_h2) layout_v.addWidget(self.table) self.proxy.setSourceModel(self.model) self.table.setModel(self.proxy) main_layout = QVBoxLayout() self.formularz.setLayout(layout_v) main_layout.addWidget(self.formularz) main_layout.addLayout(hbox) self.setLayout(main_layout) cancel_button.clicked.connect(self.anulowanie) self.edit_wysz.textChanged.connect(self.wyszukiwanie) self.combo_typ.activated[str].connect(self.onActiveNarz) # Menu kontekstowe własne self.table.setContextMenuPolicy(Qt.CustomContextMenu) self.table.customContextMenuRequested.connect(self.prawoklik) def prawoklik(self): menu = QMenu(self) if self.model.rowCount(): akcja = QAction('Usuń narzędzie', self) akcja.triggered.connect(self.usun_wiersz) menu.addAction(akcja) menu.exec_(QCursor.pos()) def usun_wiersz(self): ok = QMessageBox.question(self, 'Potwierdzenie', 'Czy na pewno chcesz usunąć narzędzie?', QMessageBox.Ok, QMessageBox.Cancel) if ok == QMessageBox.Ok: selected = self.table.currentIndex() self.model.removeRow(selected.row()) self.model.submitAll() self.model.select() self.parent.statusBar().showMessage("Usunięto narzędzie", 10000) def onActiveNarz(self, tekst): slownik = { 'Frez palcowy': 'frezy_palcowe', 'Frez płytkowy (głowica)': 'frezy_plytkowe', 'Gwintownik': 'gwintowniki', 'Nóż tokarski': 'noze_tokarskie', 'Oprawka': 'oprawki', 'Piła': 'pily', 'Pozostałe': 'pozostale', 'Rozwiertak': 'rozwiertaki', 'Wiertło': 'wiertla', 'Wiertło składane': 'wiertla_skladane', 'Wygniatak': 'wygniataki', 'Brak': '' } naglowki = { 'idfrezy_palcowe': 'ID', 'symbol_freza': 'Symbol', 'producent_fr': 'Producent', 'srednica_fr': 'Średnica', 'dl_fr': 'Długość całkowita', 'dl_rob_fr': 'Długość robocza', 'idfrezy_plytkowe': 'ID', 'symbol_frez_pl': 'Symbol', 'producent_fp': 'Producent', 'srednica_fr_pl': 'Średnica', 'ilosc_plytek': 'Ilość płytek', 'symbol_pl': 'Symbol płytek', 'ilosc_krawedzi_pl': 'Ilość krawędzi płytki', 'idgwintowniki': 'ID', 'symbol_g': 'Symbol', 'producent_gw': 'Producent', 'rozmiar_gwintu': 'Rozmiar gwintu i skok', 'typ_gwintownika': 'Typ gwintownika', 'idnoze_tokarskie': 'ID', 'symbol_n': 'Symbol', 'producent_n': 'Producent', 'plytki_n': 'Symbol płytek', 'ilosc_krawedzi_pl_n': 'Ilość krawędzi', 'idpily': 'ID', 'symbol_p': 'Symbol', 'producent_pil': 'Producent', 'srednica_p': 'Średnica', 'grubosc_p': 'Grubość', 'rodzaj_pl_p': 'Symbol płytek', 'ilosc_pl_p': 'Ilość płytek', 'ilosc_kraw_p': 'Ilość krawędzi płytki', 'idpozostale': 'ID', 'symbol_poz': 'Symbol', 'producent_poz': 'Producent', 'srednica_poz': 'Średnica', 'ilosc_pl_poz': 'Ilość płytek', 'plytki_poz': 'Symbol płytek', 'idrozwiertaki': 'ID', 'symbol_r': 'Symbol', 'producent_roz': 'Producent', 'rozmiar_r': 'Rozmiar', 'idwiertla': 'ID', 'symbol_w': 'Symbol', 'producent_w': 'Producent', 'srednica_w': 'Średnica', 'dlugosc_w': 'Długość [mm]', 'idwiertla_skladane': 'ID', 'symbol_w_skl': 'Symbol', 'producent_ws': 'Producent', 'srednica_w_skl': 'Średnica', 'plytki_w_skl': 'Symbol płytek', 'idwygniataki': 'ID', 'symbol_wyg': 'Symbol', 'producent_wyg': 'Producent', 'rozmiar_gw': 'Rozmiar gwintu' } self.model.setTable(slownik[tekst]) self.model.setEditStrategy(QSqlTableModel.OnManualSubmit) self.model.select() # 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]) @pyqtSlot(str) def wyszukiwanie(self, text): search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp ) self.proxy.setFilterRegExp(search) # Odpowiedzialne za kolumnę, po której filtruje self.proxy.setFilterKeyColumn(-1) def widok(self): # Ustawianie własciwości widoku self.table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.table.setSelectionMode(QAbstractItemView.SingleSelection) self.table.setSelectionBehavior(QAbstractItemView.SelectRows) self.table.verticalHeader().setVisible(False) self.table.setSortingEnabled(True) self.table.setModel(self.model) def anulowanie(self): self.parent.statusBar().clearMessage() from opcje_qt import Wewnatrz menu_gl = Wewnatrz(self.parent) self.parent.setCentralWidget(menu_gl)
class TableToTreeModel2(QAbstractItemModel): """ Более новый вариант - используем композицию, то есть абстрактная модель включает в себя sql табличную модель только для работы с базой данных """ def __init__(self, m, connection): QAbstractItemModel.__init__(self, m) # попробуем сделать композицию self.dbmodel = QSqlTableModel(self, connection) self.dbmodel.setEditStrategy(0) # при каждом изменении поля #print (self.dbmodel.hasIndex(1,12)) self.headers = [ 'id', '_buy', 'deadline', 'made', 'significance', 'urgency', '_children', '_next', '_parents', '_prev', 'season', 'short text', 'tags', 'text' ] self.rootItem = TreeItem(self.headers) def setTable(self, tname): self.dbmodel.setTable(tname) def select(self): self.dbmodel.select() #здесь должны грузиться данные dct = dict() #словарь айди - список строк с данными for ind in range(self.dbmodel.rowCount()): #dct[int(self.dbmodel.data(self.dbmodel.index(ind,0)))] = [self.dbmodel.data(self.dbmodel.index(ind,j)) for j in range(self.dbmodel.columnCount())] dct[int(self.dbmodel.data(self.dbmodel.index(ind, 0)))] = [ self.dbmodel.data(self.dbmodel.index(ind, j)) for j in range(self.dbmodel.columnCount()) ] def find_children_and_append(item: TreeItem, dct): chlist = eval(item.data(6)) for ch in chlist: tri = TreeItem(dct[ch], item) if tri.data(6) != '[]': find_children_and_append(tri, dct) item.appendChild(tri) for i in [j for j in dct.values() if j[8] == '[]']: tri = TreeItem(i, self.rootItem) find_children_and_append(tri, dct) self.rootItem.appendChild(tri) def columnCount(self, QModelIndex_parent=None, *args, **kwargs): return self.dbmodel.columnCount() def data(self, index, role): if not index.isValid(): return None if role != Qt.DisplayRole: return None item = index.internalPointer() return item.data(index.column()) def flags(self, index): if not index.isValid(): return Qt.NoItemFlags return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable def headerData(self, section, orientation, role): if orientation == Qt.Horizontal and role == Qt.DisplayRole: return self.headers[section] #return self.dbmodel.headerData(section,orientation,role) def index(self, row, column, parent): if not self.hasIndex(row, column, parent): return QModelIndex() if not parent.isValid(): parentItem = self.rootItem else: parentItem = parent.internalPointer() childItem = parentItem.child(row) if childItem: return self.createIndex(row, column, childItem) else: return QModelIndex() def rowCount(self, parent): if parent.column() > 0: return 0 if not parent.isValid(): parentItem = self.rootItem else: parentItem = parent.internalPointer() return parentItem.childCount() def parent(self, index): if not index.isValid(): return QModelIndex() childItem = index.internalPointer() parentItem = childItem.parent() if parentItem == self.rootItem: return QModelIndex() return self.createIndex(parentItem.row(), 0, parentItem) def getIndexById(self, _id): for i in range(self.dbmodel.rowCount()): if int(self.dbmodel.data(self.dbmodel.index(i, 0))) == _id: return self.dbmodel.index(i, 0) return QModelIndex() def setData(self, modelIndex, value, int_role=Qt.EditRole): """ Функция вызывается при установке данных :param QModelIndex: :param QVariant: :param int_role: :return: """ print(self.dbmodel.record(0).setValue(12, 'sdfsfsdf')) r = self.dbmodel.record(1) r.setValue(12, 'Krevedko') print(self.dbmodel.setRecord(0, r)) print(r) return 1
class Customer(QWidget): """ Klasa odpowiedzialna za widget klienci """ def __init__(self, parent, db): super(QWidget, self).__init__(parent) self.parent = parent self.btn_usun = QPushButton('Usuń') self.btn_mod = QPushButton('Modyfikuj') self.txt_imie = QLineEdit() self.txt_nazwisko = QLineEdit() self.txt_email = QLineEdit() self.txt_tel = QLineEdit() self.txt_ulica = QLineEdit() self.txt_nr_dom = QLineEdit() self.txt_kod = QLineEdit() self.txt_miasto = QLineEdit() self.proxy = QSortFilterProxyModel(self) self.view = QTableView() # Parametry połączenia z bazą self.model = QSqlTableModel(self, db) self.id_modify = -1 self.initUI() def initUI(self): """ Inicjuje UI """ self.table_init() self.btn_usun.setDisabled(True) self.btn_mod.setDisabled(True) # Walidacja self.txt_kod.setInputMask('99-999') # Tworzenie kontrolek lbl_wyszukaj = QLabel('Wyszukaj klienta:') txt_wysz = QLineEdit(self) btn_dodaj = QPushButton('Dodaj') lbl_1 = QLabel('Imię:') lbl_2 = QLabel('Nazwisko:') lbl_3 = QLabel('Email:') lbl_4 = QLabel('Telefon:') lbl_5 = QLabel('Ulica:') lbl_6 = QLabel('Numer domu:') lbl_7 = QLabel('Kod pocztowy:') lbl_8 = QLabel('Miejscowość:') # Tworzenie widoków centralbox = QVBoxLayout() hbox_wysz = QHBoxLayout() gropubox = QGroupBox('Edycja danych klienta') grop_layout = QGridLayout() hbox_btn = QHBoxLayout() form_left = QFormLayout() form_right = QFormLayout() # Metody self.view.clicked.connect(self.change) btn_dodaj.clicked.connect(self.add) self.btn_mod.clicked.connect(self.modify) self.btn_usun.clicked.connect(self.remove) txt_wysz.textChanged.connect(self.searching) # Ustawianie widoków hbox_wysz.addWidget(lbl_wyszukaj) hbox_wysz.addWidget(txt_wysz) hbox_btn.addWidget(self.btn_usun) hbox_btn.addWidget(self.btn_mod) hbox_btn.addWidget(btn_dodaj) form_left.setSpacing(9) form_right.setSpacing(9) form_left.setContentsMargins(0, 0, 10, 0) form_right.setContentsMargins(10, 0, 0, 0) form_left.addRow(lbl_1, self.txt_imie) form_left.addRow(lbl_2, self.txt_nazwisko) form_left.addRow(lbl_3, self.txt_email) form_left.addRow(lbl_4, self.txt_tel) form_right.addRow(lbl_5, self.txt_ulica) form_right.addRow(lbl_6, self.txt_nr_dom) form_right.addRow(lbl_7, self.txt_kod) form_right.addRow(lbl_8, self.txt_miasto) grop_layout.addItem(form_left, 0, 0) grop_layout.addItem(form_right, 0, 1) gropubox.setLayout(grop_layout) centralbox.addLayout(hbox_wysz) centralbox.addWidget(self.view) centralbox.addWidget(gropubox) centralbox.addLayout(hbox_btn) self.setLayout(centralbox) self.show() def change(self): """ Metoda edytująca zaznaczone wiersze - Wstawia wartości z wierszy w odpowiednie pola """ index = (self.view.selectionModel().currentIndex()) value = index.sibling(index.row(), index.column()).data() self.id_modify = index.sibling(index.row(), 0).data() self.txt_imie.setText(index.sibling(index.row(), 1).data()) self.txt_nazwisko.setText(str(index.sibling(index.row(), 2).data())) self.txt_email.setText(index.sibling(index.row(), 3).data()) self.txt_tel.setText(index.sibling(index.row(), 4).data()) self.txt_ulica.setText(index.sibling(index.row(), 5).data()) self.txt_nr_dom.setText(index.sibling(index.row(), 6).data()) self.txt_miasto.setText(index.sibling(index.row(), 7).data()) self.txt_kod.setText(index.sibling(index.row(), 8).data()) if self.id_modify >= 0 and self.txt_imie.text( ) and self.txt_nazwisko.text(): self.btn_mod.setEnabled(True) self.btn_usun.setEnabled(True) else: self.btn_usun.setDisabled(True) self.btn_mod.setDisabled(True) value.setText('') def table_init(self): """ Inicjuje wygląd tabeli """ self.model.setTable('klienci') query = QSqlQuery( 'SELECT klienci_id, imie, nazwisko, email, telefon, ulica, numer_mieszkania, miejscowosc, poczta FROM ' 'klienci;') self.model.setQuery(query) self.proxy.setSourceModel(self.model) 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.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(1, Qt.AscendingOrder) self.view.setEditTriggers(QAbstractItemView.NoEditTriggers) 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 len(self.txt_imie.text()) < 3 or len(self.txt_nazwisko.text()) < 1: msg = QMessageBox() 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 add(self): """ Dodaje nowego klienta do bazy danych i odświeża widok. """ tekst = 'Nie wprowadzono wszystkich danych' # Dodanie nowego użytkownika query = 'INSERT INTO klienci (imie, nazwisko, email, telefon, ulica, numer_mieszkania, miejscowosc, ' \ 'poczta) VALUES (%s, %s, %s, %s, %s, %s, %s, %s);' val = (self.txt_imie.text(), self.txt_nazwisko.text(), self.txt_email.text(), self.txt_tel.text(), self.txt_ulica.text(), self.txt_nr_dom.text(), self.txt_miasto.text(), self.txt_kod.text()) if self.if_checked(tekst, query, val): msg = QMessageBox(self) msg.setIcon(QMessageBox.Information) msg.setText('Klient został dodany do bazy danych') msg.setWindowTitle("Dodano nowego klienta") msg.exec_() # Odświeżanie widoku tabeli self.model.select() self.view.reset() def modify(self): """ Modyfikuje bazę danych """ tekst = 'Nie wprowadzono wszystkich danych' # Dodanie nowego użytkownika query = 'UPDATE klienci SET imie = %s, nazwisko = %s, email = %s, telefon = %s, ulica = %s, ' \ 'numer_mieszkania = %s, miejscowosc = %s, poczta = %s WHERE klienci_id = %s;' val = (self.txt_imie.text(), self.txt_nazwisko.text(), self.txt_email.text(), self.txt_tel.text(), self.txt_ulica.text(), self.txt_nr_dom.text(), self.txt_miasto.text(), self.txt_kod.text(), self.id_modify) if self.if_checked(tekst, query, val): msg = QMessageBox(self) msg.setIcon(QMessageBox.Information) msg.setText('Dane klienta zostały pomyślnie zmodyfikowane') msg.setWindowTitle("Dane klienta zostały zmodyfikowane") msg.exec_() # Odświeżanie widoku tabeli self.model.select() self.view.reset() def remove(self): """ Usuwa klientów z bazy danych """ test = 'Błąd! Nie można usunąć danej usługi!' query = 'DELETE FROM klienci WHERE klienci_id = %s' query1 = 'DELETE FROM wizyty WHERE klienci_id = %s' val = (self.id_modify, ) ret = QMessageBox.question( self, 'Usuwanie klienta', "Czy na pewno chcesz usunąć danego klienta?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if ret == QMessageBox.Yes: if self.if_checked(test, [(query1, val), (query, val)]): msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText('Klient został usunięty') msg.setWindowTitle("Usunięto") msg.exec_() self.txt_imie.setText('') self.txt_nazwisko.setText(''), self.txt_email.setText(''), self.txt_tel.setText(''), self.txt_ulica.setText(''), self.txt_nr_dom.setText(''), self.txt_miasto.setText(''), self.txt_kod.setText('') # Odświeżanie widoku tabeli self.model.select() self.view.reset() @pyqtSlot(str) def searching(self, text): """ Wyszukuje po wszystkich kolumnach tabeli :param text: """ search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp) self.proxy.setFilterRegExp(search) # Odpowiedzialne za kolumnę, po której filtruje self.proxy.setFilterKeyColumn(-1)
class TableToTreeModel2 (QAbstractItemModel): """ Более новый вариант - используем композицию, то есть абстрактная модель включает в себя sql табличную модель только для работы с базой данных """ def __init__(self, m, connection): QAbstractItemModel.__init__(self, m) # попробуем сделать композицию self.dbmodel = QSqlTableModel(self, connection) self.dbmodel.setEditStrategy(0) # при каждом изменении поля #print (self.dbmodel.hasIndex(1,12)) self.headers=['id', '_buy', 'deadline', 'made', 'significance', 'urgency', '_children', '_next', '_parents', '_prev', 'season', 'short text', 'tags', 'text'] self.rootItem = TreeItem (self.headers) def setTable(self, tname): self.dbmodel.setTable(tname) def select(self): self.dbmodel.select() #здесь должны грузиться данные dct = dict () #словарь айди - список строк с данными for ind in range (self.dbmodel.rowCount()): #dct[int(self.dbmodel.data(self.dbmodel.index(ind,0)))] = [self.dbmodel.data(self.dbmodel.index(ind,j)) for j in range(self.dbmodel.columnCount())] dct[int(self.dbmodel.data(self.dbmodel.index(ind,0)))] = [self.dbmodel.data(self.dbmodel.index(ind,j)) for j in range(self.dbmodel.columnCount())] def find_children_and_append (item:TreeItem, dct): chlist = eval(item.data(6)) for ch in chlist: tri = TreeItem(dct[ch], item) if tri.data(6) != '[]': find_children_and_append(tri,dct) item.appendChild(tri) for i in [j for j in dct.values() if j[8]=='[]']: tri = TreeItem(i, self.rootItem) find_children_and_append(tri,dct) self.rootItem.appendChild(tri) def columnCount(self, QModelIndex_parent=None, *args, **kwargs): return self.dbmodel.columnCount() def data(self, index, role): if not index.isValid(): return None if role != Qt.DisplayRole: return None item = index.internalPointer() return item.data(index.column()) def flags(self, index): if not index.isValid(): return Qt.NoItemFlags return Qt.ItemIsEnabled | Qt.ItemIsSelectable |Qt.ItemIsEditable def headerData(self, section, orientation, role): if orientation == Qt.Horizontal and role == Qt.DisplayRole: return self.headers[section] #return self.dbmodel.headerData(section,orientation,role) def index(self, row, column, parent): if not self.hasIndex(row, column, parent): return QModelIndex() if not parent.isValid(): parentItem = self.rootItem else: parentItem = parent.internalPointer() childItem = parentItem.child(row) if childItem: return self.createIndex(row, column, childItem) else: return QModelIndex() def rowCount(self, parent): if parent.column() > 0: return 0 if not parent.isValid(): parentItem = self.rootItem else: parentItem = parent.internalPointer() return parentItem.childCount() def parent(self, index): if not index.isValid(): return QModelIndex() childItem = index.internalPointer() parentItem = childItem.parent() if parentItem == self.rootItem: return QModelIndex() return self.createIndex(parentItem.row(), 0, parentItem) def getIndexById(self, _id): for i in range (self.dbmodel.rowCount()): if int (self.dbmodel.data(self.dbmodel.index(i,0)))==_id: return self.dbmodel.index(i,0) return QModelIndex() def setData(self, modelIndex, value, int_role=Qt.EditRole): """ Функция вызывается при установке данных :param QModelIndex: :param QVariant: :param int_role: :return: """ print (self.dbmodel.record(0).setValue(12, 'sdfsfsdf')) r = self.dbmodel.record(1) r.setValue(12, 'Krevedko') print (self.dbmodel.setRecord(0,r)) print (r) return 1
class MainWindow(QMainWindow, Ui_MainWindow): def __init__(self): super(MainWindow, self).__init__() self.folder_path = QDir.current().path() self.init_ui() def init_ui(self): """Initialize ui.""" self.setupUi(self) self.move_to_center() self.init_table_view() icon = QIcon('subtitle_analyze_gui.ico') self.setWindowIcon(icon) movie = QMovie('processing.gif') self.label.setMovie(movie) movie.start() self.label.setVisible(False) self.tableView.resizeColumnsToContents() self.tableView.resizeRowsToContents() self.tableView.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) self.actionOpen_Folder.triggered.connect(self.open_folder) self.actionSave_As.triggered.connect(self.save_result) self.actionExit.triggered.connect(self.close) self.refreshPushButton.released.connect(self.refresh) def init_table_view(self): """Initialize the table view""" if not create_connection(): sys.exit(1) self.model = QSqlTableModel() initialize_model(self.model) self.tableView.setModel(self.model) self.tableView.setSortingEnabled(True) reflesh_model(self.model) def move_to_center(self): """Move windows to the center of the screen.""" screen = QDesktopWidget().screenGeometry() size = self.geometry() self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2) def open_folder(self): """Set target folder.""" self.folder_path = QFileDialog.getExistingDirectory( self, 'Open the folder', QDir.currentPath()) if not self.folder_path: self.folder_path = QDir.current().path() def save_result(self): """Save analyze result.""" filename = QFileDialog.getSaveFileName( self, 'Save analyze result', os.path.join(QDir.current().path(), 'result.csv'), 'File (*.csv)') with open(filename[0], 'w', encoding='utf-8') as file: row = self.model.rowCount() col = self.model.columnCount() for i in range(row): text = '' for j in range(col): text += str(self.model.data(self.model.index(i, j))) + '\t' text += '\n' file.writelines(text) def analyze_subtitle(self): """Analyze subtitles""" filename_list = get_subtitle_filename_list(self.folder_path, mode='r') result_dict = single_thread_analyze(filename_list) for key in result_dict.keys(): add_record(result_dict[key][0], result_dict[key][1], result_dict[key][2] / 1000, result_dict[key][3]) def refresh(self): """Execute analysis task.""" self.label.setVisible(True) self.refreshPushButton.setEnabled(False) reflesh_model(self.model) self.task_thread = TaskThread() self.task_thread.set_task(self.analyze_subtitle) self.task_thread.finish_signal.connect(self.process_thread_message) self.task_thread.start() def process_thread_message(self, message): """Processing thread message.""" reflesh_model(self.model) self.label.setVisible(False) self.refreshPushButton.setEnabled(True)
class Services(QWidget): """ Klasa odpowiedzialna za widget usług """ def __init__(self, parent, db): super(QWidget, self).__init__(parent) self.parent = parent self.proxy = QSortFilterProxyModel(self) self.view = QTableView() self.txt_nazwa = QLineEdit() self.txt_cena = QLineEdit() self.txt_czas = QLineEdit() self.txt_opis = QTextEdit() self.btn_mod = QPushButton('Modyfikuj') self.btn_usun = QPushButton('Usuń') self.id_modify = -1 # Parametry połączenia z bazą self.model = QSqlTableModel(self, db) self.initUI() def initUI(self): """ Inicjuje UI """ self.table_init() self.btn_usun.setDisabled(True) self.btn_mod.setDisabled(True) self.txt_czas.setInputMask('99:00') # Tworzenie kontrolek lbl_wysz = QLabel("Wyszukaj zabieg:") txt_wysz = QLineEdit(self) btn_dodaj = QPushButton('Dodaj') lbl_nazwa = QLabel('Nazwa:') lbl_cena = QLabel('Cena:') lbl_czas = QLabel('Czas:') lbl_opis = QLabel('Opis:') # Tworzenie widoków centralbox = QHBoxLayout() findbox = QHBoxLayout() vbox = QVBoxLayout() groupbox = QGroupBox('Zabiegi') groupbox_layout = QVBoxLayout() button_hbox = QHBoxLayout() formbox = QFormLayout() # Metody self.view.clicked.connect(self.change) txt_wysz.textChanged.connect(self.searching) btn_dodaj.clicked.connect(self.add) self.btn_mod.clicked.connect(self.modify) self.btn_usun.clicked.connect(self.remove) # Ustawianie widoków findbox.addWidget(lbl_wysz) findbox.addWidget(txt_wysz) button_hbox.addWidget(btn_dodaj) button_hbox.addWidget(self.btn_mod) button_hbox.addWidget(self.btn_usun) formbox.addRow(lbl_nazwa, self.txt_nazwa) formbox.addRow(lbl_cena, self.txt_cena) formbox.addRow(lbl_czas, self.txt_czas) formbox.addRow(lbl_opis, self.txt_opis) groupbox_layout.addLayout(formbox) groupbox_layout.addLayout(button_hbox) groupbox.setLayout(groupbox_layout) vbox.addLayout(findbox) vbox.addWidget(groupbox) centralbox.addLayout(vbox) centralbox.addWidget(self.view) self.setLayout(centralbox) self.show() def table_init(self): """ Inicjuje wygląd tabeli """ self.model.setTable('uslugi') # query = QSqlQuery('SELECT uzytkownik_id, uzytkownik_nazwa, imie, nazwisko, pracownik FROM uzytkownik;') # self.model.setQuery(query) self.model.select() self.proxy.setSourceModel(self.model) naglowki = { 'uslugi_id': 'ID', 'nazwa': 'Nazwa', 'cena': 'Cena', "czas": 'Czas', 'Opis': 'Opis', } # 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(1, Qt.AscendingOrder) self.view.setEditTriggers(QAbstractItemView.NoEditTriggers) def change(self): """ Metoda edytująca zaznaczone wiersze - Wstawia wartości z wierszy w odpowiednie pola """ index = (self.view.selectionModel().currentIndex()) value = index.sibling(index.row(), index.column()).data() self.id_modify = index.sibling(index.row(), 0).data() self.txt_nazwa.setText(index.sibling(index.row(), 1).data()) self.txt_cena.setText(str(index.sibling(index.row(), 2).data())) self.txt_czas.setText(index.sibling(index.row(), 3).data()) self.txt_opis.setText(index.sibling(index.row(), 4).data()) if self.id_modify >= 0 and self.txt_nazwa.text( ) and self.txt_cena.text() and self.txt_czas.text(): self.btn_mod.setEnabled(True) self.btn_usun.setEnabled(True) else: self.btn_usun.setDisabled(True) self.btn_mod.setDisabled(True) value.setText('') 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 len(self.txt_nazwa.text()) < 3 or len( self.txt_cena.text()) < 1 or len(self.txt_czas.text()) < 2: msg = QMessageBox() 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') t = query_to_db(q, val) print(t) return t # = polaczenie(q, val) else: print('Transakcja') return transaction_to_db(q) def add(self): """ Dodaje nową usługę do bazy danych i odświeża widok. """ tekst = 'Nie wprowadzono wszystkich danych' # Dodanie nowego użytkownika query = 'INSERT INTO uslugi (nazwa, cena, czas, Opis) VALUES (%s, %s, %s, %s)' val = (self.txt_nazwa.text(), self.txt_cena.text().replace(',', '.'), self.txt_czas.text(), self.txt_opis.toPlainText()) if self.if_checked(tekst, query, val): msg = QMessageBox(self) msg.setIcon(QMessageBox.Information) msg.setText('Dodano nową usługę') msg.setWindowTitle("Dodano nową usługę") msg.exec_() else: msg = QMessageBox(self) msg.setIcon(QMessageBox.Warning) msg.setText('Usługa znajduje się już w bazie') msg.setWindowTitle("Błąd!") msg.exec_() # Odświeżanie widoku tabeli self.model.select() self.view.reset() def modify(self): """ Modyfikuje bazę danych """ test = 'Dane zostały błędnie zmodyfikowane.' query = 'UPDATE uslugi SET nazwa = %s, cena = %s, czas = %s, Opis = %s WHERE uslugi_id = %s;' val = (self.txt_nazwa.text(), self.txt_cena.text().replace(',', '.'), self.txt_czas.text(), self.txt_opis.toPlainText(), self.id_modify) if self.if_checked(test, query, val): msg = QMessageBox(self) msg.setIcon(QMessageBox.Information) msg.setText('Informacje o usłudze zostały pomyślnie zmodyfikowane') msg.setWindowTitle("Zmodyfikowano usługi") msg.exec_() # Odświeżanie widoku tabeli self.model.select() self.view.reset() def remove(self): """ Usuwa dane z bazy danych """ test = 'Błąd! Nie można usunąć danej usługi!' query2 = 'DELETE FROM wizyty WHERE uslugi_id = %s' query = 'DELETE FROM uslugi WHERE uslugi_id = %s' val = (self.id_modify, ) query1 = 'DELETE FROM uzytkownik_usluga WHERE uslugi_id = %s' ret = QMessageBox.question(self, 'Usuwanie usługi', "Czy na pewno chcesz usunąć daną usługę?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if ret == QMessageBox.Yes: if self.if_checked(test, [(query2, val), (query1, val), (query, val)]): msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText('Usługa została usunięta') msg.setWindowTitle("Usunięto") msg.exec_() self.txt_nazwa.setText('') self.txt_cena.setText('') self.txt_czas.setText('') self.txt_opis.setText('') # Odświeżanie widoku tabeli self.model.select() self.view.reset() @pyqtSlot(str) def searching(self, text): """ Wyszukuje po wszystkich kolumnach tabeli :param text: """ search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp) self.proxy.setFilterRegExp(search) # Odpowiedzialne za kolumnę, po której filtruje self.proxy.setFilterKeyColumn(1)
class mainwindow(QMainWindow): def __init__(self): super().__init__() self.UI = Ui_MainWindow() self.UI.setupUi(self) self.UI.action_mn1_1.triggered.connect(self.action_mn1_1_triggered) self.UI.action_mn1_2.triggered.connect(self.close) self.UI.action_mn2_1.triggered.connect(self.action_mn2_1_triggered) self.UI.action_mn2_2.triggered.connect(self.action_mn2_2_triggered) self.UI.listView_pg1_gp1_1.clicked.connect( self.listView_pg1_gp1_1_clicked) self.UI.listView_pg1_gp1_1.setEditTriggers( QAbstractItemView.NoEditTriggers) self.UI.pushButton_pg1_gp1_1.clicked.connect( self.pushButton_pg1_gp1_1_clicked) self.UI.pushButton_pg1_gp1_2.clicked.connect( self.pushButton_pg1_gp1_2_clicked) self.UI.pushButton_pg1_gp1_3.clicked.connect( self.pushButton_pg1_gp1_3_clicked) self.UI.pushButton_pg1_gp2_1.clicked.connect( self.pushButton_pg1_gp2_1_clicked) self.UI.pushButton_pg1_gp2_2.clicked.connect( self.pushButton_pg1_gp2_2_clicked) self.UI.pushButton_pg1_gp2_3.clicked.connect( self.pushButton_pg1_gp2_3_clicked) self.UI.pushButton_pg1_gp2_4.clicked.connect( self.pushButton_pg1_gp2_4_clicked) self.UI.pushButton_pg1_gp2_5.clicked.connect( self.pushButton_pg1_gp2_5_clicked) self.UI.stackedWidget.setCurrentIndex(2) self.show() logindialog = logindialogue() if logindialog.exec_(): self.IPaddress = logindialog.IPaddress self.account = logindialog.account self.password = logindialog.password else: self.close() def action_mn1_1_triggered(self): """主菜单注销""" self.UI.stackedWidget.setCurrentIndex(2) logindialog = logindialogue() if logindialog.exec_(): self.IPaddress = logindialog.IPaddress self.account = logindialog.account self.password = logindialog.password else: self.close() def action_mn2_1_triggered(self): """主菜单,产品,管理""" self.UI.stackedWidget.setCurrentIndex(0) self.UI.groupBox_pg1_2.setDisabled(True) db = QSqlDatabase.addDatabase('QMYSQL') db.setHostName(self.IPaddress) db.setUserName(self.account) db.setPassword(self.password) db.setDatabaseName('project') db.open() self.standarditemmodel = QStandardItemModel() for i in db.tables(): t = QStandardItem(i) t.setTextAlignment(Qt.AlignCenter) self.standarditemmodel.appendRow(t) self.UI.listView_pg1_gp1_1.setModel(self.standarditemmodel) db.close() def action_mn2_2_triggered(self): """主菜单,产品,分析""" self.UI.stackedWidget.setCurrentIndex(1) def pushButton_pg1_gp1_1_clicked(self): """第0页,第一组,删除按钮""" selectionmodel = self.UI.listView_pg1_gp1_1.selectionModel() modelindexlist = selectionmodel.selectedRows() for i in modelindexlist: reply = QMessageBox.question(self, "提示", "确定要删除" + i.data() + "产品的所有数据", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: query = QSqlQuery() query.exec("drop table " + i.data()) self.standarditemmodel.removeRow(i.row()) def pushButton_pg1_gp1_2_clicked(self): """第0页,第一组,新建按钮""" newproducttabledialog = newproducttabledialogue( self.IPaddress, self.account, self.password) if newproducttabledialog.exec_(): db = QSqlDatabase.addDatabase('QMYSQL') db.setHostName(self.IPaddress) db.setUserName(self.account) db.setPassword(self.password) db.setDatabaseName('project') db.open() self.standarditemmodel = QStandardItemModel() for i in db.tables(): t = QStandardItem(i) t.setTextAlignment(Qt.AlignCenter) self.standarditemmodel.appendRow(t) self.UI.listView_pg1_gp1_1.setModel(self.standarditemmodel) db.close() self.UI.groupBox_pg1_2.setDisabled(True) def pushButton_pg1_gp1_3_clicked(self): """第0页,第一组,查询按钮""" keyword = str(self.UI.lineEdit_pg1_gp1_1.text()) db = QSqlDatabase.addDatabase('QMYSQL') db.setHostName(self.IPaddress) db.setUserName(self.account) db.setPassword(self.password) db.setDatabaseName('project') db.open() self.standarditemmodel = QStandardItemModel() for i in db.tables(): if search(keyword, i): t = QStandardItem(i) t.setTextAlignment(Qt.AlignCenter) self.standarditemmodel.appendRow(t) self.UI.listView_pg1_gp1_1.setModel(self.standarditemmodel) db.close() def listView_pg1_gp1_1_clicked(self, index): """"第0页,第一组,列表被点击""" self.UI.groupBox_pg1_2.setDisabled(False) self.UI.groupBox_pg1_2.setTitle(index.data() + '数据:') self.UI.comboBox_pg1_gp2_1.clear() self.sqltablemodel = QSqlTableModel() self.sqltablemodel.setEditStrategy(QSqlTableModel.OnManualSubmit) self.sqltablemodel.setTable(index.data()) self.sqltablemodel.select() for i in range(self.sqltablemodel.columnCount()): self.UI.comboBox_pg1_gp2_1.addItem( self.sqltablemodel.headerData(i, Qt.Horizontal)) self.UI.tableView_pg1_gp2_1.setModel(self.sqltablemodel) def pushButton_pg1_gp2_1_clicked(self): """第0页,第二组, 增加按钮""" record = self.sqltablemodel.record() self.sqltablemodel.insertRecord(self.sqltablemodel.rowCount(), record) def pushButton_pg1_gp2_2_clicked(self): """第0页,第二组, 删除按钮""" selectionmodel = self.UI.tableView_pg1_gp2_1.selectionModel() modelindexlist = selectionmodel.selectedRows() for i in modelindexlist: self.sqltablemodel.removeRow(i.row()) def pushButton_pg1_gp2_3_clicked(self): """第0页,第二组, 确定按钮""" if self.sqltablemodel.submitAll(): QMessageBox.information(self, '提示', '提交成功') else: QMessageBox.warning(self, '错误', 'ID相同,提交失败') def pushButton_pg1_gp2_4_clicked(self): """第0页,第二组, 取消按钮""" self.sqltablemodel.revertAll() self.sqltablemodel.submitAll() def pushButton_pg1_gp2_5_clicked(self): """第0页,第二组, 查找按钮""" if len(self.UI.lineEdit_pg1_gp2_1.text()): filterword = self.UI.comboBox_pg1_gp2_1.currentText( ) + ' = ' + self.UI.lineEdit_pg1_gp2_1.text() self.sqltablemodel.setFilter(filterword) self.sqltablemodel.select() else: self.sqltablemodel.setFilter('') self.sqltablemodel.select()
class ServEmpl(QWidget): """ Klasa odpowiedzialna za widget pracownicy-usługi """ def __init__(self, parent, db): super(QWidget, self).__init__(parent) self.parent = parent self.lbl_imie = QLabel() self.lbl_nazwisko = QLabel() self.view_p = QTableView() self.view_pu = QTableView() self.view_u = QTableView() self.proxy_p = QSortFilterProxyModel(self) self.proxy_pu = QSortFilterProxyModel(self) self.proxy_u = QSortFilterProxyModel(self) self.id_pracownik = -1 # Parametry połączenia z bazą self.model_p = QSqlTableModel(self, db) self.model_pu = QSqlRelationalTableModel(self, db) self.model_u = QSqlTableModel(self, db) self.initUI() def initUI(self): """ Inicjuje UI """ pracownicy = ''' Kliknij <u>tutaj</u> aby wybrać danego pracownika. Poniżej znajdują się wszystkie usługi, jakie dany pracownik może robić. ''' uslugi = ''' Kliknij dwukrotnie <u>tutaj</u> aby <b>przypisać</b> daną usługę do wybranego pracownika. ''' pracownik_uslugi = ''' Kliknij dwukrotnie <u>tutaj</u> aby <b>usunąć</b> przypisanie danej usługi pracownikowi. ''' self.table_init_u() self.table_init_p() self.table_init_pu() self.view_p.setToolTip(pracownicy) self.view_u.setToolTip(uslugi) self.view_pu.setToolTip(pracownik_uslugi) # Tworzenie kontrolek lbl_wyszukaj = QLabel('Wyszukaj pracownika:') lbl_imie_static = QLabel('Imię:') lbl_nazwisko_static = QLabel('Nazwisko:') txt_wysz = QLineEdit(self) # Tworzenie widoków centralbox = QHBoxLayout() hbox_p = QHBoxLayout() hbox_pu = QHBoxLayout() hbox_u = QHBoxLayout() vbox_right = QVBoxLayout() vbox_left = QVBoxLayout() groupbox_p = QGroupBox('Pracownicy') groupbox_pu = QGroupBox('Wykonywane usługi') groupbox_u = QGroupBox('Usługi') formbox = QFormLayout() # Metody txt_wysz.textChanged.connect(self.searching) self.view_p.clicked.connect(self.change_p) self.view_u.doubleClicked.connect(lambda: self.change_add_remove(True)) self.view_pu.doubleClicked.connect(lambda: self.change_add_remove(False)) # Ustawianie widoków formbox.addRow(lbl_wyszukaj, txt_wysz) formbox.addRow(lbl_imie_static, self.lbl_imie) formbox.addRow(lbl_nazwisko_static, self.lbl_nazwisko) formbox.setSpacing(15) vbox_left.addLayout(formbox) vbox_left.addWidget(groupbox_u) vbox_left.setSpacing(200) hbox_p.addWidget(self.view_p) hbox_pu.addWidget(self.view_pu) hbox_u.addWidget(self.view_u) groupbox_p.setLayout(hbox_p) groupbox_pu.setLayout(hbox_pu) groupbox_u.setLayout(hbox_u) vbox_right.addWidget(groupbox_p) vbox_right.addWidget(groupbox_pu) vbox_right.setSpacing(25) centralbox.addLayout(vbox_left) centralbox.addLayout(vbox_right) self.setLayout(centralbox) self.show() def change_p(self): """ Metoda edytująca zaznaczone wiersze - Wstawia wartości z wierszy w odpowiednie pola """ index = (self.view_p.selectionModel().currentIndex()) self.id_pracownik = index.sibling(index.row(), 0).data() self.lbl_imie.setText("<b>" + index.sibling(index.row(), 2).data() + "</b>") self.lbl_nazwisko.setText("<b>" + index.sibling(index.row(), 3).data() + "</b>") # Odświeżanie widoku tabeli query = QSqlQuery( 'SELECT uslugi.uslugi_id, uslugi.nazwa, uslugi.cena, uslugi.czas FROM uslugi, uzytkownik_usluga WHERE ' 'uslugi.uslugi_id = uzytkownik_usluga.uslugi_id AND uzytkownik_usluga.uzytkownik_id = ' + str( self.id_pracownik) + ';') self.model_pu.setQuery(query) self.view_pu.reset() def change_add_remove(self, quest): """ Metoda ogólna odpowiadająca za dodawanie i usuwanie usług wybranemu pracownikowi """ tekst_p = "Czy chcesz dodać nową usługę do użytkownika {}?".format(self.lbl_imie.text()) if quest: index = (self.view_u.selectionModel().currentIndex()) id_modify = index.sibling(index.row(), 0).data() ret = QMessageBox.question(self, 'Dodawanie usługi', tekst_p, QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if ret == QMessageBox.Yes: query = 'INSERT INTO uzytkownik_usluga (uzytkownik_id, uslugi_id) VALUES (%s, %s); ' val = ( self.id_pracownik, id_modify ) if query_to_db(query, val): msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText('Usługa została dodana do usług oferowanych przez pracownika') msg.setWindowTitle("Dodano usługę") msg.exec_() else: index = (self.view_pu.selectionModel().currentIndex()) id_modify = index.sibling(index.row(), 0).data() ret = QMessageBox.question(self, 'Usuwanie usługi', "Czy na pewno chcesz usunąć daną usługę?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if ret == QMessageBox.Yes: query = 'DELETE FROM uzytkownik_usluga WHERE uzytkownik_id = %s AND uslugi_id = %s; ' val = ( self.id_pracownik, id_modify ) if query_to_db(query, val): msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText('Usługa została dodana do usług oferowanych przez pracownika') msg.setWindowTitle("Dodano usługę") msg.exec_() # Odświeżanie widoku tabeli query = QSqlQuery( 'SELECT uslugi.uslugi_id, uslugi.nazwa, uslugi.cena, uslugi.czas FROM uslugi, uzytkownik_usluga WHERE ' 'uslugi.uslugi_id = uzytkownik_usluga.uslugi_id AND uzytkownik_usluga.uzytkownik_id = ' + str( self.id_pracownik) + ';') self.model_pu.setQuery(query) self.view_pu.reset() def table_init_u(self): """ Inicjuje wygląd tabeli usługi """ self.model_u.setTable('uslugi') # query = QSqlQuery('SELECT uzytkownik_id, uzytkownik_nazwa, imie, nazwisko, pracownik FROM uzytkownik;') # self.model.setQuery(query) self.model_u.select() self.proxy_u.setSourceModel(self.model_u) naglowki = { 'uslugi_id': 'ID', 'nazwa': 'Nazwa', 'cena': 'Cena', "czas": 'Czas', 'Opis': 'Opis', } # 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_p(self): """ Inicjuje wygląd tabeli pracownicy """ self.model_p.setTable('pracownicy') query = QSqlQuery('SELECT uzytkownik_id, uzytkownik_nazwa, imie, nazwisko, pracownik FROM uzytkownik WHERE pracownik = 1;') self.model_p.setQuery(query) # self.model_u.select() self.proxy_p.setSourceModel(self.model_p) naglowki = { 'uzytkownik_id': 'ID', 'uzytkownik_nazwa': 'Login', 'imie': 'Imię', "nazwisko": 'Nazwisko', 'pracownik': 'Pracownik', } # 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.hideColumn(4) self.view_p.sortByColumn(1, Qt.AscendingOrder) self.view_p.setEditTriggers(QAbstractItemView.NoEditTriggers) def table_init_pu(self): """ Inicjuje wygląd tabeli pracownicy-usługi """ query = QSqlQuery( 'SELECT uslugi.uslugi_id, uslugi.nazwa, uslugi.cena, uslugi.czas FROM uslugi, uzytkownik_usluga WHERE ' 'uslugi.uslugi_id = uzytkownik_usluga.uslugi_id AND uzytkownik_usluga.uzytkownik_id = ' + str( self.id_pracownik) + ';') self.model_pu.setQuery(query) self.proxy_pu.setSourceModel(self.model_pu) naglowki = { 'uslugi_id': 'ID usługi', 'nazwa': 'Nazwa usługi', 'cena': 'Cena', 'czas': 'Czas' } # Ustawianie nagłówków ilosc_kolumn = self.model_pu.columnCount() for i in range(ilosc_kolumn): nazwa_kolumn = self.model_pu.headerData(i, Qt.Horizontal) self.model_pu.setHeaderData(i, Qt.Horizontal, naglowki[nazwa_kolumn]) self.view_pu.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContentsOnFirstShow) self.view_pu.setSortingEnabled(True) self.view_pu.setAlternatingRowColors(True) # Wczytanie danych self.view_pu.setModel(self.proxy_pu) self.view_pu.hideColumn(0) self.view_pu.sortByColumn(1, Qt.AscendingOrder) self.view_pu.setEditTriggers(QAbstractItemView.NoEditTriggers) @pyqtSlot(str) def searching(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)