手动模仿Qt5创建GUI程序过程记录

    本文是手动模仿Qt Creator创建一个GUI的程序的记录。具体过程如下:

    1、首先用Qt Designer创建一个GUI界面,简单的一个窗口程序,在这里用一个登录框演示,如下:

这里写图片描述

在这里并不创建任何信号与槽,直接保存为LoginFrame.ui,其中窗口的名字就叫LoginFrame.

    2、用命令行进入同一目录,在目录下运行命令:

qmake -project //这一行会根据你现在的文件目录生成"目录.pro"文件
mic LoginFrame.h -o ui_LoginFrame.h

然后用文本编辑器打开目录下生成的”目录.pro”文件,在第一行加上一句:

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

    3、在同一目录下创建main.cpp文件,内容如下:

#include <QApplication>
#include <QDialog>
#include "ui_LoginFrame.h"
int main(int argc,char* argv[])
{
    QApplication app(argc,argv);
    Ui::LoginFrame ui;
    QDialog* dialog=new QDialog; //设置父窗体
    ui.setupUi(dialog);
    dialog->show();
    return app.exec();
}

在命令行下在输入:

qmake "目录.pro" //生成Makefile文件
make  //编辑

这样就生成了一个可执行文件了。点击就可运行了。


但是现在这个应用程序只是显示了界面,下面讲解如何设置信号与槽,也就是点击按键等有相应事件生:

    4、首先我们来看一下上面生成的ui_LoginFrame.h文件的内容:

#ifndef UI_LOGINFRAME_H
#define UI_LOGINFRAME_H

#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QDialog>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>

QT_BEGIN_NAMESPACE

class Ui_LoginFrame
{
public:
    QLineEdit *userName;
    QLineEdit *Password;
    QLabel *label;
    QLabel *label_2;
    QPushButton *btnOk;
    QPushButton *btnCancel;

    void setupUi(QDialog *LoginFrame)
    {
        if (LoginFrame->objectName().isEmpty())
            LoginFrame->setObjectName(QStringLiteral("LoginFrame"));
        LoginFrame->resize(400, 300);
        userName = new QLineEdit(LoginFrame);
        userName->setObjectName(QStringLiteral("userName"));
        userName->setGeometry(QRect(140, 90, 171, 30));
        Password = new QLineEdit(LoginFrame);
        Password->setObjectName(QStringLiteral("Password"));
        Password->setGeometry(QRect(140, 160, 171, 30));
        label = new QLabel(LoginFrame);
        label->setObjectName(QStringLiteral("label"));
        label->setGeometry(QRect(30, 90, 81, 20));
        label_2 = new QLabel(LoginFrame);
        label_2->setObjectName(QStringLiteral("label_2"));
        label_2->setGeometry(QRect(30, 160, 81, 20));
        btnOk = new QPushButton(LoginFrame);
        btnOk->setObjectName(QStringLiteral("btnOk"));
        btnOk->setEnabled(false);
        btnOk->setGeometry(QRect(40, 240, 96, 28));
        btnCancel = new QPushButton(LoginFrame);
        btnCancel->setObjectName(QStringLiteral("btnCancel"));
        btnCancel->setGeometry(QRect(240, 240, 96, 28));

        retranslateUi(LoginFrame);

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

    void retranslateUi(QDialog *LoginFrame)
    {
        LoginFrame->setWindowTitle(QApplication::translate("LoginFrame", "Dialog", 0));
        label->setText(QApplication::translate("LoginFrame", "UserName:", 0));
        label_2->setText(QApplication::translate("LoginFrame", "Password:", 0));
        btnOk->setText(QApplication::translate("LoginFrame", "OK", 0));
        btnCancel->setText(QApplication::translate("LoginFrame", "Cancel", 0));
    } // retranslateUi

};

namespace Ui {
    class LoginFrame: public Ui_LoginFrame {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_LOGINFRAME_H

分析一下先,在自动生成的文件中有一个setupUi()函数用来设置UI,但是要传入父窗体,传进来的父窗体的会被resize为你在Qt Designer中你设置的窗体的大小。在最后在namespace Ui中创建了一个新类LoginFrame,这个类只是简单的继承Ui_LoginFrame,并没有做任何事情。


    5、接下来我们继续,创建一个LoginFrame.h与LoginFrame.c放在前面的目录里,内容如下:

/******LoginFrame.h*********/
#ifndef LOGINFRAME_H
#define LOGINFRAME_H
#include<ui_LoginFrame.h>

class LoginFrame:public QDialog
{
    Q_OBJECT
public:
    LoginFrame(QWidget* parent=0);
private slots:
    void on_userName_textChanged();
 private:
    Ui::LoginFrame* ui;
};

#endif // LOGINFRAME_H
/*********LoginFrame.cpp***********/
#include "ui_LoginFrame.h"
#include "LoginFrame.h"
LoginFrame::LoginFrame(QWidget* parent):QDialog(parent),
    ui(new Ui::LoginFrame)
{
    ui->setupUi(this);
    QRegExp regExp("[A-Za-z][1-9][0-9]{0,2}");
    ui->userName->setValidator(new QRegExpValidator(regExp,this));
    connect(ui->btnOk,SIGNAL(clicked()),this,SLOT(accept()));
    connect(ui->btnCancel,SIGNAL(clicked()),this,SLOT(reject()));

}

void LoginFrame::on_userName_textChanged()
{
    ui->btnOk->setEnabled(ui->userName->hasAcceptableInput());
}

    6、将目录中生成的.pro文件,还有Makefile文件删除,重复步骤2,将main.cpp文件改为如下内容,然后make,

#include<QApplication>
#include<LoginFrame.h>

int main(int argc,char* argv[])
{
    QApplication app(argc,argv);
    LoginFrame ui;
    ui.show();
    return app.exec();
}

之后生成的可执行文件就已经添加了信号与槽了。

以上便是手动完全模仿了Qt Creator生成一个Gui程序的过程,你可以用Qt Creator创建一个文件看是否一样,不过Qt Creator在创建时.pro文件会自动加上greaterThan(QT_MAJOR_VERSION, 4): QT += widgets这一句,这句话也是到QT5后取消QtGui后才有的,目前并不知道如何用qmake直接生成带有这句话的.pro文件,只能这样。


    注意在LoginFrame.h中LoginFrame类可以直接继承Ui::LoginFrame或Ui_LoginFrame,这样就可以不用有private 的ui变量,并且后面设置槽的话也不用代有许多->了,并且直接setupUi(this)为自身为自身的交窗体就行了,因为本身继承了QDialog,具体示例如下。但是为了于Qt Creator保持一致,便采用了上述做法,注意这种方法要初始化ui。

/****************LoginFrame.h***********/
#ifndef LOGINFRAME_H
#define LOGINFRAME_H
#include<ui_LoginFrame.h>

class LoginFrame:public QDialog,Ui::LoginFrame
{
    Q_OBJECT
public:
    LoginFrame(QWidget* parent=0);
private slots:
    void on_userName_textChanged();
};

#endif // LOGINFRAME_H
/***************LoginFrame.cpp***********/
#include "ui_LoginFrame.h"
#include "LoginFrame.h"
LoginFrame::LoginFrame(QWidget* parent):QDialog(parent)
{
    setupUi(this);
    QRegExp regExp("[A-Za-z][1-9][0-9]{0,2}");
    userName->setValidator(new QRegExpValidator(regExp,this));
    connect(btnOk,SIGNAL(clicked()),this,SLOT(accept()));
    connect(btnCancel,SIGNAL(clicked()),this,SLOT(reject()));

}

void LoginFrame::on_userName_textChanged()
{
    btnOk->setEnabled(userName->hasAcceptableInput());
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章