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/