• 6066阅读
  • 5回复

如何在一个子类中使用ui文件?(我的一个实验程序的问题) [复制链接]

上一主题 下一主题
离线snakedy
 
只看楼主 倒序阅读 楼主  发表于: 2010-01-24
我想实验一个find窗口,自己做的方法没有问题,但想和ui界面相互结合,因此重新编写了代码,其代码如下:
不用ui的程序:
finddialog.h
#ifndef FINDDIALOG_H
#define FINDDIALOG_H
#include <QDialog>

class QCheckBox;
class QLabel;
class QLineEdit;
class QPushButton;
class FindDialog : public QDialog
{
Q_OBJECT
public:
   FindDialog(QWidget *parent = 0);
signals:
   void findNext(const QString &str, Qt::CaseSensitivity cs);
   void findPrevious(const QString &str, Qt::CaseSensitivity cs);
private slots:
   void findClicked();
   void enableFindButton(const QString &text);
private:
   QLabel *label;
   QLineEdit *lineEdit;
   QCheckBox *caseCheckBox;
   QCheckBox *backwardCheckBox;
   QPushButton *findButton;
   QPushButton *closeButton;
};
#endif

finddialog.cpp
#include <QtGui>
#include "finddialog.h"

FindDialog::FindDialog(QWidget *parent): QDialog(parent)
{
label = new QLabel(tr("Find &what:"));
lineEdit = new QLineEdit;
label->setBuddy(lineEdit);
caseCheckBox = new QCheckBox(tr("Match &case"));
backwardCheckBox = new QCheckBox(tr("Search &backward"));
findButton = new QPushButton(tr("&Find"));
findButton->setDefault(true);
findButton->setEnabled(false);
closeButton = new QPushButton(tr("Close"));
connect(lineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(enableFindButton(const QString &)));
connect(findButton, SIGNAL(clicked()), this, SLOT(findClicked()));
connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
QHBoxLayout *topLeftLayout = new QHBoxLayout;
topLeftLayout->addWidget(label);
topLeftLayout->addWidget(lineEdit);
QVBoxLayout *leftLayout = new QVBoxLayout;
leftLayout->addLayout(topLeftLayout);
leftLayout->addWidget(caseCheckBox);
leftLayout->addWidget(backwardCheckBox);
QVBoxLayout *rightLayout = new QVBoxLayout;
rightLayout->addWidget(findButton);
rightLayout->addWidget(closeButton);
rightLayout->addStretch();
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addLayout(leftLayout);
mainLayout->addLayout(rightLayout);
setLayout(mainLayout);
setWindowTitle(tr("Find"));
setFixedHeight(sizeHint().height());
}

void FindDialog::findClicked()
{
QString text = lineEdit->text();
Qt::CaseSensitivity cs =
caseCheckBox->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive;
if (backwardCheckBox->isChecked())
{
   emit findPrevious(text, cs);
}
else
{
   emit findNext(text, cs);
}
}

void FindDialog::enableFindButton(const QString &text)
{
findButton->setEnabled(!text.isEmpty());
}

main.cpp
#include <QApplication>
#include "finddialog.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
FindDialog *dialog = new FindDialog;

dialog->show();
return app.exec();
}

执行没有问题
离线snakedy
只看该作者 1楼 发表于: 2010-01-24
我的改进代码如下:
finddialog.h

#ifndef FINDDIALOG_H
#define FINDDIALOG_H

#include <QDialog>

class QCheckBox;
class QLabel;
class QLineEdit;
class QPushButton;

class FindDialog : public QDialog
{
Q_OBJECT
public:
  FindDialog(QWidget *parent = 0);
signals:
  void findNext(const QString &str, Qt::CaseSensitivity cs);
  void findPrevious(const QString &str, Qt::CaseSensitivity cs);
public slots:
  void findClicked();
  void enableFindButton(const QString &text);
};

#endif // FINDDIALOG_H

finddialog.cpp
#include <QtGui>
#include "finddialog.h"
#include "ui_dialog.h"

extern Ui::Form ui;

FindDialog::FindDialog(QWidget *parent): QDialog(parent)
{
connect(ui.lineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(enableFindButton(const QString &)));
connect(ui.findButton, SIGNAL(clicked()), this, SLOT(findClicked()));
ui.rightLayout->addStretch();
setLayout(ui.mainLayout);
setWindowTitle(tr("Find"));
setFixedHeight(sizeHint().height());
}

void FindDialog::findClicked()
{
QString text = ui.lineEdit->text();
Qt::CaseSensitivity cs =
ui.caseCheckBox->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive;
if (ui.backwardCheckBox->isChecked())
{
   emit findPrevious(text, cs);
}
else
{
   emit findNext(text, cs);
}
}

void FindDialog::enableFindButton(const QString &text)
{
ui.findButton->setEnabled(!text.isEmpty());
}

main.cpp
#include <QApplication>
#include "finddialog.h"
#include "ui_dialog.h"
Ui::Form ui;

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
FindDialog *dialog = new FindDialog;

ui.setupUi(dialog);
dialog->show();
return app.exec();
}


ui出来的,h是
/********************************************************************************
** Form generated from reading UI file 'dialog.ui'
**
** Created: Sun Jan 24 15:10:45 2010
**      by: Qt User Interface Compiler version 4.6.0
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_DIALOG_H
#define UI_DIALOG_H

#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QCheckBox>
#include <QtGui/QHBoxLayout>
#include <QtGui/QHeaderView>
#include <QtGui/QLabel>
#include <QtGui/QLineEdit>
#include <QtGui/QPushButton>
#include <QtGui/QVBoxLayout>
#include <QtGui/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Form
{
public:
    QWidget *horizontalLayoutWidget_2;
    QHBoxLayout *mainLayout;
    QVBoxLayout *leftLayout;
    QHBoxLayout *topLeftLayout;
    QLabel *label;
    QLineEdit *lineEdit;
    QCheckBox *caseCheckBox;
    QCheckBox *backwardCheckBox;
    QVBoxLayout *rightLayout;
    QPushButton *findButton;
    QPushButton *closeButton;

    void setupUi(QWidget *Form)
    {
        if (Form->objectName().isEmpty())
            Form->setObjectName(QString::fromUtf8("Form"));
        Form->resize(507, 160);
        Form->setMinimumSize(QSize(507, 160));
        Form->setMaximumSize(QSize(16777215, 326));
        Form->setLayoutDirection(Qt::LeftToRight);
        horizontalLayoutWidget_2 = new QWidget(Form);
        horizontalLayoutWidget_2->setObjectName(QString::fromUtf8("horizontalLayoutWidget_2"));
        horizontalLayoutWidget_2->setGeometry(QRect(0, 0, 431, 161));
        mainLayout = new QHBoxLayout(horizontalLayoutWidget_2);
        mainLayout->setSpacing(0);
        mainLayout->setObjectName(QString::fromUtf8("mainLayout"));
        mainLayout->setSizeConstraint(QLayout::SetMaximumSize);
        mainLayout->setContentsMargins(0, 0, 0, 0);
        leftLayout = new QVBoxLayout();
        leftLayout->setSpacing(20);
        leftLayout->setObjectName(QString::fromUtf8("leftLayout"));
        leftLayout->setSizeConstraint(QLayout::SetMaximumSize);
        topLeftLayout = new QHBoxLayout();
        topLeftLayout->setSpacing(0);
        topLeftLayout->setObjectName(QString::fromUtf8("topLeftLayout"));
        label = new QLabel(horizontalLayoutWidget_2);
        label->setObjectName(QString::fromUtf8("label"));
        label->setScaledContents(false);

        topLeftLayout->addWidget(label);

        lineEdit = new QLineEdit(horizontalLayoutWidget_2);
        lineEdit->setObjectName(QString::fromUtf8("lineEdit"));

        topLeftLayout->addWidget(lineEdit);


        leftLayout->addLayout(topLeftLayout);

        caseCheckBox = new QCheckBox(horizontalLayoutWidget_2);
        caseCheckBox->setObjectName(QString::fromUtf8("caseCheckBox"));

        leftLayout->addWidget(caseCheckBox);

        backwardCheckBox = new QCheckBox(horizontalLayoutWidget_2);
        backwardCheckBox->setObjectName(QString::fromUtf8("backwardCheckBox"));

        leftLayout->addWidget(backwardCheckBox);


        mainLayout->addLayout(leftLayout);

        rightLayout = new QVBoxLayout();
        rightLayout->setSpacing(0);
        rightLayout->setObjectName(QString::fromUtf8("rightLayout"));
        findButton = new QPushButton(horizontalLayoutWidget_2);
        findButton->setObjectName(QString::fromUtf8("findButton"));
        findButton->setEnabled(false);
        findButton->setDefault(true);

        rightLayout->addWidget(findButton);

        closeButton = new QPushButton(horizontalLayoutWidget_2);
        closeButton->setObjectName(QString::fromUtf8("closeButton"));
        QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
        sizePolicy.setHorizontalStretch(0);
        sizePolicy.setVerticalStretch(0);
        sizePolicy.setHeightForWidth(closeButton->sizePolicy().hasHeightForWidth());
        closeButton->setSizePolicy(sizePolicy);

        rightLayout->addWidget(closeButton);


        mainLayout->addLayout(rightLayout);

#ifndef QT_NO_SHORTCUT
        label->setBuddy(lineEdit);
#endif // QT_NO_SHORTCUT

        retranslateUi(Form);
        QObject::connect(findButton, SIGNAL(clicked()), Form, SLOT(close()));

        QMetaObject::connectSlotsByName(Form);
    } // setupUi

    void retranslateUi(QWidget *Form)
    {
        Form->setWindowTitle(QApplication::translate("Form", "Form", 0, QApplication::UnicodeUTF8));
        label->setText(QApplication::translate("Form", "Find &what:", 0, QApplication::UnicodeUTF8));
        caseCheckBox->setText(QApplication::translate("Form", "Match &case", 0, QApplication::UnicodeUTF8));
        backwardCheckBox->setText(QApplication::translate("Form", "Search &backward", 0, QApplication::UnicodeUTF8));
        findButton->setText(QApplication::translate("Form", "Find", 0, QApplication::UnicodeUTF8));
        closeButton->setText(QApplication::translate("Form", "Close", 0, QApplication::UnicodeUTF8));
    } // retranslateUi

};

结果编译时候出现:
C:\TEST\FindDialog_new\debug\FindDialog_new.exe 启动中...
QObject::connect: Cannot connect (null)::textChanged(const QString &) to FindDialog::enableFindButton(const QString &)
QObject::connect: Cannot connect (null)::clicked() to FindDialog::findClicked()
C:\TEST\FindDialog_new\debug\FindDialog_new.exe 以代码 0 退出
错误,检查并未发现相应问题,请问,难道connect的时候不能用ui的么,其实想将这两个连接也放到ui皮中,但是不知道有什么办法,请问有这种办法么?

namespace Ui {
    class Form: public Ui_Form {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_DIALOG_H
离线snakedy
只看该作者 2楼 发表于: 2010-01-24
感觉好象ui不能这样引用好象
离线snakedy
只看该作者 3楼 发表于: 2010-01-24
改进了一下连接部分,程序如下:
finddialog.h
#ifndef FINDDIALOG_H
#define FINDDIALOG_H

#include <QDialog>
#include "ui_dialog.h"

class QCheckBox;
class QLabel;
class QLineEdit;
class QPushButton;

class FindDialog : public QDialog
{
Q_OBJECT
public:
  FindDialog(QWidget *parent = 0);
  Ui::Form *ui;
signals:
  void findNext(const QString &str, Qt::CaseSensitivity cs);
  void findPrevious(const QString &str, Qt::CaseSensitivity cs);
public slots:
  void findClicked();
  void enableFindButton(const QString &text);
};

#endif // FINDDIALOG_H

finddialog.cpp
#include <QtGui>
#include "finddialog.h"

//extern Ui::Form ui;

FindDialog::FindDialog(QWidget *parent): QDialog(parent)
{
connect(ui->lineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(enableFindButton(const QString &)));
connect(ui->findButton, SIGNAL(clicked()), this, SLOT(findClicked()));
ui->rightLayout->addStretch();
setLayout(ui->mainLayout);
setWindowTitle(tr("Find"));
setFixedHeight(sizeHint().height());
}

void FindDialog::findClicked()
{
QString text = ui->lineEdit->text();
Qt::CaseSensitivity cs =
ui->caseCheckBox->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive;
if (ui->backwardCheckBox->isChecked())
{
   emit findPrevious(text, cs);
}
else
{
   emit findNext(text, cs);
}
}

void FindDialog::enableFindButton(const QString &text)
{
ui->findButton->setEnabled(!text.isEmpty());
}

main.cpp
#include <QApplication>
#include "finddialog.h"
#include "ui_dialog.h"


int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Ui::Form ui;
FindDialog *dialog = new FindDialog;
dialog->ui = &ui;
ui.setupUi(dialog);
dialog->show();
return app.exec();
}

编译没有问题了,但是执行出现core问题,感觉是ui对象是个空,在finddialog类构造函数的第一个connect的时候就内存溢出了,呵呵
离线snakedy
只看该作者 4楼 发表于: 2010-01-24
再次进行修改后发现没有问题了,代码如下:
finddialog.h
#ifndef FINDDIALOG_H
#define FINDDIALOG_H

#include <QDialog>
//#include "ui_dialog.h"

class QCheckBox;
class QLabel;
class QLineEdit;
class QPushButton;

class FindDialog : public QDialog
{
Q_OBJECT
public:
  FindDialog(QWidget *parent = 0);
  //Ui::Form *ui;
signals:
  void findNext(const QString &str, Qt::CaseSensitivity cs);
  void findPrevious(const QString &str, Qt::CaseSensitivity cs);
public slots:
  void findClicked();
  void enableFindButton(const QString &text);
};

#endif // FINDDIALOG_H

finddialog.cpp
#include <QtGui>
#include "finddialog.h"
#include "ui_dialog.h"

//extern Ui::Form ui;
Ui::Form ui;
FindDialog::FindDialog(QWidget *parent): QDialog(parent)
{
ui.setupUi(this);
connect(ui.lineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(enableFindButton(const QString &)));
connect(ui.findButton, SIGNAL(clicked()), this, SLOT(findClicked()));
ui.rightLayout->addStretch();
setLayout(ui.mainLayout);
setWindowTitle(tr("Find"));
setFixedHeight(sizeHint().height());
}

void FindDialog::findClicked()
{
QString text = ui.lineEdit->text();
Qt::CaseSensitivity cs =
ui.caseCheckBox->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive;
if (ui.backwardCheckBox->isChecked())
{
   emit findPrevious(text, cs);
}
else
{
   emit findNext(text, cs);
}
}

void FindDialog::enableFindButton(const QString &text)
{
ui.findButton->setEnabled(!text.isEmpty());
}

main.cpp
#include <QApplication>
#include "finddialog.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
FindDialog *dialog = new FindDialog;
dialog->show();
return app.exec();
}
主要是C++使用的问题,应该将声明放在ui中,就正确的了
离线yangfanxing
只看该作者 5楼 发表于: 2010-01-24
小推荐一个吧~~~
http://www.qtcn.org/bbs/read.php?tid=25279
按这里的做下,就比较清晰地整合了ui到一个类中了~~~(个人觉得哈~~~呵呵。。。)

当然LZ的方案最后是OK的。
PHPWind好恶心。。。不想看这种界面。。。
快速回复
限100 字节
 
上一个 下一个