发布Qt Widgets桌面应用程序的方法



  • Qt是一款优秀的跨平台开发框架,它可以在桌面、移动平台以及嵌入式平台上运行。目前Qt 5介绍程序发布的文章帖子比较少。大家又非常想要知道如何发布Qt应用程序,于是我花了一点儿时间介绍一下如何发布Qt桌面应用程序。

    首先我们从最简单的项目Qt Widgets开始说起。Qt Widgets项目是除了Qt Console项目之外依赖最少的项目模板了。而我们将用一个非常简单的方式来部署这个应用。
    1、创建一个Qt Widgets项目,这里我们将项目的名称命名为TestQtWidgetsApp:
    0_1451532270272_1.png
    2、运行一下我们的项目,我们看到结果出来了,是一个空的窗体;
    0_1451532274860_2.png
    3、假设我们已经这个程序开发完毕了,那么又如何发布的呢?网上提出了很多方法,不外乎就是使用了Qt给我们自带的windeployqt这个实用工具。这里我介绍一个更加便捷的方法,使用这个方法可以不再打开黑屏程序敲击命令了,在项目面板上直接输入一些文字就可以解决这件事儿。见下图:
    0_1451532280331_3.png
    也就是说,在项目面板中输入
    命令:windeployqt
    参数:%{buildDir}/%{CurrentBuild:Type}/%{CurrentProject:Name}.exe
    工作目录:%{buildDir}

    这样的话,大家去发布的文件夹中,会发现在部署这个过程中,已经将所有依赖都放好了。十分方便。



  • 这个方法很赞,我转走了~



  • @Zero 谢谢支持,这个方法的确是比较简单的方法呢。



  • 在现有的项目里面添加,提示如下错误,如果是新建工程时,添加命令,则ok.

    0_1451547051733_QQ截图20151231153036.png



  • @Pixellots 启动不了windeployqt?这个是不是因为windeployqt无法运行?可能是权限的原因?总之想办法运行windeployqt才行啊。



  • 在用到MySQL、在网络上get或者post时候
    windeployqt还不能把所有的依赖添加进来
    自己要注意找齐所以依赖



  • @hezhongfeng 如果是MySQL,那么作为插件的qsqlmysql.dll是不会自动复制过来的。需要自己手动操作。windeployqt只会检查Qt直接依赖的部分。



  • @jiangcaiyang 恰恰相反,qsqlmysql.dll和其他数据库的dll都会copy过来
    但是libmysql.dll和libeay32.dll、msvcr120.dll、ssleay32.dll是不会复制过来的
    这4个才是坑,当初累死了才找出来~
    希望别人少走弯路



  • @hezhongfeng 哦,发布Qt Quick应用程序的时候,出了libeay.dll和ssleay.dll没有复制过来,sqldrivers这个文件夹没有复制过来,还有QML的一些插件没有复制过来,这个是我也遇到的问题。还遇到了在Windows XP中无法在msvcrt.dll中定位vsprintf_s这个函数的问题。



  • @hezhongfeng
    这些个dll,我也都碰到了。但是我的方案比你简单:
    QT5静态编译,就不需要qsqlmysql
    libeay32.dll、ssleay32.dll可以通过openssl静态编译解决,就不需要了
    msvcr120.dll 可以通过mingw编译,所以也不需要了



  • @stlcours
    因为授权的一些问题
    一般不使用静态~
    当然,我还不会静态,O(∩_∩)O哈哈哈~



  • @hezhongfeng 用动态的,加上Qt Installer Framework进行打包一样能行。



  • 群主 怎么用qtcreator查看程序运行时的依赖库?我记得 可以查看的 就是忘了



  • @kpper dependency walker,这个是windows的,Linux的用dd命令。



  • 在cmd用windeployqt打包,貌似还有一系列的libgcc......dll包不进去


Log in to reply
 

走马观花

最近的回复

  • C

    Qt for MCU需要商业授权的

    read more
  • Qt for MCUs

    搭建Qt for MCUs PC端开发环境。qt for mcus提供了一个完整的图形框架和工具包,包含了在MCUs上设计、开发和部署gui所需的一切。它允许您在裸机或实时操作系统上运行应用程序。

    先决条件

    开发主机环境支持仅限于Windows 10

    MSVC compiler v19.16 (Visual Studio 2017 15.9.9 or newer) x64

    CMake v3.13 or newer (you can install it using the Qt Online installer) x64

    使用Qt联机安装程序安装Qt for MCUs,该安装程序可通过Qt帐户下载

    安装Qt 5.14和Qt Creator 4.11 or higher

    安装链接

    › Qt: https://account.qt.io/downloads
    › CMake: https://cmake.org/download/
    › Python 2.7 32-bit: https://www.python.org/downloads/release/python-2716/
    › Arm GCC: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnutoolchain/gnu-rm/downloads
    › J-Link Software Pack: https://www.segger.com/downloads/jlink/JLink_Windows.exe
    › J-Link OpenSDA Firmware: https://www.segger.com/downloads/jlink/OpenSDA_MIMXRT1050-EVKHyperflash
    › STM32CubeProgrammer: https://www.st.com/en/development-tools/stm32cubeprog.html
    › STM32 ST-LINK Utility: https://www.st.com/en/development-tools/stsw-link004.html​​​​​​​

    Qt Creator设置 启用Qt Creator插件 选择“帮助>关于插件”,然后从列表中选择“MCU支持(实验性)”插件,重新启动Qt Creator以应用更改
    替代文字 为MCU创建Qt工具包

    选择工具>选项>设备>MCU

    选择Qt for MCUs-Desktop 32bpp作为目标

    如果尚未设置,请提供Qt for MCUs安装目录的路径。

    单击Apply应用。

    替代文字

    替代文字
    替代文字

    注意:

    编译器要选X64,Qt版本要选64bit,CMake Tool选x64

    打开恒温器项目demo

    选择文件>打开文件或项目。。。

    打开CMakefiles.txt文件来自thermo文件夹的文件。

    选择Qt作为MCU-桌面32bpp套件。

    单击“配置项目”以完成。

    替代文字

    问题

    开发主机环境支持仅限于Windows 10

    C++编译失败,文本大字体.pixelSize.

    文本类型无法正确呈现需要复杂文本布局的unicode序列。对复杂文本使用StaticText

    read more
  • H

    hi 有问题请教你,方便加个联系方式吗

    read more
  • boost.asio是一个很棒的网络库,这回儿我也开始系统地学习起来了。想想当年接触boost,也有八年多了。这次开始接触boost,觉得既熟悉又陌生。熟悉的是小写字母+下划线的命名方式、晦涩的模板、很慢的编译速度以及较大的程序体积,陌生的是asio的各种概念:io服务、接收器、套接字等等:我之前对网络编程不是非常了解。

    于是根据我的理解,参考《Boost.Asio C++网络编程》实现了这样一个简单的客户端和服务端通信的例子,例子非常简单,还不完善,但是幸运的是,可以在本机上互通了。
    下面是客户端的代码:

    #include <iostream> #include <boost/asio.hpp> #include <boost/proto/detail/ignore_unused.hpp> using namespace std; using namespace boost::asio; using namespace boost::system; using namespace boost::proto::detail;// 提供ignore_unused方法 void writeHandler( const boost::system::error_code& ec, size_t bytesTransferred ) { if ( ec ) { cout << "Write data error, code: " << ec.value( ) << "transferred: " << bytesTransferred << endl; } else { cout << "OK! " << bytesTransferred << "bytes written. " << endl; } } int main(int argc, char *argv[]) { ignore_unused( argc ); ignore_unused( argv ); io_service service; ip::tcp::socket sock( service ); ip::tcp::endpoint ep( ip::address::from_string( "127.0.0.1" ), 6545 ); boost::system::error_code ec; sock.connect( ep, ec ); if ( ec ) { cout << "Connect error, code: " << ec.value( ) << ", We will exit." << endl; return ec.value( ); } else { char buf[1024] = "Hello world!"; sock.async_write_some( buffer( buf ), writeHandler ); sock.close( ); } return service.run( ); }

    下面是服务端的代码:

    #include <iostream> #include <boost/asio.hpp> #include <boost/proto/detail/ignore_unused.hpp> using namespace std; using namespace boost::asio; using namespace boost::system; using namespace boost::proto::detail;// 提供ignore_unused方法 void acceptHandle( const boost::system::error_code& code ) { cout << "Accepted." << endl; } int main(int argc, char *argv[]) { ignore_unused( argc ); ignore_unused( argv ); io_service service; ip::tcp::endpoint ep( ip::address::from_string( "127.0.0.1" ), 6545 ); boost::system::error_code ec; ip::tcp::socket sock( service ); ip::tcp::acceptor acceptor( service, ep ); acceptor.async_accept( sock, acceptHandle ); if ( ec ) { cout << "There is an error in server. code: " << ec.value( ) << endl; } return service.run( );// 阻塞运行 }

    运行结果是这样的:
    78448d7b-b3ae-42fc-9e2e-4dd2fbdac2c2-image.png

    我对boost.asio中几个概念的理解:

    io_service,这就是一个类似事件循环的东西,它为io设备提供服务,故名。不管是套接字、文件还是串口设备,都要使用它的服务。它的run()函数相当于启动了一个事件循环。一旦有消息了,即进行响应。这也是实现异步编程的重要基础。 socket,这个类则是套接字,可以处理TCP或者是UDP请求。有同步以及异步的处理方式,也有带异常以及不带异常的处理方式。 acceptor,接收器,仅仅是服务端使用。相当于其余框架中的listener,作接收用的。

    比较浅显,如果有不当之处,敬请指正。

    read more

关注我们

微博
QQ群