侧边栏壁纸
博主头像
Into The Abyss 博主等级

My Life is a Death Race

  • 累计撰写 34 篇文章
  • 累计创建 7 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

QT速通

Administrator
2024-03-18 / 0 评论 / 0 点赞 / 494 阅读 / 0 字
//QApplication a(argc, argv);管理qt程序运行,和设置qt应用程序,针对QWidget应用程序
QApplication a(argc, argv);

//QGuiApplication a(argc, argv);管理qt程序运行,和设置qt应用程序,针对非QWidget应用程序,如QQuick
QGuiApplication a(argc, argv);

//QCoreApplication a(argc, argv);管理qt程序运行,和设置qt应用程序,针对无界面应用程序
QCoreApplication a(argc, argv);

//return a.exec();事件循环,等待鼠标或者键盘等其他的输入
return a.exec();

信号与槽

在 Qt 中,信号与槽(Signals and Slots)是一种用于处理事件和通信的机制。它允许对象之间进行松散耦合的通信,是 Qt 中非常重要的一部分。

signals:qt信号关键字,只声明,不用定义

slots:qt槽函数关键字,声明后还需要定义。且需要添加public/private

class School : public QObject
{
    Q_OBJECT
public:
    explicit School(QObject *parent = nullptr);

signals:
    void sendMessages();
};

class Student : public QObject
{
    Q_OBJECT
public:
    explicit Student(QObject *parent = nullptr);

signals:
public slots:
    void comeBackToClass();
};

void Student::comeBackToClass()
{
    qDebug()<< "学生上课"<<Qt::endl;
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    school = new School(this);
    student = new Student(this);

    connect(school,SIGNAL(sendMessages()),student,SLOT(comeBackToClass()));
    emit school->sendMessages();
}

在 Qt 中,emit 是一个关键字,用于在发射信号时标识信号的发射。当你在 QObject 类中声明了一个信号,并想要发射这个信号时,就需要使用 emit 关键字。

一个信号可以连接多个槽;多个信号也可以连接同一个槽

界面

可以使用ui文件进行图形化编辑

也可以使用代码进行创建,如创建一个pushbutton

pushButton = new QPushButton(this);
pushButton->setText("按钮1");
pushButton->setGeometry(50,50,100,100);
pushButton->setObjectName("codebutton"); //设置ObjectName后,就可以在qss文件中使用设置的名称更改样式

样式表示例

QPushButton {
    border-image: url(:/icons/play.svg);
}

QPushButton:hover {
    border-image: url(:/icons/pause.svg)
}

QPushButton:checked {
    border-image: url(:/icons/pause.svg)
}

QPushButton:checked:hover {
    border-image: url(:/icons/play.svg);
}

也可以使用qss文件进行样式表的配置,使用qss文件时,必须在界面显示之前读取qss文件,下面是一个qss文件加载例子

#include <QFile>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QFile file(":/style.qss");
    if(file.exists()){
        file.open(QIODeviceBase::ReadOnly);
        QString styleSheet = QLatin1String(file.readAll());
        qApp->setStyleSheet(styleSheet);
        file.close();
    }
    MainWindow w;
    w.show();
    return a.exec();
}

qss文件示例

QPushButton#codebutton{background-color: red}
QRadioButton::indicator:unchecked{image:url(:/icons/radiobox-blank.svg)}
QRadioButton::indicator:checked{image:url(:/icons/radiobox-marked.svg)}
QRadioButton#radioButton_6::indicator,QRadioButton#radioButton_7::indicator,QRadioButton#radioButton_8::indicator {
    width:0px;
    height:0px;  /*去掉QRadioButton前面的圆点*/
}

QRadioButton#radioButton_6,QRadioButton#radioButton_7,QRadioButton#radioButton_8 {
    background-color: #FF8080; /* 设置背景颜色为红色 */
    color: white; /* 设置文本颜色为白色 */
    border: 2px solid blue; /* 设置边框为蓝色实线 */
    border-radius: 10px;  /* 圆角效果 */
}

QRadioButton#radioButton_6:checked,QRadioButton#radioButton_7:checked,QRadioButton#radioButton_8:checked {
    background-color: #CDFADB; /* 设置背景颜色为青色 */
}

一些属性

margin:一个控件的边框到另一个控件的边框的距离,属于容器外部的距离

padding:自身边框到自身内部另一个容器边框的距离,属于容器内距离

布局

水平布局、垂直布局、网格布局

spacing:布局中各个组件的间隔

stretch:拉伸因子,布局中每个组件的宽度比例

sizePolicy:窗口拉伸时的空间大小变化策略,

分裂器

分裂器(Splitter)是一个用于分割窗口或布局中的部件的小部件。它允许用户通过拖动分隔条来调整分裂器中的部件的大小,从而改变它们之间的相对大小。分裂器通常用于创建可调整大小的面板布局,例如创建一个可以调整大小的窗口,以显示不同大小的部件或子窗口。

在 Qt 中,用于创建分裂器的类是 QSplitter

  1. orientation:分裂器的方向。可以是 Qt::Horizontal(水平方向)或 Qt::Vertical(垂直方向)。

  2. opaqueResize:为false时,在拖动时会显示一条灰色的线条,在拖动到位并释放鼠标后再显示分割线条。默认为true,实时更新子控件大小。

  3. handleWidth:分隔条的宽度。用于设置或获取分隔条的宽度。

隔离弹簧

隔离弹簧(QSpacerItem)是一种布局部件,用于在布局管理器中创建空白空间或弹簧效果。它通常用于在布局中创建间距或者弹簧效果,以实现对部件的对齐或者调整布局的空白间距。

隔离弹簧可以在水平布局和垂直布局中使用。它允许你控制布局中的部件的相对位置,并调整它们之间的距离。隔离弹簧的大小可以通过设置其大小策略来进行调整。

  1. orientation:隔离弹簧的方向。可以是 Qt::Horizontal(水平方向)或 Qt::Vertical(垂直方向)。

  2. sizeType:弹簧的大小策略。可以设置为 QSizePolicy::Fixed(固定大小)、QSizePolicy::Minimum(最小尺寸)、QSizePolicy::Maximum(最大尺寸)、QSizePolicy::Preferred(首选尺寸)等。

  3. sizeHint:弹簧的尺寸提示。用于设置或获取弹簧的推荐大小。

文件读写

QT中使用QFile进行文件操作,使用前必须先按照需求导入头文件#include <QFile>#include <QFileDialog>

打开文件:使用QFileDialog::getOpenFileName()返回一个字符串,包括了路径+文件名;使用open();方法代开文本

读写文件:使用readall()readline()write()等方法进行文件读写

关闭文件:使用close()关闭

void Widget::on_pushButton_clicked()
{
    QString filename = QFileDialog::getOpenFileName(this,"选择文本","/home/pjw6/downloads");
    qDebug()<<filename<<Qt::endl;

    //设置要打开的文件名
    file.setFileName(filename);

    //打开文件
    if(!file.open(QIODevice::ReadOnly))
    {
        qDebug()<<"文件打开失败!"<<Qt::endl;
    }

    //通过QString的构造函数自动类型转换,将QByteArray转换为QString类型
    ui->textEdit->setPlainText(file.readAll());

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

}


void Widget::on_pushButton_2_clicked()
{
    if(file.fileName().isEmpty())
    {
        return;
    }

    if(!file.open(QIODevice::ReadWrite))
    {
        qDebug()<<"文件打开失败!"<<Qt::endl;
        return;
    }

    //写入文件
    file.write(ui->textEdit->toPlainText().toUtf8());

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

    ui->textEdit->clear();

}

文本流:QTextStream,轻量级数据,int,float,double
数据流:QDataStream,类,对象,与系统平台无关

读写ini

//头文件
#include <QSettings>
			//写ini
    connect(ui->ip_btn,&QPushButton::clicked,[=]{
        QSettings pwrite(QCoreApplication::applicationDirPath() + "\\config.ini",QSettings::IniFormat);
        pwrite.beginGroup("net");
        QString ipvalue = ui->ip_edit->text();
        qDebug()<<ipvalue;
        pwrite.setValue("ip",ipvalue);
        pwrite.endGroup();
    });
    connect(ui->port_btn,&QPushButton::clicked,[=]{
        QSettings pwrite(QCoreApplication::applicationDirPath() + "\\config.ini",QSettings::IniFormat);
        QString portvalue = ui->port_edit->text();
        qDebug()<<portvalue;
        pwrite.beginGroup("net");
        pwrite.setValue("port",portvalue);
        pwrite.endGroup();
    });
			/读ini
    connect(ui->show_btn,&QPushButton::clicked,this,&Widget::readini);

void Widget::readini()
{
    QSettings pread(QCoreApplication::applicationDirPath() + "\\config.ini",QSettings::IniFormat);
    QString ipvalue = pread.value("/net/ip").toString();
    QString portvalue = pread.value("/net/port").toString();
    qDebug()<<"ip:"+ipvalue+" port:"+portvalue;
    ui->label->setText("ip:"+ipvalue+" port:"+portvalue);
}

QPainter

QPainter 是 Qt 中用于在各种设备上进行绘图的类。它提供了许多绘制图形、图像和文本的方法,使开发者可以轻松地创建自定义的绘图效果。QPainter 可以用于在 QWidget、QPixmap、QImage 等画布上进行绘制,从而实现界面的绘制、图像处理、绘制图表等功能。使用前需要导入#include <QPainter>#include <QPainterPath>(按需),并且在相关头文件中添加void paintEvent(QPaintEvent *event) override;

void Widget::paintEvent(QPaintEvent *event)
{
    // this指定绘图对象
    QPainter painter(this);
    //设置抗锯齿
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
    //设置画笔
    QPen pen;
    pen.setWidth(5);
    pen.setColor(QColor("#FF4848"));
    //将画笔传递给painter
    painter.setPen(pen);
    //设置刷子,填充图形
    QBrush brush("#DCFFB7");
    //将刷子传递给painter
    painter.setBrush(brush);
    //画矩形
    painter.drawRect(200,100,100,100);
    //画三角形
    QPolygon polygon;
    polygon.setPoints(3,100,20,200,50,300,100);
    painter.drawPolygon(polygon);
    //画直线
    painter.drawLine(400,400,500,500);
    //画椭圆
    painter.drawEllipse(200,200,100,50);
    //画文字
    QRectF rectf(0,0,200,100);
    painter.drawText(rectf,Qt::AlignCenter,"pjw是我!");
    //画路径
    QPainterPath path;
    path.moveTo(20,80);
    path.lineTo(20,30);
    path.cubicTo(80,0,50,50,80,80);
    painter.drawPath(path);
    //结束绘制
    painter.end();

}

QThread多线程

linux查看进程中的线程ps -mp 进程号

#include <QThread>

class MyThread : public QThread
{
    Q_OBJECT
public:
    MyThread(QWidget *parent = nullptr) {

    }
    ~MyThread(){
        qDebug()<<"线程销毁!!"<<Qt::endl;
    }
    //只有run方法在新的线程中
    void run() override {
        qDebug()<<"线程开启!!"<<Qt::endl;
        sleep(5);
        qDebug()<<"线程关闭!!"<<Qt::endl;
        deleteLater();
    }
};

//在相关的头文件中声明相关变量,如MyThread *mythread;

//一些示例方法
void Widget::on_pushButton_clicked()
{
    MyThread *mythread = new MyThread(this);
    mythread->start();
}


void Widget::on_pushButton_2_clicked()
{
    if(mythread->isFinished()){
        mythread->terminate();
    }
}

QT事件

Qt事件是Qt框架中的核心概念之一,用于处理用户输入、系统事件以及应用程序中的其他信号。Qt事件系统允许应用程序通过事件处理器(event handlers)对各种事件做出响应,从而实现用户界面的交互性和动态性,例如QKeyEvent、QMouseEvent等。

// 头文件声明
#include <QMouseEvent>
void mousePressEvent(QMouseEvent *event) override;
void wheelEvent(QWheelEvent *event) override;
void closeEvent(QCloseEvent *event) override;
void keyPressEvent(QKeyEvent *event) override;

// cpp实现
void MainWindow::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::RightButton){
        qDebug()<<"Qt::RightButton pressed";
    }
    else if(event->button() == Qt::LeftButton){
        qDebug()<<"Qt::LeftButton pressed";
    }
}

void MainWindow::wheelEvent(QWheelEvent *event)
{
    if(event->angleDelta().y()>0){
        qDebug() << "Mouse wheel scrolled up";
    }else if (event->angleDelta().y() < 0) {
        qDebug() << "Mouse wheel scrolled down";
    }
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    qDebug() << "close window";
}

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if(event->modifiers() == (Qt::ControlModifier | Qt::AltModifier) && event->key() == Qt::Key_A){
        qDebug()<<"pressed ctrl+alt+a!";
    }
}

事件过滤示例(linetext只能输入数字)

//头文件
bool eventFilter(QObject *watched, QEvent *event) override;
//属性设置以及安装事件过滤
ui->lineEdit->setAttribute(Qt::WA_InputMethodEnabled,false);
ui->lineEdit->installEventFilter(this);
//实现
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
    if(watched == ui->lineEdit){
        if(event->type() == QEvent::KeyPress){
            QKeyEvent *keyevent = static_cast<QKeyEvent*>(event);
            switch (keyevent->key()) {
            case Qt::Key_0:
            case Qt::Key_1:
            case Qt::Key_2:
            case Qt::Key_3:
            case Qt::Key_4:
            case Qt::Key_5:
            case Qt::Key_6:
            case Qt::Key_7:
            case Qt::Key_8:
            case Qt::Key_9:
            case Qt::Key_Backspace:
                return false;
            default:
                QMessageBox::information(this,"title","please input number!");
                return true;
            }
        }
    }
    return false;
}

QChart

//mychart.h
#ifndef MYCHART_H
#define MYCHART_H

#include <QChart>
#include <QtCharts/QVal/ueAxis>
#include <QtCharts/QSplineSeries>
#include <QtCharts/QChartView>

class QSplineSeries;
class QValueAxis;


class mychart : public QChart
{
    Q_OBJECT
public:
    mychart(QGraphicsItem *parent = nullptr, Qt::WindowFlags wFlags = Qt::WindowFlags());
    ~mychart();

public:
    QSplineSeries *m_spseries;
    QValueAxis *m_paxisx;
    QValueAxis *m_paxisy;
    qreal x;
    qreal y;
};

#endif // MYCHART_H

//mychart.cpp
#include "mychart.h"

mychart::mychart(QGraphicsItem *parent, Qt::WindowFlags wFlags):QChart(parent,wFlags)
{
    m_paxisx = new QValueAxis(this);
    m_paxisy = new QValueAxis(this);
    x = 8;
    y = 1;
    QPen pen(Qt::red);
    pen.setWidth(2);
    m_spseries = new QSplineSeries(this);
    m_spseries->setPen(pen);
    m_spseries->append(x,y);
    addSeries(m_spseries);

    //设置坐标轴位置
    addAxis(m_paxisx,Qt::AlignBottom);
    addAxis(m_paxisy,Qt::AlignLeft);
    m_spseries->attachAxis(m_paxisx);
    m_spseries->attachAxis(m_paxisy);
    //设置刻度数
    m_paxisx->setTickCount(10);
    m_paxisy->setTickCount(8);
    m_paxisx->setRange(0,10);
    m_paxisy->setRange(-5,10);

}

mychart::~mychart()
{

}

//mainwindow.cpp
#include <QRandomGenerator>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_timer = new QTimer(this);
    m_chart = new mychart();

    m_chart->setTitle("实验数据");
    m_chart->legend()->hide();
    m_chart->setAnimationOptions(QChart::AllAnimations);

    QChartView *pview = new QChartView(m_chart);
    ui->verticalLayout->addWidget(pview);

    connect(m_timer,&QTimer::timeout,[=]{
        qreal xvalue = (m_chart->m_paxisx->max()-m_chart->m_paxisx->min())/m_chart->m_paxisx->tickCount();
        m_chart->x += xvalue;
        qreal yvalue = QRandomGenerator::global()->bounded(5);
        m_chart->y = yvalue;
        m_chart->m_spseries->append(m_chart->x,m_chart->y);
        qreal x = m_chart->plotArea().width()/m_chart->m_paxisx->tickCount();
        m_chart->scroll(x,0);
    });
    connect(ui->start_btn,&QPushButton::clicked,[=]{
        m_timer->start(500);
    });
    connect(ui->stop_btn,&QPushButton::clicked,[=]{
        m_timer->stop();
    });
}

程序启动界面

//头文件
#include <QSplashScreen>
#include <QDateTime>

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

    //设置文字显示位置
    Qt::Alignment br = Qt::AlignBottom | Qt::AlignRight;
    QString path = ".\\test.png";

    //设置启动画面
    QSplashScreen *pSS = new QSplashScreen(QPixmap(path));
    pSS->show();

    //显示文字信息
    pSS->showMessage("程序正在初始化!!", Qt::AlignCenter ,Qt::white);

    a.processEvents();

    //启动画面做延时
    QDateTime dt = QDateTime::currentDateTime();
    QDateTime now;
    do{
        now = QDateTime::currentDateTime();
    }while (dt.secsTo(now) <= 5);

    MainWindow w;
    w.show();
    //关闭启动窗口
    pSS->finish(&w);
    delete pSS;
    pSS = NULL;
    return a.exec();
}

添加图标

将要设置的图片资源添加到项目的qrc文件中
setWindowIcon(QIcon(":/icon/favicon.ico"));

启动外部进程

#include <QProcess>

connect(ui->pushButton,&QPushButton::clicked,[=]{
        QProcess *process = new QProcess(this);
        process->start("D:\\app\\VLC\\vlc.exe");
        bool isok = process->waitForStarted(3000);
        if(isok){
            qDebug()<<"succeed";
        }else {
            qDebug()<<"fail";
        }
    });

设置系统托盘

#include <QMenu>

ptray = new QSystemTrayIcon(QIcon(":/icon/sy1lm8.png"));
ptray->setToolTip("qt托盘");
createrightmenu();
ptray->show();
connect(ptray,&QSystemTrayIcon::activated,[=](QSystemTrayIcon::ActivationReason reason){
    //左键托盘显示主界面
    if(reason == QSystemTrayIcon::Trigger){
        this->show();
        this->setWindowState(Qt::WindowActive);
        this->activateWindow();
    }
});

void Widget::createrightmenu()  //右键托盘显示菜单
{
    QMenu *pmenu = new QMenu(this);
    QAction *p1 = new QAction("显示主界面",this);
    QAction *p2 = new QAction("退出",this);
    pmenu->addAction(p1);
    pmenu->addSeparator();
    pmenu->addAction(p2);
    ptray->setContextMenu(pmenu);
    connect(p1,&QAction::triggered,[=]{
        this->show();
        this->setWindowState(Qt::WindowActive);
        this->activateWindow();
    });
    connect(p2,&QAction::triggered,[=]{
        exit(0);
    });
}
0

评论区