零声QT学习 一

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
	//QApplication a(argc, argv),针对QWidget应用程序,管理和设置Qt程序的运行
	//QGuiApplication a(argc, argv),针对非QWidget应用程序,如QQuick
	//QcoreApplication a(argc, argv),针对无界面的应用程序
    MainWindow w;
	//MainWindow是我们自己定义的类,w是创建的对象
    w.show();
	
    return a.exec();
	//事件循环,QEventLoop::exec(),等待鼠标或键盘等其他的输入
}

快捷键

Ctrl + r:运行项目
Ctrl + b:构建项目
Ctrl + a、Ctrl + i:对齐代码
Ctrl + shift + pageup/pagedown:向上/下移动行代码
F4:头文件/源文件切换

命名规范

文件命名都是小写字母的
类、变量的首字母大写,单词之间首字母大写
除了构造函数和析构函数,成员函数的首字母都是小写的

信号槽

学校通知学生上课
学校:发送者
通知:信号
学生:接受者
上课:槽函数

手写信号槽

MyWindow::MyWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MyWindow)
{
    ui->setupUi(this);
    connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(close()));
	//connect 信号与槽关联
}

实例:学校通知学生上课

School类
School.h

#ifndef SCHOOL_H
#define SCHOOL_H

#include <QObject>
#include <QWidget>

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

signals://QT信号的关键字
    void SendMessages();//声明信号

public slots:
};

#endif // SCHOOL_H

school.cpp

#include "school.h"

School::School(QObject *parent) : QObject(parent)
{
	//信号可以只声明不实现
}

Student类
student.h

#ifndef STUDENT_H
#define STUDENT_H

#include <QObject>

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

signals:

public slots:
    //槽函数,声明后还需定义
    void ClassBegin();
};

#endif // STUDENT_H

student.cpp

#include "student.h"
#include <QDebug>
Student::Student(QObject *parent) : QObject(parent)
{

}

void Student::ClassBegin() //槽函数必须有定义
{
    qDebug()<<"学生开始上课了."<<endl;
}

mywindow.h

#ifndef MYWINDOW_H
#define MYWINDOW_H
#include "school.h"
#include "student.h"

#include <QMainWindow>

namespace Ui {
class MyWindow;
}

class School;
class Student;
//自定义类
class MyWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MyWindow(QWidget *parent = nullptr);
    ~MyWindow();

private:
    Ui::MyWindow *ui;
    School *school;
    Student *student;
};

#endif // MYWINDOW_H

mywindow.cpp

#include "mywindow.h"
#include "ui_mywindow.h"

MyWindow::MyWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MyWindow)
{
    ui->setupUi(this);
    school = new School(this);
    student = new Student(this);
    connect(school,SIGNAL(SendMessages()),student,SLOT(ClassBegin()));//信号连接槽
    connect(school,SIGNAL(SendMessages2()),this,SIGNAL(iconSizeChanged()));
    connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(close()));
    emit school->SendMessages();//学校发送信号
    emit school->SendMessages2();
}

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

总结:信号可以只声明不实现,槽函数必须实现,一个信号可以连接多个槽函数,槽函数安装连接的顺序执行。多个信号可以连接同一个槽

通过代码方式创建界面和按钮

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    pushButton = new QPushButton("YES",this);//YES为按钮文本,this为父对象,显示在父对象的上面
    //pushButton->show();显示按钮,若父对象显示,则按钮也显示
    this->resize(800,600);
    pushButton->setGeometry(50,100,150,50);//以父对象左上角为参考原点

}

Qt对象树

两种设置父对象的方法

  1. 通过构造函数
  2. 通过setParent()函数

Widget

qss文件的使用

先创建资源文件res.qrc,再添加文件style.qss
image
qss文件语言同样式表

加载qss文件

#include "widget.h"
#include <QApplication>
#include <QFile> //必备头文件

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QFile file(":/style.qss");
    if(file.exists()) //判断文件是否存在
    {
        file.open(QFile::ReadOnly);//只读方式打开
        QString stylesheet = QLatin1String(file.readAll());//以字符串的方式保存读取的结果
        qApp->setStyleSheet(stylesheet);//设置全局样式
        file.close();//关闭文件
    }
    Widget w;
    w.show();
    
    return a.exec();
}

pushButton

设计一个动态按钮

QPushButton#pushButton_2 {border-image:url(:/img/1.jpg)}
QPushButton#pushButton_2:hover {border-image:url(:/img/2.jpg)}
QPushButton#pushButton_2:checked {border-image:url(:/img/3.jpg)}
QPushButton#pushButton_2:checked:hover {border-image:url(:/img/4.jpg)}

radioButton

在同一个父类中是互斥的,如果需要取消互斥,则需要选中多个按钮——右键按钮——新建按钮组,使其属于不同的按钮组;也可以设置按钮组为exclusive = false

按钮组

选中多个按钮设置为同一按钮组

checkBox

状态变化槽函数

void Widget::on_checkBox_stateChanged(int arg1)
{
    switch(arg1)
    {
    case Qt::Checked:
        qDebug()<<"checkBox Checked.";
        break;
    case Qt::PartiallyChecked:
        qDebug()<<"checkBox PartiallyChecked.";
        break;
    case Qt::Unchecked:
        qDebug()<<"Unchecked.";
        break;
    }
}

margin&padding

margin:一个控件的边框到另一个控件的边框的距离,属于容器外部距离
padding:自身边框到自身内部另一个容器边框之间的距离,属于容器内距离
image

QWidget
{
background-color:gray;
border-style:solid;
border-width:50px;
border-color:#458B00;
padding-top:50px
}

水平/垂直布局

layoutspacing:每个控件之间的距离
layoutStretch:每个控件的拉伸系数
总窗口跟着布局变化

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setLayout(ui->horizontalLayout);
}

image

对话框

模态对话框:阻塞主界面

#include <QDialog>
    QDialog dialog;
    dialog.setWindowTitle(tr("人脸库加载"));
    dialog.exec();

非模态对话框

注意:1.对话框要创建在堆上 2.由于对话框的特性,可以设置对话框关闭,自动销毁对话框

#include <QDialog>
    QDialog* dialog = new QDialog();
    dialog->setAttribute(Qt::WA_DeleteOnClose);//设置关闭时自动销毁对象
    dialog->setWindowTitle("人脸库加载");
    dialog->show(); 

标准对话框:Qt内置的通用对话框

分类

image

文件对话框

void MainWindow::on_pushButton_clicked() //打开一个文件
{
    QString filename = QFileDialog::getOpenFileName(this,"选择图片","C:/Users/ZJQ/Pictures","Images (*.jpg *.png)");
    if(!filename.isEmpty())
    {
        qDebug()<<filename<<endl;
    }
}

void MainWindow::on_pushButton_2_clicked() //打开多个文件
{
    QStringList filenames = QFileDialog::getOpenFileNames(this,"选择图片","C:/Users/ZJQ/Pictures","Images (*.jpg *.png)");
    for(auto v:filenames)
    {
        qDebug()<<v<<endl;
    }
}

颜色对话框

void MainWindow::on_pushButton_3_clicked()
{
    QPalette pal = ui->plainTextEdit->palette();//获取现有palette
    QColor prv_color = pal.color(QPalette::Text);//读取文字先前颜色
    QColor mycolor = QColorDialog::getColor(prv_color,this,"选择颜色");//打开颜色选择窗口
    if(mycolor.isValid()) 
    {
        pal.setColor(QPalette::Text,mycolor);//设置调色板颜色
        ui->plainTextEdit->setPalette(pal);//设置文字的调色板
    }
}

字体对话框

void MainWindow::on_pushButton_4_clicked()
{
    bool ok;
     QFont font = QFontDialog::getFont(
                     &ok, ui->plainTextEdit->font(), this,"选择字体");
     if (ok) {
         // the user clicked OK and font is set to the font the user selected
         ui->plainTextEdit->setFont(font);
     } else {
         // the user canceled the dialog; font is set to the initial

     }
}

消息对话框

void MainWindow::on_pushButton_5_clicked()
{
    QMessageBox::critical(this,"Error","文件不能为空");
    QMessageBox::warning(this,"Warning","人脸库为空");
    QMessageBox::information(this,"Info","加载完成");
    QMessageBox::StandardButton res =  QMessageBox::question(this,"Question","是否保存?",QMessageBox::Yes|QMessageBox::No|QMessageBox::Help);
    switch(res)
    {
    case QMessageBox::Yes:
        qDebug()<<"Saving"<<endl;
        break;
    case QMessageBox::No:
        qDebug()<<"Cancel"<<endl;
        break;
    case QMessageBox::Help:
        qDebug()<<"Help"<<endl;
        break;
    }
}

输入对话框

void MainWindow::on_pushButton_6_clicked()
{
    bool ok;
    QString name = QInputDialog::getText(this, tr("输入姓名"),
                                         tr("姓名:"), QLineEdit::Normal,
                                         "", &ok);
    if (ok && !name.isEmpty())
        ui->plainTextEdit->setPlainText(name);
}

示例:登录对话框

BoxLayout

widget.cpp

void Widget::Boxlayout()
{
    QLabel *label_username = new QLabel("用户名");
    line_username = new QLineEdit();
    QHBoxLayout *hlayout1 = new QHBoxLayout();
    hlayout1->addWidget(label_username);
    hlayout1->addWidget(line_username);

    QLabel *label_password = new QLabel("密码");
    line_password = new QLineEdit();
    line_password->setEchoMode(QLineEdit::Password);
    QHBoxLayout *hlayout2 = new QHBoxLayout();
    hlayout2->addWidget(label_password);
    hlayout2->addWidget(line_password);
    QPushButton *button_confirm = new QPushButton("确认");
    QPushButton *button_cancel = new QPushButton("取消");
    connect(button_confirm,SIGNAL(clicked()),this,SLOT(login()));
    connect(button_cancel,SIGNAL(clicked()),this,SLOT(close()));
    QHBoxLayout *hlayout3 = new QHBoxLayout();
    hlayout3->addWidget(button_confirm);
    hlayout3->addWidget(button_cancel);
    QVBoxLayout *vlayout = new QVBoxLayout();
    vlayout->addLayout(hlayout1);
    vlayout->addLayout(hlayout2);
    vlayout->addLayout(hlayout3);
    this->setLayout(vlayout);
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class Widget : public QWidget
{
    Q_OBJECT
public:
    explicit Widget(QWidget *parent = nullptr);

signals:

public slots:
    void login();
};

#endif // WIDGET_H

main.cpp

#include "mainwindow.h"
#include <QApplication>
#include <widget.h>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
//    MainWindow w;
//    w.show();
    Widget *widget = new Widget();
    widget->show();
    return a.exec();
}

FormLayout 表格布局

void Widget::Formlayout()
{
    QLabel *label_username = new QLabel("用户名");
    line_username = new QLineEdit();
    QFormLayout *layout = new QFormLayout();
    layout->addRow(label_username,line_username);

    QLabel *label_password = new QLabel("密码");
    line_password = new QLineEdit();
    line_password->setEchoMode(QLineEdit::Password);
    layout->addRow(label_password,line_password);

    QPushButton *button_confirm = new QPushButton("确认");
    QPushButton *button_cancel = new QPushButton("取消");
    connect(button_confirm,SIGNAL(clicked()),this,SLOT(login()));
    connect(button_cancel,SIGNAL(clicked()),this,SLOT(close()));
    layout->addRow(button_confirm,button_cancel);
    layout->setLabelAlignment(Qt::AlignRight);
    this->setLayout(layout);
}

GridLayout 网格布局

void Widget::Gridlayout()
{
    QLabel *label_username = new QLabel("用户名");
    line_username = new QLineEdit();
    QGridLayout *layout = new QGridLayout();
    layout->addWidget(label_username,0,0);
    layout->addWidget(line_username,0,1);

    QLabel *label_password = new QLabel("密码");
    line_password = new QLineEdit();
    line_password->setEchoMode(QLineEdit::Password);
    layout->addWidget(label_password,1,0);
    layout->addWidget(line_password,1,1);
    QPushButton *button_confirm = new QPushButton("确认");
    QPushButton *button_cancel = new QPushButton("取消");
    connect(button_confirm,SIGNAL(clicked()),this,SLOT(login()));
    connect(button_cancel,SIGNAL(clicked()),this,SLOT(close()));
    layout->addWidget(button_confirm,2,0);
    layout->addWidget(button_cancel,2,1);
    layout->setAlignment(Qt::AlignRight);
    this->setLayout(layout);
}

信号和槽

示例:自定义信号

form.h

#ifndef FORM_H
#define FORM_H

#include <QWidget>

namespace Ui {
class Form;
}

class Form : public QWidget
{
    Q_OBJECT

public:
    explicit Form(QWidget *parent = nullptr);
    ~Form();

protected:
    virtual void showEvent(QShowEvent *event);//重载
    virtual void hideEvent(QHideEvent *event);

signals:
    void showSignal();
    void hideSignal();

private:
    Ui::Form *ui;
};

#endif // FORM_H

form.cpp

#include "form.h"
#include "ui_form.h"
#include <QDebug>

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

}

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

//若删除QShowEvent参数,在窗口开关时无法执行该Event函数
void Form::showEvent(QShowEvent *event)
{
    qDebug()<<"---showEvent---";

    emit showSignal();
}

//若删除QHideEvent参数,在窗口开关时无法执行该Event函数
void Form::hideEvent(QHideEvent *event)
{
    qDebug()<<"---hideEvent---";

    emit hideSignal();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <form.h>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    Form *form;
private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

    void on_pushButton_3_clicked();

    void on_pushButton_5_clicked();

    void on_pushButton_4_clicked();

    void on_showSignal();

    void on_hideSignal();

    void on_pushButton_6_clicked();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QColorDialog>
#include <QFontDialog>
#include <QInputDialog>
#include <QDebug>
#include <QAction>
#include <QMenu>
#include <QIcon>
#include <QLabel>
#include <QDockWidget>
#include <QTableWidget>
#include <QSettings>
#include <form.h>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->form = new Form();
    connect(form,&Form::hideSignal,this,&MainWindow::on_hideSignal);
    connect(form,&Form::showSignal,this,&MainWindow::on_showSignal);

}

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

void MainWindow::on_pushButton_clicked()
{
    QString curPath = QDir::currentPath();
    QString path = QFileDialog::getOpenFileName(this,"选择文件或目录",curPath,"所有文件(*.*)");
    if(!path.isEmpty())
    {
        ui->plainTextEdit->setPlainText(path);
        QMessageBox::information(this,"提示","选择完毕",QMessageBox::Ok);
    }
}

void MainWindow::on_pushButton_2_clicked()
{
    QPalette pal = ui->plainTextEdit->palette();
    QColor inicolor = pal.color(QPalette::Text);
    QColor color = QColorDialog::getColor(inicolor,this,"选择颜色");
    if(color.isValid())
    {
        pal.setColor(QPalette::Text,color);
        ui->plainTextEdit->setPalette(pal);
    }
}

void MainWindow::on_pushButton_3_clicked()
{
    bool ok = false;
    QFont font = QFontDialog::getFont(&ok);
    if(ok)
    {
        ui->plainTextEdit->setFont(font);
    }
}

void MainWindow::on_pushButton_5_clicked()
{
    bool ok = false;
    QString input = QInputDialog::getText(this,"请输入姓名","输入姓名",QLineEdit::Normal,"",&ok);
    if(ok && !input.isEmpty())
    {
        qDebug()<<input;
        ui->plainTextEdit->clear();
        ui->plainTextEdit->setPlainText(input);
    }
}

void MainWindow::on_showSignal()
{
    qDebug()<<"on_showSignal";
}

void MainWindow::on_hideSignal()
{
    qDebug()<<"on_hideSignal";
}

void MainWindow::on_pushButton_4_clicked()
{
    form->hide();
}

void MainWindow::on_pushButton_6_clicked()
{
    form->show();
}

定时器与进度条

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTimer>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

    void on_pushButton_3_clicked();

    void on_timer_timeout();

private:
    Ui::Widget *ui;
    QTimer *timer;
    int progress_value;
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    progress_value = 0;
    timer = new QTimer();
    timer->setInterval(20);
    connect(timer,&QTimer::timeout,this,&Widget::on_timer_timeout);
    ui->progressBar->setValue(progress_value);
    ui->progressBar->setRange(0,10);
}

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

void Widget::on_pushButton_clicked()
{
    timer->start();
}

void Widget::on_pushButton_2_clicked()
{
    timer->stop();
}

void Widget::on_pushButton_3_clicked()
{
    timer->stop();
    ui->progressBar->reset();
    progress_value = 0;
    ui->progressBar->setValue(progress_value);
}

void Widget::on_timer_timeout()
{
    ui->progressBar->setValue(progress_value++);
    if(progress_value>=90)
    {
        timer->stop();
    }
}
posted @ 2024-11-11 19:49  安河桥北i  阅读(69)  评论(0)    收藏  举报