qt-C++笔记之信号与槽

news2024/11/16 19:44:01

qt-C++笔记之信号与槽

code review!

本文抄自公众号:嵌入式小生

文章目录

  • qt-C++笔记之信号与槽
    • 一.信号
      • 2.1.信号的发出
      • 2.2.信号的处理
    • 二.槽函数
      • 2.1.带有默认参数的信号和槽函数
      • 2.2.使用QObject::connect()将信号连接到槽函数的三种方法
        • 2.2.1.第一种方法:使用函数指针
        • 2.2.2.第二种方法:连接到C++11的lambda
        • 2.2.3.第三种方法:使用QObject::connect()以及信号和槽声明宏。
      • 2.3.信号和槽函数的一些高级用法
      • 2.4.使用disconnect断开信号/槽连接
    • 三.使用Qt与第三方信号和槽函数
    • 四.SIGNAL()和SLOT()是Qt定义的两个宏
    • 五.Qt中QEvent和信号槽的区别——未完,没搞明白,搞明白就补充
    • 六.阿西拜编程——信号与槽部分PPT
    • 七.通过函数名称将信号与槽关联
    • 八.ChatGpt——信号与槽
      • 8.1.一些常见的信号与槽的用法
      • 8.2.this指针
      • 8.3.使用特定的函数命名约定可以自动将信号与槽关联
      • 8.4.一个例程

在这里插入图片描述

一.信号

2.1.信号的发出

由于某种条件到达可能引起了对象改变,其内部状态将发生改变,这时候对象就会发出信号。信号是公共访问函数,可以从任何地方发出,但是建议:【只从定义该信号的类及其子类发出信号】。

在Qt框架下,信号发出分为两种:

1、【每个类预定义的信号】:这些信号何时发出可以通过查看官方文档获知。

2、【自定义的信号】:这些信号的发出由开发人员自行定义。

2.2.信号的处理

当一个信号发出时,连接到它的槽函数通常会立即执行,就像一个普通函数调用一样。在这种情况下,信号和槽函数机制是完全独立于GUI事件循环的,也并不会干扰GUI的事件循环。emit语句之后的代码将在所有槽函数都返回之后才执行。如果使用排队连接(queued connections),情况略有不同,在这种情况下,emit关键字后面的代码将立即继续,槽函数将在后续执行。

如果几个槽函数连接到同一个信号上,当信号发出时,这些槽函数将按照它们连接时的顺序依次执行【这一点很重要】。

信号是由moc工具自动生成,不能在.cpp文件中实现,所以信号永远不能有返回类型(必须使用void关键字定义信号)。

关于信号和槽参数的注意事项:经验表明,如果信号和槽函数不使用特殊类型,那么代码具有极强的可重用性。

下表是使用connect()创建信号和槽函数连接时,可以指定5种不同的连接类型:

序号类型含义
1Qt::AutoConnection如果接收者生活在发出信号的线程中,Qt::DirectConnection被使用。否则,使用Qt::QueuedConnection。连接类型是在信号发出时确定。【这是Qt创建信号和槽函数时的默认连接方式】
2Qt::DirectConnection当信号发出时,槽函数立即被调用。槽函数在发送信号的线程中执行。
3Qt::QueuedConnection当控制返回到接收方线程的事件循环时,将调用槽函数。槽函数在接收方的线程中执行。
4Qt::BlockingQueuedConnection与Qt::QueuedConnection相同,只是在槽函数返回之前线程会阻塞。如果接收方存在于发送信号的线程中,则不能使用此连接,否则应用程序将会死锁。
5Qt::UniqueConnection这是一个标志,可以使用按位OR与上述的连接类型进行组合。当Qt::UniqueConnection被设置时,如果连接已经存在,QObject::connect()将失败(例如,如果相同的信号已经连接到同一对对象的相同槽位)。注:这个标志在Qt 4.6中引入。

二.槽函数

当一个连接到槽函数的信号被发射时,槽函数将被调用。槽函数是普通的C++函数,在实际开发中也可以正常调用;它们唯一的特点是:【信号可以与它们相连接】。

由于槽是普通的成员函数,所以它们在直接调用时遵循普通的C++规则。但是,作为槽函数时,任何组件都可以通过信号连接从而调用它们。

还可以将槽函数定义为虚拟的,这在开发中非常有用。

与回调机制相比,信号和槽函数机制的速度稍微慢一些,这一点对于实际应用程序来说,这种差别并不显著。一般来说,发送一个连接到某些槽函数的信号,比直接调用非虚函数要慢大约10倍。这是定位连接对象、安全地遍历所有连接(即检查后续接收方在发射过程中没有被销毁)以及以函数调用增加的开销。虽然10个非虚函数调用听起来很多,但是它比new操作或delete操作的开销要小得多。一旦在后台执行一个需要new或delete的字符串、向量或列表操作,信号和槽函数的开销只占整个函数调用开销的很小一部分。在槽函数中执行系统调用时也是如此(或间接调用超过十个函数)。因此信号和槽函数机制的简单性和灵活性是值得的,这些开销在实际应用场景下甚至不会注意到。

注意,当与基于Qt的应用程序一起编译时,定义为信号或槽的变量的第三方库可能会导致编译器出现警告和错误。要解决这个问题,使用#undef来定义出错的预处理器符号即可。

2.1.带有默认参数的信号和槽函数

信号和槽可以包含参数,参数可以有默认值。例如:QObject::destroyed():

void destroyed(QObject* = nullptr);

当QObject被删除时,它会发出这个QObject::destroyed()信号。无论我们在哪里有一个悬空引用指向已删除的QObject,都希望捕捉到这个信号,这样就可以清除它。合适的槽参数可以是:

void objectDestroyed(QObject* obj = nullptr);

2.2.使用QObject::connect()将信号连接到槽函数的三种方法

2.2.1.第一种方法:使用函数指针
connect(sender, &QObject::destroyed, this, &MyObject::objectDestroyed);

将QObject::connect()与函数指针一起使用有几个优点。它允许编译器检查信号的参数是否与槽的参数兼容。当然,编译器还可以隐式地转换参数。

2.2.2.第二种方法:连接到C++11的lambda
connect(sender, &QObject::destroyed, this, [=](){ this->m_objects.remove(sender); });

在这种情况下,我们在connect()调用中提供这个上下文。上下文对象提供关于应该在哪个线程中执行接收器的信息。
当发送方或上下文被销毁时,lambda将断开连接。注意:当信号发出时,函数内部使用的所有对象依然是激活的。

2.2.3.第三种方法:使用QObject::connect()以及信号和槽声明宏。

在SIGNAL()和SLOT()宏中包含参数(如果参数有默认值)的规则是:传递给SIGNAL()宏的参数不能少于传递给SLOT()宏的参数。

例如以下代码都是合法的:

connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(Qbject*)));
connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed()));
connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed()));

但是这种是非法的:

connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed(QObject*)));

因为槽函数期望的是一个信号不会发送的QObject。此连接将报告运行时错误。

注意,使用这种方法时,在使用QObject::connect()关联信号和槽函数时,编译器不会自动检查信号和槽函数的参数之间是否匹配。

综上:使用第一种方法 创建信号和槽 在开发中较为常用,也较为合适。

2.3.信号和槽函数的一些高级用法

当需要获取信号发送方的信息时,使用Qt提供QObject::sender()函数,该函数返回一个指向发送信号对象的指针。

Lambda表达式是传递自定义参数到槽的一种方便方式:

connect(action, &QAction::triggered, engine,[=]() { engine->processAction(action->text()); });

2.4.使用disconnect断开信号/槽连接

disconnect()用于断开对象发送器中的信号与对象接收器中的方法的连接。如果连接成功断开,则返回true;否则返回false。

当对信号/槽关联的两方中的任何一个对象进行销毁时,信号/槽连接将被移除。

disconnect()有三种使用方法,如下示例所示:

1、断开所有与对象相连的信号/槽:

disconnect(myObject, nullptr, nullptr, nullptr);

相当于非静态重载函数:

myObject->disconnect();

2、断开所有与特定信号相连的对象:

disconnect(myObject, SIGNAL(mySignal()), nullptr, nullptr);

相当于非静态重载函数:

myObject->disconnect(SIGNAL(mySignal()));

3、断开特定接收对象的连接:

disconnect(myObject, nullptr, myReceiver, nullptr);

相当于非静态重载函数:

myObject->disconnect(myReceiver);

nullptr可以用作通配符,分别表示“任何信号”、“任何接收对象”或“接收对象中的任何槽”。

如下格式的使用示例:

disconnect(发送对象,信号,接收对象,方法)

发送对象不会是nullptr。

如果信号为nullptr,将断开接收对象和槽函数与所有信号的连接。否则只断开指定的信号。

如果接收对象是nullptr,它断开所有关联该信号的连接。否则,只断开与接收对象的槽函数连接。

如果方法是nullptr,它会断开任何连接到接收对象的连接。如果不是,只有命名为方法的槽函数连接将被断开。如果没有接收对象,方法必须为nullptr。即:

disconnect(发送对象,信号,nullptrnullptr

三.使用Qt与第三方信号和槽函数

当第三方库中也有信号/槽函数机制时,这时候又需要使用Qt的信号和槽函数机制。对于这种开发场景,Qt可以在同一个项目中使用这两种机制。需将下面一行添加到qmake项目(.pro)工程配置文件中:

CONFIG += no_keywords
该配置将告诉Qt不要定义moc关键字信号、槽函数和emit,因为这些名称将被第三方库使用(例如Boost)。如果要在使用no_keywords标志下继续使用Qt信号和槽机制,需将源文件中所有的Qt moc关键字替换为对应的Qt宏:Q_SIGNALS(或Q_SIGNAL)、Q_SLOT(或Q_SLOT)和Q_EMIT。

四.SIGNAL()和SLOT()是Qt定义的两个宏

SIGNAL()和SLOT()是Qt定义的两个宏,它们返回其参数的C语言风格的字符串(const char*)。因此,下面关联信号和槽的两个语句是等同的:

connect(button,SIGNAL(clicke()),this,SLOT(showArea()));
connect(button,"clicked()",this,"showArea()");

五.Qt中QEvent和信号槽的区别——未完,没搞明白,搞明白就补充

六.阿西拜编程——信号与槽部分PPT

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

七.通过函数名称将信号与槽关联

在Qt Designer中提供了一个快速关联信号和槽函数的方式:使用『转到槽…』对话框创建选定控件之间的信号和槽函数关联。
在这里插入图片描述

在这里插入图片描述

从上图可知,首先QObject和QWidget下的信号是公共的,QAbstractButton是按钮类独有的,Qt使用该类抽象出了按钮的一些公共操作,并已定义好具体的信号。当选中具体信号后,点击“确定”按钮,QtCreator会自动生成一个槽函数,例如,如果选择了clicked()这个信号,则会在代码中生成如下代码,在头文件生成代码如下:
在这里插入图片描述

本质上,QtCreator生成代码的成员函数的命名是能够被QMetaObject的自动连接工具识别的,在构建过程中,在uic生成的用于描述界面的C++文件中,会出现以下代码:
在这里插入图片描述

因此,通过connectSlotByName()就将名称和槽函数进行了关联,该函数会递归搜索给定对象的所有子对象,并将它们的匹配信号连接到遵循特定格式命名的槽函数,格式如下:

void on_<object name>_<signal name>(<signal parameters>)
  • :对象名称。
  • :信号名称。
  • :传入的参数。

在实际使用过程中,只需要声明和实现一个槽函数,其名称遵循标准约定,就可以将一个控件对象的信号和具体槽函数关联,当然这个过程由QtCreator自动完成。

Qt提供的信号和槽函数的自动连接机制,为开发小部件提供了标准命名约定和显式接口。通过提供实现给定界面的源代码,在设计用户界面时无需再编写代码就可以检查设计是否真正有效了。

总结

基于QtCreator,提供的信号和槽函数的自动连接机制在实际开发中,经常会被使用到,特别是在需要快速验证功能和需求的时候,这种方式比使用connect()关联信号和槽函数的开发效率要快很多。但是,如果界面中同类型控件较多的情况下,就需要注释清楚,不然不好区分具体控件下的功能。

在实际项目开发中,对于自定义的信号,习惯使用connect()进行槽函数的关联。对于具体界面中控件,如果是Qt提供的标准控件,则可以使用信号和槽函数的自动连接机制,以加快开发效率。

八.ChatGpt——信号与槽

8.1.一些常见的信号与槽的用法

Qt是一个强大的C++框架,它提供了多种形式的信号与槽机制,用于在应用程序中管理事件和数据流。以下是一些常见的信号与槽的用法:

  1. 基本信号与槽连接:

    QObject::connect(sender, SIGNAL(mySignal()), receiver, SLOT(mySlot()));
    
  2. 信号与槽连接,传递参数:

    QObject::connect(sender, SIGNAL(mySignal(int, QString)), receiver, SLOT(mySlot(int, QString)));
    
  3. 使用Lambda表达式连接信号与槽:

    QObject::connect(sender, &Sender::mySignal, receiver, [=](int value) {
        // 处理信号
    });
    
  4. 断开信号与槽连接:

    QObject::disconnect(sender, SIGNAL(mySignal()), receiver, SLOT(mySlot()));
    
  5. 使用Qt5新的连接语法:

    QObject::connect(sender, &Sender::mySignal, receiver, &Receiver::mySlot);
    
  6. 使用Qt的QueuedConnection连接信号与槽,实现跨线程通信:

    QObject::connect(sender, &Sender::mySignal, receiver, &Receiver::mySlot, Qt::QueuedConnection);
    
  7. 自定义信号:

    class MyObject : public QObject {
        Q_OBJECT
    
    public:
        void myFunction() {
            // 发射自定义信号
            emit mySignal();
        }
    
    signals:
        void mySignal();
    };
    
  8. 重载信号:

    class MyObject : public QObject {
        Q_OBJECT
    
    public slots:
        void mySlot(int value) {
            // 处理整数参数
        }
    
    signals:
        void mySignal(int value);
    };
    
  9. 信号连接到多个槽函数:

    QObject::connect(sender, SIGNAL(mySignal()), receiver1, SLOT(mySlot1()));
    QObject::connect(sender, SIGNAL(mySignal()), receiver2, SLOT(mySlot2()));
    
  10. 连接同一信号的多个槽函数,指定连接类型:

    QObject::connect(sender, SIGNAL(mySignal()), receiver1, SLOT(mySlot1()), Qt::DirectConnection);
    QObject::connect(sender, SIGNAL(mySignal()), receiver2, SLOT(mySlot2()), Qt::QueuedConnection);
    

这些是Qt中信号与槽的常见用法示例,Qt的信号与槽机制非常灵活,可以适应多种不同的场景和需求。

8.2.this指针

在Qt中,通常可以使用this指针将当前对象(QObject的派生类)连接到信号和槽。以下是一些使用this指针的示例:

  1. 使用this指针将当前对象连接到信号和槽:
QObject::connect(this, SIGNAL(mySignal()), this, SLOT(mySlot()));

这将连接当前对象的mySignal信号到当前对象的mySlot槽函数。

  1. 使用Lambda表达式连接信号和槽,其中this指针也可以使用:
QObject::connect(this, &MyClass::mySignal, this, [this]() {
    // 使用this指针处理信号
});
  1. 自定义信号和槽函数,并在类的方法内连接:
class MyClass : public QObject {
    Q_OBJECT

public slots:
    void mySlot() {
        // 处理槽函数的逻辑
    }

public:
    void connectSignalsAndSlots() {
        QObject::connect(this, SIGNAL(mySignal()), this, SLOT(mySlot()));
    }

signals:
    void mySignal();
};

上述示例中,connectSignalsAndSlots方法连接了当前对象的mySignal信号到当前对象的mySlot槽函数。

使用this指针连接信号与槽是非常常见的,特别是在一个类内部的方法中连接信号与槽,以确保连接正确的对象。但请注意,当断开信号与槽连接时,也需要使用相同的this指针。

8.3.使用特定的函数命名约定可以自动将信号与槽关联

在Qt C++中,使用特定的函数命名约定可以自动将信号与槽关联。这一约定通常用于与Qt Designer或Qt Creator的UI设计器一起工作,以便在UI元素发出信号时,自动生成槽函数。以下是关于这一方式的详细解释:

  1. 函数命名约定
    通常,函数命名约定的格式是:void on_<object name>_<signal name>(<signal parameters>);。这个函数名称中包括了以下部分:

    • on_:前缀,表示这是一个槽函数。
    • <object name>:发送信号的对象的名称,通常是Qt Designer或Qt Creator中为UI元素分配的名称。
    • <signal name>:信号的名称,表示与UI元素关联的信号。
    • <signal parameters>:信号的参数列表,如果信号带有参数的话。
  2. 自动生成槽函数
    当你使用Qt Designer或Qt Creator的UI设计器来创建UI界面时,你可以在设计器中选择一个UI元素(例如按钮、复选框等),然后在属性编辑器中为该元素分配名称并选择要关联的信号。UI设计器会自动创建与该信号关联的槽函数,并使用上述命名约定来命名该函数。

  3. 示例
    假设你在UI设计器中有一个名为pushButton的按钮,并希望在点击按钮时触发一个槽函数。你可以将按钮的clicked信号与槽函数关联,然后Qt会自动为你生成槽函数。槽函数的命名约定如下:

    void on_pushButton_clicked();
    

    当按钮被点击时,这个槽函数会自动被调用。

这种函数命名约定使信号与槽的关联变得更加简单,尤其对于与UI元素的交互非常有用。这样的自动生成槽函数提高了代码的可读性和维护性,因为开发人员可以轻松识别哪些槽函数与UI元素关联。

需要注意的是,这种方式在Qt的UI设计器工具中特别有用,但如果你需要手动创建信号与槽的关联或需要更多的灵活性,还是可以使用QObject::connect来手动连接信号与槽。

8.4.一个例程

以下是一个使用this指针形式的完整Qt C++示例,演示如何创建一个简单的Qt应用程序并实现信号与槽的不同形式。这个示例包括使用this指针连接信号与槽的不同情况:

#include <QCoreApplication>
#include <QObject>
#include <QDebug>

class MyObject : public QObject {
    Q_OBJECT

public slots:
    void slot1() {
        qDebug() << "Slot 1 called";
    }

    void slot2(int value) {
        qDebug() << "Slot 2 called with value: " << value;
    }

signals:
    void signal1();
};

int main(int argc, char *argv[]) {
    QCoreApplication app(argc, argv);

    MyObject obj;

    // 连接信号与槽,使用this指针
    QObject::connect(&obj, SIGNAL(signal1()), &obj, SLOT(slot1()));
    QObject::connect(&obj, SIGNAL(signal1()), &obj, SLOT(slot2(int)));

    // 发射信号
    emit obj.signal1();

    return app.exec();
}

#include "main.moc" // 自动生成的moc文件

在这个示例中,我们创建了一个名为MyObject的自定义QObject派生类,该类包括两个槽函数:slot1slot2,以及一个信号函数signal1。在main函数中,我们创建了一个MyObject对象,并使用this指针将其信号和槽连接在一起。

  • 使用QObject::connect函数,我们将signal1信号连接到slot1slot2槽函数,以便在发射信号时调用这些槽函数。
  • 通过emit关键字,我们触发了signal1信号的发射。

当运行这个应用程序时,它将输出:

Slot 1 called
Slot 2 called with value: 0

这个示例展示了如何使用this指针在同一对象内部连接信号与槽,以及如何传递参数给槽函数。这是Qt中信号与槽机制的一个基本用法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1121541.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

整理MongoDB文档:身份验证

整理MongoDB文档:身份验证 个人博客&#xff0c;求关注。 文章概叙 本文主要讲MongoDB在单机状态下的账户配置。理解了MongoDB的语法&#xff0c;对于如何配置用户权限会知道怎么配置&#xff0c;但是请注意给谁配置什么权限才是最重要的。 最小权限原则 系统的每个程序或者…

【C++编程语言】STL常用算法 算术生成和集合算法

1.算术生成算法概念 算法简介&#xff1a; accumlate 计算容器元素累计总和fill 向容器中添加元素 注意&#xff1a;算术生成算法属于小型算法 使用时包含头文件为#include<numeric> 2.accumulate /*函数原型&#xff1a;int accumulate(iterator beg ,iterator end…

热点不热!如何修复笔记本电脑未连接到移动热点的问题

当你远离常规Wi-Fi时,移动热点是让你的笔记本电脑上网的关键,但当它没有按计划运行时,你会怎么办?以下是Windows笔记本电脑无法连接到移动热点时的几种修复方法。 为什么我的笔记本电脑没有连接到我的热点 由于你的笔记本电脑正试图连接到另一个有限制和可能存在问题的设…

前端学成在线项目详细解析二

12-banner区域-课程表布局 HTML布局 <div class"right"><h3>我的课程表</h3><div class"content">1</div> </div> CSS样式 /* 课程表 */ .banner .right {margin-top: 60px;width: 218px;height: 305px;background-…

STM32F4_照相机

目录 前言 1. BMP编码 2. JPEG编码 前言 我们所要实现的照相机&#xff0c;支持BMP图片格式的照片和JPEG图片格式的照片。 1. BMP编码 BMP文件是由文件头、位图信息头、颜色信息和图形数据四部分构成。 1. BMP文件头&#xff08;14个字节&#xff09;&#xff1a;BMP文件…

在ESP32-Arduino开发中添加其它Arduino库

目录 前言 原理说明 操作步骤 下载Bounce 安装Bounce 将下载的文件夹(压缩包需要解压)移动到components/arduino/libraries路径下&#xff0c;并重命名为Bounce2 查看添加库里所有的源文件位置 在arduino的CMakeList.txt里添加库源文件 使用Bounce 前言 乐鑫官方的es…

HTTP介绍 原理 消息结构 客户端请求 服务器响应 HTTP状态码

一、HTTP介绍二、HTTP工作原理HTTP三点注意事项 三、HTTP消息结构四、客户端请求消息五、服务器响应消息HTTP请求方法 七、HTTP响应头信息八、HTTP状态码&#xff08;HTTP Status Code&#xff09;下面是常见的HTTP状态码&#xff1a;HTTP状态码分类HTTP状态码列表 一、HTTP介绍…

旁注、目录越权、跨库查询、cdn绕过

原理&#xff1a; 搭建网站多IP多端口&#xff0c;更多一个域名多网站&#xff0c;IIS的在属性-高级里面设置主机头设置域名&#xff0c;域名是收费的需要自己买一个 旁注&#xff1a;在同一服务器上有多个站点&#xff0c;要攻击的这个站点假设没有漏洞&#xff0c;可以攻击…

Spark大数据分析与实战笔记(第一章 Scala语言基础-5)

文章目录 每日一句正能量章节概要1.5 Scala的模式匹配与样例类1.5.1 模式匹配字符匹配匹配字符串守卫匹配类型匹配数组、元组、集合 1.5.2 样例类 课外补充偏函数 每日一句正能量 “成功的秘诀&#xff0c;在于对目标的执着追求。”——爱迪生 无论是在工作、学习、还是生活中&…

控制台的设置

目录 win32 API &#xff1a; 什么是API &#xff1a; 控制台&#xff1a; 控制台与VS&#xff1a; 控制台的控制&#xff1a; 控制台窗口设置&#xff1a; 1、mode函数&#xff1a; 2、title 函数&#xff1a; 在C语言中的实现&#xff1a; 控制台的坐标设置&#…

python 之numpy 之随机生成数

文章目录 1. **生成均匀分布的随机浮点数**&#xff1a;2. **生成随机整数**&#xff1a;3. **生成标准正态分布随机数**&#xff1a;4. **生成正态分布随机数**&#xff1a;5. **生成均匀分布的随机浮点数**&#xff1a;6. **生成随机抽样**&#xff1a;7. **设置随机数种子**…

Linux下Samba服务安装及启用全攻略

Linux下Samba服务安装及启用全攻略 前言一、安装SSH Server二、安装Samba Server1.安装net-tool2.建立账号的samba3.windows通过Samba与linux共享文件4.使用远程工具登录Linux 总结 前言 提示&#xff1a;本文详解了在Linux系统下如何安装和启用Samba服务&#xff0c;涵盖了从…

商家收款码手续费太高了

在竞争激烈、各行各业都如此内卷的当下&#xff0c;商家需要不断寻求提高利润的方法。所谓开源节流&#xff0c;既要学会提高利润率&#xff0c;也要学会节省成本&#xff0c;毕竟钱是挣出来的&#xff0c;同时也是省出来的。作为一个经常使用收款工具的商家&#xff0c;很多人…

Ubuntu源码编译samba

概述 本人最近研究samba的源码&#xff0c;但是在源码编译的时候&#xff0c;本以为直接config,make,make install。没想到编译过程中碰到很多麻烦&#xff0c;主要是各种依赖问题。 基于此&#xff0c;本文把samba编译的详细过程记录下来&#xff0c;以供再次研究借鉴。 软件…

Javascript命令模式

Javascript命令模式 1 什么是命令模式2 命令模式的例子—菜单程序3 JavaScript 中的命令模式4 撤销命令5 宏命令 1 什么是命令模式 在一个餐厅中&#xff0c;当客人现场点餐或者打电话订餐时&#xff0c;老板会把客人的需求写在清单上&#xff0c;厨师会按照清单的顺序给客人炒…

qt 多语言版本 QLinguist使用方法

在使用qt开发一款软件时&#xff0c;可能需要考虑显示文本中英文等多语言版本。可以使用qt语言家的方式实现。 步骤&#xff1a; 1、代码中给控件设置文本时&#xff0c;记得带上QObject::tr() 2、工程pro文件中加入 TRANSLATIONS demo2_en.ts 3、Qt creator点击“工具”—“外…

C语言【文件】

目录 概念 文件名 文件的打开和关闭 fopen fclose 输入输出函数 fputc fgetc fputs fgets fprintf fscanf fwrite fread 三种流 scanf和sprintf 结构体转化 ​编辑 文件的随机读写 fseek ftell rewind 文本文件和二进制文件 文件读取结束的判定 文件缓冲…

【试题035】逻辑非!例题

1.题目&#xff1a;下列表达式值为1的是&#xff1f; A. 3 & 4 B. 2 >5 C. ! !8 D. 0 &#xff01; 0 2.分析&#xff1a; 关于A选项&#xff1a; 3的二进制是&#xff1a;0011 4的二进制是&#xff1a;0100 0011 & 0100 00000 关于B选项&#xff1a; …

双势阱模型

双势阱模型 原子钟 传统的原子钟利用氨分子 由于隧道效应&#xff0c;上顶点的氮原子可以贯穿三个氢原子形成的势垒&#xff0c;到达下顶点对体系注入微波能量后&#xff0c;氮原子在上下定点之间振荡&#xff0c;体系的能量在两个稳定态之间交替变换&#xff0c;其振荡频率决…

2023淘宝十一预售今天20点开启!有什么优惠活动我们来一起看一下!

2023双11预售玩法将于今天20点正式开启&#xff01;有神优惠活动和玩法攻略&#xff0c;我&#xff0c;们一起来看一下&#xff01; 今双十一预售有加购赢清空购物车大奖&#xff0c;攒幸运值领红包&#xff0c;限时抢免定金福利&#xff0c;做任务攒幸运值赢免定特权这几大活…