I had set a fixed size on my Login window however once you login in and it takes you to the LoadingBar window the size restrictions stay even though I set a new fixed size. This leaves my window with blank area. I have tried looking for similar posts but have not found any. This may have a very simple fix and I may have made a very stupid mistake. I would appreciate any help and an explantion. There is no error when running the code
#IMPORTS
import sys, os, sqlite3
import random, datetime
from PyQt5 import QtCore, QtGui, uic
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5 import QtWidgets #, QtWebEngineWidgets
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox
import sqlite3
import time
#WINDOWS
window1 = uic.loadUiType("login.ui")[0]
window2 = uic.loadUiType("SIGNUP.ui")[0]
window3 = uic.loadUiType("main.ui")[0]
window4 = uic.loadUiType("login_loadingbar.ui")[0]
#CLASSES AND MODULES
class Login(QtWidgets.QMainWindow, window1):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent)
self.setupUi(self)
#Set title
self.setWindowTitle('Login Window')
self.setFixedWidth(480)
self.setFixedHeight(620)
self.loginButton.clicked.connect(self.loginfunction)
self.password_field.setEchoMode(QtWidgets.QLineEdit.Password)
self.signupHereButton.clicked.connect(self.gotocreate)
def loginfunction(self):
username = self.username_field.text() #ctansley0#imdb.com
password = self.password_field.text() #ptWYccjTQSKX
if len(username) == 0 or len(password) == 0:
self.login_text.setText("Please input all fields")
else:
conn = sqlite3.connect("customersSQL.db")
cur = conn.cursor()
query = 'SELECT password FROM customer_data WHERE email = \''+username+"\'"
cur.execute(query)
result_pass = cur.fetchone()[0]
if result_pass == password:
self.login_text.setText("Successfully logged in")
gotoload = LoadingBar()
widget.addWidget(gotoload)
widget.setCurrentIndex(widget.currentIndex()+1)
gotoload.progress()
else:
self.login_text.setText("Incorrect username or password")
def gotocreate(self):
createacc=CreateAcc()
widget.addWidget(createacc)
widget.setCurrentIndex(widget.currentIndex()+1)
class CreateAcc(QtWidgets.QMainWindow, window2):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent)
self.setupUi(self)
#title
self.setWindowTitle('Signup Window')
#Push button
self.signupButton.clicked.connect(self.createaccfunction)
self.passwordSignup_field.setEchoMode(QtWidgets.QLineEdit.Password)
self.confirmPass_field.setEchoMode(QtWidgets.QLineEdit.Password)
def createaccfunction(self):
'This is the create account function where it takes the users input and addes it into the database'
email = self.usernameSignUp_field.text()
password = self.confirmPass_field.text()
if self.passwordSignup_field.text()==self.confirmPass_field.text():
password=self.passwordSignup_field.text()
self.signup_text.setText("Successfully created account")
conn = sqlite3.connect("customersSQL.db")
cur = conn.cursor()
#query1 = """INSERT INTO customer_data (email,password)
# VALUES(?,?)""", (email,password)
print (email,password)
cur.execute("""INSERT INTO customer_data (email,password)
VALUES(?,?)""", (email,password))
conn.commit()
time.sleep(3)
login=Login()
widget.addWidget(login)
widget.setCurrentIndex(widget.currentIndex()+1)
class LoadingBar(QtWidgets.QMainWindow, window4):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent)
self.setupUi(self)
#title
self.setWindowTitle('Loading')
self.setWindowFlag(Qt.FramelessWindowHint)
self.setFixedHeight(693)
self.setFixedWidth(351)
#makes progress bar go from 0-100, time scaled
def progress(self):
for i in range(100):
time.sleep(0.1)
self.login_progressBar.setValue(i)
QtWidgets.QApplication.processEvents()
class MainWindow(QtWidgets.QMainWindow, window3):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent)
self.setupUi(self)
app=QApplication(sys.argv)
w1=Login()
widget=QtWidgets.QStackedWidget()
widget.addWidget(w1)
widget.show()
app.exec_()
Related
I am newbie and in that project I am stuck at one point. How can I access functions in MainWindow class from another Window.
For example I need to access Main.list_refresh when Child_EditAccount.btn_EDIT_ACCOUNT_3.clicked . I tried something like signal & slot but doesn't work. I maked 3 different Window with pyQt Designer and I need to link the three together.
new.py
# Designs
from design import Ui_MainWindow
from design_addAccount import Ui_MainWindow_Add
from design_editAccount import Ui_MainWindow_Edit
# Modules
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import pyqtSignal, pyqtSlot
import sqlite3
con = sqlite3.connect('shorts.sqlite3')
cur = con.cursor()
class Main(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Main, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.account_process = AccountProcess()
self.ui.lst_accounts.itemClicked.connect(self.account_process.edit_account)
self.ui.btn_delete_account.clicked.connect(self.account_process.delete_account)
self.ui.btn_edit_account.clicked.connect(self.account_process.edit_account)
self.ui.btn_add_account.clicked.connect(self.account_process.add_account)
self.ui.btn_refresh.clicked.connect(self.list_refresh)
self.refresh_trigger = Child_EditAccount()
self.refresh_trigger.buttonClicked.connect(self.list_refresh)
def list_refresh(self):
self.ui.lst_accounts.clear()
for row in cur.execute("SELECT * FROM users"):
self.ui.lst_accounts.addItem('%s' % (str(row[3])))
class Child_AddAccount(QtWidgets.QMainWindow,Ui_MainWindow_Add):
def __init__(self, parent=None):
super(Child_AddAccount, self).__init__()
self.ui = Ui_MainWindow_Add()
self.ui.setupUi(self)
class Child_EditAccount(QtWidgets.QMainWindow,Ui_MainWindow_Edit):
buttonClicked = pyqtSignal()
def __init__(self, parent=None):
super(Child_EditAccount, self).__init__()
self.ui = Ui_MainWindow_Edit()
self.ui.setupUi(self)
def edit_infos(self, username, password, nickname, id):
self.id = id
self.ui.txtBox_username_3.insert(username)
self.ui.txtBox_password_3.insert(password)
self.ui.txtBox_nickname_3.insert(nickname)
self.ui.btn_EDIT_ACCOUNT_3.clicked.connect(self.update_by_id)
def update_by_id(self):
cur.execute('UPDATE users SET username="%s", password="%s", nickname="%s" WHERE id=%s' % (self.ui.txtBox_username_3.text(), self.ui.txtBox_password_3.text(), self.ui.txtBox_nickname_3.text(), self.id))
con.commit()
self.buttonClicked.emit()
class AccountProcess(QtCore.QObject):
def add_account(self):
self.child_add = Child_AddAccount()
self.child_add.show()
print('Pressed edit button')
def delete_account(self):
print('Pressed delete button')
def edit_account(self, item):
self.child_edit = Child_EditAccount()
for i in cur.execute(f"SELECT * FROM users WHERE nickname=\"{item.text()}\";"):
self.child_edit.edit_infos(str(i[1]), str(i[2]), str(i[3]), str(i[0]))
self.child_edit.show()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
main = Main()
main.show()
sys.exit(app.exec_())
You can use a pyqtSignal to do what you want.
in the Child_EditAccount class add a pyqtsignal
class Child_EditAccount(QtWidgets.QMainWindow,Ui_MainWindow_Add):
buttonClicked = pyqtSignal()
def __init__(self, parent=None):
before the __init__, then when you need to trigger the function use
buttonClicked.emit()
in the function where the button is used in the Child_EditAccount class
Then in the main window, you can create a connection to a function via the pyqtsignal
self.Child_EditAccount.buttonClicked.connect(self.myfunction)
in the __init__ of the main class. where self.Child_EditAccount is the instance of your Child_EditAccount class and self.function is the function you want to trigger Main.list_refresh
You can also create a signal from QtDesigner itself when you create the Ui_MainWindow_Edit
https://doc.qt.io/qt-5/designer-connection-mode.html
be carefull, Child_EditAccount inherite from Ui_MainWindow_Add instead of Ui_MainWindow_Edit probably.
____
what you can also do is link the sigal of the button directly in the main program as in this little example
# Modules
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import pyqtSignal, pyqtSlot
class Main2(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Main2, self).__init__()
self.centralWidget = QtWidgets.QWidget()
self.setCentralWidget(self.centralWidget)
self.but= QtWidgets.QPushButton('tdvfdbt')
self.l = QtWidgets.QHBoxLayout()
self.l.addWidget(self.but)
self.centralWidget.setLayout(self.l)
class Main(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Main, self).__init__()
self.win = Main2()
self.a = self.win.show()
self.win.but.clicked.connect(self.myfunction)
def myfunction(self):
print('called from sub window')
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
ex = Main(app)
ex.setWindowTitle('Model micro GUI')
# ex.showMaximized()
ex.show()
sys.exit(app.exec())
if you know the name of the button widget of the Child_EditAccount class you can link it via
self.Child_EditAccount.btn_EDIT_ACCOUNT_3.clicked.connect(self.myfunction)
##______
Put the pystsignal in the AccountProcess class
class AccountProcess(QtCore.QObject):
buttonClicked = pyqtSignal()
def add_account(self):
self.child_add = Child_AddAccount()
self.child_add.show()
print('Pressed edit button')
def delete_account(self):
print('Pressed delete button')
def edit_account(self, item):
self.child_edit = Child_EditAccount()
for i in cur.execute(f"SELECT * FROM users WHERE nickname=\"{item.text()}\";"):
self.child_edit.edit_infos(str(i[1]), str(i[2]), str(i[3]), str(i[0]))
self.child_edit.buttonClicked.connect(self.EmitAgain)
self.child_edit.show()
def EmitAgain(self):
self.buttonClicked.emit()
Then use it in the main class
class Main(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Main, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.account_process = AccountProcess()
self.account_process.buttonClicked.connect(self.list_refresh)
I am trying to create a gallery view in PyQT5. I am currently trying to group the photos (grey boxes) in months as seen below. I am reading the file location and the date taken of the images through a SQL database.
So far I have managed to lazy load all of the images into the QtWidgets.QListView using a basic model, seen below. I have never worked with PyQt before and I am getting a little lost. Can anyone help me?
import sys
import CustomWidgets as cw
import platform
from PyQt5 import QtCore, QtGui, QtWidgets
import os
import threading
import math
import pyodbc
# GUI FILE
from PhotosPage import Ui_MainWindow
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
# connect tab Pages
self.ui.PageButton_Photos.clicked.connect(lambda: self.ui.stackedWidget.setCurrentWidget(self.ui.PhotosPage))
self.ui.PageButton_Albums.clicked.connect(lambda: self.ui.stackedWidget.setCurrentWidget(self.ui.AlbumsPage))
self.ui.PageButton_People.clicked.connect(lambda: self.ui.stackedWidget.setCurrentWidget(self.ui.PeoplePage))
self.ui.PageButton_Groups.clicked.connect(lambda: self.ui.stackedWidget.setCurrentWidget(self.ui.GroupsPage))
# hide Album info
self.ui.AlbumInfoFrame.hide()
# set model for photos
model = TestListModel(self.ui.PhotosFrame)
self.ui.PhotosFrame.setModel(model)
self.ui.PhotosFrame.setSpacing(5)
self.show()
class TestListModel(QtCore.QAbstractListModel):
def __init__(self, parent=None):
QtCore.QAbstractListModel.__init__(self, parent)
self.list = parent
self.fileList = os.listdir('P:/PhotoSorterInfo/MiniPhotos')
# self.setFileList()
def setFileList(self):
print(self.readDataBase()[0])
def rowCount(self, index):
return len(self.fileList)
def data(self, index, role):
if role == QtCore.Qt.DisplayRole:
if not self.list.indexWidget(index):
button = QtWidgets.QPushButton()
button.setIcon(QtGui.QIcon("P:/PhotoSorterInfo/MiniPhotos/" + self.fileList[index.row()]))
button.setIconSize(QtCore.QSize(300, 175))
button.setFlat(True)
self.list.setIndexWidget(index, button)
return QtCore.QVariant()
if role == QtCore.Qt.SizeHintRole:
return QtCore.QSize(300, 175)
def columnCount(self, index):
pass
def readDataBase(self, id=10):
returnInfo = DataBase.execute(
"""SELECT Files_tbl.ID, Files_tbl.Name, Files_tbl.FileType, Files_tbl.Width, Files_tbl.Height, Files_tbl.Size, Files_tbl.DateTaken, FileDirectories_tbl.FileLocation
FROM Files_tbl, FileDirectories_tbl
WHERE FileDirectories_tbl.ID = Files_tbl.FileLocation
ORDER BY DateTaken DESC;""")
# place info into dictionary
Photos = []
results = []
columns = [column[0] for column in DataBase.description]
for row in returnInfo.fetchall():
Photos.append(dict(zip(columns, row)))
return Photos
if __name__ == "__main__":
filePath = os.getcwd()
DataBase = pyodbc.connect(r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=' + filePath + r'\Database\PhotosDatabase.accdb;')
DataBase = DataBase.cursor()
import sys
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec_())
In PyQt5, I have a window which reads from a database and adds that information to a widget. There is also a second window, which, when opened, adds a new table to the database. What I'm trying to do is reload the main window when the secondary window is closed. I don't want to change the secondary window to a QDialoge and need to use .show(), not .exec_(). Is there any way I could do this.
There is my code:
import sys
import sqlite3
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow, QPushButton, QListWidget, QVBoxLayout, QWidget
from PyQt5.QtCore import Qt
class SecondWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(SecondWindow, self).__init__(*args, **kwargs)
self.setWindowTitle("App 2")
label = QLabel("INSERTED VALUES")
label.setAlignment(Qt.AlignCenter)
self.setCentralWidget(label)
#Open Database
self.conn = sqlite3.connect("connections.db")
self.cursor = self.conn.cursor()
#Add New Table To Database
self.cursor.execute('''CREATE TABLE `New`
(name text, GD text)''')
self.conn.commit()
self.conn.close()
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.setWindowTitle("App")
self.list = QListWidget()
self.cursorCount = 0
#Open Database
self.conn = sqlite3.connect("connections.db")
self.cursor = self.conn.cursor()
try:
#Try To Create A Table If It Doesn't exit
self.cursor.execute('''CREATE TABLE `Default`
(name text, GD text)''')
except:
pass
#Get A List Of All The Tables
self.cursor.execute('SELECT name FROM sqlite_master WHERE type= "table"')
for table in self.cursor.fetchall():
self.list.insertItem(self.cursorCount, table[0])
self.cursorCount += 1
self.conn.commit()
self.conn.close()
self.list.item(0).setSelected(True)
self.btn = QPushButton()
self.btn.setText("click me!")
self.btn.clicked.connect(self.openWin)
winWidget = QWidget()
self.setCentralWidget(winWidget)
layout = QVBoxLayout()
layout.addWidget(self.list)
layout.addWidget(self.btn)
winWidget.setLayout(layout)
def openWin(self):
self.win = SecondWindow()
self.win.show()
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
Any help would be appreciated
I am not sure I got your problem right but I think you could use signals from PyQt5 and the closeEvent method. Basically, you should create a signal in the second window that will be emitted when the close event happens, and connect this signal to a slot in the first window.
import with:
from PyQt5.QtCore import pyqtSignal
when declaring the second window class, before init, declare your signal:
class SecondWindow(QMainWindow):
window_closed = pyqtSignal()
create a method named closeEvent that will be called when you close the window, and when it happens it should emit the signal you previously declared:
def closeEvent(self, event):
self.window_closed.emit()
event.accept()
# event.ignore() # if you want the window to never be closed
and modify the MainWindow openWin method to connect the signal from the second window to the method you want to be called:
def openWin(self):
self.win = SecondWindow()
self.win.window_closed.connect(self.do_something)
self.win.show()
def do_something(self):
print("You closed the second window!")
Edit:
The entire code should be something like this (I removed the parts database related to test myself, seems to be working fine).
import sys
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow, QPushButton, QListWidget, QVBoxLayout, QWidget
from PyQt5.QtCore import Qt, pyqtSignal
class SecondWindow(QMainWindow):
window_closed = pyqtSignal()
def __init__(self, *args, **kwargs):
super(SecondWindow, self).__init__(*args, **kwargs)
self.setWindowTitle("App 2")
label = QLabel("INSERTED VALUES")
label.setAlignment(Qt.AlignCenter)
self.setCentralWidget(label)
def closeEvent(self, event):
self.window_closed.emit()
event.accept()
# event.ignore() # if you want the window to never be closed
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.setWindowTitle("App")
self.btn = QPushButton()
self.btn.setText("click me!")
self.btn.clicked.connect(self.openWin)
winWidget = QWidget()
self.setCentralWidget(winWidget)
layout = QVBoxLayout()
layout.addWidget(self.btn)
winWidget.setLayout(layout)
def openWin(self):
self.win = SecondWindow()
self.win.window_closed.connect(self.do_something)
self.win.show()
def do_something(self):
print("You closed the second window!")
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
In the default behavior of editing a cell in a QtableView, when the user clicks away either to another widget or closes the form, the edits are lost. After a lot of googling, I have found a way to save the edits if the user selects another widget in the form, but if the form is closed, the edits are still lost. The blog post is here.
I attempted to call the closeEditor method from the forms closeEvent, but it requires two parameters: the editor and hint. I can provide QAbstractItemDelegate.NoHint but the editor is expecting the QlineEdit object where the editing is taking place. I am lost on how to provide this for the cell currently being edited.
Here is a gif of the current behaviour:
My question is how do I provide the QlineEdit of the cell being edited?
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSql import *
from PyQt5.QtWidgets import *
from phones import *
class Main(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self, parent)
self.resize(490, 998)
self.layoutWidget = QWidget(self)
self.layoutWidget.setObjectName("layoutWidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.layoutWidget)
self.horizontalLayout_7 = QtWidgets.QHBoxLayout()
self.new_phone = QtWidgets.QPushButton(self.layoutWidget)
self.new_phone.setObjectName("new_phone")
self.new_phone.setText("New Phone")
self.horizontalLayout_7.addWidget(self.new_phone)
self.delete_phone = QtWidgets.QPushButton(self.layoutWidget)
self.delete_phone.setObjectName("delete_phone")
self.delete_phone.setText("Delete phone")
self.horizontalLayout_7.addWidget(self.delete_phone)
self.verticalLayout.addLayout(self.horizontalLayout_7)
self.phone_view = Syn_tableview()
self.verticalLayout.addWidget(self.phone_view)
self.cont_id = '9'
self.setCentralWidget(self.layoutWidget)
self.new_phone.clicked.connect(self.add_phone)
self.populate_phones()
def populate_phones(self):
self.phone_model = QSqlTableModel(self)
self.phone_model.setTable("contact_phones")
self.phone_model.setFilter("contact_id='{0}'".format(self.cont_id))
self.phone_model.select()
self.phone_view.setModel(self.phone_model)
self.phone_view.resizeColumnsToContents()
def add_phone(self):
self.phone_model.submitAll()
self.phone_model.setEditStrategy(QSqlTableModel.OnManualSubmit)
row = self.phone_model.rowCount()
record = self.phone_model.record()
record.setGenerated('id', False) #primary key
record.setValue('contact_id', self.cont_id) #foreign key
self.phone_model.insertRecord(row, record)
phone_index_edit = self.phone_model.index(row, self.phone_model.fieldIndex('phone_number'))
self.phone_view.edit(phone_index_edit)
def closeEvent(self, event):
submit = self.phone_model.submitAll()
#This is the problem
self.phone_view.closeEditor("QLineEdit", QAbstractItemDelegate.NoHint)
class Syn_tableview(QTableView):
def __init__(self, *args, **kwargs):
QTableView.__init__(self, *args, **kwargs)
def closeEditor(self, editor, hint):
if hint == QAbstractItemDelegate.NoHint:
QTableView.closeEditor(self, editor,
QAbstractItemDelegate.SubmitModelCache)
if __name__=="__main__":
app=QApplication(sys.argv)
db = QSqlDatabase.addDatabase("QPSQL");
db.setHostName(server)
db.setDatabaseName(database)
db.setUserName(user)
db.setPassword(pword)
myapp = Main()
myapp.show()
sys.exit(app.exec_())
The delegate editors are children of the QTableView so you can use findChildren to get them, to make sure they are not other children you can set an objectName that allows you to filter them:
import sys
from PyQt5 import QtCore, QtSql, QtWidgets
def create_connection():
db = QtSql.QSqlDatabase.addDatabase("QPSQL")
# FIXME
db.setHostName("server")
db.setDatabaseName("database")
db.setUserName("user")
db.setPassword("pword")
if not db.open():
print(db.lastError().text())
return False
return True
class Syn_Delegate(QtWidgets.QStyledItemDelegate):
def createEditor(self, parent, option, index):
editor = super(Syn_Delegate, self).createEditor(parent, option, index)
if isinstance(editor, QtWidgets.QWidget):
editor.setObjectName("syn_editor")
return editor
class Syn_Tableview(QtWidgets.QTableView):
def closeEditor(self, editor, hint):
if hint == QtWidgets.QAbstractItemDelegate.NoHint:
hint = QtWidgets.QAbstractItemDelegate.SubmitModelCache
super(Syn_Tableview, self).closeEditor(editor, hint)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.new_phone = QtWidgets.QPushButton(self.tr("New Phone"))
self.delete_phone = QtWidgets.QPushButton(self.tr("Delete phone"))
self.phone_view = Syn_Tableview()
self.phone_model = QtSql.QSqlTableModel()
self.phone_model.setEditStrategy(QtSql.QSqlTableModel.OnManualSubmit)
self.phone_view.setModel(self.phone_model)
self.phone_view.resizeColumnsToContents()
delegate = Syn_Delegate(self)
self.phone_view.setItemDelegate(delegate)
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
lay = QtWidgets.QGridLayout(central_widget)
lay.addWidget(self.new_phone, 0, 0)
lay.addWidget(self.delete_phone, 0, 1)
lay.addWidget(self.phone_view, 1, 0, 1, 2)
self._contact_id = "9"
self.populate_phones()
self.new_phone.clicked.connect(self.add_phone)
#property
def contact_id(self):
return self._contact_id
def populate_phones(self):
self.phone_model.setTable("contact_phones")
self.phone_model.setFilter("contact_id='{0}'".format(self.contact_id))
self.phone_model.select()
#QtCore.pyqtSlot()
def add_phone(self):
self.phone_model.submitAll()
row = self.phone_model.rowCount()
record = self.phone_model.record()
record.setGenerated("id", False) # primary key
record.setValue("contact_id", self.contact_id) # foreign key
self.phone_model.insertRecord(row, record)
phone_index_edit = self.phone_model.index(
row, self.phone_model.fieldIndex("phone_number")
)
if phone_index_edit.isValid():
self.phone_view.edit(phone_index_edit)
def closeEvent(self, event):
for editor in self.phone_view.findChildren(QtWidgets.QWidget, "syn_editor"):
self.phone_view.commitData(editor)
submit = self.phone_model.submitAll()
super().closeEvent(event)
def main():
app = QtWidgets.QApplication(sys.argv)
if not create_connection():
sys.exit(-1)
w = MainWindow()
w.show()
w.resize(640, 480)
ret = sys.exit(app.exec_())
sys.exit(ret)
if __name__ == "__main__":
main()
Problems with Qt How to open 2 windows that are called between them
Hi all, I'm new with Qt, the problem I have is the following:
I have a Login.py window when I call with a button open a new Panel_administrator.py window and this window has a button that can call Login.py
in a nutshell:
Login.py---->calls -----> Panel_Administrador.py and
Panel_Administrador.py ----> calls ----> Login.py
Gives me the following error:
Traceback (most recent call last):
.................
ImportError: cannot import name 'panel_administrador'
my code:
import sys
import time
from PyQt5 import uic
from PyQt5.QtWidgets import QApplication, QWidget
import Con_pos
from Registro import Registro
from Panel_Administrador import panel_administrador
class Login(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent= parent)
uic.loadUi("UI/Login.ui", self)
self.registro.clicked.connect(self.view_Registro)
self.ingresar.clicked.connect(self.autenticar)
def autenticar(self):
pid = self.getPID()
con = Con_pos.con_pos()
user = self.in_login.text()
password = self.in_pass.text()
fecha = time.strftime("%X") + " " + time.strftime("%x")
if user != "" and password != "":
consulta = ''' SELECT "id_usuario" FROM "usuarios"."Usuario" WHERE "id_usuario" = '%s' ; ''' %(user)
c_user = con.consulta(consulta)
consulta = ''' SELECT "pass" FROM "usuarios"."Usuario" WHERE "id_usuario" = '%s' ;''' %(user)
c_pass = con.consulta(consulta)
if c_user != None or not c_pass:
c_pass = c_pass[0][0]
if c_pass == password:
consulta = ''' INSERT INTO "usuarios"."sesion" VALUES ('%s', '%s', %s); '''%(user ,fecha, pid)
con.insertar(consulta)
print("Ingresando al sistema...")
if self.administrador(user):
self.admi = panel_administrador()
self.admi.show()
else:
print("Usuario o password incorrecto")
def administrador(self, user):
ad = ''' SELECT "id_rol" FROM "usuarios"."Rol" WHERE "rol" = 'administrador'; '''
consulta = ''' SELECT "id_usuario_Usuario" FROM "usuarios"."Usuario_Rol" WHERE "id_rol_Rol" = %s and "id_usuario_Usuario" = '%s' ''' %(ad, user)
con_res = Con_pos.con_pos().consulta(consulta)
print(con_res)
if con_res or con_res != None:
return True
else:
return False;
def getPID(self):
con = Con_pos.con_pos()
func = "pg_backend_pid"
pid = con.call_proc(func)
pid = pid[0][0]
return pid
def view_Registro(self):
self.reg = Registro()
self.reg.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
login = Login()
login.show()
sys.exit(app.exec())
Panel_Administrador.py
import sys
from PyQt5 import uic
from PyQt5.QtWidgets import QApplication, QWidget
from Designar import designar
from Funciones import funciones
from Login import Login
from Admi_Users import admin_user
from Rol import rol
class panel_administrador(QWidget):
def __init__(self):
QWidget.__init__(self)
uic.loadUi("UI/Panel_Administrador.ui", self)
self.btn_funciones.clicked.connect(self.view_funciones)
self.btn_roles.clicked.connect(self.view_roles)
self.btn_usuarios.clicked.connect(self.view_usuario)
self.btn_designar.clicked.connect(self.view_designar)
self.btn_login.clicked.connect(self.view_login)
def view_funciones(self):
self.f = funciones()
self.f.show()
def view_roles(self):
self.r = rol()
self.r.show()
def view_usuario(self):
self.u = admin_user()
self.u.show()
def view_designar(self):
self.d = designar()
self.d.show()
def view_login(self):
self.l = Login()
self.l.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
pa = panel_administrador()
pa.show()
sys.exit(app.exec())
The problem that occurs is called circular import, where it generates a recursive cycle. The solution is to structure the code better. In this case I will show an example of how to do it, I will create 2 classes called admin panel and Login that contains a button each, the object is to call the other window and vice versa. Create another file that I will call main.py where I will make the connections between the buttons.
The files have the following structure:
├── Login.py
├── main.py
└── Panel_Administrador.py
Login.py
from PyQt5.QtWidgets import QWidget, QPushButton, QVBoxLayout
class Login(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent= parent)
self.setWindowTitle("Login")
lay = QVBoxLayout(self)
self.btn = QPushButton("LLamar a Panel Administrador")
lay.addWidget(self.btn)
self.btn.clicked.connect(self.hide)
Panel_Administrador.py
from PyQt5.QtWidgets import QWidget, QPushButton, QVBoxLayout
class panel_administrador(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent=parent)
self.setWindowTitle("Panel de Administración")
lay = QVBoxLayout(self)
self.btn = QPushButton("Llamar a Login")
lay.addWidget(self.btn)
self.btn.clicked.connect(self.hide)
main.py
from PyQt5.QtWidgets import QApplication
import sys
from Panel_Administrador import panel_administrador
from Login import Login
if __name__ == "__main__":
app = QApplication(sys.argv)
p = panel_administrador()
l = Login()
l.btn.clicked.connect(p.show)
p.btn.clicked.connect(l.show)
p.show()
sys.exit(app.exec())