QT控件学习

信号与槽函数

信号与槽( Signal & Slot)是 Qt 编程的基础,也是 Qt 的一大创新。因 为有了信号与槽的编程机制,在 Qt 中处理界面各个组件的交互操作时变得更加 直观和简单。
信号(Signal)就是在特定情况下被发射的事件,例如 PushButton 最常见 的信号就是鼠标单击时发射的clicked() 信号,一个 ComboBox 最常见的信号 是选择的列表项变化时发射的 CurrentIndexChanged() 信号。

一、实验目的
1.学习 Qt 信号与槽机制的定义。
2.学习如何在项目里定义我们的信号与槽的创建和使用方法。

二、实验内容

  1. 使用 UI 界面添加一个 PushButton 并创建槽函数。
  2. 使用纯代码添加 PushButton 并创建槽函数。

三、实验代码
“mainwindow.h”代码:

#ifndef MAINWINDOW_H 
#define MAINWINDOW_H 

#include <QMainWindow> 
/* 引入 QPushButton */ 
#include <QPushButton> 

namespace Ui { 
class MainWindow; 
 } 
 
 class MainWindow : public QMainWindow 
 { 
 Q_OBJECT 
 
 public: 
 explicit MainWindow(QWidget *parent = 0); 
 ~MainWindow(); 
 
 signals: 
 /* 声明一个信号,只需声明,无需定义 */ 
 void pushButtonTextChanged(); 
private slots: 
 void on_pushButton_clicked(); 
 
 /* 声明一个槽函数 */ 
 void changeButtonText(); 
 /* 声明按钮点击的槽函数 */ 
 void pushButtonClicked(); 
 
 private: 
 Ui::MainWindow *ui; 
 /* 声明一个对象 pushButton */ 
 QPushButton *pushButton; 
 }; 
 
 #endif // MAINWINDOW_H

“mainwindow.cpp”代码:

#include "mainwindow.h" 
#include "ui_mainwindow.h" 

MainWindow::MainWindow(QWidget *parent) : 
QMainWindow(parent), 
ui(new Ui::MainWindow) 
{ 
ui->setupUi(this); 

 /* 设置窗体的宽为 800,高为 480 */ 
 this->resize(800,480); 
 
 /* 实例化 pushButton 对象 */ 
 pushButton = new QPushButton(this); 
 
 /* 调用 setText()方法设定按钮的文本 */ 
 pushButton->setText("我是一个按钮"); 
 
 /* 信号与槽连接 */ 
 connect(pushButton, SIGNAL(clicked()), this, SLOT(pushButtonClicked())); 
 connect(this, SIGNAL(pushButtonTextChanged()), this, SLOT(changeButtonText())); 
 } 
 
 MainWindow::~MainWindow()
 { 
 delete ui; 
 } 
 
 void MainWindow::on_pushButton_clicked() 
 { 
 this->close(); 
 } 
 
 /* 实现按钮点击槽函数 */ 
 void MainWindow::pushButtonClicked() 
 { 
 /* 使用 emit 发送信号 */ 
 emit pushButtonTextChanged(); 
 } 
 
 /* 实现按钮文本改变的槽函数 */ 
 void MainWindow::changeButtonText() 
 { 
 /* 在槽函数里改变按钮的文本 */ 
 pushButton->setText("被点击了!"); 
 }

四、运行结果
初始界面:
在这里插入图片描述
点击按钮后文字发生改变:
在这里插入图片描述

控件

QPushButton

1.QPushButton(按钮):
作用: 创建可点击的按钮,用于触发特定的操作或事件。
使用方法: 创建一个 QPushButton 对象,并设置按钮的文本、图标等属性。
通过连接按钮的信号(例如 clicked())到相应的槽函数,可以在按钮点击时执 行特定的代码。

“mainwindow.h”代码:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPushButton>
/* 引入 QToolButton 类 */
#include <QToolButton>
/* 引入 QToolBar 类 */
#include <QToolBar>
class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private:
    QPushButton pushButton1;
    QPushButton pushButton2;
    /* 声明一个 QToolButton 对象 */
    QToolButton *toolButton;
    /* 声明一个 QToolBar 对象 */
    QToolBar *toolBar;

private slots:
/* 声明对象 pushButton1 的槽函数 */
    void pushButton1_Clicked();
    /* 声明对象 pushButton2 的槽函数 */
    void pushButton2_Clicked();
};


#endif // MAINWINDOW_H

“mainwindow.cpp”代码:

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 设置宽高为 800×480,位置在 0, 0。(0, 0)代表原点,Qt 默认最左上角的点为原
    点 */
    this->setGeometry(0, 0, 800, 480);

    /* 实例化两个按钮对象,并设置其显示文本为窗口皮肤 1 和窗口皮肤 2 */
    //pushButton1 = new QPushButton("窗口皮肤 1", this);
    //pushButton2 = new QPushButton("窗口皮肤 2", this);
    //实例化按钮对象也可以使用栈直接实例化,因为后面信号槽连接需要传入&pushButton1
    //pushButton1 = QPushButton("窗口皮肤 1", this);
    //pushButton2 = QPushButton("窗口皮肤 2", this);
    //需要手动设置父对象才能在窗口中显示
    pushButton1.setParent(this);
    pushButton2.setParent(this);
    pushButton1.setText("窗口皮肤 1");
    pushButton2.setText("窗口皮肤 2");
    /* 设定两个 QPushButton 对象的位置     指针使用->,其他用.    */
     pushButton1.setGeometry(300,200,80,40);
     pushButton2.setGeometry(400,200,80,40);
     /* 信号槽连接,如果用栈实例化的pushbutton需要用&,堆实例化则不需要 */
     connect(&pushButton1, SIGNAL(clicked()), this,SLOT(pushButton1_Clicked()));
     connect(&pushButton2, SIGNAL(clicked()), this,SLOT(pushButton2_Clicked()));
}

MainWindow::~MainWindow()
{

}

/* 槽函数的实现 */
void MainWindow::pushButton1_Clicked()
{
/* 设置主窗口的样式 1 */
this->setStyleSheet("QMainWindow { background-color: rgba(255, 245, 238, 100%); }");
}
 /* 槽函数的实现 */
 void MainWindow::pushButton2_Clicked()
 {
/* 设置主窗口的样式 2 */
     this->setStyleSheet("QMainWindow { background-color: rgba(238, 122, 233, 100%); }");
 }

运行结果
初始界面:
在这里插入图片描述
点击“窗口皮肤 1”后:
在这里插入图片描述
点击“窗口皮肤 2”后:
在这里插入图片描述

QComboBox

2.QComboBox(下拉框):
作用: 创建一个下拉框,用户可以从预定义的选项中选择。
使用方法: 创建一个 QComboBox 对象,然后使用 addItem()方法添加选项。
用户可以通过下拉框选择其中一个选项。通常,可以连接 activated()信号到槽
函数,以便在用户选择某个选项时执行相应的操作。
“mainwindow.h”代码:

#ifndef MAINWINDOW_H 
#define MAINWINDOW_H3. 
#include <QMainWindow> 
/* 引入 QComboBox */ 
#include <QComboBox> 

namespace Ui { 
class MainWindow; 
 } 
 
 class MainWindow : public QMainWindow 
 { 
 Q_OBJECT 
 
 public: 
 explicit MainWindow(QWidget *parent = 0); 
 ~MainWindow(); 
 
 private: 
 Ui::MainWindow *ui; 
 /* 声明一个 QComboBox 对象 */ 
 QComboBox *comboBox; 
 
 private slots: 
 /* 声明 QComboBox 对象的槽函数 */ 
 void comboBoxIndexChanged(int); 
 }; 
 
 #endif // MAINWINDOW_H 

“mainwindow.cpp”代码:

#include "mainwindow.h" 
#include "ui_mainwindow.h" 
/* 引入 QDebug */ 
#include <QDebug> 

MainWindow::MainWindow(QWidget *parent) : 
QMainWindow(parent), 
ui(new Ui::MainWindow) 
{ 
 ui->setupUi(this); 
 
 /* 设置主窗体的显示位置与大小 */ 
 this->setGeometry(0, 0, 800, 480);14. 
 /* 实例化对象 */ 
 comboBox = new QComboBox(this); 
 
 /* 设置 comboBox 的显示位置与大小 */ 
 comboBox->setGeometry(300, 200, 150, 30); 
 
 /* 添加项,我们添加三个省份,作为 comboBox 的三个选项 */ 
 comboBox->addItem("广东(默认)"); 
 comboBox->addItem("湖南"); 
 comboBox->addItem("四川"); 
 
 /* 信号槽连接 */ 
 connect(comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(co 
mboBoxIndexChanged(int))); 
 } 
 
 MainWindow::~MainWindow() 
 { 
 delete ui; 
 } 
 
 void MainWindow::comboBoxIndexChanged(int index) 
 { 
 /* 打印出选择的省份 */ 
 qDebug()<<"您选择的省份是"<< comboBox->itemText(index)<<endl; 
 }

运行结果

初始界面:
在这里插入图片描述
选择四川后:
在这里插入图片描述
控制台输出:
在这里插入图片描述

QLineEdit和QLabel

3.QLineEdit(文本输入框):
作用: 创建一个文本输入框,用于接收用户的文本输入。
使用方法: 创建一个 QLineEdit 对象,用户可以在该文本框中输入文本。
可以通过 text()方法获取文本框中的文本,或者通过 textChanged()信号连接到槽函数,以在文本发生变化时执行特定的操作。

4.QLabel(标签):
作用: 创建一个用于显示文本或图像的标签。
使用方法: 创建一个 QLabel 对象,并设置标签的文本、图像等属性。可以通过 setText()方法设置文本内容,或者通过 setPixmap()方法设置图像。标签通常用于显示静态信息,而不直接响应用户输入。

“mainwindow.h”代码:

#ifndef MAINWINDOW_H 
#define MAINWINDOW_H 

#include <QMainWindow> 
#include <QLineEdit> 
#include <QPushButton> 
#include <QLabel> 

namespace Ui { 
 class MainWindow; 
 } 
 
 class MainWindow : public QMainWindow 
 { 
 Q_OBJECT 
 
 public: 
 explicit MainWindow(QWidget *parent = 0); 
 ~MainWindow(); 
 
 private: 
 Ui::MainWindow *ui; 
 
 /* 声明一个 QLineEdit 对象 */ 
 QLineEdit *lineEdit; 
 
 /* 声明一个 QPushButton 对象 */ 
 QPushButton *pushButton; 
 
 /* 声明一个 QLabel 对象 */31. QLabel *label; 
 
 private slots: 
 /* 声明一个槽函数,响应 pushButton 的 clicked 事件 */ 
 void pushButtonClicked(); 
 }; 
 
 #endif // MAINWINDOW_H 

“mainwindow.cpp”代码:

#include "mainwindow.h" 
#include "ui_mainwindow.h" 

MainWindow::MainWindow(QWidget *parent) : 
QMainWindow(parent), 
ui(new Ui::MainWindow) 
{ 
ui->setupUi(this); 

 this->setGeometry(0, 0, 800, 480); 
 
 lineEdit = new QLineEdit(this); 
 lineEdit->setGeometry(280, 200, 200, 20); 
 
 pushButton = new QPushButton(this); 
 pushButton->setGeometry(500, 200, 50, 20); 
 pushButton->setText("确认"); 
 
 label = new QLabel(this); 
 label->setGeometry(280, 250, 400, 20); 
 label->setText("您输入的内容是:"); 
 
 /* 信号槽连接 */ 
 connect(pushButton,SIGNAL(clicked()), this, SLOT(pushButtonClicked())); 
 } 
 
 MainWindow::~MainWindow() 
 { 
 delete ui; 
 } 
 
 void MainWindow::pushButtonClicked()33. { 
 /* 字符串变量 str */ 
 QString str; 
 
 str = "您输入的内容是:"; 
 str += lineEdit->text(); 
 
 /* 设置 label 里的文本显示内容 */ 
 label->setText(str); 
 
 /* 在点击了确认键之后清空 lineEdit 单行输入框 */ 
 lineEdit->clear(); 
 }

运行结果
初始界面:
在这里插入图片描述
输入test:
在这里插入图片描述
标签显示:
在这里插入图片描述

布局

QHBoxLayout 和 QVBoxLayout

作用: QHBoxLayout(水平布局)和 QVBoxLayout(垂直布局)用于在水平或垂直方向上排列控件。
使用方法: 创建相应的布局对象,使用 addWidget()方法添加控件,最后将布局对象设置为父窗口或容器的布局。

用法示例
“mainwindow.h”代码:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QPushButton>
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
private:
    /* 声明按钮对象数组 ,这是一个指针数组*/
    QPushButton *pushButton[6];
    /* 定义两个 widget,用于容纳排布按钮 */
    QWidget *hWidget;
    QWidget *vWidget;
    /* QHBoxLayout 与 QVBoxLayout 对象 */
    QHBoxLayout *hLayout;
    QVBoxLayout *vLayout;


};

#endif // MAINWINDOW_H

“mainwindow.cpp”代码:

#include "mainwindow.h"
#include <QList>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 设置主窗口的位置与大小 */
    this->setGeometry(0, 0, 800, 480);

    /* 实例化与设置位置大小 */
    hWidget = new QWidget(this);
    hWidget->setGeometry(0, 0, 800, 240);

    vWidget = new QWidget(this);
    vWidget->setGeometry(0, 240, 800, 240);

    hLayout = new QHBoxLayout();
    vLayout = new QVBoxLayout();

    /* QList<T>是 Qt 的一种泛型容器类。
     * 它以链表方式存储一组值,
     * 并能对这组数据进行快速索引
     */
     QList <QString>list;
     /* 将字符串值插入 list */
     list<<"one"<<"two"<<"three"<<"four"<<"five"<<"six";

     /* 用一个循环实例化 6 个按钮 */
     for(int i = 0; i < 6; i++){
     pushButton[i] = new QPushButton();
     pushButton[i]->setText(list[i]);
     if(i < 3) {
        /* 将按钮添加至 hLayout 中 */
        hLayout->addWidget(pushButton[i]);
     } else {
     /* 将按钮添加至 vLayout 中 */
         vLayout->addWidget(pushButton[i]);
         }
         }
        /* 设置间隔为 50 */
       hLayout->setSpacing(50);

       /* hWidget 与 vWidget 的布局设置为 hLayout/vLayout */
       hWidget->setLayout(hLayout);
       vWidget->setLayout(vLayout);
}

MainWindow::~MainWindow()
{

}

控件效果
在这里插入图片描述

QGridLayout网格布局

控件简介
QGridLayout 类提供了布局管理器里的一种以网格(二维)的方式管理界面组件,以按钮组件为例,它们所对应网格的坐标下表,与二维数组类似。QGridLayout继承QLayout。QGridLayout获取可用的空间(通过其父布局或parentWidget())),将其分为行和列,并将其管理的每个小部件放入正确的单元格中。由于网格布局管理器中的组件也是会随着窗口拉伸而发生变化的,所以也是需要设置组件之间的比例系数的,与QBoxLayout 不同的是网格布局管理器还需要分别设置行和列的比例系数。
作用:QGridLayout 用于在表格中排列控件,每个控件占用一个表格单元格。
使用方法: 创建 QGridLayout 对象,使用 addWidget()方法设置控件的行和列索引,将布局对象设置为父窗口或容器的布局。
用法示例
mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QGridLayout>
#include <QPushButton>

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

/* 声明 widget 窗口部件,用于容纳下面 4 个 pushButton 按钮 */
    QWidget *gWidget;

/* 声明 QGridLayout 对象 */
    QGridLayout *gridLayout;

/* 声明 pushButton 按钮数组 */
    QPushButton *pushButton[4];
};

#endif // MAINWINDOW_H

mainwindow.cpp
注意:在没有ui的情况下需要先实例化一个QWidget(this)作为容器承载gridlayout

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    /* 设置位置与大小 */
    this->setGeometry(0, 0, 800, 480);

    /* 实例化 */
    gWidget = new QWidget(this);
     /* 设置 gWidget 居中央 */
     this->setCentralWidget(gWidget);

     gridLayout = new QGridLayout();
     /* QList 链表,字符串类型 */
     QList <QString> list;
     list<<"按钮 1"<<"按钮 2"<<"按钮 3"<<"按钮 4";
     for (int i = 0; i < 4; i++){
     pushButton[i] = new QPushButton();
     pushButton[i]->setText(list[i]);
     /* 设置最小宽度与高度 */
     pushButton[i]->setMinimumSize(100, 30);
     /* 自动调整按钮的大小 */
     pushButton[i]->setSizePolicy(
     QSizePolicy::Expanding,
     QSizePolicy::Expanding
     );
     switch (i) {
     case 0:
     /* 将 pushButton[0]添加至网格的坐标(0,0),下同 */
     gridLayout->addWidget(pushButton[i], 0, 0);
     break;
     case 1:
     gridLayout->addWidget(pushButton[i], 0, 1);
     break;
     case 2:
     gridLayout->addWidget(pushButton[i], 1, 0);
     break;
     case 3:
     gridLayout->addWidget(pushButton[i], 1, 1);
     break;
     default:
     break;
         }
          }
         /* 设置第 0 行与第 1 行的行比例系数 */
         gridLayout->setRowStretch(0, 2);
         gridLayout->setRowStretch(1, 3);

         /* 设置第 0 列与第 1 列的列比例系数 */
         gridLayout->setColumnStretch(0, 1);
         gridLayout->setColumnStretch(1, 3);

         /* 将 gridLayout 设置到 gWidget */
         gWidget->setLayout(gridLayout);
}

MainWindow::~MainWindow()
{

}

控件效果
在这里插入图片描述

QStackedLayout布局

作用:QStackedLayout 用于将一组控件叠放在一起,只显示其中一个控件。
使用方法: 创建 QStackedLayout 对象,使用 addWidget()方法添加多个控件,通过 setCurrentIndex()方法在这些控件之间切换,最后将布局对象设置父窗口或容器的布局。

“mainwindow.h”代码:

#ifndef MAINWINDOWG_H
#define MAINWINDOWG_H

#include <QMainWindow>
#include <QStackedWidget>
#include <QHBoxLayout>
#include <QListWidget>
#include <QLabel>

class MainWindowg : public QMainWindow
{
    Q_OBJECT

public:
    MainWindowg(QWidget *parent = 0);
    ~MainWindowg();
private:
    QWidget *widget;
    QHBoxLayout *hBoxLayout;
    QListWidget *listWidget;
    QStackedWidget *stackedWidget;
    QLabel *label[3];

};

#endif // MAINWINDOWG_H

“mainwindow.cpp”代码:

#include "mainwindowg.h"

MainWindowg::MainWindowg(QWidget *parent)
    : QMainWindow(parent)
{
    this->setGeometry(0, 0, 800, 480);
    widget = new QWidget(this);
    /* 设置居中 */
    this->setCentralWidget(widget);
    /* 垂直布局实例化 */
    hBoxLayout = new QHBoxLayout();

    /* 堆栈部件实例化 */
    stackedWidget = new QStackedWidget();

    /* 列表实例化 */
    listWidget = new QListWidget();

    QList <QString>strListWidgetList;
    strListWidgetList<<"窗口一"<<"窗口二"<<"窗口三";

    listWidget->insertItems(3,strListWidgetList);

    QList <QString>strLabelList;
    strLabelList<<"标签一"<<"标签二"<<"标签三";

    for (int i =0;i<3;i++){
        label[i]=new QLabel;
        label[i]->setText(strLabelList[i]);
        /* 标签对齐方式(居中) */
        label[i]->setAlignment(Qt::AlignCenter);
        stackedWidget->addWidget(label[i]);
    }
    /* 设置列表的最大宽度 */
    listWidget->setMaximumWidth(200);
    /* 添加到水平布局 */
    hBoxLayout->addWidget(listWidget);
    hBoxLayout->addWidget(stackedWidget);
    /* 将 widget 的布局设置成 hboxLayout */
    widget->setLayout(hBoxLayout);
    /* 利用 listWidget 的信号函数 currentRowChanged()与
    57 * 槽函数 setCurrentIndex(),进行信号与槽连接
    58 */
    connect(listWidget, SIGNAL(currentRowChanged(int)),
    stackedWidget, SLOT(setCurrentIndex(int)));

}

MainWindowg::~MainWindowg()
{
}

控件效果
在这里插入图片描述

文件操作和多线程

QFile

QFile 类提供了用于文件的输入和输出的功能。它允许你读取和写入文 件,以及执行一些文件操作,如重命名、删除等。
使用 QFile 类读写文本。
“mainwindow.h”代码:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTextEdit>
#include <QFile>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
private:
 /* 用于读取文件后显示 */
QTextEdit *textEdit;

/* QFile 类型对象 */
QFile file;

/* 水平布局 */
QHBoxLayout *hBoxLayout;
/* 垂直布局 */
QVBoxLayout *vBoxLayout;

/* 水平布局 Widget */
QWidget *hWidget;

/* 垂直布局 Widget */
QWidget *vWidget;

/* 打开文件按钮 */
QPushButton *openPushButton;

/* 关闭文件按钮 */
QPushButton *closePushButton;
private slots:
bool openFile();
void closeFile();
};

#endif // MAINWINDOW_H

“mainwindow.cpp”代码:

#include "mainwindow.h"
#include <QFileDialog>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    this->setGeometry(0, 0, 800, 480);

     /* 布局设置 */
     textEdit = new QTextEdit();
     vBoxLayout = new QVBoxLayout();
     hBoxLayout = new QHBoxLayout();
     vWidget = new QWidget();
     hWidget = new QWidget();
     openPushButton = new QPushButton();
     closePushButton = new QPushButton();
     /* 设置两个按钮的大小 */
     openPushButton->setMinimumHeight(50);
     openPushButton->setMaximumWidth(120);
     closePushButton->setMinimumHeight(50);
     closePushButton->setMaximumWidth(120);
     /* 设置两个按钮的文本 */
     openPushButton->setText("打开文件");
     closePushButton->setText("关闭并保存");
     /* 设置关闭按钮为不可用属性,需要打开文件才设置为可用属性 */
     closePushButton->setEnabled(false);
     /* 水平布局 */
     hBoxLayout->addWidget(openPushButton);
     hBoxLayout->addWidget(closePushButton);
     hWidget->setLayout(hBoxLayout);
     /* 垂直布局 */
     vBoxLayout->addWidget(textEdit);
     vBoxLayout->addWidget(hWidget);
     vWidget->setLayout(vBoxLayout);
     /* 居中 */
     setCentralWidget(vWidget);
     /* 信号槽连接 */
     connect(openPushButton, SIGNAL(clicked()),
     this, SLOT(openFile()));
     connect(closePushButton, SIGNAL(clicked()),
     this, SLOT(closeFile()));
}

MainWindow::~MainWindow()
{

}

bool MainWindow::openFile()
 {
/* 获取文件的路径 */
 QString fileName = QFileDialog::getOpenFileName(this);

/* 指向文件 */
file.setFileName(fileName);

/* 判断文件是否存在 */
 if (!file.exists())
    return false;
/* 以读写的方式打开 */
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    return false;


/* 使用文本流读取文件 */
QTextStream stream(&file);

/* 读取文本到 textEdit */
textEdit->setPlainText(stream.readAll());

/* 设置打开按钮不可用,需要关闭再打开 */
openPushButton->setEnabled(false);

/* 设置关闭按钮为可用属性 */
closePushButton->setEnabled(true);

 /* 关闭文件 */
 file.close();

return true;
 }
void MainWindow::closeFile()
{
/* 检测打开按钮是否可用,不可用时,说明已经打开了文件 */
    if (!openPushButton->isEnabled()) {
/* 获取 textEdit 的文本内容 */
        QString str = textEdit->toPlainText();
/* 以只读的方式打开 */
        if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
            return;
       
        /* 转换为字节数组 */
        QByteArray strBytes = str.toUtf8();

        /* 写入文件 */
        file.write(strBytes, strBytes.length());

        /* 清空 textEdit 的显示内容 */
        textEdit->clear();

        /* 关闭文件 */
        file.close();

        /* 重新设置打开和关闭按钮的属性 */
        openPushButton->setEnabled(true);
        closePushButton->setEnabled(false);
       }
 }

控件效果
初始界面:
在这里插入图片描述

选择mainwindows.cpp文件:
在这里插入图片描述

成功打开后:
在这里插入图片描述

QThread

QThread 类提供了多线程的支持,允许在单独的线程中执行耗时的操作, 而不会阻塞主线程。

使用 QThread 类实现多线程。
“mainwindow.h”代码:


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QThread>
#include <QDebug>
#include <QPushButton>

/* 使用下面声明的 WorkerThread 线程类 */
 class WorkerThread;

 class MainWindow : public QMainWindow
 {
 Q_OBJECT

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

 private:
 /* 在 MainWindow 类里声明对象 */
 WorkerThread *workerThread;

 /* 声明一个按钮,使用此按钮点击后开启线程 */
 QPushButton *pushButton;

 private slots:
 /* 槽函数,用于接收线程发送的信号 */
 void handleResults(const QString &result);

 /* 点击按钮开启线程 */
 void pushButtonClicked();
 };

 /* 新建一个 WorkerThread 类继承于 QThread */
 class WorkerThread : public QThread
 {
 /* 用到信号槽即需要此宏定义 */
 Q_OBJECT

 public:
 WorkerThread(QWidget *parent = nullptr) {
 Q_UNUSED(parent);
 }

 /* 重写 run 方法,继承 QThread 的类,只有 run 方法是在新的线程里 */
 void run() override {
 QString result = "线程开启成功";

 /* 这里写上比较耗时的操作 */
 // ...
 // 延时 2s,把延时 2s 当作耗时操作
 sleep(2);

 /* 发送结果准备好的信号 */
 emit resultReady(result);
 }

 signals:
 /* 声明一个信号,译结果准确好的信号 */
 void resultReady(const QString &s);
 };

 #endif // MAINWINDOW_H

“mainwindow.cpp”代码:

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
/* 设置位置与大小 */
this->setGeometry(0, 0, 800, 480);

/* 对象实例化 */
 pushButton = new QPushButton(this);
 workerThread = new WorkerThread(this);

 /* 按钮设置大小与文本 */
 pushButton->resize(100, 40);
 pushButton->setText("开启线程");

 /* 信号槽连接 */
 connect(workerThread, SIGNAL(resultReady(QString)),
 this, SLOT(handleResults(QString)));
 connect(pushButton, SIGNAL(clicked()),
 this, SLOT(pushButtonClicked()));
 }

 MainWindow::~MainWindow()
 {
 /* 进程退出,注意本例 run()方法没写循环,此方法需要有循环才生效 */
 workerThread->quit();

 /* 阻塞等待 2000ms 检查一次进程是否已经退出 */
 if (workerThread->wait(2000)) {
 qDebug()<<"线程已经结束!"<<endl;
 }
 }

 void MainWindow::handleResults(const QString &result)
 {
 /* 打印出线程发送过来的结果 */
 qDebug()<<result<<endl;
 }

 void MainWindow::pushButtonClicked()
 {
 /* 检查线程是否在运行,如果没有则开始运行 */
 if (!workerThread->isRunning())
 workerThread->start();
 }

控件效果
初始界面:
在这里插入图片描述

点击开启线程的按钮,控制台输出:
在这里插入图片描述

opencv

通过在 Qt 中结合 OpenCV 库完成了图像处理的任务。主要步骤包括:
UI 控件添加:在界面上添加了对比度和亮度的滑动条等控件,方便用户调整图像处理参数。
图片处理:使用 OpenCV 库读取图片数据,并将其转换为适合在 Qt 中显示的格式(RGB888)。实现了图像的对比度和亮度的调整功能。
界面显示:通过 Qt 的界面控件,在程序中实时显示经过处理的图像。

  1. 使用 UI 界面添加需要的控件。
    在这里插入图片描述

  2. 使用代码完成 OpenCV 功能。
    “mainwindow.h”代码:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "opencv2/opencv.hpp"

using namespace cv;

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void initMainWindow(); 
    void imgProc(float contrast, int brightness);
    void imgShow();




private slots:
    void on_contrastVerticalSlider_sliderMoved(int position);

    void on_contrastVerticalSlider_valueChanged(int value);

    void on_brightnessVerticalSlider_sliderMoved(int position);

    void on_brightnessVerticalSlider_valueChanged(int value);

private:
    Ui::MainWindow *ui;
    //全局变量
    Mat myImg;
    QImage myQImg;
    
};

#endif // MAINWINDOW_H

“mainwindow.cpp”代码:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    initMainWindow();
}

void MainWindow::initMainWindow () {

//QString imgPath = "D:\\Qt\\imgproc\\girl~iver.jpg"; //路径中不能含中文字符
QString imgPath = "/home/hugo/img_pro/3.png";//本地路径(图片直接存放在项目目录下)
Mat imgData = imread(imgPath.toLatin1().data()); //读取图片数据
cvtColor(imgData, imgData, COLOR_BGR2RGB); //图片格式转换
myImg = imgData;
myQImg=QImage((const unsigned char*) (imgData.data), imgData.cols, imgData.rows, QImage::Format_RGB888);
imgShow(); //(b)
}

void MainWindow::imgShow () {
ui->viewLabel->setPixmap(QPixmap::fromImage(myQImg.scaled(ui->viewLabel->size(),Qt::KeepAspectRatio))); //在 Qt 界面上显示图片
}

void MainWindow::imgProc(float contrast, int brightness) {
Mat imgSrc = myImg;
Mat imgDst = Mat::zeros (imgSrc.cols,imgSrc.rows,imgSrc.type());
imgSrc.convertTo(imgDst,-1,contrast,brightness);
myQImg = QImage((const unsigned char*) (imgDst.data), imgDst.cols, imgDst.rows, QImage::Format_RGB888);
imgShow();

}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_contrastVerticalSlider_sliderMoved(int position)
{
    imgProc(position / 33.3, 0);
}

void MainWindow::on_contrastVerticalSlider_valueChanged(int value)
{
    imgProc(value / 33.3, 0);
}

void MainWindow::on_brightnessVerticalSlider_sliderMoved(int position)
{
     imgProc(1.0, position);
}

void MainWindow::on_brightnessVerticalSlider_valueChanged(int value)
{
    imgProc(1.0, value);
}

运行结果
初始界面:
在这里插入图片描述

调节对比度:
在这里插入图片描述

同时调亮度:
在这里插入图片描述

  • 14
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值