Уведомления

Группа в Telegram: @pythonsu

#1 Ноя. 1, 2017 15:47:33

yuyu_yaya
Зарегистрирован: 2017-11-01
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Как правильно реализовать логин-форму на PyQt5 + cx_Oracle?

Всё работает. Но явно - это можно сделать как-то проще и правильнее. Подскажите,пожалуйста, как или ткните - где можно почитать. Upd: И насколько правильно так закрывать соединение с базой? Можно ли это делать в деструкторе объекта?

from PyQt5 import QtWidgets,QtCore
import cx_Oracle

class LoginWindow(QtWidgets.QWidget):

connect_db = QtCore.pyqtSignal()
def __init__(self,parent=None):
super().__init__(parent)
self.setUi()

def setUi(self):
self.setWindowFlags(QtCore.Qt.WindowCloseButtonHint)
self.setFixedSize(400,200)
vbox = QtWidgets.QVBoxLayout()
self.button = QtWidgets.QPushButton("&Отправить")
self.lineEditUser = QtWidgets.QLineEdit()
self.lineEditPassword = QtWidgets.QLineEdit()
self.lineEditPassword.setEchoMode(QtWidgets.QLineEdit.Password)
self.lineEditDB = QtWidgets.QLineEdit()
groupBox = QtWidgets.QGroupBox()
form = QtWidgets.QFormLayout()
form.addRow("&Имя пользователя: ", self.lineEditUser)
form.addRow("&Пароль: ", self.lineEditPassword)
form.addRow("&База данных: ", self.lineEditDB)
groupBox.setLayout(form)
vbox.addWidget(groupBox)
vbox.addWidget(self.button)
self.setLayout(vbox)
self.button.clicked.connect(self.on_clicked)

@QtCore.pyqtSlot()
def on_clicked(self):
try:
self.setCursor(QtCore.Qt.WaitCursor)
w.connect_db(self.lineEditUser.text(),self.lineEditPassword.text(),self.lineEditDB.text())
self.unsetCursor()
self.close()
self.connect_db.emit()
except cx_Oracle.DatabaseError as e:
self.show_message("Ошибка подключения к базе данных", "Ошибка базы данных: %s" % e)
self.unsetCursor()

def show_message(self,title,message):
QtWidgets.QMessageBox.about(self,title,message)

class MainWindow (QtWidgets.QMainWindow):
def __init__(self,parent=None):
super().__init__(parent)
self.resize(800,600)

def __del__(self):
self.disconnect_db()

def connect_db(self,user,password,db):
try:
self.con = cx_Oracle.connect(user,password,db)
except cx_Oracle.DatabaseError as e:
raise
else:
self.cursor = self.con.cursor()

def disconnect_db(self):
try:
self.cursor.close()
self.con.close()
except AttributeError:
pass


if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
l = LoginWindow()
w = MainWindow()
l.connect_db.connect(w.show)
l.show()
sys.exit(app.exec_())

Отредактировано yuyu_yaya (Ноя. 1, 2017 19:52:04)

Офлайн

#2 Ноя. 1, 2017 16:22:05

vic57
Зарегистрирован: 2015-07-07
Сообщения: 893
Репутация: +  126  -
Профиль   Отправить e-mail  

Как правильно реализовать логин-форму на PyQt5 + cx_Oracle?

логин лучше делать на основе QDialog
https://github.com/baoboa/pyqt5/tree/master/examples/dialogs

Офлайн

#3 Ноя. 1, 2017 19:49:04

yuyu_yaya
Зарегистрирован: 2017-11-01
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Как правильно реализовать логин-форму на PyQt5 + cx_Oracle?

vic57
Спасибо за ссылку. Погляжу - что там. Перепишу через QDialog. Главная сложность для меня - это обработка исключений, а также то, где и как правильно создать и проверить соединение - то ли сразу в главном окне, то ли в диалоговом, а потом передать его в конструктор главного окна.

Отредактировано yuyu_yaya (Ноя. 1, 2017 19:49:34)

Офлайн

#4 Ноя. 2, 2017 09:58:57

vic57
Зарегистрирован: 2015-07-07
Сообщения: 893
Репутация: +  126  -
Профиль   Отправить e-mail  

Как правильно реализовать логин-форму на PyQt5 + cx_Oracle?

там же на гите есть sql примеры.
я работаю по схеме: подключился->запрос-ответ->отключился

Офлайн

#5 Ноя. 2, 2017 14:00:14

yuyu_yaya
Зарегистрирован: 2017-11-01
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Как правильно реализовать логин-форму на PyQt5 + cx_Oracle?

vic57
Пока примеры на git не привели меня к пониманию. По sql там какой-то совсем простой код. Попробовал переписать c использованием QDialog и по схеме постоянного открытия/закрытия соединения для каждой операции. Как-то так получилось:

 from PyQt5 import QtWidgets,QtCore
import cx_Oracle
# from mainwindow import Ui_MainWindow
class Login(QtWidgets.QDialog):
    def __init__(self,parent=None):
        super().__init__(parent)
        self.setUi()
    def setUi(self):
        self.setWindowFlags(QtCore.Qt.WindowCloseButtonHint)
        self.setFixedSize(400,200)
        vbox = QtWidgets.QVBoxLayout()
        self.button = QtWidgets.QPushButton("&Отправить")
        self.lineEditUser = QtWidgets.QLineEdit()
        self.lineEditPassword = QtWidgets.QLineEdit()
        self.lineEditPassword.setEchoMode(QtWidgets.QLineEdit.Password)
        self.lineEditDB = QtWidgets.QLineEdit()
        groupBox = QtWidgets.QGroupBox()
        form = QtWidgets.QFormLayout()
        form.addRow("&Имя пользователя: ", self.lineEditUser)
        form.addRow("&Пароль: ", self.lineEditPassword)
        form.addRow("&База данных: ", self.lineEditDB)
        groupBox.setLayout(form)
        vbox.addWidget(groupBox)
        vbox.addWidget(self.button)
        self.setLayout(vbox)
        self.button.clicked.connect(self.on_clicked)
# Насколько правильно использовать менеджер контекста? Вроде бы  курсоры и соединения так закрываются автоматически.
    def on_clicked(self):
        self.user = self.lineEditUser.text()
        self.password = self.lineEditPassword.text()
        self.dns = self.lineEditDB.text()
        try:
            with cx_Oracle.connect(self.user,self.password,self.dns) as con:
                pass
            self.accept()
        except cx_Oracle.DatabaseError as e:
            self.show_message("Ошибка подключения к базе данных", "Ошибка базы данных: %s" % e)
    def show_message(self, title, message):
        QtWidgets.QMessageBox.warning(self, title, message)
class Window(QtWidgets.QMainWindow):
    def __init__(self, parent=None,user="",password="",dns=""):
        super().__init__(parent)
        self._user = user
        self._password = password
        self._dns = dns
        self.show_banner("select banner from v$version")
        # self.ui = Ui_MainWindow()
        # self.ui.setupUi(self)
# Правильно ли открывать соединения так каждый раз? Или существует какой-то другой способ получше?
    def show_banner (self,sql):
        try:
            with cx_Oracle.connect(self._user,self._password,self._dns) as con:
                cursor = con.cursor()
                cursor.execute(sql)
                for row in cursor:
                    print(row[0])
        except cx_Oracle.DatabaseError as e:
            self.show_message("Ошибка подключения к базе данных", "Ошибка базы данных: %s" % e)
    def show_message(self, title, message):
        QtWidgets.QMessageBox.warning(self, title, message)
if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    login = Login()
# Правильно ли так передавать учётные данные в главное окно?
    if login.exec_() == QtWidgets.QDialog.Accepted:
        window = Window(user=login.user, password=login.password, dns=login.dns)
        window.show()
        sys.exit(app.exec_())
Так лучше?

Отредактировано yuyu_yaya (Ноя. 2, 2017 14:01:29)

Офлайн

#6 Ноя. 2, 2017 15:08:41

vic57
Зарегистрирован: 2015-07-07
Сообщения: 893
Репутация: +  126  -
Профиль   Отправить e-mail  

Как правильно реализовать логин-форму на PyQt5 + cx_Oracle?

ну можно и так, но я бы сначала в консоле все отработал, потом бы в гуй запихал
и всю работу с БД я выделяю в отдельный класс типа connection(host,user….blabla)

Отредактировано vic57 (Ноя. 2, 2017 15:42:07)

Офлайн

#7 Ноя. 2, 2017 16:01:13

yuyu_yaya
Зарегистрирован: 2017-11-01
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Как правильно реализовать логин-форму на PyQt5 + cx_Oracle?

Я на тестовой базе Oracle, которая на виртуалке крутится, всё это делаю. Мне интересно собрать всё воедино и посмотреть как получится. Потом,конечно, когда буду переносить всё на реальную базу - все запросы, функции, процедуры буду сначала тщательно тестировать в консоли. И только потом в гуй переносить.
Update: Я думал насчёт отдельного класса для БД. Только так для себя не понял, какую от этого выгоду можно получить!?

Отредактировано yuyu_yaya (Ноя. 2, 2017 19:00:38)

Офлайн

#8 Ноя. 2, 2017 16:49:39

vic57
Зарегистрирован: 2015-07-07
Сообщения: 893
Репутация: +  126  -
Профиль   Отправить e-mail  

Как правильно реализовать логин-форму на PyQt5 + cx_Oracle?

yuyu_yaya
Update: Я думал на счёт отдельного класса для БД. Только так для себя не понял, какую от этого выгоду можно получить!?
можно отработать в консоли и пользовать где угодно, так же как и диалог соединения
у вас как-то все вперемешку, не видно модульной структуры
правило UNIX - делай одно, но делай хорошо

Офлайн

#9 Ноя. 2, 2017 16:50:30

vic57
Зарегистрирован: 2015-07-07
Сообщения: 893
Репутация: +  126  -
Профиль   Отправить e-mail  

Как правильно реализовать логин-форму на PyQt5 + cx_Oracle?

yuyu_yaya
Update: Я думал на счёт отдельного класса для БД. Только так для себя не понял, какую от этого выгоду можно получить!?
можно отработать в консоли и пользовать где угодно, так же как и диалог соединения
у вас как-то все вперемешку, не видно модульной структуры
правило UNIX - делай одно, но делай хорошо

Офлайн

#10 Ноя. 2, 2017 16:58:25

vic57
Зарегистрирован: 2015-07-07
Сообщения: 893
Репутация: +  126  -
Профиль   Отправить e-mail  

Как правильно реализовать логин-форму на PyQt5 + cx_Oracle?

yuyu_yaya
Update: Я думал на счёт отдельного класса для БД. Только так для себя не понял, какую от этого выгоду можно получить!?
можно отработать в консоли и пользовать где угодно, так же как и диалог соединения
у вас как-то все вперемешку, не видно модульной структуры
правило UNIX - делай одно, но делай хорошо

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version