当前位置:首页 > QT
  • Qt 5.15 RC 发布

    Qt 5.15 RC 发布

    Qt 5.15 首个 RC 版已发布,开发团队表示目前正在为 Qt 5.15 寻求最后的测试,希望用户在试用后能立即反馈错误。此外,团队希望在5月19日左右发布稳定版,同时确认Qt 5.15.1 将在稳定版发布不久之后推出,以修复 5.15.0 中的错误。Qt 5.15 是 Qt 6.0 发布前的最后一个重大更新,部分更新内容包括:为 Qt 3D 带来了改进的分析支持将 OpenGL 渲染器以独立插件的形式提供各种内核方面的更改改进 QColorSpace针对 QML 的各种改进通过 Qt Quick Controls 2 改进对表格的支持升级 Qt WebEngine通过 Wayland 平台代码对 Vulkan 进行实验性支持在 Android 平台支持原生文件对话框支持使用 Qt Multimedia 渲染到多个表面qmlformat 根据 QML 编码准则格式化 QML 代码……

    时间:2020-05-26 关键词: QT

  • 开发者讨论将 Qt 5 代码移植到 Qt 6 的工具

    开发者讨论将 Qt 5 代码移植到 Qt 6 的工具

    Qt 是一个跨平台的C++图形用户界面应用程序框架。它提供给开发者建立图形用户界面所需的功能,广泛用于开发GUI程序,也可用于开发非GUI程序。Qt是完全面向对象的,很容易扩展,并且允许真正地组件编程。虽然 Qt 作为开源项目的未来还不太清楚,但现在看来一切都在顺利推进中。Qt 开发团队的邮件列表显示他们正在讨论一个将 Qt 5 代码移植到 Qt 6 的工具。此工具基于 Clang,可帮助开发者自动将所有 Qt 5 语法转换为与 Qt 6 兼容。如果这个工具能够在很大程度上将大多数 Qt 5 代码转换为 Qt 6 兼容的用法,那么它就可以极大地帮助提升 Qt 6 的采用率。Qt 公司的 Vitaly Fanaskov 认为官方应该提供基于 Clang 的工具,将用户的代码库(半)自动移植到新版本的 Qt 上。这些工具可能还需要具备对代码进行修复的功能,或者至少在可能存在问题的地方添加一个注释,以便用户对代码进行修正。修改 API 的开发者也应该为这些工具实现一个规则。当然也需要稍微调整一下 API 设计指南。如果确实能够(半)自动将 Qt 5 代码转换为 Qt 6 代码,或者至少降低编码的门槛,这无疑是一个有趣的概念。LLVM/Clang 已经被用于自动代码格式化、代码翻译和其他创新用例,所以这并非不可能的事情。但目前还没有人真正写出这个实用程序,也不清楚 Qt 公司自己是否打算这么做。反对这个提议的观点是,Clang 无法编译所有使用 Qt 的代码库,所以它不能通用,而且这种转换代码也还没有被写出来。除此之外,自动生成的代码也往往不如手写的代码好。Qt 6 将在2020年年底首次亮相,这个提议是否会被采用,又能否提升 Qt 6 的采用率,不妨拭目以待。

    时间:2020-05-14 关键词: QT

  • KDE 社区称 Qt 公司正考虑仅面向付费用户提供新版本

    KDE 社区称 Qt 公司正考虑仅面向付费用户提供新版本

    近日,一封题为 Qt, Open Source and corona 的邮件在 KDE 社区引发了广泛的讨论,其内容主要是指出 Qt 公司正考虑在 Qt 发布新版后的 12 个月内,新版本将限制为仅面向付费客户提供(即不将其作为开源项目发布)。也就意味着,在新版发布后长达一年的时间里,开源用户将无法使用它——除非成为付费客户。就此引发的各种讨论,Qt 公司进行了简短的回应,大意是说这些内容不能代表 Qt 公司的观点和计划,最后还表示 Qt 公司为自己致力于客户、开源和 Qt 治理模型的理念而感到自豪。然而整篇声明没有重申其及时开源 Qt 和面向所有用户提供下载等承诺,这样的回应显然得不到信服。下面介绍此次事件的背景信息。首先有必要说明 KDE 社区、Qt 项目和 Qt 公司这三者之间的关系:• KDE 基于 Qt 框架开发,因此 KDE 社区既受益于 Qt 也直接为 Qt 贡献代码• Qt 既背靠着拥有雄厚资金实力的 Qt 公司,也从庞大且知名的 KDE 社区中获益甚多• Qt 公司受益于 KDE 社区,因为大量开源贡献者、开发者和社区专家帮助其改进 Qt 项目可以看到三者有着密切的关系,且都能从中获益。不过根据邮件的描述,Qt 公司目前正在考虑停止这种健康的合作。据 Olaf Schmidt-Wischhöfer(任职于 KDE Free Qt Foundation 董事会的 KDE 开发者)的介绍,在过去两年里,Qt 公司和 KDE Free Qt 基金会一直在就更新合同进行谈判,后者在谈判中的目标是:• 在不损害 Qt 项目和 KDE 社区的前提下,帮助 Qt 公司增加收入• 加强对 Qt 项目和 KDE 社区的保护• 避免 Qt 公司和 Qt+KDE 社区之间的分裂谈判的具体内容包括:• 修复 Qt 付费许可条款与使用/贡献开源软件之间的不兼容问题• 修复 Qt Design Studio(属于受限的自由软件)与现有合同不兼容的问题• 要求 Qt 公司及时发布 Qt 自由软件版本的更新以确保 KDE LTS 版本的安全修复• 更新合同并将 Wayland 纳入其中• 评估公司提出的合同变更建议,以使 Qt 业务的经济效益更高,例如可以选择将 Qt 与其他软件捆绑销售,或与第三方专有软件进行整合然而,Qt 公司在今年1月宣布的三个变更让谈判遭遇了挫折:• 需要使用 Qt 帐户才能获取安装 Qt 的二进制文件(源码文件不受限制)• 长期支持版本(LTS)和离线安装程序仅面向拥有商业许可证的用户提供• 面向初创企业和小型企业提供新版 Qt 每年收费 499 美元尽管如此,这时双方仍在努力寻找对各方都有利的方案。然而就在上周,Olaf 表示 Qt 公司突然通知 KDE e.V. 董事会和 KDE Free Qt 基金会,称由于新冠病毒造成的经济前景给他们带来了更大的压力,所以需要增加短期收入。因此 Qt 公司考虑,在所有 Qt 版本发布新版后的 12 个月内,新版本将限制为仅面向付费客户提供。对此,Olaf 希望 Qt 公司能重新认真考虑此方案,毕竟这对开源社区造成的威胁是可以预见的。Qt 公司表示只有当 KDE 社区在其他方面能给他们提供让步时,他们才愿意重新考虑此方案。但 Olaf 提到,半年前双方在讨论合同更新期间,Qt 公司突然限制了 LTS 版本的发布。KDE 社区和 Qt 公司之间曾经达成过一项协议,其中规定:如果 Qt 公司在开源许可证有效的情况下停止开发自由软件版本的 Qt(Qt Free Edition),那么基金会有权以 BSD 许可证或其他开源许可证发布 Qt。“[…] should The Qt Company discontinue the development of the Qt Free Edition under the required licenses, then the Foundation has the right to release Qt under a BSD-style license or under other open source licenses.”虽然 Qt 公司并未正面回应“仅面向付费客户提供新版本 Qt”的传闻,但从目前的情况来看,Qt 公司大刀阔库进行商业化的举动无疑已受到广泛的抨击。在 KDE 社区中,有些人已经呼吁社区与其他 Qt 利益相关者合作(例如 fork 出另一个 Qt),并且在与 Qt 公司的对话中不要做出让步。不过无论如何,相信没人会受益于 Qt 公司和 KDE 社区之间的严重分歧。

    时间:2020-05-04 关键词: QT kde

  • Qt封装DLL

    Qt封装DLL

    由于原文章没有转载链接,只好直接粘贴过来,附上原文地址:http://www.cnblogs.com/feiyangqingyun/p/3720777.html 既然QT也是C++,而且有个大名鼎鼎的WPS都是QT和MFC混合编程的,所以肯定有方法的,百度谷歌,找到一个qtwinmigrate的东西,在这里万分感谢qtwinmigrate的作者! 第一步: 打开qt creator,新建C++ 库项目 依次下一步,记得在选择需要的模块的时候选择QtGui模块,如果没有选中的话,后面编译通不过,qmfcapp这个类里面用了QtGui模块中的方法。   第二步: 将多余的文件删除,_global.h还有其他两个文件删除,因为这是QT新建DLL自带的,我们要写的是可以供其他语言调用的DLL,我这里的例子是只用了一个函数和事件,没有用到界面的东西,所以从qtwinmigrate下面的src文件夹拷贝qmfcapp.h和qmfcapp.cpp这两个文件过来即可,如下。     第三步: 更改pro文件,改为 TARGET = qtdll TEMPLATE = lib CONFIG += dll   SOURCES +=      qmfcapp.cpp      main.cpp   HEADERS += qmfcapp.h   main.cpp代码如下 #include "qmfcapp.h" #include "windows.h" //windows下DLL函数入口 BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpvReserved ) { static bool ownApplication = FALSE; if ( dwReason == DLL_PROCESS_ATTACH ) ownApplication = QMfcApp::pluginInstance( hInstance ); if ( dwReason == DLL_PROCESS_DETACH && ownApplication ) delete qApp; return TRUE; } //定义函数回调指针 typedef void (CALLBACK *FunCallBack)(int par); //定义回调函数 FunCallBack OnEvent=NULL; //定义回调参数 int par; //定义C语言类型导出事件函数 extern "C" __declspec(dllexport) void SetFunCallBack(FunCallBack fun,int p) { OnEvent=fun; par=p; } //定义C语言类型导出函数 extern "C" __declspec(dllexport) int add(int i) { //下面这段代码用来触发事件,如果仅仅是使用add函数的话可以删除. if (i==110){ if (OnEvent){ //当传入参数为110而且已经定义过回调函数的话,则触发事件. OnEvent(120); } } return i*2; }View Code 选择release编译,在目录下生成了一个DLL文件,这个文件就可以供VC/C#/VB/JAVA等调用了。   第四步:编写VC和C语言程序测试 main.c代码如下: #include #include //定义函数指针 typedef int (*Add)(int); //定义回调函数指针 typedef void (CALLBACK *FunCallBack)(int); //定义回调函数处理方法 void CALLBACK HandleEvent(int par) { printf("%dn", par); } //主函数入口 int main(int argc, char const *argv[]) { //定义DLL句柄 HINSTANCE hDll = LoadLibrary("qtdll.dll"); if (hDll != NULL) { //定义回调函数指针 typedef void (CALLBACK *PFunCallBack)(FunCallBack); //实例化回调函数指针 PFunCallBack SetFunCallBack=(PFunCallBack)GetProcAddress(hDll,"SetFunCallBack"); //执行回调函数 if (SetFunCallBack){ SetFunCallBack(HandleEvent); } //实例化函数指针 Add add = (Add)GetProcAddress(hDll,"add"); //调用DLL中的方法 printf("%dn", add(1)); //调用DLL中的方法并触发事件 printf("%dn", add(110)); FreeLibrary(hDll); } return 0; }View Code运行结果如图: 当传入的参数为110时,会触发事件,返回值120。   第五步:编写C#程序测试 using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace qtdllTestNET { class Program { //声明DLL中的函数 [DllImport("qtdll.dll")] public static extern int add(int i); //声明DLL中的回调函数,即事件 [DllImport("qtdll.dll")] public static extern void SetFunCallBack([MarshalAs(UnmanagedType.FunctionPtr)] CallbackFun pCallbackFun); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void CallbackFun(int i); public static void HandleEvent(int i) { Console.WriteLine(i); } static void Main(string[] args) { CallbackFun HandleEventX = HandleEvent; SetFunCallBack(HandleEventX); Console.WriteLine(add(1)); Console.WriteLine(add(110)); Console.ReadLine(); } } }View Code运行结果:

    时间:2020-01-09 关键词: vc QT

  • Qt Quick Material开源组件ApplicationWindow

    import QtQuick 2.6 import QtQuick.Controls 1.4 import QtQuick.Window 2.2 import Material 0.1 as Material import Material.ListItems 0.1 as ListItem //源码参考: // onPrimaryColorChanged: Theme.primaryColor = primaryColor // onPrimaryDarkColorChanged: Theme.primaryDarkColor = primaryDarkColor // onAccentColorChanged: Theme.accentColor = accentColor // onBackgroundColorChanged: Theme.backgroundColor = backgroundColor // Material.ApplicationWindow{ id:demo theme { //Material定义的颜色数组别名列表 [颜色][别名(深度)] //前景色 primaryColor: Material.Palette.colors["blue"]["A700"] //未知 primaryDarkColor: Material.Palette.colors["blue"]["700"] //未知 accentColor: Material.Palette.colors["teal"]["500"] //tab子控件的高亮色 tabHighlightColor: "red" onTabHighlightColorChanged: Theme.tabHighlightColor = tabHighlightColor } //添加一个堆栈页面初始页 initialPage: Material.Page{ id:page title:"demo" } } “`

    时间:2020-01-09 关键词: QT qml

  • 【Qt】QML中的JavaScript用法详解

    熟悉JavaScript的应该都了解Netscape公司,一代骄子虽然倒下了,却给后人留下了最为珍贵的产品和经验,在互联网发展史上享有举足轻重的地位,这里就不讲故事了,虽然很精彩,从未被磨灭。QML是对JavaScript的扩展,提供了JS主机环境,用法相似,但有些地方与浏览器/服务器端提供的JS主机环境(如Node.js)是不同的,用起来又有一些限制,下面列举一些常用的方法。1、QML文件中的JS表达式初始化时属性绑定——[plain] view plain copy// Property.qml    import QtQuick 2.0    Rectangle {      id: colorButton      width: 360; height: 360      color: mouseArea.pressed ? "steelblue" : "lightsteelblue"        MouseArea {          id: mouseArea          anchors.fill: parent      }  }  使用Qt.binding()完成属性绑定——[plain] view plain copy// Property2.qml    import QtQuick 2.0    Rectangle {      id: colorbutton      width: 360; height: 360      color: "yellow"        MouseArea {          id: mouseArea          anchors.fill: parent      }        Component.onCompleted: {          color = Qt.binding(function() { return mouseArea.pressed ? "red" : "green" })      }  }  信号处理中的JS表达式——[plain] view plain copy// Handler.qml    import QtQuick 2.0    Rectangle {      id: button      width: 200; height: 100; color: "lightblue"        MouseArea {          id: mouseArea          anchors.fill: parent          onPressed: label.text = "I am Pressed!"          onReleased: label.text = "Click Me!"      }        Text {          id: label          anchors.centerIn: parent          text: "Press Me!"      }  }  QML文件中函数的JS表达式——[plain] view plain copy// InlineFunction.qml    import QtQuick 2.0    Item {      function factorial(a) {          a = parseInt(a);          if (a 

    时间:2020-01-08 关键词: QT qml

  • Qt for android如何在静态java类中调用非静态方法

    Qt for android如何在静态java类中调用非静态方法

            一般正常情况开发下,在java的静态类方法中,调用一个非静态方法是会报错,编译不通过的,但是在Qt调用Java正常函数会不生效,不会出现任何异常提示,反正调用了就跟没调用一样,这个是我再Qt5.6中测试过的效果,现在Qt5.9不知道修复了这个问题没有,反正现在要说的问题就是:Qt需要调用Java静态方法才能触发java的非静态原生方法。看下面一个例子:这样在一个静态方法中调用,是绝对会报错的,因为Toast toast不属于静态类,重点在于Toast.makeText本身就是一个常规类,需要在常规类中调用使用,所以,接下来我们就要解决这个难题。我们需要构建一个静态消息句柄,来传送该消失,实现就会在java线程中实现了调用之后会自动调用下面实现的线程类这样就会在Qt调用静态类中使用常规类了。当然可能现在Qt5.9已经解决了Qt调用常规类无效的一个问题。

    时间:2019-12-13 关键词: java 调用 QT 非静态方法

  • 编写qml到安卓手机的一些小心得

    最近在开发一些关于安卓的app的程序,期间发现了很多坑,于是想到在此记下,以便后续能更好的总结。 一、C++注册QML规范 C++注册qml共有两种机制,第一种是采用qmlRegisterType注册到qml中,由qml去实例化,调用相关接口,只在qml中使用,与其他C++关联性不多,第二种情况是既要被C++其他类调用,又要被qml调用,但是只能拥有一个实例,采用setContextProperty,在C++中实例,然后暴露接口给qml调用。根据本人经验,建议在非必要情况下尽可能采用第一种注册机制。注意,无论哪种情况,务必要在main.cpp加载qml文件之前调用。 一、多个QML文档中信号和槽的连接心得  在main.cpp中注册或暴露接口给qml调用的类对象,在qml中无论是调用其方法还是采用槽连接获取信息,一律在main.cpp中资源加载的qml文件中实现调用,不可跨多个文档调用,不然会出现不可预料的bug(程序会崩溃),一般main.cpp资源加载的qml文件名称,系统默认指定为main.qml,加载方式一般为:engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));  多个qml文档,互相调用信号槽传递信息时,要在main.cpp资源加载指定的qml中统一实例化,然后接收相关的信号,实现相关槽功能,不可在自身qml文档中自行发送信号后,自行接收信号实现相关功能,若实现的功能不跨文档调用,可自行实现。 二、公用属性值 一般多个文档可能使用同一属性值时,在qml没有宏的概念,要使用公有属性,最好是在main.cpp加载的qml中自定义property属性值,,该属性值必须定义在id的后面,顶层窗口中。只能在实例化相关对象或其它qml文档后使用,凡实例化后的对象或qml文档中即可使用同一个属性值。 三、控件的自适应    目前知道的控件适应方法有两种,第一种,获取设备的dpi,然后以毫米为单位来固定相关的控件高度和宽度,由毫米*dpi =像素,这种方式依赖硬件的dpi,如果dpi未变,设备改变了原有的分辨率,控件可能会出现错乱不规律的现象,需要更加深入的了解来解决这一问题,目前正在解决中。    第二种方法,需要获取设计方案图纸的比例,通过比例的换算转成相关像素,比例*控件设备宽高=像素,不依赖相关硬件,设备改变了原有的分辨率,也不会出现控件错乱现象,但是会出现控件细微的拉伸情况,看改变的幅度大小(通过dpi转换的不会改变),是目前考虑的实现方式。   后续有关安卓的java交互的坑后面在写。

    时间:2019-12-09 关键词: QT qml qt安卓

  • QDockWidget嵌套布局详解-实现Visual Studio布局

    概述 许多工程软件,如Qt Creator,VS,matlab等,都是使用dock布局窗口,这样用户可以自定义界面,自由组合窗口。 Qt的嵌套布局由QDockWidget完成,用Qt Creator拖界面得到的dock布置形式比较固定,不能得想要的任意组合形式,要得到如下图所示的效果,后续布局必须通过代码来完成。 ps:这是自己没事写的一个数据可视化软件 下面说说如何实现完全自由的界面布局效果: QDockWidget在QMainWindow的布局函数 要在QMainWindow里对dock进行布局,需要用到如下几个函数: 添加dock函数 此函数用于给dock指定位置,同时也可以更改dock的位置,此函数命名为addDockWidget有点容易误导,因为不仅仅有add的功能,还有chang的功能 void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget) void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget, Qt::Orientation orientation) 分割dock窗口函数 此函数的功能是把两个dock进行左右或上下并排布置,做成一个类似QSplit的功能 void QMainWindow::splitDockWidget(QDockWidget * first, QDockWidget * second, Qt::Orientation orientation) tab化窗口函数 此函数的功能是把多个dock变成一个tab形式的窗体 void QMainWindow::tabifyDockWidget(QDockWidget * first, QDockWidget * second) 设置dock嵌套布局 此函数是设置嵌套布局的关键 void QMainWindow::setDockNestingEnabled(bool enabled) 以上几个函数就能完成比较复杂的嵌套布局了。 设置嵌套布局 下面通过例子来讲解如何设置复杂的嵌套布局 先用Qt Creator拖放9个dock进视图里,为了好区分,给每个dock设置一个背景颜色: dock属性随便设置,保证都任意区域可以停靠即可 由于这里不需要MainWindow的中间窗口,整个视图都由dock组成,因此先把QMainWindow的中间窗口部件去除: 在MainWindow的构造函数加入如下语句,即可把MainWindow的中间窗口去除,这时整个MainWindow只有Dock组成 QWidget* p = takeCentralWidget(); if(p) delete p; 编译出来的效果如图所示: 拖动dock可以发现,只能在两边进行组合,我想把dock放置到中间是无法实现的,这是由于为了简化dock的吸附,QMainWindow默认是把dock嵌套关闭的,需要我们手动设置,在MainWindow的构造函数里添加: setDockNestingEnabled(true); 即可打开嵌套功能,这时编译出来的窗口能实现如下嵌套: 此时,整个窗口的布局将变得非常灵活且复杂,由于Qt Creator在ui编辑器中无法像编译出来的程序那样任意调整位置,因此需要手动对窗口进行设置。下面将介绍如何用代码设置复杂的dock 为了方便,添加两个函数和一个成员变量: head: public: //移除并隐藏所有dock void removeAllDock(); //显示dock窗口 void showDock(const QList& index = QList()); private: QList m_docks;///< 记录所有dockWidget的指针 CPP: MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); //删除中央窗体 QWidget* p = takeCentralWidget(); if(p) delete p; //允许嵌套dock setDockNestingEnabled(true); //记录所有的dock指针 m_docks.append(ui->dockWidget_1); m_docks.append(ui->dockWidget_2); m_docks.append(ui->dockWidget_3); m_docks.append(ui->dockWidget_4); m_docks.append(ui->dockWidget_5); m_docks.append(ui->dockWidget_6); m_docks.append(ui->dockWidget_7); m_docks.append(ui->dockWidget_8); m_docks.append(ui->dockWidget_9); } MainWindow::~MainWindow() { delete ui; } /// /// brief 移除并隐藏所有的dock /// void MainWindow::removeAllDock() { for(int i=0;ishow(); } } } void removeAllDock();函数可以把所有的dock隐藏void showDock(const QList& index = QList())则可以显示指定的dock。 下面先对需要用到的几个函数进行示范: addDockWidget addDockWidget函数用于给MainWindow添加dock窗体,指定添加的区域,如果想改变dock的位置,也可以使用此函数进行移动。 void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget) void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget, Qt::Orientation orientation) 如: addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1); addDockWidget(Qt::RightDockWidgetArea,ui->dockWidget_2); addDockWidget(Qt::TopDockWidgetArea,ui->dockWidget_3); addDockWidget(Qt::BottomDockWidgetArea,ui->dockWidget_4); 把4个dock按照上下左右布置,效果如下: splitDockWidget splitDockWidget void QMainWindow::splitDockWidget(QDockWidget * first, QDockWidget * second, Qt::Orientation orientation) 此函数可以把一个dock(QDockWidget * first)在其位置上进行嵌套,嵌套可以指定水平嵌套或者垂直嵌套,嵌套方向是从左到右,从上到下,也就是QDockWidget * first相对于QDockWidget * second永远在左边或者上边。 如: removeAllDock(); addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1); splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Horizontal); splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal); splitDockWidget(ui->dockWidget_3,ui->dockWidget_4,Qt::Horizontal); splitDockWidget(ui->dockWidget_4,ui->dockWidget_5,Qt::Horizontal); showDock(QList()dockWidget_5,Qt::Vertical); showDock(QList()dockWidget_5,Qt::Vertical); splitDockWidget(ui->dockWidget_3,ui->dockWidget_6,Qt::Vertical); splitDockWidget(ui->dockWidget_4,ui->dockWidget_7,Qt::Vertical); splitDockWidget(ui->dockWidget_5,ui->dockWidget_8,Qt::Vertical); splitDockWidget(ui->dockWidget_6,ui->dockWidget_9,Qt::Vertical); showDock(); 实现代码: removeAllDock(); //原则,先左右,再上下 addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1); splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Horizontal); splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal); splitDockWidget(ui->dockWidget_1,ui->dockWidget_4,Qt::Vertical); splitDockWidget(ui->dockWidget_3,ui->dockWidget_6,Qt::Vertical); splitDockWidget(ui->dockWidget_4,ui->dockWidget_7,Qt::Vertical); splitDockWidget(ui->dockWidget_6,ui->dockWidget_9,Qt::Vertical); showDock(QList()dockWidget_5,ui->dockWidget_8); tabifyDockWidget(ui->dockWidget_3,ui->dockWidget_9); showDock(); 代码: 本例代码下载:本例代码免积分-

    时间:2019-11-26 关键词: QT 界面

  • Qt Quick中的ListView

    Qt Quick中的ListView初学 ListView 3要素: model : 负责每一个行的 数据 delegate:负责每一个行的 外观 3.与外界如何交互,删除和添加数据(通过model和js) 通过JavaScript控制边线,0,2,4,6…..才显示边框,用来显示每一行的界限,界限颜色用Qt自带的函数就可以了 JavaScript代码: Myhelp.js .pragma library function 求余数(date) { var ret =date%2; console.log("余数:"+ret); if(ret==0) { return 1; } return 0; } Window { visible: true width: 240; height: 320; //导出listview的model 供按钮使用 由于在一个文件中,不需要了 ListView{ id:list_view; anchors.left: parent.left; anchors.top: parent.top; width: parent.width; height: 180; model:m_listmodel; delegate:delegete1; } //ListView的model ListModel{ id:m_listmodel;//model对象中 有数组ListElement 存储所有的列表数据对象 ListElement{name:"hello"} } //listview的代理 Component{ id:delegete1; Rectangle{ width: parent.width; height: 40; color: "#4b3b3b" border.color: Qt.lighter(color) //颜色暗淡些 不然显得有点粗 //当序号为2的倍数才有边框用来分割 border.width: MyHELP.求余数(index); Text { anchors.fill: parent; id: m_txt; color: "#f3e3e3" text:name+"序号"+index; font.family: "Consolas" font.pointSize: 14 horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter } } } //新建按钮用来测试 Button{ id:m_btn; anchors.top: list_view.bottom; anchors.left:parent.left; width: parent.width; height: 40; text: qsTr("添加"); onClicked: { m_listmodel.append({name:qsTr(m_input.text)}); } } Button{ id:m_delete; anchors.top: m_btn.bottom; anchors.left:parent.left; width: parent.width; height: 40; text: qsTr("删除"); onClicked: { m_listmodel.remove(m_input.text,1);//删除指定的项 第二个参数:删除个数 1就行了不然乱 } } TextInput{ id:m_input; horizontalAlignment: Text.AlignHCenter font.pointSize: 14 anchors.left:m_delete.left; anchors.top: m_delete.bottom; height: 40; width: parent.width; color: "#c69191" autoScroll: true; text: qsTr("请输入") } }

    时间:2019-11-25 关键词: QT qml-quick

  • QT的进程与线程

    该文章原创于Qter开源社区(www.qter.org),作者yafeilinux,转载请注明出处! 导语 在前面的几节内容中讲解了Qt网络编程的一些基本内容,这一节来看一下在Qt中进程和线程的基本应用。 环境:Windows Xp + Qt 4.8.5+Qt Creator2.8.0 目录 一、进程 二、线程 正文 一、进程     在设计一个应用程序时,有时不希望将一个不太相关的功能集成到程序中,或者是因为该功能与当前设计的应用程序联系不大,或者是因为该功能已经可以使用现成的程序很好的实现了,这时就可以在当前的应用程序中调用外部的程序来实现该功能,这就会使用到进程。Qt应用程序可以很容易的启动一个外部应用程序,而且Qt也提供了在多种进程间通信的方法。     Qt的QProcess类用来启动一个外部程序并与其进行通信。下面我们来看一下怎么在Qt代码中启动一个进程。 1.首先创建QtGui应用。 工程名称为“myProcess”,其他选项保持默认即可。 2.然后设计界面。 在设计模式往界面上拖入一个Push Button部件,修改其显示文本为“启动一个进程”。 3.修改槽。 在按钮上点击鼠标右键,转到其clicked()信号对应的槽,更改如下: void MainWindow::on_pushButton_clicked() {      myProcess.start("notepad.exe"); } 4.进入mainwindow.h文件添加代码。 先添加头文件包含:#include ,然后添加私有对象定义:QProcess myProcess; 5.运行程序。 当单击界面上的按钮时就会弹出一个记事本程序。 这里我们使用QProcess对象运行了Windows系统下的记事本程序(即notepad.exe程序),因为该程序在系统目录中,所以这里不需要指定其路径。大家也可以运行其他任何的程序,只需要指定其具体路径即可。我们看到,可以使用start()来启动一个程序,有时启动一个程序时需要指定启动参数,这种情况在命令行启动程序时是很常见的,下面来看一个例子,还在前面的例子的基础上进行更改。 1.在mainwindow.h文件中添加代码。 添加私有槽: private slots:     void showResult(); 2.在mainwindow.cpp文件中添加代码。 (1)先添加头文件包含:#include ,然后在构造函数中添加如下代码: connect(&myProcess,SIGNAL(readyRead()), this, SLOT(showResult())); (2)然后添加showResult()槽的定义: void MainWindow::showResult() {     qDebug() stopButton->setEnabled(false);     } }     在启动线程时调用了start()函数,然后设置了两个按钮的状态。在终止线程时,先使用isRunning()来判断线程是否在运行,如果是,则调用stop()函数来终止线程,并且更改两个按钮的状态。现在运行程序,按下“启动线程”按钮,查看应用程序输出栏的输出,然后再按下“终止线程”按钮,可以看到已经停止输出了。     下面我们接着来优化这个程序,通过信号和槽来将子线程中的字符串显示到主界面上。 1.在mythread.h文件中添加信号的定义: signals: void stringChanged(const QString &); 2.然后到mythread.cpp文件中更改run()函数的定义: void MyThread::run() {     long int i = 0;     while (!stopped) {        QString str = QString("in MyThread: %1").arg(i);        emit stringChanged(str);        msleep(1000);        i++;     }     stopped = false; } 这里每隔1秒就发射一次信号,里面包含了生成的字符串。 3.到dialog.h文件中添加槽声明: private slots:     void changeString(const QString &); 4.打开dialog.ui,然后向主界面上拖入一个Label标签部件。 5.到dialog.cpp文件中,在构造函数里面添加信号和槽的关联: // 关联线程中的信号和本类中的槽 connect(&thread, SIGNAL(stringChanged(QString)), this, SLOT(changeString(QString))); 6.然后添加槽的定义: void Dialog::changeString(const QString &str) {     ui->label->setText(str); }     这里就是将子线程发送过来的字符串显示到主界面上。现在可以运行程序,查看效果了。 (二)线程同步     Qt中的QMutex、QReadWriteLock、QSemaphore和QWaitCondition类提供了同步线程的方法。虽然使用线程的思想是多个线程可以尽可能的并发执行,但是总有一些时刻,一些线程必须停止来等待其他线程。例如,如果两个线程尝试同时访问相同的全局变量,结果通常是不确定的。QMutex提供了一个互斥锁(mutex);QReadWriteLock即读-写锁;QSemaphore即信号量;QWaitCondition即条件变量。 (三)可重入与线程安全 在查看Qt的帮助文档时,在很多类的开始都写着“All functions in this class are reentrant”,或者“All functions in this class are thread-safe”。在Qt文档中,术语“可重入(reentrant)”和“线程安全(thread-safe)”用来标记类和函数,来表明怎样在多线程应用程序中使用它们: 一个线程安全的函数可以同时被多个线程调用,即便是这些调用使用了共享数据。因为该共享数据的所有实例都被序列化了。 一个可重入的函数也可以同时被多个线程调用,但是只能是在每个调用使用自己的数据时。 结语 最后要注意的是,使用线程是很容易出现问题的,比如无法在主线程以外的线程中使用GUI类的问题(可以简单的通过这样的方式来解决:将一些非常耗时的操作放在一个单独的工作线程中来进行,等该工作线程完成后将结果返回给主线程,最后由主线程将结果显示到屏幕上)。大家应该谨慎的使用线程。

    时间:2019-11-14 关键词: QT 线程

  • Qt之FTP上传/下载

    简述 为了方便网络编程,Qt 提供了 Network 模块。该模块包含了许多类,例如:QFtp - 能够更加轻松使用 FTP 协议进行网络编程。 但是,从 Qt5.x 之后,Qt Network 发生了很大的变化,助手中关于此部分描述如下: The QFtp and QUrlInfo classes are no longer exported. Use QNetworkAccessManager instead. Programs that require raw FTP or HTTP streams can use the Qt FTP and Qt HTTP compatibility add-on modules that provide the QFtp and QHttp classes as they existed in Qt 4. 意思是说:不再导出 QFtp 和 QUrlInfo 类,改用 QNetworkAccessManager。 简述开启 FTP 服务效果FtpManager使用更多参考 开启 FTP 服务 Linux 下实现 FTP 服务的软件很多,最常见的有:vsftpd、Wu-ftpd 和 Proftp 等。 访问 FTP 服务器时需要经过验证,只有经过了 FTP 服务器的相关验证,用户才能访问和传输文件。 首先,服务器需要安装 FTP 软件,以 vsftpd 为例: [root@localhost wang]# which vsftpd /sbin/vsftpd 1 2 这说明服务器已经安装了 vsftpd,再进行一系列配置即可使用。 关于 FTP 服务的搭建、配置属于 Linux 范畴,这里就不过多赘述了,请自行查看资料。 效果 实现效果如下: 如果要获取更多关于:文件剩余大小、平均速度、瞬时速度 、剩余时间等相关信息,请参考:Qt之HTTP上传/下载 FtpManager 为了便于使用,封装一个简单的 FtpManager 管理类,用于上传、下载文件。 FTPManager.h #ifndef FTP_MANAGER #define FTP_MANAGER #include #include #include #include class FtpManager : public QObject { Q_OBJECT public: explicit FtpManager(QObject *parent = 0); // 设置地址和端口 void setHostPort(const QString &host, int port = 21); // 设置登录 FTP 服务器的用户名和密码 void setUserInfo(const QString &userName, const QString &password); // 上传文件 void put(const QString &fileName, const QString &path); // 下载文件 void get(const QString &path, const QString &fileName); signals: void error(QNetworkReply::NetworkError); // 上传进度 void uploadProgress(qint64 bytesSent, qint64 bytesTotal); // 下载进度 void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); private slots: // 下载过程中写文件 void finished(); private: QUrl m_pUrl; QFile m_file; QNetworkAccessManager m_manager; }; #endif // FTP_MANAGER FTPManager.cpp #include #include "FTPManager.h" FtpManager::FtpManager(QObject *parent) : QObject(parent) { // 设置协议 m_pUrl.setScheme("ftp"); } // 设置地址和端口 void FtpManager::setHostPort(const QString &host, int port) { m_pUrl.setHost(host); m_pUrl.setPort(port); } // 设置登录 FTP 服务器的用户名和密码 void FtpManager::setUserInfo(const QString &userName, const QString &password) { m_pUrl.setUserName(userName); m_pUrl.setPassword(password); } // 上传文件 void FtpManager::put(const QString &fileName, const QString &path) { QFile file(fileName); file.open(QIODevice::ReadOnly); QByteArray data = file.readAll(); m_pUrl.setPath(path); QNetworkReply *pReply = m_manager.put(QNetworkRequest(m_pUrl), data); connect(pReply, SIGNAL(uploadProgress(qint64, qint64)), this, SIGNAL(uploadProgress(qint64, qint64))); connect(pReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SIGNAL(error(QNetworkReply::NetworkError))); } // 下载文件 void FtpManager::get(const QString &path, const QString &fileName) { QFileInfo info; info.setFile(fileName); m_file.setFileName(fileName); m_file.open(QIODevice::WriteOnly | QIODevice::Append); m_pUrl.setPath(path); QNetworkReply *pReply = m_manager.get(QNetworkRequest(m_pUrl)); connect(pReply, SIGNAL(finished()), this, SLOT(finished())); connect(pReply, SIGNAL(downloadProgress(qint64, qint64)), this, SIGNAL(downloadProgress(qint64, qint64))); connect(pReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SIGNAL(error(QNetworkReply::NetworkError))); } // 下载过程中写文件 void FtpManager::finished() { QNetworkReply *pReply = qobject_cast(sender()); switch (pReply->error()) { case QNetworkReply::NoError : { m_file.write(pReply->readAll()); m_file.flush(); } break; default: break; } m_file.close(); pReply->deleteLater(); } 注释很详细,我就不再多做解释了。。。 注意:下载过程中文件写入是在主线程中进行的,如果文件过大,频繁写入会造成主线程卡顿现象。要避免此种情况,请在工作线程中进行。 使用 这里,只贴主要代码: // 构建需要的控件 QPushButton *pUploadButton = new QPushButton(this); QPushButton *pDownloadButton = new QPushButton(this); m_pUploadBar = new QProgressBar(this); m_pDownloadBar = new QProgressBar(this); pUploadButton->setText(QString::fromLocal8Bit("上传")); pDownloadButton->setText(QString::fromLocal8Bit("下载")); // 接信号槽 connect(pUploadButton, SIGNAL(clicked(bool)), this, SLOT(upload())); connect(pDownloadButton, SIGNAL(clicked(bool)), this, SLOT(download())); // 设置 FTP 相关信息 m_ftp.setHostPort("192.168.***.***", 21); m_ftp.setUserInfo("wang", "123456"); 其中,m_ftp 是类变量 FtpManager。 // 上传文件 void MainWindow::upload() { m_ftp.put("E:\Qt.zip", "/home/wang/Qt.zip"); connect(&m_ftp, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(error(QNetworkReply::NetworkError))); connect(&m_ftp, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(uploadProgress(qint64, qint64))); } // 下载文件 void MainWindow::download() { m_ftp.get("/home/wang/Qt.zip", "F:\Qt.zip"); connect(&m_ftp, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(error(QNetworkReply::NetworkError))); connect(&m_ftp, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadProgress(qint64, qint64))); } // 更新上传进度 void MainWindow::uploadProgress(qint64 bytesSent, qint64 bytesTotal) { m_pUploadBar->setMaximum(bytesTotal); m_pUploadBar->setValue(bytesSent); } // 更新下载进度 void MainWindow::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) { m_pDownloadBar->setMaximum(bytesTotal); m_pDownloadBar->setValue(bytesReceived); } // 错误处理 void MainWindow::error(QNetworkReply::NetworkError error) { switch (error) { case QNetworkReply::HostNotFoundError : qDebug()

    时间:2019-10-09 关键词: ftp QT

  • Qt on Android:图文详解Hello World全过程

    Qt on Android:图文详解Hello World全过程

    转载于:http://blog.csdn.net/foruok/article/details/23528293  我将从实践出发,带领大家一步一步完成在 Android 上的第一个 Qt 应用: Hello Qt on Android 。应用本身非常简单(仅仅是在屏幕上显示一个字符串 "Hello Qt on Android" ),这也是每种编程语言的入门教程中 Hello World 程序的共性。    下面我将和大家一起来探索使用 Qt Creator 3.0 创建、管理、编译、部署 Qt on Android 应用的整个过程。每一个步骤都配以我精心挑选并编排整理的截图,力求初学者可以按图索骥、顺畅地走下去,完成自己在 Android 平台上的第一次观光旅行。创建工程    打开 Qt Creator ,点击文 "件(F)" 菜单,在弹出的菜单列表中选择 "新建文件或项目(N)" 。如下图所示:    如上操作后, Qt Creator 会弹出新建工程界面,让我们选择工程模板。如下面的所示:    这里我们选择 "应用程序" 项目, "Qt Widgets Application" 模板。可以看到最右侧的实时提示,支持的平台中有 Android(蓝线所示),看到这点,说明前面的开发环境搭建是正确的。    点击 "选择(C)..." 按钮,新建工程向导会指引我们进入下一环节 "项目介绍和位置" 。参考下图:    我已经做了标识,编号为 1 的文本框,你可以填写项目的名字,这里是 "HelloQtAndroid" ;编号为 2 的 "浏览..." 按钮允许你选择工程的存储路径,我准备把工程放在 "D:projectsblogsqt" 目录下面。请对照下图检查你的配置:    点击 "下一步" 按钮,跟随向导进入构建套件选择("Kit Selection")环节。    我选择了两个套件,"Android for armeabi (GCC 4.7, Qt 5.2.0)" 和 "Desktop Qt 5.2.0 MinGW 32bit",分别对应下图中的标号为 1 和 2 的区域。请对照下图检查你的配置。    点击 "下一步" 按钮,跟随向导进入 "类信息" 配置环节。下图是默认的界面:    上图中标号为 1 的下拉框,可以选择待创建的 Widget 的基类,默认是 QMainWindow ,我这里选择 QWidget。标号为 2 的复选框,如果选中则会生成一个 .ui 文件,可以通过 Qt SDK 中的界面设计师来编辑界面,为了简单直接,我们去掉了选中,不使用 .ui 文件,全部使用代码完成界面构建。    请参考下图检查你的配置:    点击 "下一步" 按钮,跟随向导进入 "项目管理" 环节。在这里你可以选择是否将工程加入版本控制系统(如 svn 之类),还可以看到即将添加到我们的 "Hello Qt on Android" 工程中的文件。如下图所示:    终于看到 "完成(F)" 按钮了,赶紧点击它!看下图,我们将进入日后使用 Qt Creator 这个近乎完美的 IDE 编程时使用频度最高、相依相伴时间最久的界面。    如上图所示,这就是我们日后天天要面对、不断打交道的界面。我会选择几个最常用的功能简明扼要的介绍它的用法。    左边栏,标号为 1 的标签,是 "编辑" 标签,选中它,会进入编辑模式,就是上面的样子。    标号为 2 的标签,是 "项目" 标签,选中它,会打开项目选项配置界面。该界面功能丰富到有些繁杂,后面我们会多花些时间来一一介绍我们的 "Hello Qt on Android" 工程必须要用的选项。    标号为 3 的是 "构建版本" 按钮, 点击它,会弹出一个快捷界面,允许我们快速选择不同构建版本(如 Android 的 Release 构建, Desktop 的 Debug 构建等等)。点击 "项目" 标签所进入的配置界面中也可以完成构建版本选择。    标号为 4 的是 "运行" 按钮,点击它, Qt Creator 会执行编译、链接、打包等等工作,直到目标程序运行起来或者出错停止。    "运行" 按钮下面依次是 "开始调试" 、 "构建项目" 按钮,鼠标悬停在它们上面就可以看到提示,其用途不言自明。    标号为 5 的那一横排标签,是 Qt Creator 的输出窗口,点击任一标签,都会向上伸展出一个窗口显示与标签名字对应的信息。    问题标签对应的窗口显示构建问题,找到问题后双击就会跳转到对应的代码行或编译输出窗口(部分链接错误)。    编译输出标签对应的窗口会把编译、链接、打包、部署过程中的信息都显示出来,这是我们从外面观察 Qt Creator 工作过程的极佳途径,善加使用必将获益良多。    应用程序输出标签对应的窗口会显示应用程序使用标准输出打印的信息,APK 运行后, logcat 的日志也会显示在这里。    其它标签不再细说,开发过程中使用几次就熟悉了。    标号为 6 的区域,就是代码编辑区。    标号为 7 的区域,是侧边栏、项目管理区域,这里允许开发者以项目、类视图、大纲、文件系统、类型层次、打开文档等等方式来管理项目。项目选项    介绍完了我们的好伙伴——项目管理与代码编辑界面,接下来我们继续完成 "Hello Qt on Android" 的项目配置。点击前面介绍的标号为 2 的项目标签,会看到下面的项目选项配置界面:    我们的新建工程,默认选中了 "Desktop Qt 5.2.0 MinGW 32bit" 这个套件。请注意上图左下蓝线标出的按钮,前面提到,它是构建版本选择按钮,现在显示的是电脑图标配Debug字样。    点击标号为 1 的区域中的构建按钮(蓝色圆圈所在),切换到 "Android for armeabi" 套件,进行构建相关的配置。如下图:    构建配置选项繁多,对于我们的第一个应用,只要关注途中标识出的 1 和 2 两个功能怎么使用即可。    标号为 1 的按钮,点击可以切换到"运行"选项配置,马上就能看到。    标号为 2 的组合框,可以选择构建版本(一般是 Debug / Release 两个)。它完成和左边栏下蓝色圆圈标识的构建版本按钮一样的功能。我们这里选择 "Release" 构建。    注意蓝色圆圈标识区域,随着我们选中 "Android for armeabi" 套件和 "Release" 构建,它从电脑图标变成了安卓小机器人配 "Release" 字样的按钮。好啦,现在让我们点击标号为 1 的"运行"按钮,进行运行选项配置。对目前这个项目来说,运行配置远比构建配置复杂,请擦亮眼睛,用心体会。    切换到运行配置,界面如上图所示。先来看部署配置,点击图中标号为 1 的 "详情" 按钮,打开部署配置详情界面:    希望你没被吓到,我在上图中作了 9 处标识,比之前的编辑界面( 7 个标识)还多。让我们化繁为简,一个一个来看。    标号为 1 的下拉框,可以选择应用针对的目标 SDK 版本,这里默认是 android-17。我得说( 先请大神 BogDan Vatra 见谅 ) Qt Creator 的这种显示不够完美,如果鼠标悬停在下拉框上时悬浮窗提示一下会更好。    我这里简要说明一下 Qt Creator 中的这个配置选项。实际上它对应 Android APK 的主配置文件 AndroidManifest.xml 中的  android:targetSdkVersion 配置项。这个配置项允许你指定你的应用针对的Android API Level ,而吊诡的是,它使用 sdkVersion 来作为标签,容易引起混淆。实际上,现在我们可以简单地把 sdkVersion 和 API Level 理解为同一个东西,细微差别以后再说。    为了让大家对 Android API Level 有个概念,我截取了 Google Android 在线手册(请访问页面" http://developer.android.com/guide/topics/manifest/uses-sdk-element.html" )中的一幅图放在下面:    标号为 2 的"对包签名"复选框,选中时 Qt Creator 会自动对 APK 进行签名。而一旦你选中了它,就需要提供一个密钥文件( keystore )供 Qt Creator 使用。 如果没有,则点击标号为 3 的 "Create" 按钮, Qt Creator 会帮你创建一个;如果有,可以点击 "Browse" 选择。    标号为 4 的单选框,是 Qt 库布署策略中的一个,用 Ministro 服务安装 Qt 。我们推荐使用这个,具体原因会在" Qt 库的部署策略"一节详细介绍。另外一个可用的策略是把 Qt 库打包到你的 APK 中。    标号为 5 的复选框,选中时 Qt Creator 会在打包完成后打开包所在的目录,方便开发者访问生成的 APK 。    标号为 6 的浮现选,对应日志输出选项。    标号为 7 的按钮, "Create AndroidManifest.xml" ,如按钮名所示,帮助你创建并配置 APK 的主配置文件 AndroidManifest.xml 。如果你不点这个按钮呢, Qt Creator 会使用默认的选项帮你创建一个默认的配置文件。建议创建并配置它,否则你的 APK 包名什么的都会让你觉得怪怪的有点不舒服。    标号为 8 的按钮,"Install Ministro from APK",则是 Qt Creator 提供给我们的一个贴心服务,允许我们把下载到本地的 Ministro APK 安装到 Android 设备上。顺便说下,我在完成 "Hello Qt on Android" 项目时就遇到了无法安装 Ministro 服务的问题,我的 XT882 电信定制版手机,根本访问不到 Google Play。     标号为 9 的区域有两个按钮,允许我们添加依赖库。现在的工程用不到,以后再说。    啊,天,终于说完了,你睡着了嘛,醒醒,我们继续往下看。创建密钥文件和证书    让我们回到签名选项(别忘了,标号 2 ),选中它,然后点击标号为 3 的 "Create" 按钮,创建密钥文件和证书。你会看到下面的界面(空空如也,没错,是初始界面嘛):    如上图所示,有很多选项,照着填写就行,错了会有提示。我配置好后截了图,在下面,请参照着检查你的配置:    点击"保存"按钮,会弹出文件选择对话框,让你选择密钥文件的保存位置,你也可以修改它的名字。下面是我的配置截图,供参考:    点击——,哦,等下,先记住你刚才起的文件名和保存的位置(在市场中更新 APK 必须要使用和之前发布版本相同的签名),后面还要用到,然后再点击"保存"按钮,我们会回到运行配置界面。如下图所示:    可以对照初始的运行配置截图,我把修改过的选项用蓝色横线标注出来了。创建 AndroidManifest.xml    接下来是我们的另一个重头戏,创建 AndroidManifest.xml 文件。   好啦,下面是创建向导,允许你选择保存位置,先别动它,使用默认值(工程目录下的 android 子文件夹,回头你可以到这个位置观光一下,AndroidManifest.xml 还有你应用的图标都放在这里)就行。    直接点击"完成(F)"按钮,你会看到 Qt Creator 提供的供你编辑 AndroidManifest.xml 文件的图形化界面(当然你也可以在 Qt Creator 中查看 XML 并手动修改它)。看图:    这是个中等复杂度的界面,我做了 6 处标识,下面一一说明。    标号为 1 的编辑框,填写你的包名。如你所见,默认值是 org.qtproject.example ,看起来不那么正式。    标号为 2 的微调按钮,允许你更改应用的版本号。    标号为 3 的区域,调整最低 API Level 和 目标 API Level。    标号为 4 的区域,让你设定你的 APK 图标,有高、中、低三个尺寸(一般对应 72x72 、 48x48 、 32x32)。    标号为 5 的下拉组合框,列出了所有支持的权限,你可以考虑你的 APK 需要什么权限,选中它,点击标号为 6 的 "Add" 按钮就可以在 AndroidManifest.xml 中添加一个权限。当然你也可以点击 "Remove" 按钮来取笑一个不必要的权限。    关于 APK 的权限,这里不细说,会在"AndroidManifest.xml 介绍"一节中详细说明。对 HelloQtOnAndroid ,我保持 Qt Creator 设置的默认权限。    下面是我的配置截图,改动的部分用蓝线标注出来了,请参照检查你的配置:    Qt Creator 提供的图形化 Android Manifest 编辑界面,只支持了主要几个选项,如果你想细细调整体验掌控全局的感觉,请点击上图蓝色方框处的"XML Source"按钮,手动编辑 xml 文件。如下图所示:    和编辑 C++ 代码一样,可以在标号为 1 的编辑区来编辑 XML 文件。    谢天谢地,一百里路我们走了九十里啦,接下来就会惊吓、惊喜不断。添加代码    虽然你已经准备好迎接惊喜,我们还是得按捺一下心情,把代码稍稍修改几行。回到编辑界面,确保你左侧项目管理窗口选中"项目"方式,展开源文件夹,双击其下的 widget.cpp ,在右侧编辑区添加一行代码:[cpp] view plain copynew QLabel("Hello Qt on Android !", this);      另外还要包含 QLabel 这个头文件。    好了,看图:运行程序    好啦好啦,九十九里路啦,咫尺之遥,请点击左边栏的"运行"按钮(你是否还记得), Qt Creator 会让你选择目标设备(如果环境配置正确,连接了手机或者创建了AVD),建议直接真机运行(你没有 Android 手机吗?),如下图所示:    看见了吗?选中我的老古董手机,摩托罗拉 XT882 ,Android 版本是 2.3.6 ,点击"确定"按钮,活动一下,静待奇迹出现。    哦,吓我一跳,我看见了这个界面:    忘了吗,我们前面在运行配置中勾选了"Open package location after build"选项。如果你要在市场中发布你的应用,请注意选择(图中蓝框所示)签过名的版本。    等一下,现在该看手机了。我看到了这个界面:    你是否还记得,我们选择的 Qt 库布署策略——"使用Ministro 服务安装 Qt 库"?    现在要操作手机,摸下"确定"按钮,会尝试安装 Ministro 服务。惊吓来了,我看到手机屏幕上华丽丽地闪过一个 Toast 提示“安装 Ministro 失败”,然后就是下面的图:    看样子它是到我手机上默认的安智市场中去找 Ministro 了,没找到。按返回键吧,哦,天,停在了黑屏界面,没有任何反应……好吧,请猛击手机的返回键或者小房子(主页)键。哦,桌面出来了,谢谢。至于为什么 Ministro 安装失败会出现黑屏,请阅读后续章节。    现在我们需要回头来调整运行配置,换一个 Qt 库布署策略——"在 APK 中捆绑 Qt 库"。    再次运行,再次看到 "package location" 文件夹界面……,好吧,看手机,惊喜终于来了:    现在,终于可以停下来喘口气了,我们的第一个 Qt on Android 的应用 "HelloQtOnAndroid"终于在真机上跑起来了。    如果你是第一次使用 Qt on Android,跟随我的指南走下来,是什么感觉?反正我第一次把 "Hello Qt On Android " 跑通时,还是非常振奋的,激动了大半天。毕竟, Qt 作为在移动互联网时代,是唯一可以与 Android 、 iOS 并提的跨平台应用开发框架……;毕竟,作为 C/C++ 程序猿,我们可以为 Windows 桌面、 Linux 桌面 、 Android 手机/平板、iOS、MAC OS X 、 Tizen 、 Meego 、 Windows Mobile 、 Embedded Linux 、 Symbian等等平台开发软件而不需要切换开发框架和工具,是多么令人舒心、自豪的事儿;毕竟……       好了,第一次 Qt on Android 应用的旅程到此为此。敬请期待后续文章。

    时间:2019-10-09 关键词: Android QT for qml

  • Qt for Android 调用系统摄像头和相册

    Qt for Android 调用系统摄像头和相册

    在安卓上面要使用换头像功能,就要涉及到调用系统摄像头实时拍摄或者打开系统相册来获取照片,一般前面是我使用jni,直接再qt上面写:使用上面的方法进行拍照,也会正常使用,但是在显示图片比较多的情况下调用该方法,一般就会导致APP在后台死掉或重启,很莫名其妙。所以后来我也就放弃了这种写法,改为原生的写法。下面贴出我原生java的写法:打开系统照相机方法:首先贴出包名,免得使用会导致包名找不到,以前我就吃过这种亏import android.Manifest;import android.content.pm.PackageManager;import java.io.File;import android.os.Environment;import java.text.SimpleDateFormat;import android.Manifest;import android.content.pm.PackageManager;import android.provider.MediaStore;import android.os.Build; 使用以上包名后,再使用我下面的原生java代码应该就不会报错了,还报错可能就要靠各位自己的能力去找相应对应的包名库了,好了,闲话少说,看代码图:好了,上面打开系统照相机就算是完美搞定了,下面再来说说如果用原生java方法来打开系统相册:OK,方法就是这么简单,运用到的包名我上面也已经提及贴出来了,下面再来看Qt的调用方法流程:打开系统照相机的调用方法:打开系统相册的调用方法:好了,基本上Qt调用原生照相机和相册的程序就到此为止了,喜欢的朋友可以多多点赞。想做摄像头录像的功能的可以看我这篇博客:Qt for Android 调用原生系统摄像头进行录像并保存输出完整Demo:https://download.csdn.net/download/clinuxf/10294515

    时间:2019-10-02 关键词: QT for qt调用原生相册和照相功能 android实现拍照和相册选取

  • qt for android中文字体显示异常解决方案

    qt for android中文字体显示异常解决方案

           前面一段时间发现有些朋友遇见一个问题,qt写的程序中文显示再安卓上面有问题,pc端没有问题,其实之前我也遇见过,用了很多办法都解决不了,后来自己采用的是字库加载解决的,不知道能不能解决其他人的这些问题,现在这边说明记录一下,有用的朋友可以借鉴使用。具体代码执行如下:下面这段代码请加在main.cpp里面int fontId = QFontDatabase::addApplicationFont("XXXXXX/DroidSansFallback.ttf");//将字体Id传给applicationFontFamilies,得到一个QStringList,其中的第一个元素为新添加字体的familyQString androidFont = QFontDatabase::applicationFontFamilies(fontId).at(0);QFont font(androidFont);QGuiApplication::setFont(font);code图如下:其中的"XXXXXX/DroidSansFallback.ttf",ttf就是字库名称,xxxx是放的位置,建议放到资源文件中。好了,需要的朋友可以去试试了。分享下各种ttf的文件下载地址:点击打开链接http://download.csdn.net/download/clinuxf/10237478

    时间:2019-10-02 关键词: QT for 字体库 android中文解决

  • 关于桌面软件的开发语言和开发框架的思考

    作者:朱金灿来源:http://blog.csdn.net/clever101         什么是好的开发语言和好的开发框架?这个问题可能一千个人有一千种答案,我的答案是在满足用户效率需要的前提下能降低开发者对计算机知识的依赖而把尽可能多的精力用在满足业务开发需要的开发语言和开发框架就是好的开发语言和开发框架。这话说得有点拗口,其实它包含下面几层意思:首先是开发语言或开发框架必须满足用户的效率需要,比如一个软件它要申请大内存来处理大数据,而某种开发语言它无法申请大内存,那它肯定是不行的;二是假如满足了用户效率需要之后,降低开发者的要求从而提高开发效率就成了首要目标了。        从这个角度我开始反思以前我在桌面软件的开发语言和开发框架的选择。以前用得比较多的还是开发语言是C++,开发框架是MFC。这种选择优点是软件运行效率高,界面漂亮,缺点也是显而易见的,好的C++程序员难招,特别是还要熟悉VC的,半吊子的C++程序员造成软件有无数多的bug。         进而我想到了qt,一个比MFC更优雅的开发框架。理解信号槽机制比MFC的消息机制还是要容易一些的。还有就是qt在跨平台和多语言界面的支持比MFC要好。熟悉qt的C++程序员要比熟悉MFC的程序员要多。小众的GTK或wxWidget我基本不考虑。不过C++这门充满陷阱的开发语言依然是一道门槛。        今年试用了C#做界面,感觉真是棒,开发效率高,运行效率也不低,并且C#可以很方便的调用C接口函数,就是说在以前做的C++库增加一个C接口函数,就可以很方便的被C#调用。         在未来的桌面软件的开发,我会这样考虑:windows系统下,C#编写界面,C#编写对效率要求不高的算法,C/C++编写对效率要求高的算法。需要跨平台时,如果C#现在的跨平台做得足够好,即mono项目(注:mono是指由Novell公司(由Xamarin发起,并由Miguel de lcaza领导的,一个致力于开创·NET在Linux上使用的开源工程)足够成熟,允许商业开发,Linux也照搬windows的做法;如果C#现在的跨平台做得不好,PyQt(注:PyQt是一个创建GUI应用程序的工具包。它是Python编程语言和Qt库的成功融合)做界面,C/C++编写算法。界面使用脚本语言python编写主要是为了提高开发效率,当然前提是能够满足用户的效率需要。        C#能够在Linux取代qt吗?会有这个可能,但面临的困难也不少:微软是否会放弃C#的一些相关专利而把它贡献给开源社区;mono项目能否一直开发下去;开发者是否愿意使用mono去开发开源软件,现状是基于mono的开源代码和基于qt的开源代码在数量上不是处在同一个级别的。我希望C#在Linux上也能大放异彩,但这肯定需要一段时间!

    时间:2019-10-01 关键词: c# QT

  • Qt Quick 准确的移动平台屏幕适配

    网上大多数都是那一套公式,不适合拉伸布局,假如有一张图片或者一个被固定了大小的控件或图片,那么可能会失真,下面是自己实现的自适应,非常好用的说。而且网上大多数Qt quick开发群心高气傲,根本不要人加入。很多东西可以自己研究的,乐于分享的人太少 一句话,没图说个JB,开干! 下面写一个Col容器,宽度是固定的,这种情况下,在各种移动平台下会差别很大,不过根据我的算法就解决了,320*480是我写代码设计界面时用的界面size,在安卓上,size会根据系统的分辨率而不同,因此在代码中把320*480作为模板,换了系统会计算比例 import QtQuick 2.6 import QtQuick.Window 2.2 import QtQuick.Controls 1.4 import QtQuick.Layouts 1.3 //import QtQuick.Extras 1.4 import "./UI.js" as Mui ApplicationWindow { id:root; width: 320; height: 480; visible: true; //获取最终dpi // targetDensitydpi = uiWidth / deviceWidth * devicePixelRatio * 160; //Screen.devicePixelRatio Component.onCompleted: { } property real pixelDensity: 4.46 property real multiplierH: root.height/480 //default multiplier, but can be changed by user property real multiplierW: root.width/320 //default multiplier, but can be changed by user function dpH(numbers) { return Math.round(numbers*((pixelDensity*25.4)/160)*multiplierH); } function dpW(numbers) { return Math.round(numbers*((pixelDensity*25.4)/160)*multiplierW); } Label{ anchors.centerIn: parent id:label; text: ".."; } //固定宽高自适应屏幕 Column{ spacing: dpH(1); width: dpW(440); Repeater{ model: 17; delegate:Rectangle{ width: parent.width; height:dpH(40); color: "#2a9f8d" Text { color: "white"; font.bold: true; font.pointSize:14; text:index+ ",标题dp3+"+parent.height+","+multiplierH+","+multiplierW+","; anchors.centerIn: parent; } } } } } 注意,设计中我把界面右边留了空白 最后一行为第16列并且显示不完全.这样容易看出差异: 在电脑上的效果,此时程序的窗口大小是320*480 在电脑上手动调整界面大小的效果,此时程序的窗口大小未知 在安卓模拟器上的效果,分辨率是1280*720 192dpi 来一段显示图片的代码,好用不失真 Column{ spacing: dpH(1); width: parent.width; Repeater{ model: 5; delegate: BorderImage { id: name source: "astop.png" width: dpW(72); height: width border.left: dpW(1); border.top: dpH(1) border.right: dpW(1); border.bottom: dpH(1) } } }

    时间:2019-09-03 关键词: 移动平台 QT

  • Qt Quick实现底部导航

    有时候不得不赞叹Qt Quick的界面开发效率。今天就玩一把黑科技。做的是底部导航条,需要在安卓上写一个项目用到,非常容易实现,思路是用一个纵向的布局 固定在底部,加上icon,由于底部导航和其他控件不同:各种分辨率下的拉伸布局,如果屏幕宽度偏离很大,并且有图片,需要算法的.俺这里没写,不精通啊 封装: import QtQuick 2.6 import QtQuick.Window 2.2 import QtQuick.Controls 1.4 import QtQuick.Layouts 1.3 import QtQuick.Extras 1.4 import QtQuick.Extras.Private 1.0 import "./UI.js" as Mui Item { property real dpScale: 1.5 readonly property real dp: Math.max(Screen.pixelDensity * 25.4 / 160 * dpScale, 1) signal selchangge(var mindex); property var curTab: 0 //模拟导航栏 ListView{ anchors.bottom: parent.bottom orientation: ListView.Horizontal; width: parent.width; height: 72*dp id:myview; model:viewmode; delegate: listcomponet; } Component{ id:listcomponet; Rectangle{ id:re border.width: 1; border.color: "white" //H 4: W3 // width: myview.width/5; // height:getw(width); width: myview.width/5; height:60*dp; anchors.bottom: parent.bottom function getw(w) { console.log(w+":"+ width*0.75); return width*0.75; } color: mcolor; Behavior on color{ ParallelAnimation{ ColorAnimation { duration: 888 } } } Item { id: body; anchors.fill: parent Text{ id:tabtxxtimg anchors.bottom: tabtxxt.top anchors.horizontalCenter: parent.horizontalCenter color: txtcolor text: "" styleColor: "#332a2a" verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter anchors.bottomMargin: 4; } Text{ id:tabtxxt anchors.bottom: body.bottom anchors.bottomMargin: 10; anchors.horizontalCenter: parent.horizontalCenter color: txtcolor text: title+":"+index; styleColor: "#332a2a" verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter } } MouseArea{ id:mouse1; anchors.fill: parent; onClicked: { console.log("click"); curTab = index; 设置选中色(index); } } } } ListModel{ id:viewmode; ListElement{mcolor:"#777777";title:"XXX";txtcolor:"white"} ListElement{mcolor:"#cccccc";title:"聊天";txtcolor:"white"} ListElement{mcolor:"#cccccc";title:"通信录";txtcolor:"white"} ListElement{mcolor:"#cccccc";title:"社区";txtcolor:"white"} ListElement{mcolor:"#cccccc";title:"我的XXX";txtcolor:"white"} } function 设置选中色(index) { selchangge(index); for(var x =0;x

    时间:2019-09-03 关键词: QT qt-quick

  • Qt调用OpenGL API实现彩色旋转立方体

    pro文件QT -=gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = lesson1 TEMPLATE = app SOURCES += main.cpp HEADERS += glut.h LIBS+= -lglut32 -lopengl32 -lglu32 main.cpp#include #include #include "glut.h" /* * * 彩色旋转立方体 * 1. 定义六个面,同时定义每个顶点的颜色(与顶点坐标相对应) * 2. 启用 GL_SMOOTH 方式渲染 * * */ static float xrot = 0.0; static float yrot = 0.0; static float zrot = 0.0; void cube() { glBegin(GL_QUADS); glColor3f(1.0,1.0,0.0); glVertex3f( 1.0, 1.0,-1.0); glColor3f(0.0,1.0,0.0); glVertex3f(-1.0, 1.0,-1.0); glColor3f(0.0,1.0,1.0); glVertex3f(-1.0, 1.0, 1.0); glColor3f(1.0,1.0,1.0); glVertex3f( 1.0, 1.0, 1.0); glColor3f(1.0,0.0,1.0); glVertex3f( 1.0,-1.0, 1.0); glColor3f(0.0,0.0,1.0); glVertex3f(-1.0,-1.0, 1.0); glColor3f(0.0,0.0,0.0); glVertex3f(-1.0,-1.0,-1.0); glColor3f(1.0,0.0,0.0); glVertex3f( 1.0,-1.0,-1.0); glColor3f(1.0,1.0,1.0); glVertex3f( 1.0, 1.0, 1.0); glColor3f(0.0,1.0,1.0); glVertex3f(-1.0, 1.0, 1.0); glColor3f(0.0,0.0,1.0); glVertex3f(-1.0,-1.0, 1.0); glColor3f(1.0,0.0,1.0); glVertex3f( 1.0,-1.0, 1.0); glColor3f(1.0,0.0,0.0); glVertex3f( 1.0,-1.0,-1.0); glColor3f(0.0,0.0,0.0); glVertex3f(-1.0,-1.0,-1.0); glColor3f(0.0,1.0,0.0); glVertex3f(-1.0, 1.0,-1.0); glColor3f(1.0,1.0,0.0); glVertex3f( 1.0, 1.0,-1.0); glColor3f(0.0,1.0,1.0); glVertex3f(-1.0, 1.0, 1.0); glColor3f(0.0,1.0,0.0); glVertex3f(-1.0, 1.0,-1.0); glColor3f(0.0,0.0,0.0); glVertex3f(-1.0,-1.0,-1.0); glColor3f(0.0,0.0,1.0); glVertex3f(-1.0,-1.0, 1.0); glColor3f(1.0,1.0,0.0); glVertex3f( 1.0, 1.0,-1.0); glColor3f(1.0,1.0,1.0); glVertex3f( 1.0, 1.0, 1.0); glColor3f(1.0,0.0,1.0); glVertex3f( 1.0,-1.0, 1.0); glColor3f(1.0,0.0,0.0); glVertex3f( 1.0,-1.0,-1.0); glEnd(); } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(0, 0, -5); glRotatef(xrot, 1, 0, 0); glRotatef(yrot, 0, 1, 0); glRotatef(zrot, 0, 0, 1); //glPolygonMode(GL_FRONT, GL_LINE); cube(); xrot = xrot + 0.1; yrot = yrot + 0.1; zrot = zrot + 0.1; glutSwapBuffers(); } void reshape(int w, int h) { if(h==0) h = 1; glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, (GLfloat)w/(GLfloat)h, 0.1, 100.0); glMatrixMode(GL_MODELVIEW); } void init(int width, int height ) { if(height == 0) height = 1; glClearColor(0.0, 0.0, 0.0, 0.0); glClearDepth(1.0); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); glViewport(0, 0, (GLsizei) width, (GLsizei) height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, (GLfloat)width/(GLfloat)height, 1, 100.0); glMatrixMode(GL_MODELVIEW); } void keyboard(unsigned char key, int w, int h) { if(key == 'f') // 进入全屏 glutFullScreen(); if(key == 'F') // 退出全屏 { glutReshapeWindow(640, 480); // 设置窗口大小(不能用初始化的函数) glutPositionWindow(400, 100); // 设置窗口位置(不能用初始化的函数) } if(key == 27) // ESC退出程序 exit(0); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowPosition(400, 100); glutInitWindowSize(640, 480); glutCreateWindow(""); glutDisplayFunc(display); glutIdleFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); init(640, 480); glutMainLoop(); return 0; }效果源码链接:https://download.csdn.net/download/caoshangpa/10403924

    时间:2019-09-03 关键词: opengl QT

  • Qt之读(解析)XML文件

    先上代码 //从config.xml中获取标签appenvironment和oa_app_version的值 //appenvironment值为pro表示生产,为pre表示预生产 QMap readXml() { QMap mapList; mapList.clear(); QString configXMLPath = QCoreApplication::applicationDirPath()+"\config\config.xml"; QFile file(configXMLPath); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { QXmlStreamReader reader(&file); while (!reader.atEnd() && !reader.hasError()) { QXmlStreamReader::TokenType token = reader.readNext(); if (token == QXmlStreamReader::StartElement) { if (reader.name() == "appenvironment" || reader.name() == "oa_app_version") { QXmlStreamAttributes attributes = reader.attributes(); if (attributes.hasAttribute("value")) { QString strValue = attributes.value("value").toString(); mapList.insert(reader.name().toString(), strValue); } } } } //解析出错 if (reader.hasError()) { QString errorInfo = QStringLiteral("XML解析错误:%1 行号:%2 列号:%3 字符位移:%4"). arg(reader.errorString()).arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.characterOffset()); qDebug()

    时间:2019-09-03 关键词: QT xml

首页  上一页  1 2 3 4 5 6 7 8 9 10 下一页 尾页
发布文章

技术子站

更多

项目外包