Найти - Пользователи
Полная версия: Почему привязанная к кнопке процедура срабатывает сразу после старта программы?
Начало » GUI » Почему привязанная к кнопке процедура срабатывает сразу после старта программы?
1 2
Pluto
Процедура CreateOrOpenDataBase срабатывает сразу при старте программы. Вываливается окно QMessageBox из этой процедуры, а главная форма Form1 даже не появляется.
Почему так-то?

from PyQt4 import QtGui as QG, QtCore, QtSql
import sys, os
class form1(QG.QWidget):
    def __init__(self, parent = None):
        QG.QWidget.__init__(self, parent)
        self.setWindowTitle("Главное окно приложения")
        self.HBoxMain = QG.QHBoxLayout()
        self.HBox1 = QG.QHBoxLayout()
        self.HBox2 = QG.QHBoxLayout()
        self.VBox1 = QG.QVBoxLayout()
        
        self.BtnNew = QG.QPushButton("Создать новую базу")
        self.BtnNew.clicked.connect(CreateOrOpenDataBase("CREATE"))
        self.VBox1.addWidget(self.BtnNew)
        
        
        self.BtnLoad = QG.QPushButton("Загрузить базу")
        self.VBox1.addWidget(self.BtnLoad)
        self.Label1 = QG.QLabel("Заметка Заметка Заметка")
        self.HBox2.addWidget(self.Label1)
        self.HBoxMain.addLayout(self.HBox1)
        self.HBox1.addLayout(self.VBox1)
        self.HBox1.addLayout(self.HBox2)
        
        self.setLayout(self.HBoxMain)
        
def CreateOrOpenDataBase(CreateOrOpen):
    if CreateOrOpen == "CREATE":
        if os.path.exists("1.db"):
            QG.QMessageBox.warning(None, "Предупреждение", "База данных уже существует!")
        else:
            QG.QMessageBox.information(None, "Информация", "Сейчас создадим")
    
        
if __name__ == "__main__":
    app = QG.QApplication(sys.argv)
    Form1 = form1()
    Form1.show()
    sys.exit(app.exec_())
FishHook

connect(slot)
Connect a signal to a slot. An exception will be raised if the connection failed.

Parameters:
slot – the slot to connect to, either a Python callable or another bound signal.
type – the type of the connection to make.


А ты не callable передаешь, ты выполняешь этот callable и передаешь его результат, который есть None
Pluto
Для тугодумов вроде меня.
Как же надо сделать, чтобы было правильно?

Поглядел на свои прежние попытки программирования - ни разу не передавал ничего в процедуру. Потому, видать, всё и работало.
Как же передать-то?
FishHook
Тут
Есть еще сигналы нового стиля
Pluto
self.BtnNew.clicked.connect(lambda: CreateOrOpenDataBase("CREATE"))
Подставил lambda и стало работать.

Кааааааааааааааааааааааааааааааааааааааааааааааааак я ненавижу подобную неочевидную гадость.

Я не врубаюсь в это дело! Если функция указана в качестве слота для connect, значит она должна сработать только после появления сигнала!!!! После сигнала и всё тут!!! Разве это не логично????

Пардон, у меня истерика, пошёл биться головой о стену.
FishHook
Ну тут же все понятно.
У тебя есть событие. На событие подписывается обработчик. Обработчик это функция. ФУНКЦИЯ!
self.BtnNew.clicked.connect(CreateOrOpenDataBase("CREATE"))
Где у тебя здесь функция?
нету функции.
CreateOrOpenDataBase("CREATE")
Это не функция. Так же как
int('8'), map(None, []), sum([1,2,3])
НЕ ФУНКЦИИ.
int, map, sum
А теперь уже функции
Pluto
FishHook
Ну тут же все понятно.У тебя есть событие. На событие подписывается обработчик. Обработчик это функция. ФУНКЦИЯ!

А чем же тогда является моя CreateOrOpenDataBase? Процедурой, которая не тянет на функцию? Обособленным набором кода? Если добавить туда return, всё равно не будет работать.

И почему int('8') не является функцией?

Видимо, я не понимаю каких-то фундаментальных устоев питона.
FishHook
Pluto
И почему int('8') не является функцией?
>>> def fn(x):pass

>>> print type(fn)
<type 'function'>
>>> print type(fn(8))
<type 'NoneType'>
>>>
Pluto
Потому, что так сказал питон?

А смысл-то какой в это вкладывается? Кроме как неудобства в программировании доставлять?
Pluto
Эх, тудыт-растудыт.
Нашёл решение данной проблемы в собственной книжке по PyQt, которая лежит перед носом.

Является моя CreateOrOpenDataBase(“CREATE”) функцией, никто ей в таком праве не отказывает. Просто, если указывать параметры для неё, то метод connect получит ссылку не на функцию, а на результат выполнения функции, казява такая.

В книге три способа решения:
использовать lambda, как сделал я
делать ссылку не на функцию, а на экземпляр класса в котором есть метод __call__
использовать функцию partial из модуля functools, типа так:
from functools import partial
self.BtnNew.clicked.connect(partial(CreateOrOpenDataBase, (“CREATE”))
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