Lambda匿名函数

  • 有时候槽函数代码辑逻辑非常简单,可以直接用下面的Lambda匿名函数处理信号,简捷明了.需c++11支持,不支持自身递归调用.

    1
    2
    3
    4
    5
    6
    7
    QComboBox *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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?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

    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
    <?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的一些开发技巧的更多相关文章

  1. Qt 5.x 开发技巧

    出现unresolved external symbol "public: __thiscall Dialog::Dialog(class QWidget *) 或类似不太合理的错误时,可以 ...

  2. Qt移动应用开发(一):适配不同的屏幕

    Qt移动应用开发(一):适配不同的屏幕 到眼下为止.Qt5.3已经出现非常长一段时间了.而且已经有一些应用使用Qt进行构建了.我自己也完毕了第一款使用Qt构建的手机游戏<吃药了>.那么接下 ...

  3. SQL开发技巧(二)

    本系列文章旨在收集在开发过程中遇到的一些常用的SQL语句,然后整理归档,本系列文章基于SQLServer系列,且版本为SQLServer2005及以上-- 文章系列目录 SQL开发技巧(一) SQL开 ...

  4. Qt for Android开发环境搭建及测试过程记录

    最近学习了Qt的QML编程技术,感觉相较于以前的QtGUI来说更方便一些,使用QML可以将界面与业务逻辑解耦,便于开发. QML支持跨平台,包括支持Android平台,因此可以使用Qt的QML进行An ...

  5. DelphiXE2 DataSnap开发技巧收集

    DelphiXE2 DataSnap开发技巧收集 作者:  2012-08-07 09:12:52     分类:Delphi     标签: 作为DelphiXE2 DataSnap开发的私家锦囊, ...

  6. delphi XE5下安卓开发技巧

    delphi XE5下安卓开发技巧 一.手机快捷方式显示中文名称 project->options->Version Info-label(改成需要显示的中文名即可),但是需要安装到安卓手 ...

  7. 经典收藏 50个jQuery Mobile开发技巧集萃

    http://www.cnblogs.com/chu888chu888/archive/2011/11/10/2244181.html 1.Backbone移动实例 这是在Safari中运行的一款Ba ...

  8. 移动 Web 开发技巧之(后续)

    昨天的<移动 Web 开发技巧>的这篇文章,大家反响不错,因为这些问题在大家日常写移动端的页面时经常遇到的.所以那个文章还是超级实用的,那么我们今天继续来分享一下移动端的web开发技巧吧, ...

  9. Maven 安装以及一些开发技巧

    解压 apache-maven-3.2.5 在conf ->sites中配置repository 的路径. Eclipse 配置 maven 2. 3. 一些小BUG 或开发技巧 eclipse ...

随机推荐

  1. JAVA 并发编程-线程范围内共享变量(五)

    线程范围内共享变量要实现的效果为: 多个对象间共享同一线程内的变量 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsi ...

  2. vim-进入插入模式快捷键

    vim中有一些命令,是同时包含有大小写两种的.现在就集中测试下他们的区别:     1.A 跟a A-光标所在行的末尾插入 a-光标后插入 2.I 跟i I-光标所在行的非空字符前插入 i-光标前位置 ...

  3. vim 帮助文档汉化

    我们在使用vim 的时候,经常会碰到一些陌生的命令,这时候我们可以通过 :help *** 来查询一些命令的使用方法.不过呢,我们安装的vim默认的都是英文的,看起来很费劲,尤其是向我这样英语比较差的 ...

  4. 11.Axis客户端接收不同参数类型

    转自:http://www.guance.com/708.html axis只支持简单类型的返回值.在这里逐一介绍axis的各种返回值接受. 1. axis接受基本类型,如int, string等 引 ...

  5. 【习题 8-13 UVA - 10570】Meeting with Aliens

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 枚举1的位置在i 往右摆成一排. a[i+1]..a[n]..a[1]..a[i-1]变为有序的 ->寻找循环节,每个循环节的 ...

  6. 【习题 8-10 UVA - 1614】Hell on the Markets

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 证明:前i个数一定能凑够1..sum[i]中的所有数字 i=1时显然成立. 现在假设i>=2时结论成立 即前i个数字能凑出1. ...

  7. 火狐—火狐浏览器中的“HttpWatch”

    在IE下通过HttpWatch能够查看HTTP请求的相关细节.这对我们分析程序的运行效率很有帮助,但是在火狐浏览器中的难道就没有相似的工具了吗?答案是否定的--火狐浏览器中也有.在火狐浏览器中该工具叫 ...

  8. Hibernate中编程式事物的简单使用

    一,openSessioin方式开启或者关闭事物 Session session = null; try { session = HibernateUtils.getSession(); sessio ...

  9. Impala的安装(含使用CM安装 和 手动安装)(图文详解)

    Impala有两种安装方式: 1)使用CM安装Impala 2)手动安装Impala 注意:Impala不支持在Debian/Ubuntu, SuSE, RHEL/CentOS 6.5系统中安装. 基 ...

  10. uiautomator——第一个例子:打开浏览器,输入网址

    1.在sdk安装目录:E:\Test_Tools\auto_test\app\adt-bundle-windows-x86-20131030\sdk\tools下启动uiautomatorviewer ...