Russian Qt Forum
Сентябрь 28, 2024, 10:27 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 2 [3]   Вниз
  Печать  
Автор Тема: Модальный диалог  (Прочитано 24566 раз)
bigirbis
Гость
« Ответ #30 : Сентябрь 12, 2006, 11:26 »

В стандартном проверяется, установлен ли флаг Qt::WA_DeleteOnClose. И если да - вызывается delete this, если нет - ничего не происходит. Конечно лучше из стандартного выдрать - думаю никто в обиде не будет.
Записан
enola
Гость
« Ответ #31 : Сентябрь 12, 2006, 13:51 »

что-то плоховато работает, раз 20 кликнешь и вылетает с ошибкой непонятной:

Код:

#include "private/qdialog_p.h"

MDialog::MDialog(QWidget *parent, Qt::WFlags flags)
: QWidget(parent, flags | QFlag(Qt::WA_ShowModal) |   // Модальное
 QFlag(Qt::FramelessWindowHint))  // Без заголовка, без кнопки на таскбаре
{
// Фон
QPixmap bgPixmap("message.png");
QLabel *bgLabel = new QLabel(this);
bgLabel->setPixmap(bgPixmap);

// Кнопки
QPushButton *okButton = new QPushButton(tr("Продолжить"), this);
QPushButton *cancelButton = new QPushButton(tr("Отмена"), this);
int iWidthButton = 200;
int iHeightButton = 50;
okButton->setGeometry(QRect(600, 440, iWidthButton, iHeightButton));
cancelButton->setGeometry(QRect(360, 440, iWidthButton, iHeightButton));
okButton->setDefault(true);

// Сигналы
connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));

// Сообщение
messageLabel = new QLabel(this);
messageLabel->setPalette(whitePalette);
messageLabel->setGeometry(QRect(340, 260, 480, 160));
messageLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop);
messageLabel->setWordWrap(true);
messageLabel->setFont(tahomaFont);
messageLabel->setText(tr("Текст сообщения"));
}

MDialog::~MDialog()
{
hide();
}

int MDialog::result() const
{
Q_D(const QDialog);
return d->rescode;
}

void MDialog::setResult(int r)
{
Q_D(QDialog);
d->rescode = r;
}

int MDialog::exec()
{
Q_D(QDialog);
if (d->eventLoop)
return -1;

bool deleteOnClose = testAttribute(Qt::WA_DeleteOnClose);
setAttribute(Qt::WA_DeleteOnClose, false);

setResult(0);

show();

QEventLoop eventLoop;
d->eventLoop = &eventLoop;
(void) eventLoop.exec();
d->eventLoop = 0;

int res = result();
if (deleteOnClose)
delete this;
return res;
}

void MDialog::done(int r)
{
Q_D(QDialog);
hide();
setResult(r);
d->close_helper(QWidgetPrivate::CloseNoEvent);
emit finished(r);
if (r == Accepted)
emit accepted();
else if (r == Rejected)
emit rejected();

if (d->eventLoop)
d->eventLoop->exit();
}

void MDialog::accept()
{
done(Accepted);
}

void MDialog::reject()
{
done(Rejected);
}


и хидер:

Код:
#include <QtGui>
#include <QWidget>
#include <QPixmap>

QT_BEGIN_HEADER

QT_MODULE(Gui)

class QDialogPrivate;

class MDialog : public QWidget
{
    Q_OBJECT
    Q_DECLARE_PRIVATE(QDialog)

public:
enum DialogCode { Rejected, Accepted };

MDialog::MDialog(QWidget *parent = 0, Qt::WFlags flags = 0);
MDialog::~MDialog();
int result() const;
void setResult(int r);

signals:
void finished(int result);
void accepted();
void rejected();

public slots:
int exec();
void done(int r);
void accept();
void reject();

private:
Q_DISABLE_COPY(MDialog)
};

QT_END_HEADER
Записан
bigirbis
Гость
« Ответ #32 : Сентябрь 12, 2006, 14:10 »

А что за ошибка-то?
Записан
enola
Гость
« Ответ #33 : Сентябрь 12, 2006, 14:16 »

Цитировать
test.exe - обнаружена ошибка. Приложение будет закрыто. Приносим извинения за неудобства.
Если работа была не закончена, рабочие данные могут быть утеряны.
Отправить отчет. Не отправлять отчет.

 Грустный
Вот такая ошибка.

подпись ошибки:
Цитировать
AppName: test.exe    AppVer: 0.0.0.0    ModName: qtcored4.dll
ModVer: 4.1.4.0    Offset: 0010d69a
Записан
bigirbis
Гость
« Ответ #34 : Сентябрь 12, 2006, 14:20 »

Попробуй отдебажить.
Записан
enola
Гость
« Ответ #35 : Сентябрь 12, 2006, 14:34 »

Улыбающийся хм
как-то ошибка не постоянно выскакивает, раз 30-50 щелкнешь на кнопке, и вылетает, причем все приложение.
Записан
bigirbis
Гость
« Ответ #36 : Сентябрь 12, 2006, 14:38 »

Есть предположение, что у тебя память где-то течет...

Можешь вывесить метод, в котором у тебя создается/вызывается этот диалог?
Записан
enola
Гость
« Ответ #37 : Сентябрь 12, 2006, 15:11 »

без проблем:
Код:

MDialog *message = new MDialog(this);

        int i = 0;
if(message->exec())
i = 1;
else
i = 2;

if (message)
delete message;


добавлено спустя 24 минуты:

 похоже нашел где ошибка, у меня неправильно работает eventLoop, вот здесь отваливается:
Код:

int MDialog::exec()
{
Q_D(QDialog);
if (d->eventLoop)
{
return -1;
}
.....


возвращает -1 и все после этого диалог не показывается вообще, сколько не тыкай по кнопке. Все дело в том что я сократить решил код QDialog и вот здесь добавил свой код:
Код:

void MDialog::done(int r)
{
Q_D(QDialog);
hide();
setResult(r);
d->close_helper(QWidgetPrivate::CloseNoEvent);
emit finished(r);
if (r == Accepted)
emit accepted();
else if (r == Rejected)
emit rejected();

if (d->eventLoop) // Вот это добавил я
d->eventLoop->exit(); // это тоже
}


Как мне этот eventLoop самому "сотворить"?
Записан
bigirbis
Гость
« Ответ #38 : Сентябрь 12, 2006, 16:32 »

Во-первых, не смог осилить, зачем в деструкторе hide()?
Во-вторых, для создания своего объекта QEventLoop надо отказаться от макросов Q_DECLARE_PRIVATE и Q_D.
Записан
enola
Гость
« Ответ #39 : Сентябрь 13, 2006, 06:31 »

Цитировать
Во-первых, не смог осилить...

Непонял интонацию данного высказывания, это я не осилил или ты. Если ты имел ввиду меня, то у меня уже получилось Улыбающийся
А вообще большое спасибо за помощь.  :lol:
Вот как у меня работает:
Код:

MDialog::MDialog(QWidget *parent, Qt::WFlags flags)
: QWidget(parent, flags | QFlag(Qt::WA_ShowModal) |   // Модальное
 QFlag(Qt::FramelessWindowHint))  // Без заголовка, без кнопки на таскбаре
{
// Размер
MDialog::setGeometry(QRect(0, 0, 1024, 768));

// Фон
QPixmap bgPixmap("message.png");
QLabel *bgLabel = new QLabel(this);
bgLabel->setPixmap(bgPixmap);

// Кнопки
QPushButton *okButton = new QPushButton(tr("Продолжить"), this);
QPushButton *cancelButton = new QPushButton(tr("Отмена"), this);
// Настройка
int iWidthButton = 200;
int iHeightButton = 50;
okButton->setGeometry(QRect(600, 440, iWidthButton, iHeightButton));
cancelButton->setGeometry(QRect(360, 440, iWidthButton, iHeightButton));
okButton->setDefault(true);

// Сигналы
connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
}

MDialog::~MDialog()
{

}

int MDialog::result() const
{
return iResult;
}

void MDialog::setResult(int r)
{
iResult = r;
}

int MDialog::exec()
{
// Установка результата по умолчанию
setResult(0);

// Показать
show();

// Ожидание
(void) eventLoop.exec();

// Возврат результата
return result();
}

void MDialog::done(int r)
{
// Скрыть
hide();

// Установка результата
setResult(r);
if (r == Accepted)
emit accepted();
else if (r == Rejected)
emit rejected();

// Выход из ожидания
eventLoop.exit();
}

void MDialog::accept()
{
done(Accepted);
}

void MDialog::reject()
{
done(Rejected);
}
Записан
bigirbis
Гость
« Ответ #40 : Сентябрь 13, 2006, 08:51 »

Цитировать
Непонял интонацию данного высказывания

Это я не смог осилить. Улыбающийся
А в общем, вроде ничего так код получился в итоге. Улыбающийся
Записан
Страниц: 1 2 [3]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.127 секунд. Запросов: 21.