问题描述

我们用qtcreator可能好好的,但是偶然间,修改某些ui界面文件,运行后这些ui文件就不产生效果了。我是因为直接复制了别的ui文件,然后改名的,导致了这样的现象。如果我们老老实实的用qt creator的新建设计师界面类的方式,一般是不会出现这样问题的。

我的解决方法

直接把解决方法先说出来:删除Makefile文件即可。原因应该是我的ui_xx.h文件没有被gcc编译到。至于原因,看我后面的原理分析。

本质分析

做开发,要知根知底,才能节省下次遇到类似问题的消耗时间,下面我们来从原理上本质性的分析这个问题

1. 界面可视化设计原理

先说一下qt界面可视化设计的原理,以我们创建的MainWindow为例,分为几步:

  1. 编辑可视化界面,这个对应的是 mainwindow.ui 文件,这个其实是xml格式文件,用这个格式来对我们界面进行描述。因为xml文件格式描述能力太强了,超越ini、json等文件
  2. qtcreator编译过程中,会把这个xml文件转换为 ui_mainwindow.h文件(用的qt自己的uic工具),这个就是纯c++语法文件了。里面就是定义了一个Ui命名空间,这个Ui命名空间里定义了两个类,是一个Ui_MainWindow类,另一个是MainWindow类,而且让MainWindow类继承这个Ui_MainWindow类,代码如下:
     
    namespace Ui {
        class MainWindow: public Ui_MainWindow {};
    } // namespace Ui
    注意:这里面的MainWindow类跟我们自定义的MainWindow类,不是同一个类,因为它们不在一个命名空间中。所以引用Ui里面的这个类,需要这样 Ui::MainWindow
  3. 然后这个Ui::MainWindow类作为我们自己的MainWindow类(比如)的一个成员存在。

结构图如下:
 

2. 项目文件编译原理

主要分为3步,大家看我这个图就清楚了

3. 解决问题步骤如下

因此,修改了xx.ui文件,运行不奏效,查问题步骤如下:

  1. 因此首先看看.pro文件里是否包含这个xx.ui文件,因为这个能告诉qt creator将它编译成ui_xx.h文件。如果没有,那么问题就在这里了,加上即可。
  2. 打开ui_xx.h文件查看,如果该文件里确实是我们修改了控件的代码,说明qt creator将xx.ui文件转换(用的自己的uic工具)成功了的。否则,问题就在这里了,那么删除这个文件即可(直接在菜单栏的菜单项: 构建->清除 选项,可以快捷删除所有这些上次编译产生的文件,但是也要去这个文件夹里看看,防止没有删干净,因为qtcreator还是有点bug的),因为qt creator再编译时候会自动生成这个文件。
  3. 既然ui_xx.h文件本身没有问题,那么就是说明qtcreator在正式编译(gcc)时候没有编译到ui_xx.h文件,而这个过程是由makefile文件提供的编译信息,来对编译过程进行控制的。所以我们需要对这个makefile重新生成,该文件是由.pro文件用qmake工具生成的(所以可以用菜单栏的菜单项: 构建->执行qmake 选项),也就是上面的图中的第1步。

    注意:这里也有点奇怪的地方,即使执行qmake了,但是仍然可能不能真的更新这个makefile文件,那么直接去构建结果目录,把Makefile,Makefile.Debug,Makefile.Release这3个文件手动删除即可,此时qmake就会全新的生成它们了。

经过上面的步骤,再点击重新构建,或者直接构建,一般都能解决了。

此外,还有一个要注意:如果debug目录下的文件都删了,还是不行,注意看看项目源码根目录下(因为曾经采用过影子编译目录啥的,历史遗留)是不是也有大量的 .o文件,以及UI_XX.h文件,Makefile文件,这些文件被用作编译了,全部给删除,就好了。

其它解决方法

关于这个问题,大家可能在网上能搜到大量的博客了,这些解决方法整理如下:

  1. 取消影子构建,也就是让build目录在项目源码目录里,但是这也会让编译速度变慢(原理是每次构建都会重新生成),而且源码目录打包给别人时候不方便,会很大
  2. 在.pro文件中加入  UI_DIR=./  作用是直接将ui目录指定为项目目录,不知道会不会有附带作用 QtCreator修改的UI不生效 - xianyongchao - 博客园
  3. 菜单项:构建->清除,构建->执行qmake,构建->重新构建

也可以参考这个文章试试 qt修改完ui文件起不到作用 - 走看看

这些方法有时候能解决,有时候不能解决,这时候就要看我们的原理性的本质分析了,才能定位出问题。 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐