Qt教程7--一个事件触发另一个

2023-11-11

Qt教程一 —— 第七章:一个事物领导另一个

原文:QT3.1的帮助文档
翻译:zieckey (zieckey@yahoo.com.cn)
修改:zieckey (zieckey@yahoo.com.cn)

这个例子显示了如何使用信号和槽来创建自定义窗口部件,和如何使用更加复杂的方式把它们连接起来。首先,源文件被我们分成几部分并放在放在同一个目录下。

    * t7/lcdrange.h包含LCDRange类定义。
    * t7/lcdrange.cpp包含LCDRange类实现。
    * t7/main.cpp包含MyWidget和main。

/****************************************************************
**
** Definition of LCDRange class, Qt tutorial 7
**
** lcdrange.h
****************************************************************/

#ifndef LCDRANGE_H
#define LCDRANGE_H

#include <qvbox.h>

class QSlider;


class LCDRange : public QVBox
{
    Q_OBJECT
public:
    LCDRange( QWidget *parent=0, const char *name=0 );

    int value() const;

public slots:
    void setValue( int );

signals:
    void valueChanged( int );

private:
    QSlider *slider;
};


#endif // LCDRANGE_H

 

 

/****************************************************************
**
** Implementation of LCDRange class, Qt tutorial 7
**
** lcdrange.cpp
**
****************************************************************/

#include "lcdrange.h"

#include <qslider.h>
#include <qlcdnumber.h>

LCDRange::LCDRange( QWidget *parent, const char *name )
        : QVBox( parent, name )
{
    QLCDNumber *lcd  = new QLCDNumber( 2, this, "lcd"  );
    slider = new QSlider( Horizontal, this, "slider" );
    slider->setRange( 0, 99 );
    slider->setValue( 0 );
    connect( slider, SIGNAL(valueChanged(int)),
      lcd, SLOT(display(int)) );
    connect( slider, SIGNAL(valueChanged(int)),
      SIGNAL(valueChanged(int)) );
}

int LCDRange::value() const
{
    return slider->value();
}

void LCDRange::setValue( int value )
{
    slider->setValue( value );
}

 

/****************************************************************
**
** Qt tutorial 7
**
** main.cpp
**
****************************************************************/

#include <qapplication.h>
#include <qpushbutton.h>
#include <qlcdnumber.h>
#include <qfont.h>
#include <qvbox.h>
#include <qgrid.h>

#include "lcdrange.h"


class MyWidget : public QVBox
{
public:
    MyWidget( QWidget *parent=0, const char *name=0 );
};


MyWidget::MyWidget( QWidget *parent, const char *name )
        : QVBox( parent, name )
{
    QPushButton *quit = new QPushButton( "Quit", this, "quit" );
    quit->setFont( QFont( "Times", 18, QFont::Bold ) );

    connect( quit, SIGNAL(clicked()), qApp, SLOT(quit()) );

    QGrid *grid = new QGrid( 4, this );

    LCDRange *previous = 0;
    for( int r = 0 ; r < 4 ; r++ ) {
 for( int c = 0 ; c < 4 ; c++ ) {
     LCDRange* lr = new LCDRange( grid );
     if ( previous )
  connect( lr, SIGNAL(valueChanged(int)),
    previous, SLOT(setValue(int)) );
     previous = lr;
 }
    }
}


int main( int argc, char **argv )
{
    QApplication a( argc, argv );

    MyWidget w;
    a.setMainWidget( &w );
    w.show();
    return a.exec();
}

 

 

 

 


一行一行地解说

t7/lcdrange.h

这个文件主要利用了第六章的main.cpp,在这里只是说明一下改变了哪些。

    #ifndef LCDRANGE_H
    #define LCDRANGE_H

这里是一个经典的C语句,为了避免出现一个头文件被包含不止一次的情况。如果你没有使用过它,这是开发中的一个很好的习惯。#ifndef需要把这个头文件的全部都包含进去。

    #include <qvbox.h>

qvbox.h被包含了。LCDRange继承了QVBox,所以父类的头文件必须被包含。我们在前几章里面偷了一点懒,我们通过包含其它一些头文件,比如qpushbutton.h,这样就可以间接地包含qwidget.h。

    class QSlider;

这里是另外一个小技巧,但是没有前一个用的多。因为我们在类的界面中不需要QSlider,仅仅是在实现中,我们在头文件中使用一个前置的类声明,并且在.cpp文件中包含一个QSlider的头文件。

这会使编译一个大的项目变得更快,因为当一个头文件改变的时候,很少的文件需要重新编译。它通常可以给大型编译加速两倍或两倍以上。

    class LCDRange : public QVBox
    {
        Q_OBJECT
    public:
        LCDRange( QWidget *parent=0, const char *name=0 );

注意Q_OBJECT。这个宏必须被包含到所有使用信号和/或槽的类。如果你很好奇,它定义了在元对象文件中实现的一些函数。

        int value() const;
    public slots:
        void setValue( int );

    signals:
        void valueChanged( int );

这三个成员函数构成了这个窗口部件和程序中其它组件的接口。直到现在,LCDRange根本没有一个真正的接口。

value()是一个可以访问LCDRange的值的公共函数。setValue()是我们第一个自定义槽,并且valueChanged()是我们第一个自定义信号。

槽必须按通常的方式实现(记住槽也是一个C++成员函数)。信号可以在元对象文件中自动实现,所以我们不用自己动手。信号也遵守C++函数的保护法则(比如,一个类只能发射它自己定义的或者继承来的信号)。

当LCDRange的值发生变化时,valueChanged( int )信号就会被使用——你从这个名字中就可以猜到。

t7/lcdrange.cpp

这个文件主要利用了t6/main.cpp,这个代码来自LCDRange的构造函数。

 QLCDNumber *lcd  = new QLCDNumber( 2, this, "lcd"  );

lcd是一个QLCDNumber,一个可以按像LCD的方式显示数字的窗口部件。这个实例被设置为显示两个数字,并且是this的子窗口部件。它被命名为“lcd”。 
 
    slider = new QSlider( Horizontal, this, "slider" );
    slider->setRange( 0, 99 );
    slider->setValue( 0 );
   
QSlider是一个经典的滑块,用户可以通过在拖动一个东西在一定范围内调节一个整数数值的方式来使用这个窗口部件。这里我们创建了一个水平的滑块,设置它的范围是0~99(包括0和99,参见QSlider::setRange()文档)并且它的初始值是0。
   
    connect( slider, SIGNAL(valueChanged(int)),
      lcd, SLOT(display(int)) );
    connect( slider, SIGNAL(valueChanged(int)),
      SIGNAL(valueChanged(int)) );

第一个connect和你在上一章中看到的一样。第二个是新的,它把滑块的valueChanged()信号和这个对象的valueChanged信号连接起来了。带有三个参数的connect()函数连接到this对象的信号或槽。

是的,这是正确的。信号可以被连接到其它的信号。当第一个信号被发射时,第二个信号也被发射。

让我们来看看当用户操作这个滑块的时候都发生了些什么。滑块看到自己的值发生了改变,并发射了valueChanged()信号。这个信号被连接到QLCDNumber的display()槽和LCDRange的valueChanged()信号。

所以,当这个信号被发射的时候,LCDRange发射它自己的valueChanged()信号。另外,QLCDNumber::display()被调用并显示新的数字。

注意你并没有保证执行的任何顺序——LCDRange::valueChanged()也许在QLCDNumber::display()之前或者之后发射,这是完全任意的。

    int LCDRange::value() const
    {
        return slider->value();
    }

value()的实现是直接了当的,它简单地返回滑块的值。

    void LCDRange::setValue( int value )
    {
        slider->setValue( value );
    }

setValue()的实现是相当直接了当的。注意因为滑块和LCD数字是连接的,设置滑块的值就会自动的改变LCD数字的值。另外,如果滑块的值超过了合法范围,它会自动调节。

t7/main.cpp

        LCDRange *previous = 0;
        for( int r = 0 ; r < 4 ; r++ ) {
            for( int c = 0 ; c < 4 ; c++ ) {
                LCDRange* lr = new LCDRange( grid );
                if ( previous )
                    connect( lr, SIGNAL(valueChanged(int)),
                             previous, SLOT(setValue(int)) );
                previous = lr;
            }
        }

main.cpp中所有的部分都是上一章复制的,除了MyWidget的构造函数。当我们创建16个RCDRange对象时,我们现在使用信号/槽机制连接它们。每一个的valueChanged()信号都和前一个的setValue()槽连接起来了。因为当LCDRange的值发生改变的时候,发射一个valueChanged()信号(惊奇!),我们在这里创建了一个信号和槽的“链”。

编译

为一个多文件的应用程序创建一个makefile和为一个单文件的应用程序创建一个makefile是没有什么不同的。如果你已经把这个例子中的所有文件都保存到它们自己的目录中,你所要做的就是这些:

qmake -project
qmake

第一个命令调用qmake来生成一个.pro(项目)文件。第二个命令根据这个项目文件来生成一个(系统相关的)makefile。你现在可以输入make(或者nmake,如果你使用Visual Studio)。

行为

在开始的时候,这个程序看起来和上一章里的一样。试着操作滑块到右下角……

练习

seven LCDs back to 50. 使用右下角的滑块并设置所有的LCD到50。然后设置通过点击这个滑块的左侧把它设置为40。现在,你可以通过把最后一个调到左边来把前七个LCD设置回50。

点击右下角滑块的滑块的左边。发生了什么?为什么只是正确的行为?

现在你可以进行第八章了。
 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt教程7--一个事件触发另一个 的相关文章

  • 在python中访问超级(父)类变量

    我是Python新手 我尝试使用 super 方法访问子类中的父类变量 但它抛出错误 无参数 使用类名访问类变量是可行的 但我想知道是否可以使用 super 方法访问它们 class Parent object props a str a
  • 调整 QML 图像显示尺寸

    我有一个带有嵌套的 QML 窗口RowLayout 在内排我有两个图像 来源 png这些图像的文件 故意 相当大 当我尝试设置height这些图像上的属性使它们变小 但它们仍然被画得很大 Desired Appearance Actual
  • setContextProperty 和对象的 setProperty 之间的区别

    我现在真的很困惑 有什么区别 QQmlApplicationEngine engine engine rootContext setContextProperty myObject userData and object gt setPro
  • 如何将图标放置到 QLineEdit 上?

    stackoverflow com 网站的右上角有一个带有放大镜头的搜索字段和一个灰色的 搜索 关键字 我想知道是否有可能实现相同的外观QLineEdit 如果是这样那怎么办 QLineEdit lineEdit new QLineEdit
  • Ruby 对象打印为指针

    我正在尝试创建一个类 它有一个带有单个参数的构造函数 当我创建该对象的新实例时 它返回一个指针 class Adder def initialize my num my num my num end end y Adder new 12 p
  • .class 与 .java

    class 文件和 java 文件有什么区别 我正在尝试让我的小程序工作 但目前我只能在 Eclipse 中运行它 还不能嵌入 HTML 谢谢 编辑 那么如何使用 JVM 进行编译呢 class 文件是编译后的 java 文件 java 都
  • 为什么在 C++ 类中的数据成员上使用像 m_ 这样的前缀?

    许多 C 代码使用语法约定来标记数据成员 常见的例子包括 m memberName对于公共成员 在所有使用公共成员的情况下 memberName对于私人会员或所有会员 其他人尝试强制使用this gt member每当使用数据成员时 根据我
  • Qt/c++ 随机字符串生成[重复]

    这个问题在这里已经有答案了 我正在创建一个应用程序 需要生成多个随机字符串 几乎就像一个由一定长度的 ASCII 字符组成的唯一 ID 这些字符混合有大写 小写 数字字符 有没有 Qt 库可以实现这一点 如果没有 在纯 C 中生成多个随机字
  • 如何在 C++ 和 QML 应用程序中使用 qrc?

    我在 Windows7 上用 c qnd Qt Creator QML 编写了 Qt Quick Desktop 应用程序 现在 我必须部署它 并且我需要隐藏 qml 文件和图像 意味着 将它们放入资源等中 我读到有一个很好的方法可以使用
  • 使用 cmake 将两种解决方案合二为一

    我有两个单独的 Visual Studio 2013 解决方案 我想将它们迁移到一个解决方案中 因为第一个解决方案 使用 Qt 充当第二个解决方案的 GUI 最后 我希望有一个结构如下的单一解决方案 Solution All Build P
  • ECMAScript 6 类中的 getter 和 setter 有何用途?

    我对 ECMAScript 6 类中 getter 和 setter 的意义感到困惑 什么目的 下面是我参考的一个例子 class Employee constructor name this name name doWork return
  • QT/QML Android App,点击通知栏时打开应用程序

    我为 Android 应用程序制作了一个 QT 当我单击平板电脑中上面看到的按钮通知栏时 但是 如果单击通知 我的应用程序将打开 聚焦 不知道 并显示黑色窗口 简单来说怎么做呢 我的代码是 package org ays operation
  • Qt:将拖放委托给子级的最佳方式

    我在 QWidget 上使用拖放 我重新实现了 DragEnterEvent dragLeaveEvent dragMoveEvent 和 dropEvent 效果很好 在我的 QWidget 中 我有其他 QWidget 子级 我希望它们
  • QtCreator 调试暂停停在代码而不是汇编处

    如何配置 QtCreator 以便在调试并按下暂停时它会显示当前正在处理的代码 现在显示汇编 无法在任何地方找到有关此问题的答案 我使用的是 Windows 7 我在 Ubuntu 16 04 中使用 Qt Creator 4 2 2 时遇
  • Qt WinRT 应用程序无法访问文件权限被拒绝

    我需要使用 Qt 和 FFMPEG 开发 WinRT 应用程序 我根据指令构建了 WinRT 的 ffmpeghere https github com Microsoft FFmpegInterop我可以将库与我的项目链接起来 现在我需要
  • 构建 makefile 依赖/继承树

    如果我解释得不好或者问了一些明显的问题 我很抱歉 但我是 Linux 内核的新手 而且有点深入 我们有一个嵌入式 Linux 系统 它附带一个 文档非常糟糕的 SDK 其中包含数百个文件夹stuff 大多数文件夹包含rules make m
  • QTextEdit.find() 在 Python 中不起作用

    演示问题的简单代码 usr bin env python import sys from PyQt4 QtCore import QObject SIGNAL from PyQt4 QtGui import QApplication QTe
  • 参考接口创建对象

    引用变量可以声明为类类型或接口类型 如果变量声明为接口类型 则它可以引用实现该接口的任何类的任何对象 根据上面的说法我做了一个理解上的代码 正如上面所说声明为接口类型 它可以引用实现该接口的任何类的任何对象 但在我的代码中显示display
  • JavaScript - 类根据条件扩展

    事情是这样的 我有一个名为 A 的主课 我希望这个班级能够扩展 B 级 class A extends B 但事实上 我希望 B 类在特定条件下扩展 C D 或 E class B extends B1 or class B extends
  • @:(符号冒号)在 Makefile 中意味着什么?

    Makefile 中的以下内容有何作用 rule deps 我在制作手册中似乎找不到这个 它的意思是 不要在输出中回显此命令 所以这条规则是说 执行 shell 命令 并且不回显输出 当然是shell命令 是一个空操作 所以这就是说 什么都

随机推荐

  • c++使用curl库发送https请求

    一 环境win7 64位 vs2010 二 文件准备 2 1文件下载 libcurl 下载页面 http curl haxx se download html 我下载的是https curl haxx se download curl 7
  • angular项目打包发布流程

    1 从git更新代码 运行测试看有没有错误 测试ie兼容性 2 修改配置文件并编译打包代码 修改连接服务器的配置文件 双击 3 拷贝文件到服务器 xshell连接到linux 命令 pwd 查看当然文件目录 ll 列出该文件下所有的文件列表
  • Visual Studio 2019解决右侧工具栏消失

    项目场景 准备打开Visual Studio 2019却发现右侧的工具栏消失了 问题描述 新建项目后发现右侧的解决方案资源管理器消失了 不便于添加源文件书写代码 如图 原因分析 可能是以前在操作中将项目移除或删除等等将窗口删掉了 解决方案
  • 用jquery实现简单的表单验证效果

    看了 锋利的jquery 一书 练习了下期中的一个用jquery写表单验证的例子 效果如图 总结 这是个比较简单的表单验证 主要验证了表单中的用户名和邮箱两个必填选项 表单验证其实质是个不断往下过滤的过程 主要思路
  • selenium自动化录入数据

    将csv或者txt里的数据通过selenium自动录入到网页系统里 输入一个数据操作完后自动输入下一个数据 依次遍历所有的数据 比如百度搜索 有十个词要搜索 输入第一个词搜出结果后再接着输入第二个继续搜 依次遍历十个 求大神赐教 给个思路或
  • 21天打卡挑战学习MySQL——《SQL基础入门》第二周 第四篇

    活动地址 CSDN21天学习挑战赛 一 什么是SQL MySQL是一个关系型数据库管理系统 前世 瑞典MySQLAB公司 今生 属于Oracle旗下产品 MySQL是最好的RDBMS Relational Database Manageme
  • Unity游戏界面点击深色模式,游戏会退出问题的解决方法

    问题 在Unity游戏接入到android平台上时 经常会遇到这样的问题 游戏玩着玩着 点击深色模式 游戏会突然退出 具体情形下图所示 一 点击深色模式游戏退出 二 正常情况 三 解决方法 在AndroidManifest xml里 对继承
  • 【Linux】线程详解之线程概念

    前言 在我们的教材中 对线程给出以下的概念 是进程内部的一个执行分支 在进程的内部运行 属于进程的一部分 比进程更加轻量化 可能有的人看完之后都是懵的 什么叫在进程的内部运行 什么又是执行分支 为什么比进程轻量化 我们就带着这三个问题 重新
  • 2023超细致的性能测试流程,你get了吗?

    性能测试 利用工具模拟大量用户操作 验证系统承受的负载情况 性能测试的目的 找到潜在的性能问题或瓶颈 分析并解决 找出性能变化趋势 为后续扩展系统提供参考 测试监控 基准测试 配置测试 负载测试 稳定性测试 对硬件和中间件进行监控 1 学习
  • ubuntu安装ftp服务器(一般配置)

    ubuntu安装ftp服务器 1 安装vsftpd sudo apt get install vsftpd ubuntu10 10自己装了 这步省略 2 配置vsftpd 2 1 修改vsftpd的配置文件 此类配置文件通常位于 etc 目
  • Mysql建立中英文全文索引(mysql5.7以上)

    一 概念 使用索引是数据库性能优化的必备技能之一 在MySQL数据库中 有四种索引 主键索引 普通索引 唯一索引以及我们这里将要介绍的全文索引 FUNLLTEXT INDEX MySQL全文检索是利用查询关键字和查询列内容之间的相关度进行检
  • innodb存储引擎探究(一)

    mysql 体系结构和存储引擎 数据库 物理操作系统文件或者其他形式的文件 实例 mysql数据库由一个共享内存区和后台进程组成 启动mysql实例时 会读取配置文件 安装以下顺序 mysql体系结构 mysql插件式的一个存储引擎可以根据
  • java.nio.file.NoSuchFileException: /usr/share/elasticsearch/config/jvm.options es启动出错(解决)

    今天重新搭建es的时候出现这个问题 以及给相关的文件夹权限但是还是不可以 这里提供一个解决问题的方法 解决思路 放弃自动挂载 采用手动进行将容器内的文件粘贴出来 问题解决 1 直接运行es docker run d name elastic
  • window编写代码,在ubuntu服务器上面远程训练yolov5

    用途 主要用来在window上面编写python相关代码 使用ubuntu的依赖 编写完成后 在ubuntu上面进行训练 此方法其实就是方便在window写代码而已 因为它的代码都会同步到ubuntu上面的 而且它在window上面的pyc
  • uniapp之scroll-view组件的练习使用 (制作可滑动的菜单)

    今天仔细研究了一下uniapp的scroll view组件使用 顺便就做了一个可滑动的菜单 点击后能够切换样式 欢迎到https www uniapp club thread 57 htm交流学习 其中 还有用到其他知识点有 1 v for
  • React Native_手把手教你做项目(四.上拉加载更多)

    在手机应用上 上拉加载更多的功能是必不可少的 同时 在实际使用的时候 当下拉加载 数据仍未返回时 用户多次重复进行下拉加载的操作 为了不产生额外的垃圾数据 我们需要进行判断 同时为了更好的用户体验 增加数据缓存功能 list js文件 Sa
  • 1096C - Polygon for the Angle-几何-性质

    思路 根 据 几 何 性 质 正 多 边 形 所 有 三 个 点组成的 角 都 是最小角的倍数 然后根据内角公式 可以求出 正多边形 最小角为 多边形内角 n 2 然后 打表发现 180边形最小角为1 最大角 178 所以 只有 179无法
  • 阿里巴巴Java开发规约插件p3c详细教程及使用感受

    作者 13 GitHub https github com ZHENFENG13 版权声明 本文为原创文章 未经允许不得转载 阿里巴巴Java开发手册 在进入正题介绍这款插件之前 首先来谈一下 阿里巴巴Java开发手册 2017年年初 首次
  • R和Python概率分布统计和Python验证独立性和平稳性时间序列

    R概率分布和统计 R 基础知识 汇总统计数据 图形显示 概率基础知识 概率规则 条件概率 后验概率和贝叶斯 可靠性 离散分布介绍 几何分布 概率密度函数 概率密度函数 pdf 定义为 P X x
  • Qt教程7--一个事件触发另一个

    Qt教程一 第七章 一个事物领导另一个 原文 QT3 1的帮助文档翻译 zieckey zieckey yahoo com cn 修改 zieckey zieckey yahoo com cn 这个例子显示了如何使用信号和槽来创建自定义窗口