Qt的一些开发技巧

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”);来指定。

  • 下载安装

  • 参考文档,从样本模版里复制一份出来做相应的修改.

  • 一个安装包的目录结构如下:

    扫描二维码关注公众号,回复: 1062077 查看本文章
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>[email protected]</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/

猜你喜欢

转载自www.cnblogs.com/findumars/p/9098331.html