LinuxLinux学习之路编程开发

Qt开发系列2——使用Qt开发一个简单程序

2020-11-02  本文已影响0人  QuietHeart

这里介绍开发Qt程序的一些方法和步骤。
主要内容:
一、手工编写QT程序
二、使用Qt Designer进行程序界面设计
三、使用QCreator开发Qt程序

一、手工代码编写QT程序

1.程序功能

只有一个窗口的helloworld程序。

2.代码如下

//main.cpp
#include
#include
int main( int argc, char **argv )
{
QApplication a( argc, argv );


QWidget window;
window.resize(320, 240);
window.show();

return a.exec();
}

3.编译与运行

编译过程:

$qmake -project
$qmake
$make

运行:

$./main

假设生成的文件名称是main,这样运行会弹出一个简单的窗口,大小320x240。另外在X窗口运行的时候也可尝试用-geometry 100x200+10+20来指定大小。

二、使用Qt Designer进行程序界面设计

使用Qt Designer可以快速对程序界面进行设计。使用Qt Designer设计程序界面,有四种方式:

第1种方法:就是在源代码中直接利用designer生成的头文件

步骤如下:

a,首先利用designer设计界面,之后保存。

这里保存的文件为untitled.ui,xml格式。

b,在untitled.ui所在目录中随便写一个main.cpp文件里面有运行程序的main函数

(main可以先空白着)

c,运行如下命令生成ui头文件。

$qmake -project
$qmake
$make

这里,make之后可能会报错(由于main.cpp中的错误),不用管,这里目的只是先生成一个根据untitled.ui的头文件ui_untitled.h.

d,将ui界面添加到源代码中,改写main.cpp,如下:

#include
#include "ui_untitled.h"
int main(int argc, char *argv[])
{
  QApplication app(argc, argv);

  //这个window定义类型和ui_untitled.h中的setupUi参数类型一样
  QMainWindow *window = new QMainWindow;

  //这里是在程序中使用自己ui的方法,ui就是头文件定义的类对象
  //声明是Ui_MainWindow但是可以这样引用
  Ui::MainWindow ui;
  ui.setupUi(window);

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

e,编译运行:

$make
$<运行>

第2种方法:利用designer生成的类包含到自己的类中

和第一种方法不同的是,此方法不是直接使用designer生成的类,而是定义一个自己的类,类中包含designer生成类的对象(因为生成的类不继承任何所以可能不是Qobject的子类)来集中管理用户控件,自己定义的类可以继承其他QObject类,进而可以定义自己的槽和信号了。这也是后面QCreator使用Qt Designer的方式。编译和运行过程和前面类似。

第3种方法:使用多继承,继承Qt Designer生成的类

方法和第2种类似,不同的是方法2使用的是单继承一个自己喜欢的类然后在自己的类中将designer生成的类做为一个对象成员;这里却是多继承实现的:一个父类是自己喜欢继承的类,一个父类是designer生成的类。

第4种方法:运行时动态加载界面文件,不用生成界面文件的代码

这里和前面的方法都不一样,这里使用的untitled.ui文件不用生成ui_untitled.h而是动态读取。即,程序运行的时候,动态地读取untitled.ui的内容生成程序界面。这样,修改ui的时候非常方便,不用再重新编译了,只需要修改untitled.ui就行。
过程如下:

1)使用designer设计保存文件为untitled.ui

2)建立main.cpp文件内容如下:

#include
#include


//这个文件必须包含用于动态加载ui.
#include
int main(int argc, char *argv[])
{
QApplication app(argc, argv);


//加载ui文件
QUiLoader loader;
QFile file("./untitled.ui");
file.open(QFile::ReadOnly);


//根据ui文件生成界面
QWidget *uiWidget = loader.load(&file, 0);
file.close();
uiWidget->show();


//根据名称获得子部件的示例代码
//ui_Button = qFindChild(this,"name1");
//ui_textEdit = qFindChild(this, "name2");
//ui_lineEdit = qFindChild(this, "name3");


return app.exec();
}

3)生成.pro文件:

$qmake -pro

文件内容如下:

###############################
TEMPLATE = app
TARGET = 
DEPENDPATH += .
INCLUDEPATH += .

#Input
FORMS += untitled.ui
SOURCES += main.cpp

#这里是手动加的
#make时不自动生成头文件
FORMS -= untitled.ui
#使用动态加载必须这样配置
CONFIG += uitools
###############################

4)编译运行:

$qmake
$make
$./<运行程序>

三、使用QCreator开发Qt程序

QCreator是Qt的集成开发环境,利用它可以大大提高开发的效率。这里用一个完整的例子来说明使用过程。

软件版本:Qt Creator 2.4.1

安装qcreator

$sudo apt-get install qtcreator

这里,安装的版本是Qt Creator 2.4.1。

设置编译工具

参见:工具->选项->构建和运行,重点关注"Qt版本"和"工具链"两项。

编译和运行不同的版本

新建项目后,在左侧栏中选择"项目",其中,“构建设置”可设置编译成哪个版本(arm/x86/x11),“运行设置”可设置运行的参数等。

建立外部工具

这里假设建立"qvfb"模拟器,启动模拟器后可以运行qte-x86的程序。

  1. 建立方法:工具->外部->配置->外部工具->添加,然后填入启动qvfb所需的参数(这里假设添加的名字为qvfb)。
  2. 启动方法:工具->外部->qvfb。

其实,也可自己在终端手动启动qvfb,而不用添加外部工具。

编写程序

使用QtCreator创建的项目,会自动生成许多相关的文件,相比手工建立这些文件要方便,创建新项目之后,即可进行程序的创建。

下面给出一个例子:

(1)初始创建

  1. 文件->新建文件或工程
  2. 选择:Qt 控件项目->Qt Gui应用->下一步
  3. 设置好“名称”(mysinglegui)和“创建路径”->下一步
  4. 设置好编译版本(x86/arm/x11编译 debug/release版本)->下一步
  5. 采用默认的主窗口类名,ui界面文件名等设置->下一步->完成

至此,生成一个空白的gui程序,只有一个窗口。

(2)文件分析

项目目录的文件系统下主要包含的文件:

mainwindow.ui
main.cpp
mainwindow.h
mainwindow.cpp
ui_mainwindow.h(编译时根据mainwindow.ui生成)

大致介绍如下:

(a)mainwindow.ui

此文件为描述主窗口的界面文件,内容不用解释,该文件打开之后,可以通过集成进QCreator的Qt Designer用可视化方式对主窗口中的子元素进行布局和设置。编译程序时,会根据该文件自动生成一个普通类(注意它不是QObject的子类,只是普通类),它仅包含主窗口外的子元素集合,该类的类名和主窗口类名一样但是在"Ui::"命名空间声明,该类的作用是集中管理主窗口的子部件,见后对其文件的描述。

(b)main.cpp:

#include
#include "mainwindow.h"


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();


    return a.exec();
}

由此可知,此文件为程序的主入口文件,会创建MainWindow类窗口,并将其显示。

(c)mainwindow.h

#include
namespace Ui {
    class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT


    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();


    private:
        Ui::MainWindow *ui;
};

由此可见,此文件是程序主窗口的类声明,注意主窗口的界面元素和布局等其实都在其ui成员中设置,ui成员就是前面说的集中管理子界面的普通类对象。我们可在MainWindow类中定义自己的槽和信号。

(d)mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}


MainWindow::~MainWindow()
{
    delete ui;
}

此为主窗口类的实现,注意ui->setupUi(this);会将我们设置好的主窗口界面子元素设置并布局好。

(e)mysinglegui.pro

此为整个项目的配置文件,根据用户在QCreator中的操作和设置自动生成,一般不会手动修改。

(f)ui_mainwindow.h

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

QT_BEGIN_NAMESPACE

class Ui_MainWindow
{
    public:
        QMenuBar *menuBar;
        QToolBar *mainToolBar;
        QWidget *centralWidget;
        QStatusBar *statusBar;


        void setupUi(QMainWindow *MainWindow)
        {
            if (MainWindow->objectName().isEmpty())
                MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
            MainWindow->resize(400, 300);
            menuBar = new QMenuBar(MainWindow);
            menuBar->setObjectName(QString::fromUtf8("menuBar"));
            MainWindow->setMenuBar(menuBar);
            mainToolBar = new QToolBar(MainWindow);
            mainToolBar->setObjectName(QString::fromUtf8("mainToolBar"));
            MainWindow->addToolBar(mainToolBar);
            centralWidget = new QWidget(MainWindow);
            centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
            MainWindow->setCentralWidget(centralWidget);
            statusBar = new QStatusBar(MainWindow);
            statusBar->setObjectName(QString::fromUtf8("statusBar"));
            MainWindow->setStatusBar(statusBar);


            retranslateUi(MainWindow);


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


        void retranslateUi(QMainWindow *MainWindow)
        {
            MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0, QApplication::UnicodeUTF8));
            Q_UNUSED(MainWindow);
        } // retranslateUi


};


namespace Ui {
    class MainWindow: public Ui_MainWindow {};
} // namespace Ui


QT_END_NAMESPACE

这个文件是编译时根据mainwindow.ui自动生成的。前面对其进行了相关的描述。需要注意的是,在setupUi中最后的connectSlotsByName函数,它所做的是自动连接信号到MainWindow的指定槽上,具体参见后面。

(3)添加代码

(a)ui的作用

实际添加代码和不用QCreator开发类似,QCreator所做的只是将窗口的子部件全部放置一个普通类对象"ui"中集中管理。对于其它代码的添加(例如信号和槽等实现),不用修改那个自动生成的ui类,只需修改MainWindow类的相应部分即可。

(b)信号和槽

我们可以像一般QT程序那样连接信号和槽,但是如果想使ui对象的connectSlotsByName函数自动连接起作用,这要求MainWindow主窗口类中定义的槽的命名为on__,即例如想将对象名为btn的子构件的clicked信号连接,那么MainWindow中的槽名字应为:on_btn_clicked。这里的对象名不是代码中的变量名,而是QObject的objectname,是Qt控件的一个标识属性。

(c)多窗口

另外,对于多窗口程序,我们可以继续在已有项目基础上继续创建剩余窗口。通过在当前项目名下,右键->添加新文件,可以只添加.cpp .h 以及.ui文件,或者将三种文件自动一并添加,并在代码级别上使它们和主程序有所关联。但是不要在创建时ui设计器中把主窗口的对象名改变,否则其自动生成的Ui::classname变成对象名,导致无法编译通过。

(4)运行和部署

左侧"项目"->"运行设置"

这里可以设置运行的参数,以及部署的位置和命令。

待整理

具体编写代码规则等,需参见“帮助”中的文档信息。

添加槽的简单方法:在Qt Designer界面右击相应控件->转到槽->选择触发槽的相应信号。

问题:代码中头文件的包含信息丢失?

2013-11-20 17:39:10

上一篇下一篇

猜你喜欢

热点阅读