Qt的一些开发技巧
Lambda匿名函数
有时候槽函数代码辑逻辑非常简单,可以直接用下面的
Lambda匿名函数
处理信号,简捷明了.需c++11
支持,不支持自身递归调用.1234567QComboBox *cb = new QComboBox(this);QObject::connect(cb,&QComboBox::currentTextChanged,[=](QString txt){[...]baseform->changeJsonValue(btn,uname,baseform->mWindow->mItemMap.key(txt));[...]});函数内部的匿名函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
void ActionList::onCustomContextMenu(const QPoint &pos)
{
[...]
auto sawp_lambda_func = [this](int src,int dst) {
QVariantList oldvals;
for(int i = 0 ; i < mTable->columnCount();i++)
{
QWidget *w = mTable->cellWidget(src,i);
if(!QString::compare(w->metaObject()->className(),"QComboBox"))
{
oldvals.append(((QComboBox*)w)->currentText());
}else{
oldvals.append(((QLineEdit*)w)->text());
}
QObject::disconnect(w);
mTable->removeCellWidget(src,i);
w->deleteLater();
}
mTable->removeRow(src);
[...]
};
QAction up(QIcon(":/icon/icons/act_up.png") ,
QString("上移一行"),this);
QObject::connect(&up,
&QAction::triggered,[=](){
sawp_lambda_func(line,line-1);
});
[...]
}
|
模拟事件
- 一些GUI的操作,需要一些事件来完成,下面模拟一个鼠标Release的事件
1
2
3
4
5
|
[...]
QMouseEvent *event = new QMouseEvent(QMouseEvent::MouseButtonRelease,QCursor::pos(),
Qt::LeftButton,Qt::LeftButton,Qt::NoModifier);
QApplication::postEvent(this,event);
[...]
|
- 把事件转换成对其它控件的事件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
void NewGrid::wheelEvent(QWheelEvent *event)
{
if(sliderOrientation == Qt::Horizontal)
{
if(event->orientation() != Qt::Horizontal)
{
QWheelEvent *evt = new QWheelEvent(event->pos(),event->globalPos(),
event->delta(),
event->buttons(),
event->modifiers(),Qt::Horizontal);
QApplication::postEvent(mainScroll->horizontalScrollBar(),evt);
}
}
}
|
元对像,动态属性
Meta-Object System 的基本功能
Meta Object System 的设计基于以下几个基础设施:
- QObject 类
作为每一个需要利用元对象系统的类的基类 Q_OBJECT 宏,
定义在每一个类的私有数据段,用来启用元对象功能,比如,动态属性,信号和槽
元对象编译器moc (the Meta Object Complier),
moc 分析C++源文件,如果它发现在一个头文件(header file)中包含Q_OBJECT 宏定义,然后动态的生成另外一个C++源文件,这个新的源文件包含 QOBJECT 的实现代码,这个新的 C++ 源文件也会被编译、链接到这个类的二进制代码中去,因为它也是这个类的完整的一部分。通常,这个新的C++ 源文件会在以前的C++ 源文件名前面加上 moc 作为新文件的文件名。其具体过程如下图所示:
除了提供在对象间进行通讯的机制外,元对象系统还包含以下几种功能:QObject::metaObject() 方法
它获得与一个类相关联的 meta-object
QMetaObject::className() 方法
在运行期间返回一个对象的类名,它不需要本地C++编译器的RTTI(run-time type information)支持- QObject::inherits() 方法
它用来判断生成一个对象类是不是从一个特定的类继承出来,当然,这必须是在QObject类的直接或者间接派生类当中 - QObject::tr() and QObject::trUtf8()
这两个方法为软件的国际化翻译字符串 QObject::setProperty() and QObject::property()
这两个方法根据属性名动态的设置和获取属性值读写属性
1
2
3
4
5
|
QWidget *w = new QWidget()
w->setProperty("ABC1",4);
w->setProperty("ABC2","dddddd");
qDebug() << w->property("ABC1") << w->property("ABC2");
|
布署安装
对于开发QT程序来说,最好布署方法就是编译成静态执行文件,只是文件大一点.如果是动态编译就会有一些动态库链接路径的问题.比较特别的它要信赖
platforms
这个文件路经 .可以通过 QCoreApplication::addLibraryPath(“C:/WINDOWS/System32”);来指定。参考文档,从样本模版里复制一份出来做相应的修改.
一个安装包的目录结构如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
D:\QtDev\QtInstaller\netmon-root>tree /F
卷 新加卷 的文件夹 PATH 列表
卷序列号码为 0006EE44 E462:E6DB
D:.
│ build.bat
│
├─config
│ config.xml
│
└─packages
└─com.vendor.product
├─data
│ │ cares.dll
│ │ libcjson.dll
│ │ libcrypto-1_1.dll
│ │ libcurl.dll
│ │ libeay32_.dll
│ │ libgcc_s_dw2-1.dll
│ │ libmosquitto.dll
│ │ libssl-1_1.dll
│ │ libssp-0.dll
│ │ libstdc++-6.dll
│ │ libwinpthread-1.dll
│ │ libz_.dll
│ │ netmon-tray.exe
│ │ netmonui_i686.dll
│ │ print-mon_i686.dll
│ │ qt.conf
│ │ Qt5Core.dll
│ │ Qt5Gui.dll
│ │ Qt5Network.dll
│ │ Qt5Widgets.dll
│ │ ssleay32_.dll
│ │
│ ├─imageformats
│ │ qdds.dll
│ │ qgif.dll
│ │ qicns.dll
│ │ qico.dll
│ │ qjpeg.dll
│ │ qsvg.dll
│ │ qtga.dll
│ │ qtiff.dll
│ │ qwbmp.dll
│ │ qwebp.dll
│ │
│ └─platforms
│ qminimal.dll
│ qoffscreen.dll
│ qwindows.dll
│
└─meta
installscript.qs
license.txt
package.xml
page.ui
|
package.xml
123456789101112<?xml version="1.0" encoding="UTF-8"?><Package><DisplayName>显示名字</DisplayName><Description>随便写一些东西</Description><Version>0.1.0-1</Version><ReleaseDate>2017-05-11</ReleaseDate><Default>script</Default><Script>installscript.qs</Script><UserInterfaces><UserInterface>page.ui</UserInterface></UserInterfaces></Package>config.xml
123456789<?xml version="1.0" encoding="UTF-8"?><Installer><Name>程序名字</Name><Version>1.0.0</Version><Title>程序的抬头</Title><Publisher>yjdwbj@gmail.com</Publisher><StartMenuDir>网络打印客户端</StartMenuDir><TargetDir>@ApplicationsDir@/NetMon</TargetDir></Installer>isntallscript.qs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
function Component()
{
// constructor
component.loaded.connect(this, Component.prototype.loaded);
// 安装完成后自动连接到自动运行的函数
installer.installationFinished.connect(this,Component.prototype.InstallationFinishedAndRun);
installer.finishButtonClicked.connect(this,Component.prototype.installationFinished);
// if (!installer.addWizardPage(component, "Page", QInstaller.TargetDirectory))
// console.log("Could not add the dynamic page.");
}
Component.prototype.createOperations = function()
{
try {
// call the base create operations function
component.createOperations();
component.addOperation("CreateShortcut","C:/WINDOWS/System32/netmon-tray.exe",
"@StartMenuDir@/网络打印机客户端/网络打印机客户端.lnk","@workDirectory=@TargetDir@");
component.addOperation("CreateShortcut","@TargetDir@/maintenancetool.exe",
"@StartMenuDir@/网络打印机客户端/卸载.lnk","@workDirectory=@TargetDir@");
} catch (e) {
console.log(e);
}
}
Component.prototype.createOperationsForArchive = function(archive)
{
# packages\com.vendor.product\data 下面文件全部解压到system32里。
component.addOperation("Extract", archive, "C:/WINDOWS/System32");
}
Version:1.0 StartHTML:0000000107 EndHTML:0000006210 StartFragment:0000000471 EndFragment:0000006172
Component.prototype.InstallationFinishedAndRun = function()
{
try {
if(installer.isInstaller() && installer.status == QInstaller.Success)
{
installer.addWizardPageItem(component,"Page",QInstaller.InstallationFinished);
}
} catch (e) {
console.log(e);
}
}
Component.prototype.installationFinished = function()
{
try {
if(installer.isInstaller() && installer.status == QInstaller.Success)
{
var isRun = component.userInterface("Page").runCheckbox.checked;
if(isRun)
{
QDesktopServices.openUrl("C:/WINDOWS/System32/netmon-tray.exe");
}
}
} catch (e) {
console.log(e);
}
}
|
Page.ui
1234567891011121314151617181920212223242526272829303132333435363738394041<?xml version="1.0" encoding="UTF-8"?><ui version="4.0"><class>Page</class><widget class="QWidget" name="Page"><property name="geometry"><rect><x>0</x><y>0</y><width>400</width><height>300</height></rect></property><property name="windowTitle"><string>Dynamic page example</string></property><layout class="QVBoxLayout" name="verticalLayout"><item><widget class="QLabel" name="m_pageLabel"><property name="alignment"><set>Qt::AlignCenter</set></property></widget></item><item><widget class="QCheckBox" name="runCheckbox"><property name="text"><string>安装完成后,运行该程序</string></property><property name="checked"><bool>true</bool></property><property name="tristate"><bool>false</bool></property></widget></item></layout></widget><resources/><connections/></ui>最后这里用一行脚本来生成一键安装包文件。
1
|
binarycreator --offline-only -c D:\QtDev\QtInstaller\netmon-root\config\config.xml -p D:\QtDev\QtInstaller\netmon-root\packages "Z:/upload/appname-测试版%DATE%-%TIME::=_%.exe"
|
https://yjdwbj.github.io/2017/01/08/Qt%E7%9A%84%E4%B8%80%E4%BA%9B%E5%BC%80%E5%8F%91%E6%8A%80%E5%B7%A7/
Qt的一些开发技巧的更多相关文章
- Qt 5.x 开发技巧
出现unresolved external symbol "public: __thiscall Dialog::Dialog(class QWidget *) 或类似不太合理的错误时,可以 ...
- Qt移动应用开发(一):适配不同的屏幕
Qt移动应用开发(一):适配不同的屏幕 到眼下为止.Qt5.3已经出现非常长一段时间了.而且已经有一些应用使用Qt进行构建了.我自己也完毕了第一款使用Qt构建的手机游戏<吃药了>.那么接下 ...
- SQL开发技巧(二)
本系列文章旨在收集在开发过程中遇到的一些常用的SQL语句,然后整理归档,本系列文章基于SQLServer系列,且版本为SQLServer2005及以上-- 文章系列目录 SQL开发技巧(一) SQL开 ...
- Qt for Android开发环境搭建及测试过程记录
最近学习了Qt的QML编程技术,感觉相较于以前的QtGUI来说更方便一些,使用QML可以将界面与业务逻辑解耦,便于开发. QML支持跨平台,包括支持Android平台,因此可以使用Qt的QML进行An ...
- DelphiXE2 DataSnap开发技巧收集
DelphiXE2 DataSnap开发技巧收集 作者: 2012-08-07 09:12:52 分类:Delphi 标签: 作为DelphiXE2 DataSnap开发的私家锦囊, ...
- delphi XE5下安卓开发技巧
delphi XE5下安卓开发技巧 一.手机快捷方式显示中文名称 project->options->Version Info-label(改成需要显示的中文名即可),但是需要安装到安卓手 ...
- 经典收藏 50个jQuery Mobile开发技巧集萃
http://www.cnblogs.com/chu888chu888/archive/2011/11/10/2244181.html 1.Backbone移动实例 这是在Safari中运行的一款Ba ...
- 移动 Web 开发技巧之(后续)
昨天的<移动 Web 开发技巧>的这篇文章,大家反响不错,因为这些问题在大家日常写移动端的页面时经常遇到的.所以那个文章还是超级实用的,那么我们今天继续来分享一下移动端的web开发技巧吧, ...
- Maven 安装以及一些开发技巧
解压 apache-maven-3.2.5 在conf ->sites中配置repository 的路径. Eclipse 配置 maven 2. 3. 一些小BUG 或开发技巧 eclipse ...
随机推荐
- openfire 开发遇到的些问题
openfire的 jid 账户名 + '@" + 你的域名 可是当你的账户名中 有大拼音的 时候 就会变成小写 比如 Test , jid = tes ...
- 下载安装与配置Excel 2013数据挖掘加载项(SQL Server 2012 SP1 + SQLServer2012_DMAddin.msi)
一.系统要求 在安装这个数据挖掘加载项前,你的机器必须要可以支持如下的相关系统设备: (1)操作系统:windows 7 和 windows 8,暂时不支持 windows 10. (2)excel ...
- atime&&mtime&&ctime区别
- 妙味css3课程---1-2、css3中新增的伪类和伪元素有哪些
妙味css3课程---1-2.css3中新增的伪类和伪元素有哪些 一.总结 一句话总结: 1.div:target{}是什么意思? 比如a标签的锚点链接到div,div:target{}就可以找到这个 ...
- java创建节点和单向链表
package datastructure; public class Node { private Object data; private Node next; public Node() { t ...
- 对ng-repeat的表格内容添加不同样式:ng-style
对ng-repeat的表格内容添加不同样式,html代码: <tr ng-repeat="x in tableData"> <td>{{x.networkN ...
- BZOJ2402: 陶陶的难题II(树链剖分,0/1分数规划,斜率优化Dp)
Description Input 第一行包含一个正整数N,表示树中结点的个数.第二行包含N个正实数,第i个数表示xi (1<=xi<=10^5).第三行包含N个正实数,第i个数表示yi ...
- NuGet 使用及dll管理
NuGet学习笔记(1)——初识NuGet及快速安装使用 作者: 懒惰的肥兔 来源: 博客园 发布时间: 2012-05-20 21:33 阅读: 53168 次 推荐: 33 原文链接 ...
- 自绘listCtrl控件选中该行高亮(模拟windows)
CListCtrl的派生类CMyListCtrl的DrawItem()函数里添加代码 CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC); if ...
- Microsoft SQL Server Version List(SQL Server 版本)
原帖地址 What version of SQL Server do I have? This unofficial build chart lists all of the known Servic ...