Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PyQt 5 issue in spyder #4639

Closed
ciornav opened this issue Jun 23, 2017 · 24 comments
Closed

PyQt 5 issue in spyder #4639

ciornav opened this issue Jun 23, 2017 · 24 comments

Comments

@ciornav
Copy link

ciornav commented Jun 23, 2017

Description of your problem

The run of a .ui file in spyder using PyQt 5 gives an error message every 2 times I run the .py file.

What steps will reproduce the problem?

  1. Every 2 times I run the code in Python

What is the expected output? What do you see instead?
I would like to see the GUI and use the functionalities that I've coded in the .py file.

Please provide any additional information below

The code I have in the .py file is the following (guess the error comes somewhere from here):

import sys; import numpy as np;
from PyQt5 import uic, QtWidgets
 
qtCreatorFile = "vsc.ui"  #that's the .ui file I've created with teh Qt Designer
 
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)
 
class MyApp(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        Ui_MainWindow.__init__(self)
        self.setupUi(self)
        self.calcul.clicked.connect(self.Calculate_price)
    def Calculate_price(self):
        adultes = int(self.adultes_sbox.value())
        enfants = int(self.enfants_sbox.value())
        formule = (self.formule_cbox.currentIndex())
        rooms = np.ceil(adultes/2)
        total_price = str(rooms * 50) 
        self.prix_total.setText(total_price)
       
if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = MyApp()
    window.show()
    sys.exit(app.exec_())

Versions and main components

  • Spyder Version: 3.12
  • Python Version: 3.6
  • Qt Version: 5.6.2
  • PyQt Version: 5
  • Operating system: Windows 7

Dependencies

Please go to the menu entry Help > Optional Dependencies (or
Help > Dependencies), press the button Copy to clipboard
and paste the contents below:
jedi >=0.8.1 : 0.9.0 (OK)
matplotlib >=1.0 : 2.0.0 (OK)
nbconvert >=4.0 : 4.2.0 (OK)
numpy >=1.7 : 1.12.1 (OK)
pandas >=0.13.1 : 0.19.2 (OK)
pep8 >=0.6 : 1.7.0 (OK)
pyflakes >=0.6.0 : 1.5.0 (OK)
pygments >=2.0 : 2.1.3 (OK)
pylint >=0.25 : 1.6.4 (OK)
qtconsole >=4.2.0: 4.2.1 (OK)
rope >=0.9.4 : 0.9.4-1 (OK)
sphinx >=0.6.6 : 1.5.1 (OK)
sympy >=0.7.3 : 1.0 (OK)

@ccordoba12
Copy link
Member

@dalthviz, what was the solution to this problem?

@ciornav
Copy link
Author

ciornav commented Jun 23, 2017

Hello, well actually didn't found it.... it's still an issue. It works one out of 2 times and cannot compile it neither. I get this message : C:\Users\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py:2889: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.
warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)

An exception has occurred, use %tb to see the full traceback.

SystemExit: -1

@ccordoba12
Copy link
Member

Yeah, @dalthviz knows the solution to this (it's very simple indeed), so please wait until he chimes in.

@ciornav
Copy link
Author

ciornav commented Jun 23, 2017

Thanks so much! I'll wait then!

@dalthviz
Copy link
Member

Hi @ciornav, try to add a validation for a instance of QApplication in the main, something like this:

if not QtWidgets.QApplication.instance():
    app = QtWidgets.QApplication(sys.argv)
else:
    app = QtWidgets.QApplication.instance() 

This maybe is related with #4349

@ciornav
Copy link
Author

ciornav commented Jun 23, 2017

Hi @dalthviz I tried but the error persists :(
I have now something like this :
if name == "main":
if not QtWidgets.QApplication.instance():
app = QtWidgets.QApplication(sys.argv)
else:
app = QtWidgets.QApplication.instance()
window = MyApp()
window.show()
sys.exit(app.exec_())

@dalthviz
Copy link
Member

@ciornav could you submit your .ui file to test this, please?

@ciornav
Copy link
Author

ciornav commented Jun 23, 2017

Hello,

thanks for helping out with this. Apparently the .ui files are not supported in this chat. I struggle to get teh files uploaded to my github profile... guess need to look into uploading for doing it properly....

@dalthviz
Copy link
Member

You could maybe copy paste the xml code here?

@ciornav
Copy link
Author

ciornav commented Jun 23, 2017

ok so found it.... https://github.com/ciornav/files_to_test I"ve put teh .ui and .py there.

@ciornav
Copy link
Author

ciornav commented Jun 23, 2017

/********************************************************************************
** Form generated from reading UI file 'vscp49940.ui'
**
** Created by: Qt User Interface Compiler version 5.6.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef VSCP49940_H
#define VSCP49940_H

#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QCalendarWidget>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QDateEdit>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QLabel>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QSpinBox>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QTextEdit>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_MainWindow
{
public:
QAction *actionSave;
QWidget *centralwidget;
QPushButton *calcul;
QLabel *label_6;
QTextEdit *prix_total;
QWidget *layoutWidget;
QHBoxLayout *horizontalLayout_2;
QSpinBox *adultes_sbox;
QSpinBox *enfants_sbox;
QComboBox *formule_cbox;
QWidget *layoutWidget1;
QHBoxLayout *horizontalLayout;
QLabel *label_3;
QLabel *label_4;
QLabel *label_5;
QWidget *layoutWidget2;
QHBoxLayout *horizontalLayout_3;
QCalendarWidget *calendar_arivee;
QCalendarWidget *calendar_depart;
QWidget *layoutWidget3;
QHBoxLayout *horizontalLayout_4;
QLabel *label;
QLabel *label_2;
QWidget *layoutWidget4;
QHBoxLayout *horizontalLayout_5;
QDateEdit *date_arivee;
QDateEdit *date_depart;
QLabel *label_7;
QTextEdit *chambres;
QMenuBar *menubar;
QStatusBar *statusbar;

void setupUi(QMainWindow *MainWindow)
{
    if (MainWindow->objectName().isEmpty())
        MainWindow->setObjectName(QStringLiteral("MainWindow"));
    MainWindow->resize(891, 725);
    actionSave = new QAction(MainWindow);
    actionSave->setObjectName(QStringLiteral("actionSave"));
    centralwidget = new QWidget(MainWindow);
    centralwidget->setObjectName(QStringLiteral("centralwidget"));
    calcul = new QPushButton(centralwidget);
    calcul->setObjectName(QStringLiteral("calcul"));
    calcul->setGeometry(QRect(300, 530, 261, 28));
    QFont font;
    font.setPointSize(12);
    calcul->setFont(font);
    label_6 = new QLabel(centralwidget);
    label_6->setObjectName(QStringLiteral("label_6"));
    label_6->setGeometry(QRect(640, 580, 81, 20));
    label_6->setFont(font);
    prix_total = new QTextEdit(centralwidget);
    prix_total->setObjectName(QStringLiteral("prix_total"));
    prix_total->setGeometry(QRect(630, 610, 104, 41));
    layoutWidget = new QWidget(centralwidget);
    layoutWidget->setObjectName(QStringLiteral("layoutWidget"));
    layoutWidget->setGeometry(QRect(80, 440, 681, 24));
    horizontalLayout_2 = new QHBoxLayout(layoutWidget);
    horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
    horizontalLayout_2->setContentsMargins(0, 0, 0, 0);
    adultes_sbox = new QSpinBox(layoutWidget);
    adultes_sbox->setObjectName(QStringLiteral("adultes_sbox"));
    adultes_sbox->setMinimum(1);
    adultes_sbox->setMaximum(51);
    adultes_sbox->setValue(1);

    horizontalLayout_2->addWidget(adultes_sbox);

    enfants_sbox = new QSpinBox(layoutWidget);
    enfants_sbox->setObjectName(QStringLiteral("enfants_sbox"));
    enfants_sbox->setMaximum(21);

    horizontalLayout_2->addWidget(enfants_sbox);

    formule_cbox = new QComboBox(layoutWidget);
    formule_cbox->setObjectName(QStringLiteral("formule_cbox"));
    formule_cbox->setInsertPolicy(QComboBox::InsertAtBottom);

    horizontalLayout_2->addWidget(formule_cbox);

    layoutWidget1 = new QWidget(centralwidget);
    layoutWidget1->setObjectName(QStringLiteral("layoutWidget1"));
    layoutWidget1->setGeometry(QRect(80, 410, 681, 23));
    QFont font1;
    font1.setPointSize(10);
    font1.setBold(true);
    font1.setWeight(75);
    layoutWidget1->setFont(font1);
    horizontalLayout = new QHBoxLayout(layoutWidget1);
    horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
    horizontalLayout->setContentsMargins(0, 0, 0, 0);
    label_3 = new QLabel(layoutWidget1);
    label_3->setObjectName(QStringLiteral("label_3"));
    label_3->setFont(font1);

    horizontalLayout->addWidget(label_3);

    label_4 = new QLabel(layoutWidget1);
    label_4->setObjectName(QStringLiteral("label_4"));
    label_4->setFont(font1);

    horizontalLayout->addWidget(label_4);

    label_5 = new QLabel(layoutWidget1);
    label_5->setObjectName(QStringLiteral("label_5"));
    label_5->setFont(font1);

    horizontalLayout->addWidget(label_5);

    layoutWidget2 = new QWidget(centralwidget);
    layoutWidget2->setObjectName(QStringLiteral("layoutWidget2"));
    layoutWidget2->setGeometry(QRect(10, 50, 871, 238));
    horizontalLayout_3 = new QHBoxLayout(layoutWidget2);
    horizontalLayout_3->setObjectName(QStringLiteral("horizontalLayout_3"));
    horizontalLayout_3->setContentsMargins(0, 0, 0, 0);
    calendar_arivee = new QCalendarWidget(layoutWidget2);
    calendar_arivee->setObjectName(QStringLiteral("calendar_arivee"));

    horizontalLayout_3->addWidget(calendar_arivee);

    calendar_depart = new QCalendarWidget(layoutWidget2);
    calendar_depart->setObjectName(QStringLiteral("calendar_depart"));

    horizontalLayout_3->addWidget(calendar_depart);

    layoutWidget3 = new QWidget(centralwidget);
    layoutWidget3->setObjectName(QStringLiteral("layoutWidget3"));
    layoutWidget3->setGeometry(QRect(10, 10, 871, 30));
    horizontalLayout_4 = new QHBoxLayout(layoutWidget3);
    horizontalLayout_4->setObjectName(QStringLiteral("horizontalLayout_4"));
    horizontalLayout_4->setContentsMargins(0, 0, 0, 0);
    label = new QLabel(layoutWidget3);
    label->setObjectName(QStringLiteral("label"));
    QFont font2;
    font2.setPointSize(14);
    label->setFont(font2);

    horizontalLayout_4->addWidget(label);

    label_2 = new QLabel(layoutWidget3);
    label_2->setObjectName(QStringLiteral("label_2"));
    label_2->setFont(font2);

    horizontalLayout_4->addWidget(label_2);

    layoutWidget4 = new QWidget(centralwidget);
    layoutWidget4->setObjectName(QStringLiteral("layoutWidget4"));
    layoutWidget4->setGeometry(QRect(10, 300, 871, 24));
    horizontalLayout_5 = new QHBoxLayout(layoutWidget4);
    horizontalLayout_5->setObjectName(QStringLiteral("horizontalLayout_5"));
    horizontalLayout_5->setContentsMargins(0, 0, 0, 0);
    date_arivee = new QDateEdit(layoutWidget4);
    date_arivee->setObjectName(QStringLiteral("date_arivee"));
    date_arivee->setDateTime(QDateTime(QDate(2017, 9, 29), QTime(0, 0, 0)));

    horizontalLayout_5->addWidget(date_arivee);

    date_depart = new QDateEdit(layoutWidget4);
    date_depart->setObjectName(QStringLiteral("date_depart"));
    date_depart->setDateTime(QDateTime(QDate(2017, 9, 30), QTime(0, 0, 0)));

    horizontalLayout_5->addWidget(date_depart);

    label_7 = new QLabel(centralwidget);
    label_7->setObjectName(QStringLiteral("label_7"));
    label_7->setGeometry(QRect(120, 580, 101, 20));
    label_7->setFont(font);
    chambres = new QTextEdit(centralwidget);
    chambres->setObjectName(QStringLiteral("chambres"));
    chambres->setGeometry(QRect(120, 610, 104, 41));
    MainWindow->setCentralWidget(centralwidget);
    menubar = new QMenuBar(MainWindow);
    menubar->setObjectName(QStringLiteral("menubar"));
    menubar->setGeometry(QRect(0, 0, 891, 26));
    MainWindow->setMenuBar(menubar);
    statusbar = new QStatusBar(MainWindow);
    statusbar->setObjectName(QStringLiteral("statusbar"));
    MainWindow->setStatusBar(statusbar);

    retranslateUi(MainWindow);

    QMetaObject::connectSlotsByName(MainWindow);
} // setupUi

void retranslateUi(QMainWindow *MainWindow)
{
    MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0));
    actionSave->setText(QApplication::translate("MainWindow", "Save", 0));
    calcul->setText(QApplication::translate("MainWindow", "Calcul", 0));
    label_6->setText(QApplication::translate("MainWindow", "Prix total", 0));
    formule_cbox->clear();
    formule_cbox->insertItems(0, QStringList()
     << QApplication::translate("MainWindow", "Pension complete", 0)
     << QApplication::translate("MainWindow", "Demi pension", 0)
     << QApplication::translate("MainWindow", "Bed and breakfast", 0)
    );
    formule_cbox->setCurrentText(QApplication::translate("MainWindow", "Pension complete", 0));
    label_3->setText(QApplication::translate("MainWindow", "Adultes", 0));
    label_4->setText(QApplication::translate("MainWindow", "Enfants", 0));
    label_5->setText(QApplication::translate("MainWindow", "Formule", 0));
    label->setText(QApplication::translate("MainWindow", "Date d'arivee", 0));
    label_2->setText(QApplication::translate("MainWindow", "Date de depart", 0));
    label_7->setText(QApplication::translate("MainWindow", "Chambres", 0));
} // retranslateUi

};

namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui

QT_END_NAMESPACE

#endif // VSCP49940_H

@dalthviz
Copy link
Member

@ciornav what happens if instead of sys.exit(app.exec_()) you only use app.exec_()?

@ciornav
Copy link
Author

ciornav commented Jun 23, 2017

Thank you so much.... it works!!!!!

@Jeroendevr
Copy link

Jeroendevr commented Sep 15, 2017

I've had an issue with the same isuue. Is apparently it is a standard bug running PyQt applications. Is there a way about informing the user about this behavior? It should save some time for relevant users if it was mentioned in the docs for example.

Edit:
Another question regarding this Qt instance issue. When using the
exitAct.triggered.connect(qApp.quit)
Together with

    if not QApplication.instance():
        app = QApplication(sys.argv)
    else:
        app = QApplication.instance() 

Within my main the program crashes. This is also due the Spyder Qt behaviour. How to handle the quitting of the app using Spyder?

@dalthviz
Copy link
Member

Hi @Jeroendevr testing a little bit, try to make a function for the creation of the QApplication instance (to make it local and prevent it to get in the namespace of the kernel of the console), as an example (based on this):

import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QMainWindow, QLabel, QGridLayout, QWidget
from PyQt5.QtCore import QSize    
     
class HelloWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
 
        self.setMinimumSize(QSize(100, 100))    
        self.setWindowTitle("Hello world") 
        
        centralWidget = QWidget(self)          
        self.setCentralWidget(centralWidget)   
 
        gridLayout = QGridLayout(self)     
        centralWidget.setLayout(gridLayout)  
 
        title = QLabel("Hello World from PyQt", self) 
        title.setAlignment(QtCore.Qt.AlignCenter)
        gridLayout.addWidget(title, 0, 0)
        
        menu = self.menuBar().addMenu('Action for quit')
        action = menu.addAction('Quit')
        action.triggered.connect(QtWidgets.QApplication.quit)
 
if __name__ == "__main__":
    def run_app():
        app = QtWidgets.QApplication(sys.argv)
        mainWin = HelloWindow()
        mainWin.show()
        app.exec_()
    run_app()

Then most of the problems of running a QApplication multiple times inside Spyder is that a QApplication instance remains in the namespace of the kernel of the IPython console after the first run, then when you try to re-run your application you already have a QApplication instance initialized. Trying to quit a QApplication instance that you have a reference, in your case, is probably causing your program to get stuck in the blocking while-loop as suggested here, and here using sys.exit() doesn't help since is the same as trying to exit python (and hence the IPython console).

@Jeroendevr
Copy link

So is it a IPython problem then instead of an Qt-Spyder problem? There was a issue for this at the IPython repo if I recall correctly. Any update on that subject?

@dalthviz
Copy link
Member

dalthviz commented Oct 6, 2017

Hi @Jeroendevr in #4349 there was a proposal to monkeypatch QApplication to raise and exception when multiple instances are detected, but no more than that.

@Omar-Aboelsoud
Copy link

Omar-Aboelsoud commented Dec 5, 2018

@dalthviz your code solved the problem; however, after I made that change there is another warning showed up
Reloaded modules: mainPatient, mainAnalysis, MSIDB, SearchItem, SCAN_FORM, new_calendar, new_compare_form

Do you have any idea why this warning rise ?

@dalthviz
Copy link
Member

dalthviz commented Dec 5, 2018

Hi @Omar-Aboelsoud probably you are reimporting does modules when running your application. Maybe #2325 could give you some guidance to prevent the warning :)

@gigo318
Copy link

gigo318 commented Feb 10, 2019

So I was still having problems with my application not exiting, even with the suggestions given in this thread. My current understanding of the problem is that the QtWidget.QtApplication object has a flag 'quitOnLastWindowClosed' that is by default set to False. This can be set to true by calling:

QtWidget.QtApplication.setQuitOnLastWindowClosed(True)

somewhere before you call qapp.exec_(). Note that this is a static method.

If the above doesn't work for some reason, I also found adding an overridden closeEvent function to the 'HelloWindow' class that calls QtWidgets.QApplication.quit() also works (taking inspiration from @dalthviz 's quit menu button).

def closeEvent(self, ce):
    QtWidgets.QApplication.quit()

@Tommy-Zheng
Copy link

QtApplication.setQuitOnLastWindowClosed(True)

based on what you said, I added: QtWidgets.QApplication.setQuitOnLastWindowClosed(True) before app.exec(), working code as follows, though have some typos in your solution, but this is the only workable solution this problem for me, I really appreciate, if this problem have not been resolved, I would lose my faith of continuing python studying as a beginner, thanks @gigo318

if name == "main":
def run_app():
app = QtWidgets.QApplication(sys.argv)
mainWin = HelloWindow()
mainWin.show()
QtWidgets.QApplication.setQuitOnLastWindowClosed(True)
app.exec()
run_app()

@ccordoba12
Copy link
Member

This problem was fixed in our 4.1.1 version. Please update.

@Tommy-Zheng
Copy link

This problem was fixed in our 4.1.1 version. Please update.

thanks, I tried to conda upgrade spyder, but it says constrained by anaconda, I am concerned that anaconda won't work if I upgraded to 4.1.1, do u have any idea about this? sorry, I am quite new to python

@ccordoba12
Copy link
Member

Please run

conda update anaconda
conda install spyder=4.1.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants