Qt学习【2】常用控件

2023-11-17

 

1、信号与槽

信号槽是 Qt 框架引以为豪的机制之一。所谓信号槽,实际就是观察者模式。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调

#include <QApplication>
#include <QPushButton>

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

    QPushButton button("Quit");
    QObject::connect(&button, &QPushButton::clicked, &app, &QApplication::quit);
    button.show();
    return app.exec();
}

connect()函数会创建一种连接,将发送者的信号和接收者的槽函数连接起来。 connect()函数最常用的一般形式:

connect(sender, signal, receiver, slot);

参数:

  1. sender:发出信号的对象
  2. signal:发送对象发出的信号
  3. receiver:接收信号的对象
  4. slot:接收对象在接收到信号之后所需要调用的函数

信号槽要求信号和槽的参数一致,所谓一致,是参数类型一致。

自定义信号和槽

使用connect()可以让我们连接系统提供的信号和槽。但是,Qt 的信号槽机制并不仅仅是使用系统提供的那部分,还会允许我们自己设计自己的信号和槽。

例,创建一个工程,包含两个窗口,一个主窗口和一个子窗口,连接子窗口的自定义信号和主窗口的自定义槽函数。子窗口按键按下发出自定义信号,主窗口接收到信号后,调用主窗口的自定义槽函数。

自定义信号注意点:

  • 信号必须有signals关键字来声明
  • 信号没有返回值,可以有参数
  • 信号就是函数的声明,没有定义
  • 使用: emit mySignal();  调用函数前加emit关键字。emit 是 Qt 对 C++ 的扩展,是一个关键字(其实也是一个宏)。emit 的含义是发出,也就是发出newPaper()信号

lambed表达式

// Lambda表达式
    // C++11新特性, 项目文件 添加:CONFIG += C++11
    // Qt配合信号一起使用
    QPushButton *b4 = new QPushButton(this);
    b4->setText("Lambed表达式");
    b4->move(100,50);
    connect(b4,&QPushButton::clicked,
            // = :把外部所有局部变量、类中的所有成员以值传递方式
            // this:类中所有成员以值传递方式
            // & :把外部所有局部变量, 引用方式
            [=]()
                {
                    qDebug() << "11111" << endl;
                    b4->setText("擦仨4");
                }
            );

 

2、常用控件

// 菜单栏  获取菜单栏
    QMenuBar *mBar = menuBar();
    setMenuBar(mBar);

    //添加菜单
    QMenu *pFileMenu = mBar->addMenu("文件");


    // 添加菜单项
    QAction *pNew = pFileMenu->addAction("新建");
    QAction *pOpen = pFileMenu->addAction("打开");
    QAction *pSave = pFileMenu->addAction("保存");    
    pFileMenu->addSeparator(); // 添加分割线
    QAction *pExit = pFileMenu->addAction("退出");

    QMenu *pHelpMenu = mBar->addMenu("帮助");
    QAction *pHelp = pHelpMenu->addAction("帮助");
    QAction *pAbout = pHelpMenu->addAction("关于");

    connect(pExit,&QAction::triggered,this,&MainWindow::close);

    connect(pSave,&QAction::triggered,
            [=]()
            {
                qDebug() << "保存~~~~~";
            }
            );

    // 工具栏  添加工具栏
    QToolBar *pToolbar = this->addToolBar("工具栏");
    pToolbar->addAction(pNew);
    pToolbar->addAction(pOpen);
    pToolbar->addAction(pSave);

    QPushButton *pButton = new QPushButton(this);
    pButton->setText("退出");
    pToolbar->addWidget(pButton);

    connect(pButton,&QPushButton::clicked,this,&MainWindow::close);

    QToolBar *pToolbar1 = this->addToolBar("工具栏");
    pToolbar1->addAction(pNew);

    // 状态栏  获取状态栏
    QStatusBar *pStatus = this->statusBar();
    QLabel *pLabel = new QLabel(this);
    pLabel->setText("第 1 行 , 第 1 列");
    pStatus->addPermanentWidget(pLabel); // 从右往左添加

    pStatus->addWidget(new QLabel("text",this));
    pStatus->addWidget(new QLabel("edit",this));

    // 核心控件
    QTextEdit *pText = new QTextEdit(this);
    setCentralWidget(pText);

    // 浮动窗口
    QDockWidget *pDock = new QDockWidget(this);
    addDockWidget(Qt::RightDockWidgetArea,pDock);
    QTextEdit *pTextDock = new QTextEdit(this);
    pDock->setWidget(pTextDock);

    // 模态对话框

    connect(pNew,&QAction::triggered,
            [=]()
            {
                QDialog pDial;
                pDial.exec();
                qDebug() << "新建~~~~~";
            }
            );

    // 非模态对话框
    connect(pHelp,&QAction::triggered,
            [=]()
            {
                QDialog *pDial = new QDialog;
                pDial->setAttribute(Qt::WA_DeleteOnClose);
                pDial->show();
                qDebug() << "帮助~~~~~";
            }
            );

    // 标准对话框
    connect(pAbout,&QAction::triggered,
            [=]()
            {
                QMessageBox::about(this,"关于本应用","作为测试使用\n 作者:SZA");
                qDebug() << "关于~~~~~";
            }
            );
    QAction *pQuestion = pHelpMenu->addAction("提问");
    connect(pQuestion,&QAction::triggered,
            [=]()
            {
                int ret = QMessageBox::question(this,"提问","Are u ok?",QMessageBox::Ok,QMessageBox::Yes,QMessageBox::No);
                switch(ret){
                case QMessageBox::Yes:
                    qDebug() << "I'm ok.(answer yes)";
                    break;
                case QMessageBox::No:
                    qDebug() << "I'm not.(answer no)";
                    break;
                case QMessageBox::Ok:
                    qDebug() << "I'm ok.(answer ok)";
                    break;
                default:
                    break;
                }
            }
            );

    //文件对话框
    connect(pOpen,&QAction::triggered,
            [=]()
            {
                QString sPath = QFileDialog::getOpenFileName(this,"open","../",
                                                             "Source (*.cpp *.h);;"
                                                             "Text files (*.txt);;"
                                                             "All(*.*)");
                qDebug() << "打开~~~~~";
                if(sPath != nullptr)
                {
                    qDebug() << sPath;
                }
            }
            );

3、事件

事件(event)是由系统或者 Qt 本身在不同的时刻发出的。当用户按下鼠标、敲下键盘,或者是窗口需要重新绘制的时候,都会发出一个相应的事件。一些事件在对用户操作做出响应时发出,如键盘事件等;另一些事件则是由系统自动发出,如计时器事件。在执行exec()函数之后,程序将进入事件循环来监听应用程序的事件。当事件发生时,Qt 将创建一个事件对象。Qt 中所有事件类都继承于QEvent。在事件对象创建完毕后,Qt 将这个事件对象传递给QObject的event()函数。event()函数并不直接处理事件,而是按照事件对象的类型分派给特定的事件处理函数(event handler)。

在所有组件的父类QWidget中,定义了很多事件处理的回调函数,如

  1. keyPressEvent()
  2. keyReleaseEvent()
  3. mouseDoubleClickEvent()
  4. mouseMoveEvent()
  5. mousePressEvent()
  6. mouseReleaseEvent() 等。

这些函数都是 protected virtual 的,也就是说,我们可以在子类中重新实现这些函数。例如时间事件。如下程序中设置定时器,每过1000ms触发一次事件。

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

public:
    QPushButton *button;

public slots:
    void button_slot();

protected:
    void timerEvent(QTimerEvent *event);

};
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QTimer *timer = new QTimer(this);
    this->startTimer(1000);
}

void MainWindow::timerEvent(QTimerEvent *event)
{
    qDebug() << "timer";
}

4、资源文件的使用

Qt 资源系统是一个跨平台的资源机制,用于将程序运行时所需要的资源以二进制的形式存储于可执行文件内部。如果你的程序需要加载特定的资源(图标、文本翻译等),那么,将其放置在资源文件中,就再也不需要担心这些文件的丢失。也就是说,如果你将资源以资源文件形式存储,它是会编译到可执行文件内部。

使用 Qt Creator 可以很方便地创建资源文件。我们可以在工程上点右键,选择“添加新文件…”,可以在 Qt 分类下找到“Qt 资源文件”:

右侧的编辑区有个“添加”,我们首先需要添加前缀,比如我们将前缀取名为 /。然后选中这个前缀,继续点击添加文件,可以找到我们所需添加的文件。这里,我们选择 pic1.jpg 文件。那么就可以使用 :/pictures/pic1.jpg找到这个文件。

 

5、画图

Qt 的绘图系统允许使用相同的 API 在屏幕和其它打印设备上进行绘制。整个绘图系统基于QPainter,QPainterDevice和QPaintEngine三个类。我们可以把QPainter理解成画笔;把QPaintDevice理解成使用画笔的地方,比如纸张、屏幕等;QPaintEngine提供了画笔(QPainter)在不同的设备上进行绘制的统一的接口,一般不用关心。

绘图设备是指继承QPainterDevice的子类。Qt一共提供了四个这样的类,分别是QPixmap、QBitmap、QImage和 QPicture。其中,

  1. QPixmap专门为图像在屏幕上的显示做了优化
  2. QBitmap是QPixmap的一个子类,它的色深限定为1,可以使用 QPixmap的isQBitmap()函数来确定这个QPixmap是不是一个QBitmap。
  3. QImage专门为图像的像素级访问做了优化。
  4. QPicture则可以记录和重现QPainter的各条命令。
void MainWindow::paintEvent(QPaintEvent *event)
{
    QPixmap pix1(":/pictures/pic1.jpg");

    QPainter painter(this);

    painter.drawPixmap(0,0,pix1);
}

 

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

Qt学习【2】常用控件 的相关文章

  • 来自另一个类的 Qt C++ GUI 调用

    我通过 gui 拖放创建了一个按钮和一个文本浏览器 UI 以及单击按钮功能是在 mainwindow cpp 中创建的 有一个 main cpp 但这是无关紧要的 因为在单击开始按钮之前程序不会启动 include mainwindow h
  • 常量类成员、赋值运算符和 QList

    请确认我是否正确并告诉我是否有更好的解决方案 我了解具有常量成员的对象 例如int const width 无法由编译器隐式创建的合成赋值运算符处理 但是 QList 我想 std list 也是如此 需要一个有效的赋值运算符 因此 当我想
  • 使用嵌入qt的mysql?

    我正在尝试使用嵌入 QT 的 mysql 我已经有一个与 mysqld 链接的 Qt mysql 插件 该插件可以很好地加载嵌入式数据库 但 QT 没有简单的方法来设置 dataDir 等嵌入式选项 我在这里看到 http doc qt i
  • 如何将枚举类传递给 QML?

    我正在学习QML with Qt并在通过时遇到一些麻烦enum class to qml 当我使用信号时int参数 一切正常 代码运行完美 But 麻烦就在这里 如果我使用信号与一些enum class我有参数undefinedqml 信号
  • 包含 Qt 标头的正确方法是什么?

    到目前为止我知道几种方法 includeQt 类 include
  • QMessageBox::about 可以根据标题长度调整大小吗?

    我想创建一个简单的 关于 对话框 但注意到QMessageBox about不会根据标题的长度调整其大小 由于字体较大 标题通常会更长 至少在我的桌面环境中 仅根据内容调整其大小 有没有办法确保对话框足够大以显示所有标题 我当然可以向 ab
  • QFileDialog 作为 TableView 的编辑器:如何获取结果?

    我正在使用一个QFileDialog作为某些专栏的编辑QTableView 这基本上有效 对一些焦点问题取模 请参阅here https stackoverflow com questions 22854242 qfiledialog as
  • cmake 找不到 Qt4

    由于4 8 0已经发布 我重新安装了Qt 现在我也想使用cmake 为了使 cmake 工作 我记得必须添加 mingw bin 文件夹 QtSDK Desktop Qt 4 7 3 到Qt4 7 3中的PATH 所以我猜测在中会有一个类似
  • QT C++ QRegularExpression 多个匹配

    我想使用正则表达式从 QString html 中提取信息 我明确想使用正则表达式 无解析器解决方案 和类Q正则表达式 http qt project org doc qt 5 0 qtcore qregularexpression htm
  • 在信号/槽处理期间删除 QObject

    我知道从槽处理中删除 QObject 可能会使应用程序崩溃 因为它可能有其他排队的事件 因此 我将使用 obj gt deleteLater 而不是使用 delete obj 据我所知 obj 等待处理所有排队的事件 然后 删除 obj Q
  • 在 QtCreator 中调试时如何查看 qDebug 消息

    我正在从 Eclipse CDT 带有 Qt 集成插件 过渡到 QtCreator 2 0 但仍有一件事困扰着我 QtCreator 当我在 QtCreator 中调试时 我在Application output tab直到我停止正在调试的
  • 构建qt程序时未定义的符号:找不到qt_version_tag

    我正在学习Qt5 6 我正在使用 Ubuntu 14 4 当我链接我的程序时 出现以下错误 undefined reference to qt version tag 在 CMakeLists txt 中 link libraries Qt
  • 更改 Qt 中的语言环境

    我尝试使用 QLocale 和 setDefault 函数更改区域设置 但似乎不起作用 以下是使用 C 本地化库和 QLocale 更改语言环境的示例 对于 C 本地化库 它似乎可以工作 但对于 QLocale setDefault 函数调
  • Qt QML MenuItem iconSource不显示

    我有一个非常简单的设置只是为了说明问题 import QtQuick Controls 1 4 import QtQuick Window 2 2 ApplicationWindow visible true width 640 heigh
  • 如何在Qt中更快地读取数据?

    Qt读取数据库比C 慢吗 我想我错过了一些东西 为了比较阅读速度 我在 Qt 中编写了以下内容 QElapsedTimer t t start int count 0 QString cs Driver SQL Server Server
  • PyQt:使用 alpha 通道创建 QPixmap,而不是预乘颜色通道

    我想创建一个 QPixmap 来使用 QPainter 进行绘制 QPixmap 应支持透明度 而不使用预乘颜色通道 目前 我通过创建具有所需尺寸的 QPixmap 并用每个通道 包括 alpha 设置为零的 QColor 填充它来实现此目
  • 使用 QPrinter 打印第 x 页(共 y 页)

    我使用 qt 从 html 代码生成 pdf 文件 QTextDocument document new QTextDocument document gt setHtml htmlContent QPrinter printer QPri
  • Qt:关闭模式对话框关闭程序

    在我的 Qt 程序中 我有 2 个窗口 主窗口和子窗口 在程序中 一次仅显示这些窗口之一 主窗口有一个插槽 用于创建模式对话框 现在 假设子窗口中单击按钮的信号被发送到该插槽 在这种情况下 主窗口隐藏 子窗口可见 对话框显示得很好 但是当对
  • 如何阻止 Qt Creator 将可执行文件放置在“调试”子目录中?

    我正在 Qt Creator 中构建一个项目 虽然我不关心中间 obj 文件去哪里 但重要的是最终的可执行文件应放入 并运行 许多依赖项 DLL 等所在的特定目录中 被发现 因此 在 Qt Creator 中 我选择 Shadow Buil
  • 如何从 ffmpeg 中打开的文件获取流信息?

    我正在尝试使用 ffmpeg 读取视频文件 我有与其旧版本相对应的工作代码 并开始尝试升级到最新的构建版本 将所有这些已弃用的函数替换为其实际的类似函数 但是我遇到了问题 似乎没有检索到任何流 并且视频负载停止在轨道中 这是我正在使用的代码

随机推荐