При помощи QWizard создана программа - набор страниц, связанных "назад"/"далее" кнопками.
Задача - при помощи чекбоксов, выводимых на первой странице, выводить или не выводить последующие страницы. Как это реализовать?
Т.е. на первой странице чекбоксы "страница 2", "страница 3", "страница 4". Если мы отмечаем "страница 2" и "страница 4", то по нажатию "далее" будет показана страница 2, а затем 4, то есть страница 3 будет пропущена.
Какие-нибудь идеи есть?
Такая есть идея http://doc.trolltech.com/4.5/qwizard.html#creating-non-linear-wizards
Теперь такой вопрос - как из первого листа назначить nextId() для всех остальных? Пробовал по-всякому, результата нет(
class Func01Page : public QWizardPage
{
Q_OBJECT
public:
Func01Page(QWidget *parent = 0);
int nextId() const;
int IDValue;
};
int Func01Page::nextId() const
{
return ExpertSystem::Page_Func02;
}
class ExpertSystem : public QWizard
{
Q_OBJECT
public:
enum
{
Page_Intro,
Page_Func01,
// ...
Page_Func27,
Page_Outro
};
ExpertSystem(QWidget *parent = 0);
private slots:
void showHelp();
};
ExpertsSystem:: Page_Intro
enum PAGES
{
Page_Intro,
Page_Func01,
// ...
};
ExpertsSystem:: PAGES
.enum EPages{...};
Page_Intro;
ExpertSystem::Page_Intro;
На основе http://doc.trolltech.com/4.5/qwizard.html#creating-non-linear-wizards сделал визард. Но отличие в том, что на первой странице список чекбоксов, которые и определяют, какие страницы будут показаны, а какие нет. Собственно проблема в том, что кроме первой страницы я не могу ничего изменить...
Итак, есть класс:
class ExpertSystem : public QWizard
{
Q_OBJECT
public:
enum
{
Page_Intro,
Page_Func01,
// ...
Page_Func27,
Page_Outro
};
ExpertSystem(QWidget *parent = 0);
private slots:
void showHelp();
};
class IntroPage : public QWizardPage
{
Q_OBJECT
public:
IntroPage(QWidget *parent = 0);
int nextId() const;
int IDValue;
//private:
public:
QCheckBox *func01;
QCheckBox *func02;
//..
QCheckBox *func26;
QCheckBox *func27;
};
ExpertSystem::ExpertSystem(QWidget *parent)
: QWizard(parent)
{
setPage(Page_Intro, new IntroPage);
setPage(Page_Func01, new Func01Page);
setPage(Page_Func02, new Func02Page);
//..
setPage(Page_Func27, new Func27Page);
setPage(Page_Outro, new OutroPage);
setStartId(Page_Intro);
}
int IntroPage::nextId() const
{
Ну подскажите же эту строчку)
FladeX,
по аналогии действуй
int IntroPage::nextId() const
{
if (evaluateRadioButton->isChecked()) {
return LicenseWizard::Page_Evaluate;
} else {
return LicenseWizard::Page_Register;
}
}
int EvaluatePage::nextId() const
{
return LicenseWizard::Page_Conclusion;
}
int RegisterPage::nextId() const
{
if (upgradeKeyLineEdit->text().isEmpty()) {
return LicenseWizard::Page_Details;
} else {
return LicenseWizard::Page_Conclusion;
}
}
int DetailsPage::nextId() const
{
return LicenseWizard::Page_Conclusion;
}
int ConclusionPage::nextId() const
{
return -1;
}
int LicenseWizard::nextId() const
{
switch (currentId()) {
case Page_Intro:
if (field("intro.evaluate").toBool()) {
return Page_Evaluate;
} else {
return Page_Register;
}
case Page_Evaluate:
return Page_Conclusion;
case Page_Register:
if (field("register.upgradeKey").toString().isEmpty()) {
return Page_Details;
} else {
return Page_Conclusion;
}
case Page_Details:
return Page_Conclusion;
case Page_Conclusion:
default:
return -1;
}
}
Уже что-то, спасибо!
Допустим есть конструкция вида
int LicenseWizard::nextId() const
{
switch (currentId()) {
}
}
Спасибо, вроде именно то что надо.
Только вот не компилиться теперь:
moc_expertsystem.o:(.rodata._ZTV10Func02Page[vtable for Func02Page]+0xf0): undefined reference to `Func02Page::nextId() const'
moc_expertsystem.o:(.rodata._ZTV10Func01Page[vtable for Func01Page]+0xf0): undefined reference to `Func01Page::nextId() const'
moc_expertsystem.o:(.rodata._ZTV9IntroPage[vtable for IntroPage]+0xf0): undefined reference to `IntroPage::nextId() const'
Вклинюсь сюда тоже со своим вопросом, надеюсь никому не помешаю. Вопрос такой. Создал я значит свой класс производный от QWizard, для него сделал несколько страниц производных от класс QWizardPage. И вот на одной из страниц у меня есть QTableWIdget, как к нему обращаться с других страниц к примеру? В моем случае мне надо обращаться к этому виджету в методе класса QWizard::accept(), что позволило мне решить проблему следующим образом. Я создал для страницы на которой QTableWidget паблик метод, возвращающий ссылку на этот виджет и потом в классе QWizard вызываю этот метод. Такой способ решения мне кажется не очень красивым, а как с другой страницы получить доступ к этому виджету вообще непонятно.
Полагаю, что одним из этих методов:
QTableWidget *tbw = wizard()->page(id)->getTableWidgetPointer();
QTableWidget *tbw = wizard()->page(id)->findChild<QTableWidget *>("mytablewidgetname");
QTableWidget *tbw = wizard()->page(id)->justPublicTableWidgetPointer;
setDefaultProperty("QTableWidget", "currentItem", SIGNAL(currentItemChanged()));
...
QTableWidgetItem *item = field("QTableWidget").value<QTableWidgetItem *>();
Wizard::Wizard(QWidget *parent) : public QWizard(parent)
{
setProperty("pointerToMyTable", qVariantFromValue(tableWidgetPtr));
}
WizardPage1::WizardPage1(QWidget *parent) : public QWizardPage(parent)
{
QTableWidget *table = parent()->property("pointerToMyTable").value<QTableWidget *>();
}
То есть для чекбоксов получается так:
setDefaultProperty("QCheckBox", "currentItem", SIGNAL(currentItemChanged()));
func01 = new QCheckBox(QObject::trUtf8("Чекбокс"));
registerField("introfunc01", func01);
field(introfunc01)->isChecked(true)
То есть получается что для чекбоксов registerField вообще не подходит?
А с setProperty так и не разобрался, как их использовать в случае чекбоксов...
Подскажите что можно сделать с чекбоксами
На первой странице несколько чекбоксов, каждый из которых соответсвует одной странице. При checked страница будет доступна в визарде, при !checked не будет. >_<
Что-то все коллективно тупят
Kagami, и тем не менее, через registerFields у меня не получилось.
SABROG, генерировать и удалять не нужно. Есть конечный список предопределенных страниц, каждой из которых сопоставлен чекбокс. Если чекбокс отмечен, то эта страница будет отображаться в визарде по кнопке Next. Если чекбокс не отмечен, то страница эта не будет отображаться. Для такой реализации нужно просто перезадать nextId для каждой из страниц. Однако при этом я столкнулся с трудностью - область видимости переменных - чекбоксы-то только на первой странице, а nextId по одному на каждой (каждая страница - отдельный класс, унаследованный от QWizardPage).
В конструкторе страницы делаем:
registerField("checkBox1", checkBox1);
if (field("checkBox1").toBool()) {
//Если выбрано
...
} else {
//Иначе
...
}
Да, теперь все работает. Благодарю!
Еще хочу выводить в QLineEdit (на каждой странице свой) какой-нибудь текст, причем текст зависит от значений QComboBox и QCheckBox, расположенных на странице. Я все написал, но у меня теперь показывает лишь первое значение, которое характерно для дефолтного состояния QComboBox и QCheckBox, а при их изменении значение QLineEdit не изменяется, хотя должно. Подскажите, почему так?
Немного подробностей реализации бы не помешало
Func09Page::Func09Page(QWidget *parent)
: QWizardPage(parent)
{
setTitle(QObject::trUtf8("Заголовок"));
setSubTitle(QObject::trUtf8("<br>"));
setPixmap(QWizard::LogoPixmap, QPixmap(":/images/logo.png"));
setPixmap(QWizard::WatermarkPixmap, QPixmap(":/images/func09.png"));
check0901 = new QCheckBox(QObject::trUtf8("Текст"));
label0901 = new QLabel(QObject::trUtf8("Текст"));
combo0901 = new QComboBox;
label0902 = new QLabel(QObject::trUtf8("Текст"));
combo0902 = new QComboBox;
check0903 = new QCheckBox(QObject::trUtf8("Текст"));
label0903 = new QLabel(QObject::trUtf8("Текст"));
combo0903 = new QComboBox;
check0904 = new QCheckBox(QObject::trUtf8("Текст"));
label0904 = new QLabel(QObject::trUtf8("Текст"));
combo0904 = new QComboBox;
summa09 = new QLineEdit;
registerField("summafunc09", summa09);
combo0901->setMaximumWidth(250);
combo0902->setMaximumWidth(250);
combo0903->setMaximumWidth(250);
combo0904->setMaximumWidth(250);
combo0901->insertItem(1, "10");
//...
combo0901->insertItem(50, "500");
combo0902->insertItem(1, "1.5");
//...
combo0902->insertItem(14, "8.0");
combo0903->insertItem(1, "10");
//...
combo0903->insertItem(50, "500");
combo0904->insertItem(1, "10");
//....
combo0904->insertItem(50, "500");
double h, s1, s2, s3, summa;
QString hstring, s1string, s2string, s3string;
hstring = combo0902->currentText();
s1string = combo0901->currentText();
s2string = combo0903->currentText();
s3string = combo0904->currentText();
h = hstring.toDouble();
s1 = s1string.toDouble();
s2 = s2string.toDouble();
s3 = s3string.toDouble();
summa = 0;
if (check0901->isChecked())
{
if ((h>=1.5) && (h<2.0))
{
// сверхтонкая стяжка
summa += 1578.1 * s1;
}
else if ((h>=2.0) && (h<3.5))
{
// тонкая стяжка
summa += 1623.9 * s1;
}
else if ((h>=3.5) && (h<=8.0))
{
// нормальная стяжка
summa += 2040.5 * s1;
}
}
if (check0903->isChecked())
{
summa += 4 * sqrt(s2) * 273.0;
}
if (check0904->isChecked())
{
summa += 2040.5 * s3;
}
QString value = QString::number(summa);
summa09->setText(value);
QGridLayout *layout = new QGridLayout;
layout->addWidget(check0901, 0, 0);
layout->addWidget(label0901, 1, 0);
layout->addWidget(combo0901, 2, 0);
layout->addWidget(label0902, 3, 0);
layout->addWidget(combo0902, 4, 0);
layout->addWidget(check0903, 5, 0);
layout->addWidget(label0903, 6, 0);
layout->addWidget(combo0903, 7, 0);
layout->addWidget(check0904, 0, 1);
layout->addWidget(label0904, 1, 1);
layout->addWidget(combo0904, 2, 1);
layout->addWidget(summa09, 3, 1);
setLayout(layout);
}
class Func09Page : public QWizardPage
{
Q_OBJECT
public:
Func09Page(QWidget *parent = 0);
private:
QLabel *label0901;
QLabel *label0902;
QLabel *label0903;
QLabel *label0904;
QCheckBox *check0901;
QCheckBox *check0903;
QCheckBox *check0904;
QComboBox *combo0901;
QComboBox *combo0902;
QComboBox *combo0903;
QComboBox *combo0904;
QLineEdit *summa09;
};
OutroPage::OutroPage(QWidget *parent)
: QWizardPage(parent)
{
setTitle(QObject::trUtf8("Заголовок"));
setSubTitle(QObject::trUtf8("Подзаголовок"));
setPixmap(QWizard::LogoPixmap, QPixmap(":/images/logo.png"));
setPixmap(QWizard::WatermarkPixmap, QPixmap(":/images/outro.png"));
label9901 = new QLabel(QObject::trUtf8("Текст:"));
line9901 = new QLineEdit;
QString summa09 = field("summafunc09").toString();
line9901->setText(summa09);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(label9901);
layout->addWidget(line9901);
setLayout(layout);
}
Ну.. все очень просто. В данном случае надо подключать сигналы изменения чекбоксов и комбобоксов к своему слоту, который уже будет в зависимости от их состояния заполнять поле ввода. В твоей программе такой расчет происходит только один раз - при конструировании страницы.
В свой слот надо выносить вот этот кусок:
double h, s1, s2, s3, summa;
QString hstring, s1string, s2string, s3string;
hstring = combo0902->currentText();
s1string = combo0901->currentText();
s2string = combo0903->currentText();
s3string = combo0904->currentText();
h = hstring.toDouble();
s1 = s1string.toDouble();
s2 = s2string.toDouble();
s3 = s3string.toDouble();
summa = 0;
if (check0901->isChecked())
{
if ((h>=1.5) && (h<2.0))
{
// сверхтонкая стяжка
summa += 1578.1 * s1;
}
else if ((h>=2.0) && (h<3.5))
{
// тонкая стяжка
summa += 1623.9 * s1;
}
else if ((h>=3.5) && (h<=8.0))
{
// нормальная стяжка
summa += 2040.5 * s1;
}
}
if (check0903->isChecked())
{
summa += 4 * sqrt(s2) * 273.0;
}
if (check0904->isChecked())
{
summa += 2040.5 * s3;
}
QString value = QString::number(summa);
summa09->setText(value);
посмотрите пожалуйста мою тему, аналогичная ситуация, не получается выцепить значение с предыдущей страницы, хотя все как в примере делаю
http://www.forum.crossplatform.ru/index.php?showtopic=8974
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)