Найти - Пользователи
Полная версия: QCoreApplication::exec: The event loop is already running
Начало » GUI » QCoreApplication::exec: The event loop is already running
1
Spectral
Добрый день!

Возникает баг при решении задачи - ввести некоторое значение в форме 1 и отобразить форму 2 с этим заданным значением.
Код прилагаю. В результате работы скрипта значение из LineEdit, в самом деле, передается во вторую форму, но при этом возникает
QCoreApplication::exec: The event loop is already running.
Закрытие мышкой второй формы не делает активным первое окно, а процесс pythonw.exe приходится убивать руками.

Как корректно передавать eventloop между двумя окошками, так чтобы уничтожение
второй формочки перезапускало или возвращало назад первую формочку для работы?
Как верно поставить завершения цикла обработки событий в этой программе?
Буду сильно благодарен за ключевые подсказки.

# -*- coding: utf-8 -*-

import sys
from PyQt4 import QtCore, QtGui

# исполнение графического интерфейса первой формы
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(319, 184)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.lineEdit = QtGui.QLineEdit(self.centralwidget)
self.lineEdit.setGeometry(QtCore.QRect(110, 50, 101, 20))
self.lineEdit.setObjectName("lineEdit")
self.pushButton = QtGui.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(120, 80, 75, 24))
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 319, 19))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)

self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)

def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton.setText(QtGui.QApplication.translate("MainWindow", "PushButton", None, QtGui.QApplication.UnicodeUTF8))

# исполнение графического интерфейса второй формы
class Ui_SecondWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(380, 184)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.lineEdit = QtGui.QLineEdit(self.centralwidget)
self.lineEdit.setGeometry(QtCore.QRect(260, 0, 113, 20))
self.lineEdit.setObjectName("lineEdit")
self.lineEdit_2 = QtGui.QLineEdit(self.centralwidget)
self.lineEdit_2.setGeometry(QtCore.QRect(0, 120, 113, 20))
self.lineEdit_2.setObjectName("lineEdit_2")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 380, 19))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)

self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)

def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))

# инициализация класса первой формы
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)


self.connect(self.ui.pushButton, QtCore.SIGNAL('clicked()'), self.CopyAndShow)



def CopyAndShow(self):
b=(unicode(self.ui.lineEdit.displayText()))

# # инициализация класса второй формы
class SecondWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.ui = Ui_SecondWindow()
self.ui.setupUi(self)

self.ui.lineEdit.setText (b)
self.ui.lineEdit_2.setText (b)

app2 = QtGui.QApplication(sys.argv)
w2=SecondWindow()
w2.show()


app1 = QtGui.QApplication(sys.argv)
w1 =MainWindow()
w1.show()
app1.exec_()
Спасибо за внимание.
ZZZ
Мнэээ… А зачем второй QApplication? И зачем второй QMainWindow?

Если нужно, чтобы окно было модальным:
w2 = SecondWindow()
w2.exec_()
Если это просто окно:
w2 = SecondWindow()
w2.show()
А вообще, почитай про циклы событий в документации. Там всё предельно просто и понятно.
Spectral
Если это просто окно:
Код:

w2 = SecondWindow()
w2.show()
Убрал лишние QApplication, но при работе скрипта получается, что окошко второй формы появляется и тут же исчезает
Как его оставить на месте, не придумал, отсюда и неправильная строка кода с вторым QApplication…

Если нужно, чтобы окно было модальным:
Код:

w2 = SecondWindow()
w2.exec_()
Привело к: AttributeError: ‘SecondWindow’ object has no attribute ‘exec_’
ZZZ
Spectral
Привело к: AttributeError: ‘SecondWindow’ object has no attribute ‘exec_’
Ну правильно. Это же QMainWindow. Вообще, для этих целей лучше подходит QDialog. Я вот ни разу не писал такого, чтобы мне понадобилось два главных окна.

Дальше… Давай начнём с малого. Без всякого дизайнера опиши два окна (одно с кнопкой, другое без, оба окна от QWidget) и попытайся заставить это работать: запускаешь программу, видишь первое окно; давишь на кнопку – появляется второе. Это поможет понять, что ты делаешь не так.
Ну и если не получится, то давай код этой маленькой программки сюда – покритикую и объясню, как надо.

P.S. Я не сразу увидел ошибку… Просто элементарно! :-) Давай напиши, попробуй и увидишь сам.
P.P.S. Вот такие построения, это зло. Не далай так.
    def CopyAndShow(self):
b=(unicode(self.ui.lineEdit.displayText()))

# # инициализация класса второй формы
class SecondWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.ui = Ui_SecondWindow()
self.ui.setupUi(self)

self.ui.lineEdit.setText (b)
self.ui.lineEdit_2.setText (b)
Spectral
Переписал задачу с нуля.
В общем, я понял, что Designer+Pyuic4 для начала использовать вообще не стоит. Тем более, рисовать нужно немного
Насчет объявления класса внутри функции - очевидная ошибка, соглашусь с вами (когда можно было объявить переменную-объект, и через атрибуты этой переменной записать то самое значение, которое нужно было передать из первой формы).
Результатом работы над ошибками стал такой скрипт:

# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtGui
from PyQt4 import QtCore

#объявление класса второй формы с требуемыми атрибутами
class SecondForm(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setGeometry(350, 350, 370, 100)
self.setWindowTitle('OutputForm')


self.lineEdit1 = QtGui.QLineEdit(self)
self.lineEdit1.move(130, 22)
self.lineEdit2 = QtGui.QLineEdit(self)
self.lineEdit2.move(130, 42)

#объявление класса первой формы с требуемыми атрибутами
class FirstForm(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)

self.setGeometry(300, 300, 350, 80)
self.setWindowTitle('InputForm')

self.button = QtGui.QPushButton('Click2Send', self)
self.button.setFocusPolicy(QtCore.Qt.NoFocus)
self.button.move(20, 20)

self.lineEdit1 = QtGui.QLineEdit(self)
self.lineEdit1.move(130, 22)

self.connect(self.button, QtCore.SIGNAL('clicked()'), self.CopyAndShow)

# создание пользовательского отклика на нажатие кнопки из первой формы
def CopyAndShow(self):
b=(unicode(self.lineEdit1.displayText()))

# отрисовка второго окна с пользовательским значением из первой формы
w2=SecondForm()
w2.lineEdit1.setText (b)
w2.lineEdit2.setText (b)
w2.show()


app = QtGui.QApplication(sys.argv)
w1 = FirstForm()
w1.show()
app.exec_()
Вторая форма отрисовывается, в самом деле, но тут же пропадает. Как быть?
apologize828
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtGui,QtCore

class SecondForm(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.setWindowTitle('OutputForm')
#Делаем окно модальным
self.setWindowModality(QtCore.Qt.ApplicationModal)
#Создаем Компановщик,чтобы самому не задовать геометрию для компанентов формы
vb=QtGui.QVBoxLayout()
#Создаем компаненты
self.lEd1 = QtGui.QLineEdit()
self.lEd2 = QtGui.QLineEdit()
#Добавляем в компановщик нащи компаненты
vb.addWidget(self.lEd1)
vb.addWidget(self.lEd2)
#Делаем нашу форму компановщиком
self.setLayout(vb)

class FirstForm(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.setWindowTitle('InputForm')

hb=QtGui.QHBoxLayout()

bt = QtGui.QPushButton('Click2Send')
self.lEd3 = QtGui.QLineEdit()

hb.addWidget(bt)
hb.addWidget(self.lEd3)

self.setLayout(hb)
#это новый стиль сигнал/слот в PyQt4
bt.clicked.connect(self.CopyAndShow)

def CopyAndShow(self):
#это текст нашего эдита
text_w1=self.lEd3.text()
#а тут ты просто забыл дописать self ,чтобы окно не исчезало!!!
self.w2=SecondForm()
self.w2.lEd1.setText(text_w1)
self.w2.lEd2.setText(text_w1)
self.w2.show()


app = QtGui.QApplication(sys.argv)
w1 = FirstForm()
w1.show()
app.exec_()
Spectral
Ребят, спасибо большое :-)
ZZZ
То, что нужно “написать self” – ясно, но _почему_ ты понял?
Spectral
ZZZ
То, что нужно “написать self” – ясно, но _почему_ ты понял?
Как водится, сначала принял на веру, а когда полазил по гуглу после вашего вопроса:
оказывается, так устроены парадигмы ООП в Python, если из одного класса (выходит, из другого окна) хотим вызвать
другой класс (выходит, другое окно), необходимо писать self к методу другого класса.
В случае с задачей PyQt здесь (после указания модальности второй формы) это и приводит к корректной работе двух форм (не возникает ошибки с eventloop) - одна форма отображается после нажатия кнопки на первой и нормально уничтожается.
Надеюсь, не сильный бред написан, я новичок :-)
ZZZ
Сильный.
В твоём варианте w2 собирается сборщиком мусора после окончания выполнения метода FirstForm.CopyAndShow, так как не остаётся ссылок на него. Когда-то я потратил много времени на понимание этого. :-)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB