Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » GUI
  • » QCoreApplication::exec: The event loop is already running [RSS Feed]

#1 Июль 13, 2010 15:02:45

Spectral
От:
Зарегистрирован: 2010-07-13
Сообщения: 51
Репутация: +  1  -
Профиль   Отправить e-mail  

QCoreApplication::exec: The event loop is already running

Добрый день!

Возникает баг при решении задачи - ввести некоторое значение в форме 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_()
Спасибо за внимание.



Офлайн

#2 Июль 13, 2010 15:33:05

ZZZ
От: Москва
Зарегистрирован: 2008-04-03
Сообщения: 2161
Репутация: +  26  -
Профиль   Адрес электронной почты  

QCoreApplication::exec: The event loop is already running

Мнэээ… А зачем второй QApplication? И зачем второй QMainWindow?

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

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



Офлайн

#3 Июль 13, 2010 15:59:42

Spectral
От:
Зарегистрирован: 2010-07-13
Сообщения: 51
Репутация: +  1  -
Профиль   Отправить e-mail  

QCoreApplication::exec: The event loop is already running

Если это просто окно:
Код:

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

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

w2 = SecondWindow()
w2.exec_()
Привело к: AttributeError: ‘SecondWindow’ object has no attribute ‘exec_’



Офлайн

#4 Июль 13, 2010 16:45:27

ZZZ
От: Москва
Зарегистрирован: 2008-04-03
Сообщения: 2161
Репутация: +  26  -
Профиль   Адрес электронной почты  

QCoreApplication::exec: The event loop is already running

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)



Отредактировано (Июль 13, 2010 16:50:31)

Офлайн

#5 Июль 14, 2010 10:34:17

Spectral
От:
Зарегистрирован: 2010-07-13
Сообщения: 51
Репутация: +  1  -
Профиль   Отправить e-mail  

QCoreApplication::exec: The event loop is already running

Переписал задачу с нуля.
В общем, я понял, что 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_()
Вторая форма отрисовывается, в самом деле, но тут же пропадает. Как быть?



Офлайн

#6 Июль 14, 2010 12:18:56

apologize828
От:
Зарегистрирован: 2010-02-13
Сообщения: 223
Репутация: +  1  -
Профиль   Отправить e-mail  

QCoreApplication::exec: The event loop is already running

# -*- 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_()



Отредактировано (Июль 14, 2010 12:19:25)

Офлайн

#7 Июль 14, 2010 12:29:21

Spectral
От:
Зарегистрирован: 2010-07-13
Сообщения: 51
Репутация: +  1  -
Профиль   Отправить e-mail  

QCoreApplication::exec: The event loop is already running

Ребят, спасибо большое :-)



Офлайн

#8 Июль 14, 2010 12:46:13

ZZZ
От: Москва
Зарегистрирован: 2008-04-03
Сообщения: 2161
Репутация: +  26  -
Профиль   Адрес электронной почты  

QCoreApplication::exec: The event loop is already running

То, что нужно “написать self” – ясно, но _почему_ ты понял?



Отредактировано (Июль 14, 2010 12:46:51)

Офлайн

#9 Июль 14, 2010 13:46:35

Spectral
От:
Зарегистрирован: 2010-07-13
Сообщения: 51
Репутация: +  1  -
Профиль   Отправить e-mail  

QCoreApplication::exec: The event loop is already running

ZZZ
То, что нужно “написать self” – ясно, но _почему_ ты понял?
Как водится, сначала принял на веру, а когда полазил по гуглу после вашего вопроса:
оказывается, так устроены парадигмы ООП в Python, если из одного класса (выходит, из другого окна) хотим вызвать
другой класс (выходит, другое окно), необходимо писать self к методу другого класса.
В случае с задачей PyQt здесь (после указания модальности второй формы) это и приводит к корректной работе двух форм (не возникает ошибки с eventloop) - одна форма отображается после нажатия кнопки на первой и нормально уничтожается.
Надеюсь, не сильный бред написан, я новичок :-)



Отредактировано (Июль 14, 2010 13:58:39)

Офлайн

#10 Июль 14, 2010 20:54:54

ZZZ
От: Москва
Зарегистрирован: 2008-04-03
Сообщения: 2161
Репутация: +  26  -
Профиль   Адрес электронной почты  

QCoreApplication::exec: The event loop is already running

Сильный.
В твоём варианте w2 собирается сборщиком мусора после окончания выполнения метода FirstForm.CopyAndShow, так как не остаётся ссылок на него. Когда-то я потратил много времени на понимание этого. :-)



Офлайн

  • Начало
  • » GUI
  • » QCoreApplication::exec: The event loop is already running[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version