Qt学习

来源:互联网 发布:释放443端口 仍被占用 编辑:程序博客网 时间:2024/04/27 20:59

概念

Qt create

Qt create 是一个轻量级的集成开发环境,vs下的Qt设置utf-8显示#pragma once#pragma execution_character_set("utf-8")

Qt

Qt是真正指的是Qt库

GUI

G 图形 U应用   I接口

qmake

SOURCES  表示源文件HEADERS  表示头文件INCLUDEPATH 头文件路径LIBS += -L 库 LIBS += -l 路径 CONFIG +=  c++11 console 程序配置TARGET = xxx.exe  目标文件TEMPLATE = app 模板       lib 模板       dll 模板       vcapp 建立一个应用程序的visual studio文件       vclib 建立一个库的visual studio文件FORMS  添加ui文件DEFINES 定义宏所有继承自QOject 的对象,都可以通过QOject自动释放对象,但是没有继承的对象需要手动释放,否则会造成内存泄漏

内存管理

deleteLater() 在消息处理完成之后释放该对象

Qt 基础

基础

#include <QApplication>一个QT 应用只能创建一个对象,是一个单例,用于消息的控制流以及应用的设置#include <QWidget>QWidget 在Qt 属于最基本的窗口类,所有的其他的窗口有它派生而来QWidget 继承自QObject ,QObject 属于Qt中最基本的类#include <QPushButton> 按钮类控件透明styleSheet("border:0px solid #76bbff;background-color: rgba(255, 255, 255, 0%);color:#A0A0A0")

常用API

杂项

resize 窗口大小

pos 窗口起始坐标

setParent 设置父窗口

move 移动到目标坐标

QObject::connect(发送对象,SIGNAL(信号槽),处理消息对象,SLOT(执行事件))

exec 消息循环,消息泵

setText 设置按钮标题

deleteLater 在对象消息处理完成之后释放该对象

width 对象宽度

height 对象高度

setMinimunWidth 设置最小宽度

setMaximunWidth 设置最大宽度

setMinimunHeight 设置最小高度

setMaximunHeight 设置最大高度

获取屏幕大小
 不包括任务栏int x = GetSystemMetrics(SM_CXFULLSCREEN); int y = GetSystemMetrics(SM_CYFULLSCREEN);包含任务栏int x = GetSystemMetrics(SM_CXSCREEN); int y = GetSystemMetrics(SM_CYSCREEN);

QApplication

qApp 与 QApplication::instance() 等价qApp  有quit退出 函数

布局管理器

横向/竖向 布局管理器 QHBoxLayout

setLayout(QHBoxLayout()) 为窗口添加布局管理器

addStretch 增加伸缩量,弹簧

addWidget 添加对象到布局管理器,会把该对象的父窗口设置为Layout的父窗口

addSpacing 设置对象间隙

setMargin 设置边界间隙

size 窗口推荐大小

sizeHint 窗口实际大小,如果没有使用布局管理器,不可以使用该方法

表格布局管理器 QGridLayout

addWidget(object,row,col,横范围,列范围) 坐标以格子为步长

管理器可以互相嵌套

addLayout(object,row,col)

QTextEdit/ QLabel

QTextEdit

toPlainText()  获取编辑框的文本

QLineEdit

setText 设置文本Text 获取文本setEchoMode(QLineEdit::EchoMode::Password) 设置密码形式接收 设置LineEdit 只接受int类型的数据                        0 起始值; 100 最大值;QIntValidator*valid = new QIntValidator(0,100,this);QLineEdit lineEdit;lineEdit.setValidator(valid);

QLabel

setText 设置文本

信号与槽

多个信号可以跟同一个槽函数链接

一个信号可以跟多个槽函数链接

槽函数参数与信号参数不一致,但不推荐使用,会发生数据丢失等未知BUG

disconnect(object,SIGNAL(),object,SLOT()) 断开信号链接

槽函数

步骤:

1 继承QObject

2 加上Q_OBJECT 宏

3 public slots: 指明槽函数的声明区域

调用槽函数 emit func();

强转的目的是明确调用那个重载函数connect(信号产生对象,static_cast<void(QPushButton::*)(int)>&QPushButton::clicked,()[]{});connect(信号产生对象,SIGNAL(信号),调用者,SLOT(调用函数));

信号

步骤:

1 继承QObject

2 加上Q_OBJECT宏

3 signals 指明信号声明区域

4 信号只声明不定义,信号没有返回值,可以有参数

MainWindow

菜单栏

QMenuBar 菜单栏,一个窗口只有一个菜单栏

QMenuBar *menuBar = QWidget::menuBar()

QMenu 菜单

QMenu *menu = new QMenu("file(&f)",menuBar);   f 表示快捷方式,父窗口,将其管理托管到QMenuBar里面menuBar->addMenu(menu);在菜单添加并显示菜单menu->addMenu(QIcon("资源"),"name");添加子菜单,添加图标menuFile_->showFullScreen();// 全屏menuFile_->showNormal();// 最小化menuFile_->showTearOffMenu(QPoint(100,100));// 分离布局

Action 动作

menu->addAction("open file");  在菜单里面添加动作QIcon 图标menu->addAction(QIcon("资源路径"),"动作名字",调用者,SLOT(槽函数),QKeySquence("快捷方式(ctrl+s)"));menu->addActions(new QList<QAction*>(new QAction(""))); 根据链表增加多个子菜单,menu->addSeparator()  增加修饰线条menu->text() 获取子菜单名字ACtion::setCheckable(true);设置动作状态

工具栏

this->addToolBar(Qt::RightToolBarArea,new QToolBar("tool",this));在窗口左边添加工具栏QToolBar::addAction(QIcon("资源"),"名字");为工具栏添加图标,名字

状态栏

一个窗口只有一个状态栏

QStatusBar*stb = this->statusBar();stb->showMessage("消息",时间); 显示状态,显示以毫秒为单位计算stb->clearMessage(); 清除状态

设置中央窗口

QTextEdit *tEdit = new QTextEdit;文本编辑框this->setCentralWidget(tEdit);在主窗口添加文本编辑框tEdit->setReadOnly(true);只读tEdit->toPlainText(); 获取纯文本tEdit_->document()->isModified();是否被修改

停靠窗口/浮动窗口

QDockWidget *dockW = new QDockWidget; 窗口this->addDockWidget(Qt::TopDockWidgetArea,dockW);

Dialog

QDialog

QWidget 共享一个消息泵

QDialog 独享使用一个消息泵

普通窗口与模态窗口的区别

普通窗口

1 指定父窗口的时候,嵌套在父窗口上显示2 不指定父窗口,调用show函数,则以顶级方式显示3 指定父窗口,调用show函数,嵌套在父窗口上显示4 不能以模态窗口方式显示

模态窗口

1 指定父窗口,不调用show,不显示2 不指定父窗口,调用show,以顶级窗口显示3 指定父窗口,调用show,以顶级窗口显示4 可以以模态窗口的方式来显示,调用exec()截取消息

使用

在槽函数内部调用QDialog *pDialog = new QDialog(this);pDialog->done(3);设置自定义返回值pDialog->accept() 设置接受返回值pDialog->rejected() 设置拒接返回值pDialog->exec(); 开始截获消息重写accept(); 实现消息截取,需要手动调用父类的accept();

FontDialog

QFontDatabase base;系统字体数据库QStringList strlist = base.families();  当前系统已安装的字体this->font(); 当前窗口使用字体类型QFont font;font.setFamily("楷体"); 设置字体类型font.setPointSize(100); 设置字体大小this->setFont(font); 改变当前窗口下子窗口的字体类型bool ok;QFont font = QFontDialog::getFont(&ok,this);  使用系统模态窗口进行编辑this->setFont(font); 设置字体

FileDialog

打开文件Dialog
?                                   父窗口 标题 默认打开路径  需要过滤的文件QString ret = QFileDialog::getOpenFileName(this,"open",fileName,"Image (\*.png)\n allfile (\*.\*)");多个文件同时打开QStringList ret = QFileDialog::getOpenFileName(this,"open",fileName,"Image (\*.png)\n allfile (\*.\*)");
保存文件Dialog
QString fileName = QFileDialog::getSaveFileName(this,"save",fileName,"all (\*.png)");QFileInfo(fileName).fileName() ; 文件名QFileInfo(fileName).filePath(); 文件路径

palette

基本操作

QPalette palette = this->palette(); 获取系统调色板的属性palette.setColor(QPalette::Background,backgroundColor); 在调色板上修改窗口的背景属性 // palette.setColor(QPalette::Background,QColor("#FF0000")); 在调色板上修改窗口的背景属性,数字法this->setPalette(palette); 将修改过调色板更新到当前窗口

QColorDialog

使用模态对话框调整调色板的属性

                                            默认选中的颜色     调用者     Qcolor color = QColorDialog::getColor(QColor(Qt::red ),this,窗口标题);    color.isValid(); 是否点击了确定  // 获取系统调色板    QPalette palette = this->palette();    // 为调色板设置颜色    //palette.setColor(QPalette::Background,backgroudColor);    // 文本颜色    //palette.setColor(QPalette::Text,color);    // 按钮颜色    palette.setColor(QPalette::ButtonText,color);    // 设置调色板    this->setPalette(palette);

massageBox

警告消息框

  // 父窗口  标题 提示  点击按钮...  int ret = QMessageBox::warning(this,"warning","no file",QMessageBox::Ok,QMessageBox::Cancel,QMessageBox::Yes);  QMessageBox::Ok;  QMessageBox::Cancel;  QMessageBox::Yes;

#### 错误消息框

QMessageBox::critical(this,"error","known error is critical");

#### 提示消息框

QMessageBox::information(this,"message","Qt 5.9.1");

Qt 数据结构

QString

    QString str1("jk");    QString str2("bk");    QString str3("ck");    QString str4("fk");    bool flag = true;    // 最小替换符号,为起始符号    // 最大的替换符号如果比参数总数大,会自动寻找最后面的参数替换    // 参数替换,如果%1 后面的数字是1,如何处理    QString str = QString("%11 %9 %3 %2 %4").arg(str1).            arg(str2).arg(str3).arg(flag).arg(str4);      str = QString::asprintf("%s %s %s %d %d",str1.toStdString().c_str(),str2.toStdString().c_str(),str3.toStdString().c_str(),flag,num);

QByteArray

QByteArray byte("text",10);byte.toStdString().c_str()  char *str = "\x2 \x44 \x3"; // 转化16进制 qDebug() << QByteArray(str).toHex() <<QByteArray(str).toHex().size() << endl;  // 用静态函数转化    qDebug() << QByteArray::fromHex(QByteArray(str).toHex()) << endl;    // QString 与QByteArray 互转    QString str1("123_中文");    // utf - 8 编码 解析    QByteArray arr(str1.toUtf8());    // unicode编码    str1.unicode();    // 只根据asccl 码解析    auto sarr = str1.toLatin1();    qDebug() << sarr << endl;    // 转化utf 8    auto utf8 = str1.toUtf8();    qDebug() << utf8.toStdString().c_str() << endl;    // 当前系统所使用的编码    // 转化本地编码    auto load = str1.toLocal8Bit();    qDebug() << load << endl;      // QByteArray 转化QString    QByteArray byte ("123abc");    QString str2 = byte;    qDebug() << str2 << endl;    // QString 可以处理编码    // QByreArray 不可以处理编码,纯数据

QFile

  QFile file("file.text");    //        读                    写             文本方式          追加    //QIODevice::ReadOnly|QIODevice::WriteOnly|QIODevice::Text|QIODevice::Append;    if(file.open(QIODevice::ReadOnly|QIODevice::WriteOnly|QIODevice::Text|QIODevice::Append))    {        //写入        //file.write("你好");        // 读取        //file.readLine();        //file.read();    }    file.open(QIODevice::ReadOnly);    // 使用流绑定    QDataStream qDs;    qDs.setDevice(&file);    //qDs<<"12 helloworld";    QString str;    char ar[100];    file.readLine(ar,100);    //qDs >> str ;    qDebug() << ar << endl;    //qDebug() << str << endl;    file.close();

QEvent

QEvent

所有消息的集合

void event(QEvent* e)e->type()   获取消息的类型QEvent::MouseButtonPress  鼠标单击事件QEvent::MouseButtonDblClick 鼠标双击事件setMouseTracking(true)  设置获取全局移动信息,不需要点击按钮获取鼠标消息
e->accept() 声明接收了该消息return true 处理了该消息 该操作意味着在此窗口处理了的消息,父窗口将不再接收该消息,
e->ignore() 声明忽略该消息return false  不处理该消息该操作会继续传递消息

鼠标事件

ev->button() 获取鼠标按键cursor() 当前光标ev->angleDelta() 获取鼠标滚轮角度QEvent::MouseButtonPress 鼠标单击QEvent::MouseButtonDblClick 鼠标双击void mousePressEvent(QMouseEvent*ev); 鼠标点击事件void mouseReleaseEvent(QMouseEvent * ev) 鼠标释放事件void mouseMoveEvent(QMouseEvent*ev)  鼠标移动事件void wheelEvent(QWheelEvent *ev) 鼠标滚轮事件void mouseDoubleClickEvent(QMouseEvent *ev) 鼠标双击事件void enterEvent(QEvent *ev) 鼠标进入窗口事件 void leaveEvent(QEvent *ev) 鼠标离开窗口事件

键盘事件

             切换原因setFocus(Qt::OtherFocusReason) 设置焦点void keyPressEvent(QKeyEvent *ev)  键盘按下事件void keyReleaseEvent(QKeyEvent *ev)  键盘释放事件ev->key()  键盘按钮ev->text() 键盘输入的文本

事件拦截

生成对象的时候,安装拦截消息泵button->installEventFilter(this);获取拦截消息                         拦截对象   消息bool eventFilter(QObject*,QEvent*);  返回true表示拦截已处理该消息

paintEvent

基础绘制

void paintEvent(QPintEvent*);Qt::KeepAspectRatio   保存方形Qt::SmoothTransformation  设置平滑 // 画笔                  颜色             宽度    实线//QPen *pen = new QPen(QBrush("#00000000"),200,Qt::DashLine);QPen *pen = new QPen(QBrush(Qt::black),2,Qt::DashLine);QPainter painter;painter.begin(this);painter.setPen(*pen)  设置笔painter.setBrush(QBrush(Qt::blue, Qt::Dense1Pattern)); 设置画刷painter.drawPoint(width()/2, height()/2)   点painter.drawLine(width() / 2, height() / 2, width(), sizeHint().height())  线painter.rotate(10)   旋转坐标painter.scale(0, 0)  缩放painter.translate(100, 1)  原点坐标转换 即原点移动到目标点painter.drawRect(100, 100, 100, 100)   绘制矩形painter.save()  保存画家painter.restore() 恢复画家painter.drawEllipse(100, 100, 200, 300)  椭圆painter.drawText(300, 300, "")  绘制文本QPixmap pixmap("C:/Users/15187/Desktop/MINE.png");//                                  保存方形                    设置平滑pixmap = pixmap.scaled(200,200,Qt::KeepAspectRatio,Qt::SmoothTransformation);painter.drawPixmap(QPoint(100, 100), pixmap);QImage image("C:/Users/15187/Desktop/MINE.png");image = image.scaled(200, 200, Qt::KeepAspectRatio, Qt::SmoothTransformation);painter.drawImage(100, 100, image);painter.end();this->repaint(100, 100, 100, 100);//重绘局部this->update(); // 重绘全局

QPainter

对象上绘制

QPixmap pixmap(this->size());pixmap.fill(Qt::white);//填充白色pixmap.fill("#00000000");//填充透明QPainter painter(&pixmap);painter.setBrush(Qt::black);painter.drawRect(100, 100, 100, 100);painter.end();   pixmap.save("C:/Users/15187/Desktop/MINE2.png");   保存图像文件
// 无损透明,不压缩,原生像素// 32位深度解析QImage image(this->size(), QImage::Format_ARGB32_Premultiplied);image.fill("#00000000");//填充透明QPainter painter(&image);painter.setBrush(Qt::black);painter.drawRect(100, 100, 200, 200);painter.end();image.save("C:/Users/15187/Desktop/MINE3.png")
该对象只为记录画家动作,并非像素 记录QPicture pic;QPainter painter(&pic);painter.setBrush(Qt::black);painter.drawRect(100, 100, 200, 200);painter.end();pic.save("C:/Users/15187/Desktop/MINE4.png"); 打开QPicture pic;// 记录画家动作,并非记录像素,pic.load(QString("C:/Users/15187/Desktop/MINE4.png"));QPainter painter(this);painter.drawPicture(100, 100, pic);painter.end();
实现橡皮擦API

方法一: 通过使用组合模式实现橡皮擦功能

pain->setCompositionMode( QPainter::CompositionMode_Clear );// 组合模型,此为组合清除,因组合为空白,pain->fillRect(start_.x(),start_.y(),end_.x(),end_.y() ,Qt::SolidPattern );

方法二 :通过设置像素点实现橡皮擦功能

for (int i = start_.x(); i < start_.x() + end_.x(); ++i){        for (int j = start_.y(); j < start_.y() + end_.y(); ++j){            value_->setPixel(i, j, 0);// 着色,设置像素点为透明        }    }

窗口隐藏

this->setWindowFlag(Qt::FramelessWindowHint); // 隐藏标题框this->setAttribute(Qt::WA_TranslucentBackground);//透明背景this->setWindowFlag(Qt::Tool);   任务栏隐藏QPushButton::setFlat(ture); 按钮透明

定时器

QTimer *timer = new QTimer(this);connect(timer,SIGNAL(timeout()),this,SLOT(timeOutSlot()));timer->start(100);//启动时间,重复timer->stop();停止

多线程

线程的使用方式

方法一

继承自 QThread

重写run函数,在该函数内调用线程的工作内容void run() QThread::currentThreadId()  当前线程的ID 启动创建一个由QThread派生的对象,调用Object::start(),线程启动Object::isRunning() 返回线程是否在运行Object::quit() 给线程消息队列发送退出消息,处理完消息之后将会退出Qbject::wait() 等待对象处理消息,阻塞型函数,返回当前程序的消息处理情况,处理完返回true,否则返回falseQThread::sleep(1) 睡眠一秒```~<div class="se-preview-section-delimiter"></div>#### 方法二继承QObject, 通过移动对象到线程里面,实现线程通过发送信号的方式来让线程处理事件<div class="se-preview-section-delimiter"></div>

class object:QObject
{
thread_ = new QThread(this) QThread对象可以指定一个父对象来托管内存
work_ = new myWork(“thread”)
work_->moveToThread(thread_) moveToThread work_不能有父窗口 移动对象到线程内
connect(button,SIGNAL(clicked()),work_,SLOT(workding()));
// finished 线程退出之前会发出该信号
connect(thread_, SIGNAL(finished()), work_, SLOT(deleteLater())); 需要在线程退出之前,发送信号处理需要释放的动作
thread_->start() 线程启动
}
~object(){
thread_->quit();
thread_->wait()
}
线程在启动的时候会发出一个started() 的信号

<div class="se-preview-section-delimiter"></div>### 线程同步/线程锁线程同步不是同时,而是有序进行<div class="se-preview-section-delimiter"></div>#### 互斥锁<div class="se-preview-section-delimiter"></div>

阻塞型
临界资源
qMutex_->lock();上锁
int temp = *value_;
temp++;
*value_ = temp;
qMutex_->unlock();解锁

非阻塞
尝试拿锁,成功返回true,失败返回false
while (!qMutex_->tryLock(1000))// 尝试获取锁, 单位毫秒
{
do Other soming;
}
qMutex_->unlock();

<div class="se-preview-section-delimiter"></div>#### 智能锁<div class="se-preview-section-delimiter"></div>

{
智能锁
QMutexLocker lock(qMutex_);// 栈区临时对象,释放的时候才解锁 ,在原有的锁上自动管理锁
构造的时候拿锁,释放的时候解锁,阻塞
}

<div class="se-preview-section-delimiter"></div>#### 信号量<div class="se-preview-section-delimiter"></div>

QSemaphore *sem_ = new QSemaphore(3); //资源访问者个数
sem_->acquire(1);// 占用者数量 或者 sem_->acquirc() 信号量部位0的时候,调用这个函数会让信号量‐1,一旦信号量为零,阻塞等待
qDebug() << FUNCTION << name<< ” get lock ” << endl;
QThread::sleep(5);
sem_->release(1);// 释放占用的位置 使信号量+1
qDebug() << FUNCTION << name << ” unlock ” << endl;

<div class="se-preview-section-delimiter"></div>###  表格视图控件<div class="se-preview-section-delimiter"></div>#### model<div class="se-preview-section-delimiter"></div>

QStandardItemModel *model = new QStandardItemModel; 创建数据模型
this->setModel(model); 为窗口添加数据模型

<div class="se-preview-section-delimiter"></div>#### view<div class="se-preview-section-delimiter"></div>

继承自 QTableView
class object:public QTableView;

<div class="se-preview-section-delimiter"></div>#### control<div class="se-preview-section-delimiter"></div>##### 插入<div class="se-preview-section-delimiter"></div>

model->setColumnCount(3);//列数
model->setHeaderData(0,Qt::Horizontal,”Name”);// 表名
model->setHeaderData(1,Qt::Horizontal,”年龄”);// 表名
model->setHeaderData(2,Qt::Horizontal,”性别”);// 表名
model->setRowCount(2);//行数
model->setHeaderData(0,Qt::Vertical,”用户1”);// 表名
model->setHeaderData(1,Qt::Vertical,”用户2”);//
model->setItem(0,0,new QStandardItem(TOUTF8(“詹三”)));
model->setItem(0,1,new QStandardItem(TOUTF8(“20”)));
model->setItem(0,2,new QStandardItem(TOUTF8(“男”))
model->setItem(1,0,new QStandardItem(TOUTF8(“李四”)));
model->setItem(1,1,new QStandardItem(TOUTF8(“21”)));
model->setItem(1,2,new QStandardItem(TOUTF8(“男”))

<div class="se-preview-section-delimiter"></div>##### 获取用户操作通过信号来获取需要的事件<div class="se-preview-section-delimiter"></div>

QList

原创粉丝点击