Python Forum
Running external Python file as a subwindow
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Running external Python file as a subwindow
#1
Hello, everyone. I am a beginner programmer developing an MDI application. So far, I have two files:

main.py (MainWindow with mdiArea and menuBar)
users.py (window that displays users)

I am able to run the users.py file from main.py by using import subprocess and then calling it:

subprocess.call(["python", "users.py"])

It works, but I need the Users window to be a subwindow in the main application. Can anyone please point me in the right direction? Thanks a lot for your time and help.
Reply
#2
You're going to need to explain in more detail and show code. It's not clear why you (think you) need a separate process.
Reply
#3
I'm developing an MDI application which I know is going to be pretty large. It would make sense to me to split the code instead of having one huge Python file that holds everything. I come from the C# .Net world and I think code-splitting makes it easier to debug, easier to maintain.

The attached screenshot shows the User window outside the mdiArea and I would like to run it inside, otherwise it will totally defeat the purpose of developing an MDI application.

Attached Files

Thumbnail(s)
   
Reply
#4
Haven't you already achieved that here?

https://python-forum.io/thread-34470-pos...#pid145454
Reply
#5
Yes, of course splitting an application up into separate files is important in any large project, but what I'm getting at is do those really need to be entirely separate programs? Can't they just be modules with functions and classes that you import where you need them (like one would do in C#, Java or anything else really)? I don't know what MDI is, so I don't know whether it imposes this separate program thing on you.
Reply
#6
(Aug-04-2021, 05:28 PM)Axel_Erfurt Wrote: Haven't you already achieved that here?

https://python-forum.io/thread-34470-pos...#pid145454

Nope, because in regards to that Post, the entire code is in the same file and now I want to split the code, otherwise it will be a nightmare to maintain.
Reply
#7
They do not have to be separate programs. I guess they could be modules. The question now is how do I make the users.py file a module I can import. Here is the code to my users.py file:

import sys
import pymysql
from datetime import datetime
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QMessageBox

rowNo = 1

connection = pymysql.connect(
    host='--------',
    user='--------',
    password='-------',
    db='------------')

cur = connection.cursor()
sql0 = "CREATE TEMPORARY TABLE users_temp AS SELECT * FROM users_view ORDER BY name"
cur.execute(sql0)


class Ui_Dialog(object):
    def setupUi(self, myDialog):
        myDialog.setObjectName("myDialog")
        myDialog.resize(468, 291)

        # ----------------------- Buttons -----------------------
        self.pushButton_first = QtWidgets.QPushButton(myDialog)
        self.pushButton_first.setGeometry(QtCore.QRect(50, 210, 75, 23))
        self.pushButton_first.setObjectName("pushButton_first")

        self.pushButton_previous = QtWidgets.QPushButton(myDialog)
        self.pushButton_previous.setGeometry(QtCore.QRect(140, 210, 75, 23))
        self.pushButton_previous.setObjectName("pushButton_previous")

        self.pushButton_next = QtWidgets.QPushButton(myDialog)
        self.pushButton_next.setGeometry(QtCore.QRect(230, 210, 75, 23))
        self.pushButton_next.setObjectName("pushButton_next")

        self.pushButton_last = QtWidgets.QPushButton(myDialog)
        self.pushButton_last.setGeometry(QtCore.QRect(330, 210, 75, 23))
        self.pushButton_last.setObjectName("pushButton_last")

        self.pushButton_add = QtWidgets.QPushButton(myDialog)
        self.pushButton_add.setGeometry(QtCore.QRect(140, 240, 75, 23))
        self.pushButton_add.setObjectName("pushButton_add")

        self.pushButton_edit = QtWidgets.QPushButton(myDialog)
        self.pushButton_edit.setGeometry(QtCore.QRect(230, 240, 75, 23))
        self.pushButton_edit.setObjectName("pushButton_edit")

        self.pushButton_update = QtWidgets.QPushButton(myDialog)
        self.pushButton_update.setGeometry(QtCore.QRect(230, 240, 75, 23))
        self.pushButton_update.setObjectName("pushButton_update")

        self.pushButton_cancel = QtWidgets.QPushButton(myDialog)
        self.pushButton_cancel.setGeometry(QtCore.QRect(150, 240, 75, 23))
        self.pushButton_cancel.setObjectName("pushButton_cancel")

        self.pushButton_save = QtWidgets.QPushButton(myDialog)
        self.pushButton_save.setGeometry(QtCore.QRect(230, 240, 75, 23))
        self.pushButton_save.setObjectName("pushButton_save")

        self.pushButton_delete = QtWidgets.QPushButton(myDialog)
        self.pushButton_delete.setGeometry(QtCore.QRect(330, 240, 75, 23))
        self.pushButton_delete.setObjectName("pushButton_delete")

        # ----------------------- Input Fields -----------------------
        self.lineEdit_id = QtWidgets.QLineEdit(myDialog)
        self.lineEdit_id.setGeometry(QtCore.QRect(70, 80, 331, 20))
        self.lineEdit_id.setObjectName("lineEdit_id")

        self.lineEdit_name = QtWidgets.QLineEdit(myDialog,  placeholderText="Name")
        self.lineEdit_name.setGeometry(QtCore.QRect(70, 80, 331, 20))
        self.lineEdit_name.setObjectName("lineEdit_name")

        self.lineEdit_login = QtWidgets.QLineEdit(myDialog,  placeholderText="Login")
        self.lineEdit_login.setGeometry(QtCore.QRect(70, 110, 113, 20))
        self.lineEdit_login.setObjectName("lineEdit_login")

        self.lineEdit_pwd = QtWidgets.QLineEdit(myDialog,  placeholderText="Password", echoMode=2)
        self.lineEdit_pwd.setGeometry(QtCore.QRect(70, 140, 113, 20))
        self.lineEdit_pwd.setObjectName("lineEdit_pwd")

        self.reTranslateUi(myDialog)
        QtCore.QMetaObject.connectSlotsByName(myDialog)

    def reTranslateUi(self, myDialog):
        _translate = QtCore.QCoreApplication.translate
        myDialog.setWindowTitle(_translate("myDialog", "Users"))

        self.pushButton_first.setText(_translate("myDialog", "<< First"))
        self.pushButton_first.setObjectName("pushButton_first")
        self.pushButton_first.clicked.connect(ShowFirst)

        self.pushButton_previous.setText(_translate("myDialog", "< Previous"))
        self.pushButton_previous.setObjectName("pushButton_previous")
        self.pushButton_previous.clicked.connect(ShowPrevious)

        self.pushButton_next.setText(_translate("myDialog", "Next >"))
        self.pushButton_next.setObjectName("pushButton_next")
        self.pushButton_next.clicked.connect(ShowNext)

        self.pushButton_last.setText(_translate("myDialog", "Last >>"))
        self.pushButton_last.setObjectName("pushButton_last")
        self.pushButton_last.clicked.connect(ShowLast)

        self.pushButton_add.setText(_translate("myDialog", "Add +"))
        self.pushButton_add.setObjectName("pushButton_add")
        self.pushButton_add.clicked.connect(addRecord)

        self.pushButton_edit.setText(_translate("myDialog", "Edit"))
        self.pushButton_edit.setObjectName("pushButton_edit")
        self.pushButton_edit.clicked.connect(editRecord)

        self.pushButton_save.setText(_translate("myDialog", "Save"))
        self.pushButton_save.setObjectName("pushButton_save")
        self.pushButton_save.clicked.connect(saveRecord)

        self.pushButton_cancel.setText(_translate("myDialog", "Cancel"))
        self.pushButton_cancel.setObjectName("pushButton_cancel")
        self.pushButton_cancel.clicked.connect(cancelAll)

        self.pushButton_update.setText(_translate("myDialog", "Atualizar"))
        self.pushButton_update.setObjectName("pushButton_update")
        self.pushButton_update.clicked.connect(updateRecord)

        self.pushButton_delete.setText(_translate("myDialog", "Delete"))
        self.pushButton_delete.setObjectName("pushButton_delete")
        self.pushButton_delete.clicked.connect(deleteRecord)

        self.pushButton_cancel.hide()
        self.pushButton_save.hide()
        self.pushButton_update.hide()

        ShowFirst()
        lockForm()


def ShowFirst():
    global rowNo
    sql = "SELECT number, name, login, pwd, id FROM users_temp"
    cur.execute(sql)
    row = cur.fetchone()
    if row:
        ui.lineEdit_name.setText(row[1])
        ui.lineEdit_login.setText(row[2])
        ui.lineEdit_pwd.setText(row[3])
        ui.lineEdit_id.setText(str(row[4]))
        rowNo = row[0]
    else:
        QMessageBox.critical(None, "Erro:", "Não foi possível acessar os dados.\n Cheque o servidor.")


def ShowPrevious():
    global rowNo
    rowNo -= 1
    sql = "SELECT number, name, login, pwd, id FROM users_temp WHERE number=%s"
    cur.execute(sql, rowNo)
    row = cur.fetchone()
    if row:
        ui.lineEdit_name.setText(row[1])
        ui.lineEdit_login.setText(row[2])
        ui.lineEdit_pwd.setText(row[3])
        ui.lineEdit_id.setText(str(row[4]))
    else:
        rowNo += 1


def ShowNext():
    global rowNo
    rowNo += 1
    sql = "SELECT number, name, login, pwd, id FROM users_temp WHERE number=%s"
    cur.execute(sql, rowNo)
    row = cur.fetchone()
    if row:
        ui.lineEdit_name.setText(row[1])
        ui.lineEdit_login.setText(row[2])
        ui.lineEdit_pwd.setText(row[3])
        ui.lineEdit_id.setText(str(row[4]))
    else:
        rowNo -= 1


def ShowLast():
    global rowNo
    sql = "SELECT number, name, login, pwd, id FROM users_temp"
    cur.execute(sql)
    for row in cur.fetchall():
        ui.lineEdit_name.setText(row[1])
        ui.lineEdit_login.setText(row[2])
        ui.lineEdit_pwd.setText(row[3])
        ui.lineEdit_id.setText(str(row[4]))
        rowNo = row[0]


def addRecord():
    clearAll()
    ui.pushButton_edit.hide()
    ui.pushButton_delete.hide()
    ui.pushButton_add.hide()
    ui.pushButton_first.hide()
    ui.pushButton_previous.hide()
    ui.pushButton_next.hide()
    ui.pushButton_last.hide()
    ui.pushButton_save.show()
    ui.pushButton_cancel.show()
    unlockForm()


def editRecord():
    ui.pushButton_edit.hide()
    ui.pushButton_delete.hide()
    ui.pushButton_add.hide()
    ui.pushButton_first.hide()
    ui.pushButton_previous.hide()
    ui.pushButton_next.hide()
    ui.pushButton_last.hide()
    ui.pushButton_save.hide()
    ui.pushButton_cancel.show()
    ui.pushButton_update.show()
    unlockForm()


def updateRecord():
    try:
        if ui.lineEdit_name.text() and ui.lineEdit_login.text() and ui.lineEdit_pwd.text() != "":
            cur.execute("UPDATE usuarios SET user_real_name=%s, login=%s, pwd=%s WHERE cod_usuario=%s",
                        (ui.lineEdit_name.text(), ui.lineEdit_login.text(),
                         ui.lineEdit_pwd.text(), ui.lineEdit_id.text()))
            connection.commit()
            toggleButtonsVisibility()
            QMessageBox.information(None, "Informação:", "Dados atualizados com sucesso!")
            refreshData()
            lockForm()
        else:
            QMessageBox.warning(None, "Atenção:", "Por favor preencha os campos em branco!")
    except Exception as e:
        QMessageBox.critical(None, "Erro:", "Não foi possível atualizar os dados.\n Cheque o servidor. \n " + str(e))


def deleteRecord():
    cur.execute("DELETE FROM usuarios WHERE cod_usuario =" + ui.lineEdit_id.text())
    connection.commit()
    clearAll()
    toggleButtonsVisibility()
    QMessageBox.information(None, "Informação:", "Usuário deletado com sucesso!")
    refreshData()


def refreshData():
    sql1 = "DROP TEMPORARY TABLE users_temp"
    cur.execute(sql1)
    sql2 = "CREATE TEMPORARY TABLE users_temp AS SELECT * FROM users_view ORDER BY name"
    cur.execute(sql2)
    ShowFirst()


def cancelAll():
    ShowFirst()
    ui.pushButton_edit.show()
    ui.pushButton_delete.show()
    ui.pushButton_add.show()
    ui.pushButton_first.show()
    ui.pushButton_previous.show()
    ui.pushButton_next.show()
    ui.pushButton_last.show()
    ui.pushButton_save.hide()
    ui.pushButton_cancel.hide()
    ui.pushButton_update.hide()


def toggleButtonsVisibility():
    ui.pushButton_add.show()
    ui.pushButton_delete.show()
    ui.pushButton_edit.show()
    ui.pushButton_first.show()
    ui.pushButton_previous.show()
    ui.pushButton_next.show()
    ui.pushButton_last.show()
    ui.pushButton_save.hide()
    ui.pushButton_save.hide()
    ui.pushButton_cancel.hide()
    ui.pushButton_update.hide()


def lockForm():
    for fields in Dialog.findChildren(QtWidgets.QLineEdit):
        fields.setReadOnly(True)


def unlockForm():
    for fields in Dialog.findChildren(QtWidgets.QLineEdit):
        fields.setReadOnly(False)


def clearAll():
    for fields in Dialog.findChildren(QtWidgets.QLineEdit):
        fields.clear()


def saveRecord():
    try:
        if ui.lineEdit_name.text() and ui.lineEdit_login.text() and ui.lineEdit_pwd.text() != "":
            cur.execute('INSERT INTO usuarios (user_real_name, login, pwd, data_cadastro) VALUES(%s, %s, %s, %s)',
                        (ui.lineEdit_name.text(), ui.lineEdit_login.text(), ui.lineEdit_pwd.text(), datetime.today()))
            connection.commit()
            clearAll()
            toggleButtonsVisibility()
            QMessageBox.information(None, "Informação:", "Dados adicionados com sucesso!")
            refreshData()
            lockForm()
        else:
            QMessageBox.warning(None, "Atenção:", "Por favor preencha os campos em branco!")
    except Exception as e:
        QMessageBox.critical(None, "Erro:", "Não foi possível inserir os dados.\n Cheque o servidor. \n " + str(e))


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    Dialog = QtWidgets.QDialog()
    ui = Ui_Dialog()
    ui.setupUi(Dialog)
    Dialog.show()
    sys.exit(Dialog.exec_())
Reply
#8
You haven't shown any code, so it's literally impossible to help further. Of course I'm not saying each single module needs to contain a single class - perhaps there are more in there. No-one can suggest anything without seeing any code. Have you been through a Python tutorial to understand classes? If you're an experienced C# programmer, this shouldn't be too hard.
Reply
#9
I forgot to insert the code, but I edited the reply. It's there now.
Reply
#10
An Example for showing a second window

run win.py

win.py

from PyQt5.QtWidgets import QMainWindow, QApplication, QAction
from PyQt5.QtGui import QIcon
import second_win

class MainWin(QMainWindow):
    def __init__(self, parent = None):
        super(MainWin, self).__init__(parent)
        self.setupUI()
        
    def setupUI(self):
        self.setGeometry(0, 0, 600, 400)
        self.file_tool_bar = self.addToolBar("File")
        self.my_action = QAction(QIcon.fromTheme("folder"), "", triggered = self.show_second_win)
        self.file_tool_bar.addAction(self.my_action)
        
    def show_second_win(self):
        print("open second win")
        self.sw = second_win.SecondWin()
        self.sw.show()


if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    win = MainWin()
    win.setWindowTitle("Main Window")
    win.show()

    sys.exit(app.exec_())
second_win.py

from PyQt5.QtWidgets import QMainWindow, QApplication

class SecondWin(QMainWindow):
    def __init__(self, parent = None):
        super(SecondWin, self).__init__(parent)
        self.setupUI()
        
    def setupUI(self):
        self.setGeometry(100, 100, 400, 300)
        self.setWindowTitle("Second Window")
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [PyQt] Subwindow catlessness 5 2,858 Oct-23-2021, 06:28 PM
Last Post: catlessness
  [PyQt] Can't neither setWindowFlags nor setFixedSize of a subwindow. JayCee 10 4,142 Aug-06-2021, 08:06 PM
Last Post: JayCee
  [PyQt] App crashes when reopening a subwindow JayCee 13 5,088 Aug-04-2021, 01:51 AM
Last Post: JayCee

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020