Solved Show a Loading Home Dialog before starting MainWindow
-
Hi,
I have an app that parses a file and show data in QtableView. Before, I had a button in the mainwindow to load the source file. What I'm trying to implement now is a Dialog Window with only one button, the only purpose of this dialog window is to give a minimalistic and simple view to the user, where he can first select the file to be parsed and have a Loading progress bar (or something else) while the LoadData() function is runned. The Home Dialog should only be hidden/closed when the parsing is done.
What I'm achieving now:
- The Home dialog starts
- the user selects the file
- the Home dialog disappears
- LoadData is running
- when LoadData is finished, the MainWindow shows with the data being parsed and tables filled.
Which is very close to what I want, except the part when the Home Dialog disappears before LoadData gets executed.
Here's my code if anyone can help.
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self, parent=None): """ .. __init__ code lines """ self.hide() d = HomeDialog() if d.exec_(): self.LoadData(d.path) def LoadData(self, file_path): """ Parsing lines of code """ #Parsing finished -> show the mainWindow self.show() class HomeDialog(QtWidgets.QDialog, home_dialog.Ui_Dialog): def __init__(self, parent=None): super(HomeDialog, self).__init__(parent) self.setupUi(self) self.openB6.clicked.connect(self.get_file_name) def get_file_name(self): file_name = QtWidgets.QFileDialog.getOpenFileName(self, 'Open config file', dir=path.join("/"), filter="B6 (*.b6)") if not file_name[0]: return None else: self.path = file_name self.accept() if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) app.setStyle(ProxyStyle()) mainWin = MainWindow() mainWin.show() sys.exit(app.exec_())
-
Hi,
It looks a bit like a "mini-wizard" so you could use a QWizard for that.
Not that if you have a long running operation, you might want to use QtConcurrent::run to execute it and let the GUI show a QProgressBar or a QProgressDialog depending on the road you take.
-
Hi @SGaist ,
I've been looking at QWizard, not sure if this is what i'm looking for, in addition to that, I gave it a try but struggling hard to implement it. Is there now other classes I can use ?
-
-
i've looking into QProgressDialog, the progressDialog is shown but not updated. From what I saw on several forums posts: do I have to use a QThread as well ?
Here's my code:
class progressBar(QtWidgets.QProgressDialog): def __init__(self, parent= None): super(progressBar, self).__init__(parent) pd = QtWidgets.QProgressDialog('loading...', 'cancel', 0, 100, self) class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self, parent=None): """ .. __init__ code lines """ self.hide() d = HomeDialog() if d.exec_(): self.LoadData(d.path) def LoadData(self, file_path): progress = progressBar() progress.show() progress.setValue(1) """ Parsing lines of code progress.setValue(30) .. .. progress.setValue(70) .. .. """ progress.hide() #Parsing finished -> show the mainWindow self.show() class HomeDialog(QtWidgets.QDialog, home_dialog.Ui_Dialog): def __init__(self, parent=None): super(HomeDialog, self).__init__(parent) self.setupUi(self) self.openB6.clicked.connect(self.get_file_name) def get_file_name(self): file_name = QtWidgets.QFileDialog.getOpenFileName(self, 'Open config file', dir=path.join("/"), filter="B6 (*.b6)") if not file_name[0]: return None else: self.path = file_name self.accept() if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) app.setStyle(ProxyStyle()) mainWin = MainWindow() mainWin.show() sys.exit(app.exec_())
-
@hachbani said in Show a Loading Home Dialog before starting MainWindow:
class progressBar(QtWidgets.QProgressDialog):
def init(self, parent= None):
super(progressBar, self).init(parent)
pd = QtWidgets.QProgressDialog('loading...', 'cancel', 0, 100, self)Why do you create an instance of QtWidgets.QProgressDialog in progressBar which is already itself a QtWidgets.QProgressDialog?!
"do I have to use a QThread as well ?" - depends on how you process.
-
To be honest I don't really know, for aesthetic reasons I guess, I've tried without creating the class (
pd=QtWidgets.QProgressDialog('loading...', 'cancel', 0, 100, self)
) in the LoadData function. I get the same result -
@hachbani said in Show a Loading Home Dialog before starting MainWindow:
for aesthetic reasons I guess
Aesthetic reasons? There is absolutely no need for this pd - you are basically creating TWO progress dialogs (but only show one).
Why it does not work: well, you do not show how you process the data after showing progress dialog... -
@hachbani Basic approach is: show progress dialog, start your long lasting operation, on each iteration emit a signal which is connected to https://doc.qt.io/qt-5/qprogressdialog.html#value-prop slot.
-
I updated the code a follow:
created a signal: self.change_val = QtCore.Signal(int) and connected it to a slot set_progress_val
in the LoadData, I emit change_val signal at different places.
Also did some changes in the if name == 'main'
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): change_val = QtCore.Signal(int) def __init__(self, file_name,parent=None): """ super(MainWindow, self).__init__(parent) .. __init__ code lines """ change_val.connect(self.set_progress_val) self.progress = QtWidgets.QProgressDialog('loading...', 'cancel', 0, 100, self) self.progress.show() self.LoadData(d.path) @QtCore.Slot(int) def set_progress_val(self, val): self.progress.setValue(val) def LoadData(self, file_path): """ Parsing lines of code .. change_val.emit(30) .. .. change_val.emit(60) .. .. """ self.progress.hide() #Parsing finished -> show the mainWindow self.show() class HomeDialog(QtWidgets.QDialog, home_dialog.Ui_Dialog): def __init__(self, parent=None): super(HomeDialog, self).__init__(parent) self.setupUi(self) self.openB6.clicked.connect(self.get_file_name) def get_file_name(self): file_name = QtWidgets.QFileDialog.getOpenFileName(self, 'Open config file', dir=path.join("/"), filter="B6 (*.b6)") if not file_name[0]: return None else: self.path = file_name self.accept() if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) app.setStyle(ProxyStyle()) d = HomeDialog() if d.exec_(): mainWin = MainWindow(file_name=d.path) mainWin.show() sys.exit(app.exec_())
I get the following error:
'str' object has no attribute 'connect'
-
@hachbani
On which line?self.change_val[int].connect(self.set_progress_val)
? Are you using PyQt5, PySide2, or what? -
I'm using Pyside2, pyothn 3.8
I get the error on the follwoing line
mainWin = MainWindow(file_name=d.path)
-
The idea of
self.change_val[int].connect(self.set_progress_val)
is that when i'm going to call self.change_val.emit(20), the set_progress_val is called with 20 as argument, maybe I'm implementing this wrong -
@hachbani
I'll look into the possibleconnect()
issue in a moment. ButI get the error on the follwoing line
mainWin = MainWindow(file_name=d.path)
mainWin = MainWindow(file_name=d.path)
I don't see your
MainWindow.init()
has afile_name
argument?Actually, before I look, could we establish where exactly this error is really coming from? With
print()
statements/debugger, do you actually get to theself.change_val[int].connect(self.set_progress_val)
line at all? Or is the error really that constructor line?? -
Just a pasting mistake, I updated the code in my last comment.
if I remove all the progressBar code parts, the program will run successfully, but with nothing being shown while the LoadData function is runnung
-
class MainWindow(QtWidgets.QMainWindow, file_name, Ui_MainWindow): def __init__(self, parent=None):
How do you manage
file_name
in the class declaration? How do you not have it in the__init__()
? I'm not going to guess if this is in fact not the code you have, that's what pasting is for.... -
@JonB said in Show a Loading Home Dialog before starting MainWindow:
Actually, before I look, could we establish where exactly this error is really coming from? With print() statements/debugger, do you actually get to the self.change_val[int].connect(self.set_progress_val) line at all? Or is the error really that constructor line??
I added a print before and after the connect line, I get the first print and then the
'str' object has no attribute 'connect'
the file_name argument gets passed to LoadData at the end of
MainWindow __init__()
-
@hachbani said in Show a Loading Home Dialog before starting MainWindow:
the file_name argument gets passed to LoadData at the end of MainWindow init()
class MainWindow(QtWidgets.QMainWindow, file_name, Ui_MainWindow):
I don't understand. It's not an "argument", is it? You have it in the list of classes from which
MainWindow
derives?? Unless your knowledge of Python is better than mine. -
Sorry sorry, feel ridiculous, it was a mistake, the file_name is indeed an argument to MainWindow init(). I corrected the code in the comment. It was in init in my code, just a rookie mistake while making the minimalistic code
-
@hachbani
Please understand, we have to get pasting/correct code right! When you've tried to help in this forum for as much as I have you never know what posters have actually got if it's not accurate, and I have wasted too much time over the years answering questions about user code which is not actually the code! :)I'll think about your
connect()
now....