精华内容
下载资源
问答
  • 无用代码­——DO-178B/ED-12B学习笔记一1. 无用代码的定义 DO-178B/ED-12B对无用代码(Dead code)的定义是: Executable object code (or data) which, as a result of a design error cannot be executed ...

    无用代码

    ­——DO-178B/ED-12B学习笔记之一

    1.        无用代码的定义

      DO-178B/ED-12B对无用代码(Dead code)的定义是:

      Executable object code (or data) which, as a result of a design error cannot be executed (code) or used (data) in a operational configuration of the target computer environment and is not traceable to a system or software requirement. An exception is embedded identifiers.

      试译如下:

      因设计错误而产生的,在目标机环境的运行配置中不能执行的(代码)或不能使用的(数据),并且不能追踪到一个系统或软件需求的可执行的目标代码(或数据 )。嵌入的标识符号除外。

      为了准确把握无用代码的定义,还需了解DO-178B/ED-12B对目标码和源码的定义。

      DO-178B/ED-12B对目标码(Object Code)的定义是:

      A low-level representation of the computer program not usually in a form directly usable by the target computer but in a form which includes relocation information in addition to the processor instruction information.

      试译如下:

      计算机程序的一种低级表示,其格式通常不是目标(target)计算机直接可用的,而是包含了计算机指令信息以及重定位信息。

      DO-178B/ED-12B对源码(Source code)的定义是:

      Code written in source languages, such as assembly language and/or high level language, in a machine-readable form for input to an assembler or a compiler.

      试译如下:

      用源语言(如汇编语言或高级语言)编写的代码,其格式是机器可读的,以作为汇编程序或编译程序的输入。

      DO-178B/ED-12B没有定义可执行的目标码(executable object code)。那么按照上述目标码的定义和常识,可执行的目标码应是目标码经过连接程序(linker)处理后生成的目标(target)计算机直接可用的代码。

      由此可见:

      ——无用代码是针对可执行的目标码而不是源码定义的;

      ——无用代码包括代码和数据;

      ——认定为无用代码有两个条件,一是执行不到,即程序的控制流达不到该代码或数据流达不到该数据;二是追踪不到,即从该代码或数据不能追踪到任何一条系统或软件需求。

      针对可执行的目标码来定义无用代码,这可能因为最终装机的是可执行的目标码,而源码与目标码不是一一对应的。然而,为了消除可执行的目标码中的无用代码,我们首先要消除源码中的无用代码。

      源码中有些语句,如类型定义,不会直接产生目标码,因此也不会变成无用代码。但是,从软件验证角度有必要分析这些没有使用的语句,可能从中发现其它问题。

      从代码追踪到系统或软件需求有时是很困难的,尤其是当需求描述不够详细时。DO-178B/ED-12B的软件需求包括高级需求和低级需求,还有派生需求(derived requirements)。有些代码往往只能追踪到派生需求。

      无用代码的两个条件是与的关系还是或的关系?从文字上看好像是与的关系。但是,如果要两个条件都成立,那么能追踪但不能执行的就不算无用代码?

    2.        无用代码的识别

      我们在DO-178B/ED-12BDO-248B/ED-94B中只找到了以下两段与无用代码的识别有关联的论述。

      DO-178B/ED-12B6.4.4.3条的开头有这样一句,“Structural coverage analysis may reveal code structure that was not exercised during testing.”。

      DO-248B/ED-94BFAQ#74中谈论MC/DC时有这样一句,“Additionally, any dead code or unreachable paths in the code may be identified.”。

      由此可见:

      ——DO-178B/ED-12BDO-248B/ED-94B都没有明确规定识别的方法或途径

      ——结构覆盖分析可以(may)但不是必定揭示无用代码

      为了理解无用代码识别与结构覆盖分析的关系,需要理解DO-178B/ED-12B对结构覆盖分析的论述。

      DO-178B/ED-12B规定了三种结构覆盖,即语句覆盖、判定覆盖、MC/DC

      DO-178B/ED-12B6.4.4.2.b条的第一句:The structural coverage analysis may be performed on the Source Code, unless the software level is A and the compiler generates object code that is not directly traceable to Source Code statements. Then, additional verification should be performed on the object code to establish the correctness of such generated code sequences.(试译如下:一般情况下,可以只对源代码进行结构覆盖分析。但是,当软件等级是A级,以及编译器产生了不能直接追踪到源代码语句的目标码,还应对目标码进行额外验证以确定所产生的代码序列的正确性。)

      这三种结构覆盖都是面向可执行语句的,可以揭示未执行的代码,但不一定能揭示未使用的数据。因此还需要使用面向数据的覆盖测试技术,如数据覆盖测试[3][4]等,来识别未使用的数据。

      DO-178B/ED-12B6.4.2.1条论述了Normal Range Test Cases(正常范围测试用例),6.4.2.2条论述了Robustness Test Cases(健壮性测试用例)。这两类测试用例也可能揭示未使用的数据。

      以下用一个例子说明结构覆盖不足以揭示未使用的数据。设有如下C函数:

      int convert_1(int i)

      {

        int r;

        if (i == 1)

          r = 10;

        else if (i == 2)

          r = 20;

        else if (i == 3)

          r = 30;

        else

          r = 0;

        return r;

      }

      设输入参数i分别为1234,用这样4个测试用例测试函数convert_1,可以达到语句覆盖,并测试了其中的3个转换因子102030

      如果把代码改写为:

      int convert_2(int i)

      {

        static int factor_array[3] = {10, 20, 30};

        int r;

        if (i >= 1 && i <= 3)

          r = factor_array[i-1];

        else

          r = 0;

        return r;

      }

      这样用2个测试用例就可以达到语句覆盖,但不能揭示数组factor_array的三个分量是否都被使用了。

      如果是以下形式的代码:

      typedef struct

      {

        int factor_1;

        int factor_2;

        int factor_3;

      } factor_t;

      factor_t factor_record = {10, 20, 30};

      int convert_3(int i)

      {

        if (i == 1) return factor_record.factor_1;

        else return factor_record.factor_2;

      }

      某些静态数据流分析工具不能揭示factor_record.factor_3未被使用的问题。

    3.        无用代码的处理

      DO-178B/ED-12B6.4.4.3.c条规定:

      Dead code: The code should be removed and an analysis performed to assess the effect and the need for reverification.

      试译如下:

      无用代码:应消除这种代码,并进行分析以评定消除后的影响以及是否需要重新验证。

      DO-248B/ED-94BFAQ#28强调和诠释了上述要求:

      It is important to realize that DO-178B/ED-12B not only states that dead code “should be removed”: Section 6.4.4.3c continues with the statement that "an analysis (should be) performed to assess the effect (of removing the dead code) and the need for reverification."

      由此可见,无用代码处理包括两件事,一是消除,二是分析,必要时还要做第三件事——重新验证。

    参考文献

     

    [1]     DO-178B/ED-12B, Software Considerations in Airborne Systems and Equipment Certification, December 1, 1992

    [2]     DO-248B/ED-94BFinal Report for Clarification of DO-178B, October 12, 2001

    [3]     古乐、史九林,软件测试技术概论,清华大学出版社,2004

    [4]     Elfriede DustinJeff Rashka, John Paul, Automated Software Testing, 1999

     

    展开全文
  • SQL Server 索引管理——禁用无用索引

    千次阅读 2019-05-28 13:38:34
    SQL Server 索引管理——禁用无用索引 前文中,对于不再使用的索引,直接生成删除的脚本,在文中,也提到了直接删除无用索引存在的风险。为了保险起见,如果我们使用的是SQLServer 2005及以后版本,我们可以使用...

    SQL Server 索引管理——禁用无用索引

     

    前文中,对于不再使用的索引,直接生成删除的脚本,在文中,也提到了直接删除无用索引存在的风险。为了保险起见,如果我们使用的是SQL Server 2005及以后版本,我们可以使用其新增加的功能:索引禁用。这样如果后期发现禁用掉的索引是需要的,我们就可以及时重建索引,保证数据库的性能,如果通过足够时长的观察,确定索引确实无用,则可以将禁用索引删除(备份、删除禁用索引的方式将在后续文章中给出)。对于的禁用后的索引,需要重新启用,只需要使用索引重建就可以启用。

    禁用、启用索引脚本如下:

    USE [DBName]
    GO
    --禁用索引语法
    ALTER INDEX indexName ON tableName DISABLE
    GO
    --启用索引语法
    ALTER INDEX indexName ON tableName REBUILD
    GO

    下面我们根据记录索引使用状态的动态视图sys.dm_db_index_usage_stats 生成不用索引的禁用脚本。这里的索引不使用指的是:

    • 用户查找(user_seeks)次数为0

    • 用户扫描(user_scans)次数为0

    • 用户书签查找(user_lookups)次数为0

    • 索引更新(user_updates)次数大于0

    即无用索引为该索引在用户搜索、扫描、查找中都没有使用到。注意视图中的user_updates指的是表的插入、删除、更新等使得索引维护更新的次数。如果user_seeks、user_scans、user_lookups均为0,而user_updates大于0,说明索引不但对性能提升无益,还需要消耗额外的性能来维护索引,这种索引最好禁用甚至删除(当然是在确定确实没有使用的情况下)。

    DECLARE @SQL NVARCHAR(MAX)
    SELECT @SQL = stuff((
    SELECT 'ALTER INDEX '+ QUOTENAME(ind.NAME,'[')+' ON '+QUOTENAME(sch.NAME,'[')+'.'+QUOTENAME(obj.NAME,'[') +' DISABLE '+CHAR(10)
    FROM sys.dm_db_index_usage_stats ius
        INNER JOIN sys.indexes ind on ius.index_id = ind.index_id and ius.OBJECT_ID=ind.object_id
        INNER JOIN sys.objects obj on ius.OBJECT_ID = obj.OBJECT_ID
        INNER JOIN sys.schemas sch on obj.schema_id = sch.schema_id
    WHERE  OBJECTPROPERTY(ius.OBJECT_ID, 'IsSystemTable') = 0
        AND LEFT(obj.NAME, 3) NOT IN ('sys','sql','que','fil')
        AND UPPER(ind.type_desc) = 'NONCLUSTERED'
        AND ind.is_primary_key = 0
        AND ind.is_unique_constraint = 0
        AND ius.user_seeks = 0
        AND ius.user_scans = 0
        AND ius.user_lookups = 0
        AND ius.user_updates > 0
        AND ius.database_id = db_id()
        AND sch.name <> 'sys'
    FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,0,'')
    SELECT @SQL FOR XML PATH('')

    脚本中我们排除了系统表的索引,以及聚集索引,主键及有唯一约束的索引。这里最终返回的是XML数据(点击XML,即可以查看生成的文本),而不是使用PRINT打印出来,是防止文本过长而截断,另外,细心的读者会发现,在构造索引禁用语句最后加了CHAR(10)换行字符,使得最终的语句每条一行。

    注意:动态视图记录信息在数据服务重启、数据库分离后信息将会被清除,所以要在数据库运行足够长时间后方可使用本脚本生成禁用索引脚本。

    如果数据库实例足够长时间没有重启或者分离过,有用的索引都会记录到索引使用状态视图中,而没有记录到视图的这部分索引既不会被查询用到,也不需要消耗性能进行索引维护(一般出在废弃的表中)。如果硬盘空间紧张,需要对数据库进行瘦身,可以对这部分索引进行动手处理,我们给出了如下的禁用脚本生成的脚本:

    DECLARE @dbid INT=DB_ID();
    DECLARE @sql VARCHAR(MAX);
    WITH cte AS(
           SELECT
                  [object_id],index_id
           FROM sys.indexes
           EXCEPT --排除在用的对象索引
           SELECT
                  [object_id],index_id
           FROM sys.dm_db_index_usage_stats
           WHERE database_id=@dbid)
    SELECT @sql=(
           SELECT
                  'ALTER INDEX '+QUOTENAME(i.name,'[')+' on '
                           +QUOTENAME(s.name,'[')+'.'+ QUOTENAME(o.name,'[')
                           +' DISABLE '
                           + CHAR(10)  --换行符
           FROM sys.indexes i
           INNER JOIN cte ON cte.[object_id]=i.[object_id] AND cte.index_id=i.index_id 
           INNER JOIN sys.objects o ON i.[object_id]=o.[object_id]
              INNER JOIN sys.schemas s ON o.SCHEMA_ID=s.SCHEMA_ID
           WHERE o.[type] IN ('U','V')--用户表或者视图
                         AND i.[type]>0                    --非堆
           ORDER BY s.name,o.name
    FOR XML PATH(''),TYPE).value('.','NVARCHAR(MAX)');
    SELECT @sql FOR XML PATH('');

    最后,为了帮助理解什么样的操作会触发sys.dm_db_index_usage_stats记录索引使用状态,我们做了如下测试。先创建测试表:

    CREATE TABLE indexesUsageStatsTest(
           id INT IDENTITY(1,1),
           name VARCHAR(50),
           TYPE INT
    );

    表创建后,查看视图sys.dm_db_index_usage_stats

    SELECT * FROM sys.dm_db_index_usage_stats
    WHERE OBJECT_ID= OBJECT_ID('indexesUsageStatsTest',N'U')
           and database_id=DB_ID();

    此时视图无数据。

    然后分别在表上创建聚集索引、和非聚集索引,并查询视图,发现视图仍没有数据

    CREATE CLUSTERED INDEX cix_id ON indexesUsageStatsTest(id);
    CREATE NONCLUSTERED INDEX ix_type ON indexesUsageStatsTest(TYPE);

    向表中插入数据

    INSERT INTO indexesUsageStatsTest(name,TYPE)
    SELECT TOP 100 FirstName,BusinessEntityID
    FROM Person.Person;

     

    插入数据后,执行视图查询,发现视图中增加了两条记录,由于此时,该次插入数据造成所有索引都有一次更新,两个索引的user_updates值均变为1.。接下来执行如下脚本进行全表查询:

    SELECT * FROM indexesUsageStatsTest;

    执行查询时,打开“执行计划”,可以看到该查询使用了聚集索引扫描(clustered index scan)

    再执行视图查询,结果如下:

    从结果可以看出,聚集索引(index_id=1)的user_scans值变为1,并且last_user_scan的时间更新为查询执行时间。

    在上面的查询的基础上,加上条件id=10

    SELECT * FROM indexesUsageStatsTest
    WHERE id=10;

    此时使用的是聚集索引搜索,我们再执行视图的查询,并查看结果

    聚集索引(index_id=1)的user_seeks值变为1,并且last_user_seek的时间更新为查询执行时间。

    为获取书签查找,查询不包含在任何索引中的列name,并强制使用索引ix_type

    SELECT name FROM indexesUsageStatsTest with(index(ix_type))
    WHERE TYPE>38 and TYPE<7000;

    查询计划中使用ix_type进行索引查找,cix_id进行键查找。再执行视图查询,并查看结果:

    聚集索引(index_id=1)进行一次Key Lookup,其user_lookups变为1,并且非聚集索引(index_id=2)进行了移除索引查找,其对应列user_seeks 值更新为1.

    UPDATE indexesUsageStatsTest SET TYPE=50
    WHERE TYPE=38;

    更新使用非聚集索引查找,查看视图可以发现,非聚集索引的user_seeks增加1,并且更新数据引起索引维护,两个索引的user_updates均增加1.

    数据删除使用非聚集索引查找,查看视图可以发现,非聚集索引的user_seeks增加1,并且更新数据引起索引维护,两个索引的user_updates均增加1.

    DELETE indexesUsageStatsTest
    WHERE TYPE=50;

    最后我们重启一下实例,并查询视图

    发现视图没有记录对应表索引使用信息,因为实例启动时,视图记录清除,索引还没有使用。再次执行

    SELECT name FROM indexesUsageStatsTest with(index(ix_type))
    WHERE TYPE>38 and TYPE<7000;

    并查看记录

    发现增加使用的索引信息,并从0开始计数。这也是我们强调使用该脚本的要保证数据库运行足够长时间的原因。

    如果喜欢,可以搜索关注 MSSQLServer 公众号,将有更多精彩内容分享:

                                                                     

    展开全文
  • 软件测试度量是一种通过检测软件测试过程的质量和有效性来评估软件开发的量化方法。开发团队使用测试指标来... 下面这些无用的测试指标的例子可以帮助你更好地理解测试指标是否提供了所需的洞察力。 1.执行的测试用例的
  • 如何快速清除无用的css

    万次阅读 2015-08-15 03:02:12
    我们在编写CSS样式的时候,往往或遭遇CSS样式的修改或者界面设计的变更,页面的CSS在经历几个版本的修改之后,可能有些样式已经不到了,或许将某些样式更名了而原来的忘了删除,总之页面中可能存在着一些无用的...
    我们在编写CSS样式的时候,往往或遭遇CSS样式的修改或者界面设计的变更,页面的CSS在经历几个版本的修改之后,可能有些样式已经用不到了,或许将某些样式更名了而原来的忘了删除,总之页面中可能存在着一些无用的样式。这些无用的浪费了一些服务器空间和带宽消耗,也会增大我们的维护成本。那么有没有一些办法来清理那些无用的样式呢?今天就让我们来了解一下几个比较有用的工具。

       一、Dust-Me selectors

      Dust-Me是一个很有用也很好用的Firefox插件,它可以分析到你的页面中调用的所有CSS文件并分析那些在页面中没有被用到。
    •   支持本地和远程样式文件,包括使用<link>标签、<?xml-stylesheet?>处理指令、@import语句等方式引入的样式文件;(但是不支持页面中的<style>块和内联样式)
    •   支持IE条件注释中引入的样式文件;
    •   可以检查一个页面,也可以检查整个网站;
    •   支持CSS1选择器、大部分CSS2和CSS3选择器;
    •   理解通用的CSS hack,比如 “* html #fuck-ie”将会被认为是”html #fuck-ie”;
    •   支持Firefox 3.5和Firefox 3.0,事实上得益于FF 3.5的js引擎的改进,FF 3.5中的性能比FF 3.0要高50%。


    安装:点击这里。同时,你可以下载该项目的源代码,了解更多请访问 Dust-Me selector官方页面

       二、Page Speed

      Page Speed是Google提供的一个前端性能分析工具,有些类似于YSlow,但是提供了一些比较个性且很有用的工具,比如Remove unused CSS:

      Page Speed和YSlow一样依赖Firebug。

    Page Speed和YSlow一样依赖Firebug,了解详情和安装请访问这里


       三、CSS Redundancy Checker

      CSS Redundancy Checker 是一个免费的在线应用,可以检查所有的使用某个CSS文件的页面中无用的样式。可以同时检查某一个样式在多个页面中的使用情况。该工具的不足是虽然一次能检查多个HTML页面,但每次只能检查一个CSS文件,而且还要手动输入:

       四、IntelliJ IDEA

      IntelliJ IDEA 这是一个颇强大的IDE,类似于DreamWeaver,不过在国内用的不多。该软件包括一个即时代码分析工具(On-the-fly Code Analysis),可以分析CSS文件中未用到的class和id。

       五、Expression Web

      Expression Web作为微软的新一代网站开发工具,还是有很多人使用的,其CSS Report功能可以检查未用到需要被清除的CSS(我的确没有使用EW开发过网站,希望使用该软件的童鞋可以帮忙确认一下这一点)。

       小结:

      当然可能还有其它的某些工具这里没有提到,如果大家有所了解,可以与大家分享。
      另外,通常我们将整个网站的样式写入一个或多个样式文件中,然后在页面中全部调用或者分模块调用,在52CSS.com的网站样式文件组织方面的文章中,有过介绍。那么某个CSS文件中的样式可能在某个页面中的确没有用到但是在其它的页面中被用到了,所以使用这些工具检测CSS文件中多余的样式的时候,需要保持一定的谨慎,清除样式可能会影响到其它的页面,所以 page speed提供的检查结果只适用于单个页面,不适合整个网站,而使用Dust-Me或CSS Redundancy Checker的时候可以对整个网站或者网站的多个页面同时检查,这样可能能避免万无一失。
    展开全文
  • Qt深入理解gesture

    万次阅读 2010-12-09 15:17:00
    Qt深入理解gesture

    Qt最新的版本4.7中有五个gesture,分别是QPanGesture, QPinchGesture, QSwipeGesture, QTapAndHoldGesture, and QTapGesture, 前三个比较常用,但用过的人仍然很少,很多人人对这个gesture意思感觉也陌生,更不用说对说出他们之间的区别了。这里我先解释一下:
    Pan Gesture就是指一个手指在屏幕上滑动,当滑动距离超过一定大小时就产生了一个Pan Gesture的事件了,如下图所示:

    Pinch Gesture就是两指放在屏幕上,靠近或者远离,就像捏东西一样,如下图所示:

    Swipe Gesture就是一个手指在屏幕上沿着一个固定的方向滑动,滑动一段距离时就产生了一个Swipe Gesture的事件,如下图所示:

    QTapAndHoldGesture和QTapGesture比较简单这里我就偷个懒不说了,哈哈。
    Gesture是个手势,但是个组合拳,过滤Gesture是消耗很大的,一般来说它要过滤好几个事件,要与你要截获的Gesture对比,看有没有可能 是你要的那个手势,如果所有事件都会做很多无用功,因此只有真的我们需要截获那个gesture时才会让系统帮我们这么做。

    我比较喜欢看源码说事,就来看看
    每个gesture都有对应的gesture recognizer(手势识别类)来识别这个gesture,比如QPanGesture,它就有QPanGestureRecognizer。可有了 gesture recognizer,系统就认识你这个gesture了吗?不是,你还要将你的gesture recognizer注册到QGestureManager中,而QGestureManager则统一管理所有的gesture recognizer,系统只要通过QGestureManager就可以来识别相应的gesture。让我们来看看QGestureManager的构 造函数源码:

    1. QGestureManager::QGestureManager(QObject *parent )
    2.     : QObject(parent), state(NotGesture), m_lastCustomGestureId(0)
    3. {
    4.     qRegisterMetaType<Qt::GestureState>();
    5. #if defined(Q_WS_MAC)
    6.     registerGestureRecognizer(new QMacSwipeGestureRecognizer);
    7.     registerGestureRecognizer(new QMacPinchGestureRecognizer);
    8.   #if defined(QT_MAC_USE_COCOA)
    9.     registerGestureRecognizer(new QMacPanGestureRecognizer);
    10.   #endif
    11. #else
    12.     registerGestureRecognizer(new QPanGestureRecognizer);
    13.     registerGestureRecognizer(new QPinchGestureRecognizer);
    14.     registerGestureRecognizer(new QSwipeGestureRecognizer);
    15.     registerGestureRecognizer(new QTapGestureRecognizer);
    16. #endif
    17. #if defined(Q_OS_WIN)
    18.   #if !defined(QT_NO_NATIVE_GESTURES)
    19.     if (QApplicationPrivate::HasTouchSupport)
    20.         registerGestureRecognizer(new QWinNativePanGestureRecognizer);
    21.   #endif
    22. #else
    23.     registerGestureRecognizer(new QTapAndHoldGestureRecognizer);
    24. #endif
    25. }
    复制代码

    上面的代码很简单这里我只简单说说,registerGestureRecognizer就是用来注册gesture recognizer的,刚开始说的五个gesture在这里都注册了。
    我们再了看看registerGestureRecognizer函数:

    1. Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *recognizer)
    2. {
    3.     //这里也用你的recognizer创建一个你的gesture实例,如果没有创建成功就
    4.     //返回Qt::GestureType(0),表示注册失败
    5.     QGesture *dummy = recognizer->create(0);
    6.     if (!dummy) {
    7.         qWarning("QGestureManager::registerGestureRecognizer: "
    8.                  "the recognizer fails to create a gesture object, skipping registration.");
    9.         return Qt::GestureType(0);
    10.     }
    11.     //Code A
    12.     //这里如果发现你的gestureType是CustomGesture则会
    13.     //返回Qt::GestureType(Qt::CustomGesture + m_lastCustomGestureId)
    14.     //即在Qt::CustomGesture基础上加一个数字,如果是注册第一个的自定义的gesture,
    15.     //这里的m_lastCustomGestureId就是1,再注册就加2,以此类推
    16.     //这里对我们理解自定义gesture很有帮助:)
    17.     Qt::GestureType type = dummy->gestureType();
    18.     if (type == Qt::CustomGesture) {
    19.         // generate a new custom gesture id
    20.         ++m_lastCustomGestureId;
    21.         type = Qt::GestureType(Qt::CustomGesture + m_lastCustomGestureId);
    22.     }
    23.     m_recognizers.insertMulti(type, recognizer);
    24.     delete dummy;
    25.     return type;
    26. }
    复制代码

    上 面代码中注释的应该比较全,这里我只就Code A部分说一下,如果我自定义一个gesture时,无需管它的gesture类型,也不用重新实现它的gestureType方法,默认的就是 Qt::CustomGesture,这里的你的gesture类型id你可以通过调用 QGestureRecognizer::registerRecognizer方法的返回值来获得,也可以根据上面的代码在 Qt::CustomGesture基础上加上相应的数字来得到。

    说完这些,让我们来看看有关gesture的事件传递的过程:
    当你通过调用QWidget ::grabGesture来截获相应的gesture手势时
    如果你想截获某个手势,你需要调用QWidget::grabGesture方法来截获相应的手势类型,我们来看看QWidget::grabGesture方法源码:

    1. void QWidget::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags)
    2. {
    3.     Q_D(QWidget);
    4.     //这里先向gestureContext,即手势上下文,插入这个gesture类型
    5.     //gestureContext是属于这个widget的QWidgetPrivate的,可见这里的截获事件紧限于这个widget
    6.     d->gestureContext.insert(gesture, flags);
    7.    // 创建gesture manager,这里用的是单例模式,哈哈
    8.     (void)QGestureManager::instance();
    9. }
    复制代码

    这样之后,当事件最终通过经过QApplication::notify方法处理时,如果发现接受事件的widet有截获gesture时,就会将事件叫给gesture manager来过滤。
    整个过程事件传递如下图所示:

    展开全文
  • 当项目开发时间越来越久,资源不断更新的时候,...3、在当前工程上继续扩展有时会造成理解上的困难等等 使用Android Studio可以帮助我们快速定位我们工程中的无效资源和类文件。 Step1:在工具栏中找到Analyze菜...
  • 算法——个人算法的一些理解

    千次阅读 2018-02-05 14:08:49
    个人算法的一些理解  在学校的同学们之间,算法总是被放在一个非常高的位置,有多高呢?嗯...就是非常非常高啦,高到有人只要能说出几个非常牛掰的和算法有关的名词,比如NP完全问题啦、模拟退火啦就觉得自己是...
  • 以编译方式执行本地代码比解释方式更快,所以有这样的共识,除去虚拟机解释执行字节码时额外消耗时间的原因外,还有一个很重要的原因就是虚拟机设计团队几乎把代码的所有优化措施都集中在了即时编译器中(在...
  • 深入理解MySQL索引B+Tree

    万次阅读 多人点赞 2019-01-13 21:17:25
    在正式讲解之前,后面举例中使用的表结构先简单看一下: create table user ( id bigint not null comment 'id' primary key, name varchar(200) null comment 'name', age bigint null comment 'age', gender int...
  • Redis的理解总结

    千次阅读 2015-04-02 15:00:01
    这个问题的结果影响了我们怎么Redis。如果你认为Redis是一个key value store, 那可能会它来代替MySQL;如果认为它是一个可以持久化的cache, 可能只是它保存一些频繁访问的临时数据。Redis是REmote DIctionary ...
  • 无用的css样式怎么去清除?

    千次阅读 2015-09-24 16:54:21
    最近项目赶得紧,常常拿以前的项目的stylecss移植过来(公司项目速度要求),这样子,其实重用项目代码没什么不好,...在我们写样式的时候,页面的CSS在经历几个版本的修改之后,可能有些样式已经不到了,或许将某些
  • CSS技巧:清理无用的CSS样式

    万次阅读 2013-03-13 16:13:03
    我们在编写CSS样式的时候,往往或遭遇CSS样式的修改或者界面设计的变更,页面的CSS在经历几个版本的修改之后,可能有些样式已经不到了,或许将某些样式更名了而原来的忘了删除,总之页面中可能存在着一些无用的...
  • Asset Hunter 2是一款用于Unity3d清理无用资源的实用工具,能够让我们一直保持保持项目的清洁。 Asset Hunter是一个分析构建日志的工具,并为提供项目文件夹中未使用资产的易于理解的概览。 结果被分组到文件夹和...
  • jvm卸载class条件的理解

    千次阅读 2017-02-10 20:15:36
    类需要满足以下3个条件才能算是“无用的类”    1. 该类所有的实例已经被回收  2. 加载该类的ClassLoder已经被回收  3. 该类对应的java.lang.Class对象没有任何对方被引用   第2个条件有一些...
  • 我也就是把我自己学习算法过程中的一些问题和问题的理解记录一下,希望可以加深大家该算法的理解。 本篇可能不会详细讲解FP树的构建过程或是算法流程,而是会算法中的一些关键点给出自己的理解,分析算法为...
  • 背包九讲——全篇详细理解与代码实现

    万次阅读 多人点赞 2018-12-04 08:57:57
    dd_engi背包九讲的个人整理,包含代码例题及个人理解
  • Java程序最初是通过解释器(Interpreter)...并进行各种层次的优化,完成这个任务的编译器称为即时编译器,即时编译器编译性能的好坏、 代码优化程度的高低却是衡量一款商用虚拟机优秀与否的最关键的指标一,本篇博
  • 清理无用的CSS比较有用的几个工具

    千次阅读 2014-02-14 11:36:44
    项目慢慢成形,页面的CSS在经历几个版本的修改之后,可能有些样式已经不到了,或许将某些样式更名了而原来的忘了删除,总之页面中可能存在着一些无用的样式。这些无用的浪费了一些服务器空间和带宽消耗,也会增大...
  • keil Mdk 优化等级的理解

    千次阅读 2020-08-24 21:37:06
    移除未调用的内联函数和静态函数,关闭debug窗口优化,此状态也能用于调试 特点:有限的优化,去除无用的inline和无用的static函数、死代码消除等,在影响到调试信息的地方均不进行优化。在适当的代码体积和充分的...
  • 数据库索引的理解及适合建立索引的字段

    万次阅读 多人点赞 2018-03-06 13:17:43
    因本人小白,总结一下别人总结的,勿怪勿怪。转载 深入浅出数据库索引原理 , 哪些字段适合建立索引 ...如果开发的应用使用的数据库表中只有1万条数据,那么了解...9、删除无用的索引,避免执行计划造成负面影响;
  • 只读事务是否做无用功?

    千次阅读 2017-11-18 09:46:59
    有时候,我们会看到代码里面,有如下语句。 @Transaction(ReadOnly=true) 是不是没有用处呢?其实是有用处的。在mysql中是支持只读事务的。...只读事务内,不能增加、修改、删除内容,否则报Cannot execute ...
  • Java进阶深入理解String/StringBuffer与StringBuilder

    万次阅读 多人点赞 2016-07-14 18:35:39
    ●是否 JVM 字节码有足够的了解(高级) ●是否 JVM 指令有一定的认识(高级) ●考察 JVM 对象缓存机制的理解以及如何良好地使用。 ●考察 JVM 优化 Java 代码的一些技巧。 ●String 相关类的演进,比如 Java 9 中...
  • 整理CSS文件 去除无用样式

    千次阅读 2011-02-21 13:59:00
    CSS Redundancy Checker 是一个免费的在线应用,可以检查所有的使用某个CSS文件的页面中无用的样式。可以同时检查某一个样式在多个页面中的使用情况。该工具的不足是虽然一次能检查多个HTML页面,但每次只能检查一个...
  • 《深入理解Android 卷III》即将发布,作者是张大伟。此书填补了深入理解Android Framework卷中的一个主要空白,即Android Framework中和UI相关的部分。在一个特别讲究颜值的时代,本书分析了Android 4.2中...
  • 深入理解JVM垃圾回收详解

    千次阅读 热门讨论 2016-02-25 16:19:07
    一、 垃圾收集的意义 ...垃圾收集意味着程序不再需要的对象是"无用信息",这些信息将被丢弃。当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用。事实上,除了释放没用
  • 深入理解MVC

    万次阅读 多人点赞 2018-04-30 17:56:05
    MVC无人不知,可很多程序员MVC的概念的理解似乎有误,换言他们一直在错MVC,尽管即使如此软件也能被写出来,然而软件内部代码的组织方式却是不科学的,这会影响到软件的可维护性、可移植性,代码的可重用性。...
  • 那么这就不难理解了。我们Fundebug每天的数据请求为百万级别,那么日志数据自然非常大。 使用truncate命令,可以将Nginx容器的日志文件“清零”: truncate -s 0 /var/lib/docker/containers/a376aa694b22ee497f6...
  • 深入理解 JVM 垃圾回收机制及其实现原理

    万次阅读 多人点赞 2018-05-31 13:47:17
    永久代的回收主要回收两部分内容:废弃常量和无用的类。永久代空间在 Java SE8 特性中已经被移除。取而代之的是元空间(MetaSpace),因此也不会再出现java.lang.OutOfMemoryError: PermGen error的错误了。 特别...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 96,029
精华内容 38,411
关键字:

对无用之用的理解