简体   繁体   中英

PyQt5 Access MainWindow from Another Window

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM